changeset 4597:78a1636e68b1 8.0-b102

Merge
author ngthomas
date Tue, 06 Aug 2013 14:14:24 -0700
parents a010db088f27 324f1d41fc48
children 19197d39ad7f 97666cdda3fd
files apps/samples/Ensemble8/src/samples/java/ensemble/samples/controls/table/tablecellfactory/CheckBoxTableCell.java apps/samples/Ensemble8/src/samples/java/ensemble/samples/controls/table/tablecellfactory/EditingCell.java modules/graphics/src/android/java/com/oracle/dalvik/MainActivity.java modules/graphics/src/main/java/com/sun/javafx/tk/quantum/PopupScene.java modules/graphics/src/main/java/com/sun/javafx/tk/quantum/PopupStage.java netbeans/android/glass-lib-lens/Android.mk netbeans/android/glass-lib-lens/nbproject/configurations.xml netbeans/android/glass-lib-lens/nbproject/project.xml
diffstat 159 files changed, 12808 insertions(+), 1434 deletions(-) [+]
line wrap: on
line diff
--- a/.classpath	Tue Aug 06 10:13:00 2013 -0700
+++ b/.classpath	Tue Aug 06 14:14:24 2013 -0700
@@ -1,11 +1,19 @@
 <classpath>
   <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+  <classpathentry kind="src" path="tests/manual/RegionTests/src/main/java"/>
+  <classpathentry kind="src" path="tests/manual/RegionTests/src/main/resources"/>
+
+  <classpathentry kind="src" exported="true" path="/web"/>
   <classpathentry kind="src" exported="true" path="/fxml"/>
   <classpathentry kind="src" exported="true" path="/fxpackager"/>
   <classpathentry kind="src" exported="true" path="/swt"/>
   <classpathentry kind="src" exported="true" path="/swing"/>
   <classpathentry kind="src" exported="true" path="/media"/>
-  <classpathentry kind="src" exported="true" path="/web"/>
   <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+  <classpathentry kind="lib" exported="true" path="../caches/sdk/rt/lib/ext/jfxrt.jar">
+    <attributes>
+      <attribute name="optional" value="true"/>
+    </attributes>
+  </classpathentry>
   <classpathentry kind="output" path="bin"/>
 </classpath>
--- a/apps/samples/Ensemble8/src/generated/java/ensemble/generated/Samples.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/apps/samples/Ensemble8/src/generated/java/ensemble/generated/Samples.java	Tue Aug 06 14:14:24 2013 -0700
@@ -18,26 +18,26 @@
     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_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/AudioAreaChart.css","/ensemble/samples/charts/area/audio/AudioAreaChartApp.java",},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_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[]{});
-    private static final SampleInfo SAMPLE_16 = new SampleInfo("Curve-Fitted Area Chart","An area chart that demonstrates curve fitting. Styling is done through CSS. ","/Charts/Area/Curve-Fitted Area Chart","/ensemble/samples/charts/area/curvefitted","ensemble.samples.charts.area.curvefitted.CurveFittedAreaChartApp","/ensemble/samples/charts/area/curvefitted/preview.png",new String[]{"/ensemble/samples/charts/area/curvefitted/CurveFittedAreaChart.css","/ensemble/samples/charts/area/curvefitted/CurveFittedAreaChart.java","/ensemble/samples/charts/area/curvefitted/CurveFittedAreaChartApp.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/Area/Area Chart",},"/ensemble/samples/charts/area/curvefitted/CurveFittedAreaChartApp.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","-10000","max","10000","step","1"),new PlaygroundProperty("xAxis","upperBound","min","-10000","max","10000","step","1"),new PlaygroundProperty("xAxis","tickUnit","max","10000","step","1"),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","-1000","max","1000","step","1"),new PlaygroundProperty("yAxis","upperBound","min","-1000","max","2000","step","1"),new PlaygroundProperty("yAxis","tickUnit","max","1000","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","step","1"),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[]{});
+    private static final SampleInfo SAMPLE_16 = new SampleInfo("Curve-Fitted Area Chart","An area chart that demonstrates curve fitting. Styling is done through CSS. ","/Charts/Area/Curve-Fitted Area Chart","/ensemble/samples/charts/area/curvefitted","ensemble.samples.charts.area.curvefitted.CurveFittedAreaChartApp","/ensemble/samples/charts/area/curvefitted/preview.png",new String[]{"/ensemble/samples/charts/area/curvefitted/CurveFittedAreaChart.java","/ensemble/samples/charts/area/curvefitted/CurveFittedAreaChartApp.java","/ensemble/samples/charts/area/curvefitted/CurveFittedAreaChart.css",},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/Area/Area Chart",},"/ensemble/samples/charts/area/curvefitted/CurveFittedAreaChartApp.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","-10000","max","10000","step","1"),new PlaygroundProperty("xAxis","upperBound","min","-10000","max","10000","step","1"),new PlaygroundProperty("xAxis","tickUnit","max","10000","step","1"),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","-1000","max","1000","step","1"),new PlaygroundProperty("yAxis","upperBound","min","-1000","max","2000","step","1"),new PlaygroundProperty("yAxis","tickUnit","max","1000","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","step","1"),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[]{});
     private static final SampleInfo SAMPLE_17 = new SampleInfo("Stacked Area Chart","A sample that displays data in a stacked area chart. ","/Charts/Area/Stacked Area Chart","/ensemble/samples/charts/area/stacked","ensemble.samples.charts.area.stacked.StackedAreaChartApp","/ensemble/samples/charts/area/stacked/preview.png",new String[]{"/ensemble/samples/charts/area/stacked/StackedAreaChartApp.java",},new String[]{"javafx.scene.chart.StackedAreaChart","javafx.scene.chart.NumberAxis",},new String[]{"http://docs.oracle.com/javafx/2/charts/jfxpub-charts.htm","Using JavaFX Charts Tutorial",},new String[]{"/Charts/Area/Area Chart",},"/ensemble/samples/charts/area/stacked/StackedAreaChartApp.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"),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","20","step","1"),new PlaygroundProperty("yAxis","upperBound","min","-10","max","40","step","1"),new PlaygroundProperty("yAxis","tickUnit","max","10"),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","step","1"),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[]{});
-    private static final SampleInfo SAMPLE_18 = new SampleInfo("Audio Bar Chart","Bar chart that shows audio spectrum of a music file being played. ","/Charts/Bar/Audio Bar Chart","/ensemble/samples/charts/bar/audio","ensemble.samples.charts.bar.audio.AudioBarChartApp","/ensemble/samples/charts/bar/audio/preview.png",new String[]{"/ensemble/samples/charts/bar/audio/AudioBarChart.css","/ensemble/samples/charts/bar/audio/AudioBarChartApp.java",},new String[]{"javafx.scene.chart.BarChart","javafx.scene.chart.Chart","javafx.scene.chart.CategoryAxis","javafx.scene.chart.NumberAxis","javafx.scene.chart.XYChart","javafx.scene.media.AudioSpectrumListener","javafx.scene.media.Media","javafx.scene.media.MediaPlayer",},new String[]{},new String[]{},"/ensemble/samples/charts/bar/audio/AudioBarChartApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{ConditionalFeature.WEB,});
+    private static final SampleInfo SAMPLE_18 = new SampleInfo("Audio Bar Chart","Bar chart that shows audio spectrum of a music file being played. ","/Charts/Bar/Audio Bar Chart","/ensemble/samples/charts/bar/audio","ensemble.samples.charts.bar.audio.AudioBarChartApp","/ensemble/samples/charts/bar/audio/preview.png",new String[]{"/ensemble/samples/charts/bar/audio/AudioBarChartApp.java","/ensemble/samples/charts/bar/audio/AudioBarChart.css",},new String[]{"javafx.scene.chart.BarChart","javafx.scene.chart.Chart","javafx.scene.chart.CategoryAxis","javafx.scene.chart.NumberAxis","javafx.scene.chart.XYChart","javafx.scene.media.AudioSpectrumListener","javafx.scene.media.Media","javafx.scene.media.MediaPlayer",},new String[]{},new String[]{},"/ensemble/samples/charts/bar/audio/AudioBarChartApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{ConditionalFeature.WEB,});
     private static final SampleInfo SAMPLE_19 = new SampleInfo("Bar Chart","A chart that displays rectangular bars with heights indicating data values for categories. Used for displaying information when at least one axis has discontinuous or discrete data. ","/Charts/Bar/Bar Chart","/ensemble/samples/charts/bar/chart","ensemble.samples.charts.bar.chart.BarChartApp","/ensemble/samples/charts/bar/chart/preview.png",new String[]{"/ensemble/samples/charts/bar/chart/BarChartApp.java",},new String[]{"javafx.scene.chart.BarChart","javafx.scene.chart.CategoryAxis","javafx.scene.chart.NumberAxis",},new String[]{"http://docs.oracle.com/javafx/2/charts/jfxpub-charts.htm","Using JavaFX Charts Tutorial",},new String[]{"/Charts/Area/Area Chart","/Charts/Line/Line Chart","/Charts/Scatter/Scatter Chart",},"/ensemble/samples/charts/bar/chart/BarChartApp.java",new PlaygroundProperty[]{new PlaygroundProperty("chart","data"),new PlaygroundProperty(null,"-","name","xAxis"),new PlaygroundProperty("xAxis","autoRanging"),new PlaygroundProperty("xAxis","gapStartAndEnd"),new PlaygroundProperty("xAxis","startMargin"),new PlaygroundProperty("xAxis","endMargin"),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","-1000","max","3000","step","1"),new PlaygroundProperty("yAxis","upperBound","max","4000","step","1"),new PlaygroundProperty("yAxis","tickUnit","max","3000","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","step","1"),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[]{});
     private static final SampleInfo SAMPLE_20 = new SampleInfo("Horizontal Bar Chart","Horizontal bar chart with a variety of actions and settable properties for experimenting with the charts features. ","/Charts/Bar/Horizontal Bar Chart","/ensemble/samples/charts/bar/horizontal","ensemble.samples.charts.bar.horizontal.HorizontalBarChartApp","/ensemble/samples/charts/bar/horizontal/preview.png",new String[]{"/ensemble/samples/charts/bar/horizontal/HorizontalBarChartApp.java",},new String[]{"javafx.scene.chart.BarChart","javafx.scene.chart.CategoryAxis","javafx.scene.chart.NumberAxis",},new String[]{},new String[]{},"/ensemble/samples/charts/bar/horizontal/HorizontalBarChartApp.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","-1000","max","3000","step","1"),new PlaygroundProperty("xAxis","upperBound","max","4000","step","1"),new PlaygroundProperty("xAxis","tickUnit","max","3000","step","1"),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","gapStartAndEnd"),new PlaygroundProperty("yAxis","startMargin"),new PlaygroundProperty("yAxis","endMargin"),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","step","1"),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[]{});
-    private static final SampleInfo SAMPLE_21 = new SampleInfo("Image Bar Chart","A bar chart that uses CSS to display stacks of car images to indicate data values for categories. ","/Charts/Bar/Image Bar Chart","/ensemble/samples/charts/bar/image","ensemble.samples.charts.bar.image.ImageBarChartApp","/ensemble/samples/charts/bar/image/preview.png",new String[]{"/ensemble/samples/charts/bar/image/ImageBarChart.css","/ensemble/samples/charts/bar/image/ImageBarChartApp.java","/ensemble/samples/charts/bar/image/sedan-s.png","/ensemble/samples/charts/bar/image/suv-s.png","/ensemble/samples/charts/bar/image/truck-s.png","/ensemble/samples/charts/bar/image/van-s.png",},new String[]{"javafx.scene.chart.BarChart","javafx.scene.chart.CategoryAxis","javafx.scene.chart.NumberAxis",},new String[]{},new String[]{},"/ensemble/samples/charts/bar/image/ImageBarChartApp.java",new PlaygroundProperty[]{new PlaygroundProperty("chart","data"),new PlaygroundProperty(null,"-","name","xAxis"),new PlaygroundProperty("xAxis","autoRanging"),new PlaygroundProperty("xAxis","gapStartAndEnd"),new PlaygroundProperty("xAxis","startMargin"),new PlaygroundProperty("xAxis","endMargin"),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","-100","max","0","step","1"),new PlaygroundProperty("yAxis","upperBound","max","200","step","1"),new PlaygroundProperty("yAxis","tickUnit","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","step","1"),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[]{});
+    private static final SampleInfo SAMPLE_21 = new SampleInfo("Image Bar Chart","A bar chart that uses CSS to display stacks of car images to indicate data values for categories. ","/Charts/Bar/Image Bar Chart","/ensemble/samples/charts/bar/image","ensemble.samples.charts.bar.image.ImageBarChartApp","/ensemble/samples/charts/bar/image/preview.png",new String[]{"/ensemble/samples/charts/bar/image/ImageBarChartApp.java","/ensemble/samples/charts/bar/image/ImageBarChart.css","/ensemble/samples/charts/bar/image/sedan-s.png","/ensemble/samples/charts/bar/image/suv-s.png","/ensemble/samples/charts/bar/image/truck-s.png","/ensemble/samples/charts/bar/image/van-s.png",},new String[]{"javafx.scene.chart.BarChart","javafx.scene.chart.CategoryAxis","javafx.scene.chart.NumberAxis",},new String[]{},new String[]{},"/ensemble/samples/charts/bar/image/ImageBarChartApp.java",new PlaygroundProperty[]{new PlaygroundProperty("chart","data"),new PlaygroundProperty(null,"-","name","xAxis"),new PlaygroundProperty("xAxis","autoRanging"),new PlaygroundProperty("xAxis","gapStartAndEnd"),new PlaygroundProperty("xAxis","startMargin"),new PlaygroundProperty("xAxis","endMargin"),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","-100","max","0","step","1"),new PlaygroundProperty("yAxis","upperBound","max","200","step","1"),new PlaygroundProperty("yAxis","tickUnit","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","step","1"),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[]{});
     private static final SampleInfo SAMPLE_22 = new SampleInfo("Stacked Bar Chart","A sample that displays data in a stacked bar chart. ","/Charts/Bar/Stacked Bar Chart","/ensemble/samples/charts/bar/stacked","ensemble.samples.charts.bar.stacked.StackedBarChartApp","/ensemble/samples/charts/bar/stacked/preview.png",new String[]{"/ensemble/samples/charts/bar/stacked/StackedBarChartApp.java",},new String[]{"javafx.scene.chart.StackedBarChart","javafx.scene.chart.CategoryAxis","javafx.scene.chart.NumberAxis",},new String[]{},new String[]{"/Charts/Bar/Bar Chart",},"/ensemble/samples/charts/bar/stacked/StackedBarChartApp.java",new PlaygroundProperty[]{new PlaygroundProperty("chart","data"),new PlaygroundProperty(null,"-","name","xAxis"),new PlaygroundProperty("xAxis","autoRanging"),new PlaygroundProperty("xAxis","gapStartAndEnd"),new PlaygroundProperty("xAxis","startMargin"),new PlaygroundProperty("xAxis","endMargin"),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","-3000","max","0","step","1"),new PlaygroundProperty("yAxis","upperBound","min","0","max","8000","step","1"),new PlaygroundProperty("yAxis","tickUnit","max","5000","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","step","1"),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[]{});
     private static final SampleInfo SAMPLE_23 = new SampleInfo("Bubble Chart","An advanced bubble chart with a variety of actions and settable properties. ","/Charts/Bubble/Bubble Chart","/ensemble/samples/charts/bubble/chart","ensemble.samples.charts.bubble.chart.BubbleChartApp","/ensemble/samples/charts/bubble/chart/preview.png",new String[]{"/ensemble/samples/charts/bubble/chart/BubbleChartApp.java",},new String[]{"javafx.scene.chart.BubbleChart","javafx.scene.chart.NumberAxis",},new String[]{},new String[]{"/Charts/Scatter/Advanced Scatter Chart",},"/ensemble/samples/charts/bubble/chart/BubbleChartApp.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","-100","max","100","step","1"),new PlaygroundProperty("xAxis","upperBound","min","0","max","200","step","1"),new PlaygroundProperty("xAxis","tickUnit","step","1"),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"),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","-100","max","100","step","1"),new PlaygroundProperty("yAxis","upperBound","min","0","max","200","step","1"),new PlaygroundProperty("yAxis","tickUnit","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[]{});
-    private static final SampleInfo SAMPLE_24 = new SampleInfo("Candle Stick Chart","A custom candlestick chart. This sample shows how to extend XYChart base class to create your own two axis chart type. ","/Charts/Custom/Candle Stick Chart","/ensemble/samples/charts/custom/candlestick","ensemble.samples.charts.custom.candlestick.CandleStickChartApp","/ensemble/samples/charts/custom/candlestick/preview.png",new String[]{"/ensemble/samples/charts/custom/candlestick/Candle.java","/ensemble/samples/charts/custom/candlestick/CandleStickChart.css","/ensemble/samples/charts/custom/candlestick/CandleStickChart.java","/ensemble/samples/charts/custom/candlestick/CandleStickChartApp.java","/ensemble/samples/charts/custom/candlestick/CandleStickExtraValues.java","/ensemble/samples/charts/custom/candlestick/TooltipContent.java",},new String[]{"javafx.scene.chart.NumberAxis","javafx.scene.chart.XYChart",},new String[]{"http://docs.oracle.com/javafx/2/charts/jfxpub-charts.htm","Using JavaFX Charts Tutorial",},new String[]{"/Charts/Scatter/Scatter Chart","/Charts/Scatter/Advanced Scatter Chart",},"/ensemble/samples/charts/custom/candlestick/CandleStickChartApp.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","-100","max","100","step","1"),new PlaygroundProperty("xAxis","upperBound","step","1"),new PlaygroundProperty("xAxis","tickUnit","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","-100","max","30","step","1"),new PlaygroundProperty("yAxis","upperBound","step","1"),new PlaygroundProperty("yAxis","tickUnit","step","0.5"),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","step","1"),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[]{});
+    private static final SampleInfo SAMPLE_24 = new SampleInfo("Candle Stick Chart","A custom candlestick chart. This sample shows how to extend XYChart base class to create your own two axis chart type. ","/Charts/Custom/Candle Stick Chart","/ensemble/samples/charts/custom/candlestick","ensemble.samples.charts.custom.candlestick.CandleStickChartApp","/ensemble/samples/charts/custom/candlestick/preview.png",new String[]{"/ensemble/samples/charts/custom/candlestick/Candle.java","/ensemble/samples/charts/custom/candlestick/CandleStickChart.java","/ensemble/samples/charts/custom/candlestick/CandleStickChartApp.java","/ensemble/samples/charts/custom/candlestick/CandleStickExtraValues.java","/ensemble/samples/charts/custom/candlestick/TooltipContent.java","/ensemble/samples/charts/custom/candlestick/CandleStickChart.css",},new String[]{"javafx.scene.chart.NumberAxis","javafx.scene.chart.XYChart",},new String[]{"http://docs.oracle.com/javafx/2/charts/jfxpub-charts.htm","Using JavaFX Charts Tutorial",},new String[]{"/Charts/Scatter/Scatter Chart","/Charts/Scatter/Advanced Scatter Chart",},"/ensemble/samples/charts/custom/candlestick/CandleStickChartApp.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","-100","max","100","step","1"),new PlaygroundProperty("xAxis","upperBound","step","1"),new PlaygroundProperty("xAxis","tickUnit","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","-100","max","30","step","1"),new PlaygroundProperty("yAxis","upperBound","step","1"),new PlaygroundProperty("yAxis","tickUnit","step","0.5"),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","step","1"),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[]{});
     private static final SampleInfo SAMPLE_25 = new SampleInfo("Category Line Chart","A line chart demonstrating a CategoryAxis implementation. ","/Charts/Line/Category Line Chart","/ensemble/samples/charts/line/category","ensemble.samples.charts.line.category.CategoryLineChartApp","/ensemble/samples/charts/line/category/preview.png",new String[]{"/ensemble/samples/charts/line/category/CategoryLineChartApp.java",},new String[]{"javafx.scene.chart.CategoryAxis","javafx.scene.chart.LineChart","javafx.scene.chart.NumberAxis",},new String[]{"http://docs.oracle.com/javafx/2/charts/jfxpub-charts.htm","Using JavaFX Charts Tutorial",},new String[]{},"/ensemble/samples/charts/line/category/CategoryLineChartApp.java",new PlaygroundProperty[]{new PlaygroundProperty("chart","data"),new PlaygroundProperty(null,"-","name","xAxis"),new PlaygroundProperty("xAxis","autoRanging"),new PlaygroundProperty("xAxis","gapStartAndEnd"),new PlaygroundProperty("xAxis","startMargin"),new PlaygroundProperty("xAxis","endMargin"),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","-100","step","1"),new PlaygroundProperty("yAxis","upperBound","max","200","step","1"),new PlaygroundProperty("yAxis","tickUnit","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","step","1"),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[]{});
     private static final SampleInfo SAMPLE_26 = new SampleInfo("Line Chart","A chart in which lines connect a series of data points. Useful for viewing data trends over time. ","/Charts/Line/Line Chart","/ensemble/samples/charts/line/chart","ensemble.samples.charts.line.chart.LineChartApp","/ensemble/samples/charts/line/chart/preview.png",new String[]{"/ensemble/samples/charts/line/chart/LineChartApp.java",},new String[]{"javafx.scene.chart.LineChart","javafx.scene.chart.NumberAxis",},new String[]{"http://docs.oracle.com/javafx/2/charts/jfxpub-charts.htm","Using JavaFX Charts Tutorial",},new String[]{"/Charts/Area/Area Chart","/Charts/Scatter/Scatter Chart",},"/ensemble/samples/charts/line/chart/LineChartApp.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","0.2"),new PlaygroundProperty("xAxis","upperBound","max","10","step","0.2"),new PlaygroundProperty("xAxis","tickUnit","max","3","step","0.2"),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","-5","max","5","step","0.2"),new PlaygroundProperty("yAxis","upperBound","max","10","step","0.2"),new PlaygroundProperty("yAxis","tickUnit","max","3","step","0.2"),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","step","1"),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[]{});
-    private static final SampleInfo SAMPLE_27 = new SampleInfo("Stock Line Chart","A simulated stock line chart. ","/Charts/Line/Stock Line Chart","/ensemble/samples/charts/line/stock","ensemble.samples.charts.line.stock.StockLineChartApp","/ensemble/samples/charts/line/stock/preview.png",new String[]{"/ensemble/samples/charts/line/stock/StockLineChart.css","/ensemble/samples/charts/line/stock/StockLineChartApp.java",},new String[]{"javafx.scene.chart.LineChart","javafx.scene.chart.NumberAxis",},new String[]{"http://docs.oracle.com/javafx/2/charts/jfxpub-charts.htm","Using JavaFX Charts Tutorial",},new String[]{},"/ensemble/samples/charts/line/stock/StockLineChartApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_27 = new SampleInfo("Stock Line Chart","A simulated stock line chart. ","/Charts/Line/Stock Line Chart","/ensemble/samples/charts/line/stock","ensemble.samples.charts.line.stock.StockLineChartApp","/ensemble/samples/charts/line/stock/preview.png",new String[]{"/ensemble/samples/charts/line/stock/StockLineChartApp.java","/ensemble/samples/charts/line/stock/StockLineChart.css",},new String[]{"javafx.scene.chart.LineChart","javafx.scene.chart.NumberAxis",},new String[]{"http://docs.oracle.com/javafx/2/charts/jfxpub-charts.htm","Using JavaFX Charts Tutorial",},new String[]{},"/ensemble/samples/charts/line/stock/StockLineChartApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_28 = new SampleInfo("Pie Chart","A circular chart divided into segments. The value of each segment represents a proportion of the total. ","/Charts/Pie/Pie Chart","/ensemble/samples/charts/pie/chart","ensemble.samples.charts.pie.chart.PieChartApp","/ensemble/samples/charts/pie/chart/preview.png",new String[]{"/ensemble/samples/charts/pie/chart/PieChartApp.java",},new String[]{"javafx.scene.chart.PieChart",},new String[]{},new String[]{},"/ensemble/samples/charts/pie/chart/PieChartApp.java",new PlaygroundProperty[]{new PlaygroundProperty("chart","data"),new PlaygroundProperty("chart","clockwise"),new PlaygroundProperty("chart","labelLineLength"),new PlaygroundProperty("chart","labelsVisible"),new PlaygroundProperty("chart","startAngle","max","360"),new PlaygroundProperty("chart","animated"),new PlaygroundProperty("chart","legendSide"),new PlaygroundProperty("chart","legendVisible"),new PlaygroundProperty("chart","title"),new PlaygroundProperty("chart","titleSide"),},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_29 = new SampleInfo("Drilldown Pie Chart","A pie chart that provides the ability to drill down through data. Selecting a segment in the initial pie chart causes the pie chart to display detailed data for the selected segment. ","/Charts/Pie/Drilldown Pie Chart","/ensemble/samples/charts/pie/drilldown","ensemble.samples.charts.pie.drilldown.DrilldownPieChartApp","/ensemble/samples/charts/pie/drilldown/preview.png",new String[]{"/ensemble/samples/charts/pie/drilldown/DrilldownChart.css","/ensemble/samples/charts/pie/drilldown/DrilldownPieChartApp.java",},new String[]{"javafx.event.EventHandler","javafx.scene.chart.PieChart","javafx.scene.input.MouseEvent",},new String[]{},new String[]{},"/ensemble/samples/charts/pie/drilldown/DrilldownPieChartApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_30 = new SampleInfo("Live Scatter Chart","A live scatter chart. ","/Charts/Scatter/Live Scatter Chart","/ensemble/samples/charts/scatter/animated","ensemble.samples.charts.scatter.animated.LiveScatterChartApp","/ensemble/samples/charts/scatter/animated/preview.png",new String[]{"/ensemble/samples/charts/scatter/animated/LiveScatterChart.css","/ensemble/samples/charts/scatter/animated/LiveScatterChartApp.java",},new String[]{"javafx.scene.chart.ScatterChart","javafx.scene.chart.NumberAxis","javafx.animation.Timeline","javafx.animation.SequentialTransition",},new String[]{},new String[]{},"/ensemble/samples/charts/scatter/animated/LiveScatterChartApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_29 = new SampleInfo("Drilldown Pie Chart","A pie chart that provides the ability to drill down through data. Selecting a segment in the initial pie chart causes the pie chart to display detailed data for the selected segment. ","/Charts/Pie/Drilldown Pie Chart","/ensemble/samples/charts/pie/drilldown","ensemble.samples.charts.pie.drilldown.DrilldownPieChartApp","/ensemble/samples/charts/pie/drilldown/preview.png",new String[]{"/ensemble/samples/charts/pie/drilldown/DrilldownPieChartApp.java","/ensemble/samples/charts/pie/drilldown/DrilldownChart.css",},new String[]{"javafx.event.EventHandler","javafx.scene.chart.PieChart","javafx.scene.input.MouseEvent",},new String[]{},new String[]{},"/ensemble/samples/charts/pie/drilldown/DrilldownPieChartApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_30 = new SampleInfo("Live Scatter Chart","A live scatter chart. ","/Charts/Scatter/Live Scatter Chart","/ensemble/samples/charts/scatter/animated","ensemble.samples.charts.scatter.animated.LiveScatterChartApp","/ensemble/samples/charts/scatter/animated/preview.png",new String[]{"/ensemble/samples/charts/scatter/animated/LiveScatterChartApp.java","/ensemble/samples/charts/scatter/animated/LiveScatterChart.css",},new String[]{"javafx.scene.chart.ScatterChart","javafx.scene.chart.NumberAxis","javafx.animation.Timeline","javafx.animation.SequentialTransition",},new String[]{},new String[]{},"/ensemble/samples/charts/scatter/animated/LiveScatterChartApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_31 = new SampleInfo("Scatter Chart","A chart that displays plotted symbols for a series of data points. Useful for viewing the distribution of data to see if there is any pattern, indicating a correlation. ","/Charts/Scatter/Scatter Chart","/ensemble/samples/charts/scatter/chart","ensemble.samples.charts.scatter.chart.ScatterChartApp","/ensemble/samples/charts/scatter/chart/preview.png",new String[]{"/ensemble/samples/charts/scatter/chart/ScatterChartApp.java",},new String[]{"javafx.scene.chart.ScatterChart","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/Area/Area Chart",},"/ensemble/samples/charts/scatter/chart/ScatterChartApp.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","0.25"),new PlaygroundProperty("xAxis","upperBound","max","20","step","0.25"),new PlaygroundProperty("xAxis","tickUnit","max","10","step","0.25"),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","-5","max","5","step","0.25"),new PlaygroundProperty("yAxis","upperBound","max","10","step","0.25"),new PlaygroundProperty("yAxis","tickUnit","max","10","step","0.25"),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","step","1"),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[]{});
     private static final SampleInfo SAMPLE_32 = new SampleInfo("Service","A sample showing use of a Service to retrieve data in a background thread. Selecting the Refresh button restarts the Service. ","/Concurrency/Service","/ensemble/samples/concurrency/service","ensemble.samples.concurrency.service.ServiceApp","/ensemble/samples/concurrency/service/preview.png",new String[]{"/ensemble/samples/concurrency/service/DailySales.java","/ensemble/samples/concurrency/service/GetDailySalesService.java","/ensemble/samples/concurrency/service/GetDailySalesTask.java","/ensemble/samples/concurrency/service/ServiceApp.java",},new String[]{"javafx.collections.FXCollections","javafx.concurrent.Service","javafx.concurrent.Task","javafx.scene.control.ProgressIndicator","javafx.scene.control.TableColumn","javafx.scene.control.TableView",},new String[]{},new String[]{},"/ensemble/samples/concurrency/service/ServiceApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_33 = new SampleInfo("Task","A sample showing use of an an asynchronous Task to populate a table. ","/Concurrency/Task","/ensemble/samples/concurrency/task","ensemble.samples.concurrency.task.TaskApp","/ensemble/samples/concurrency/task/preview.png",new String[]{"/ensemble/samples/concurrency/task/DailySales.java","/ensemble/samples/concurrency/task/GetDailySalesTask.java","/ensemble/samples/concurrency/task/TaskApp.java","/ensemble/samples/concurrency/task/TaskApp.java.orig","/ensemble/samples/concurrency/task/TaskApp.java.save",},new String[]{"javafx.collections.FXCollections","javafx.concurrent.Task","javafx.scene.control.ProgressIndicator","javafx.scene.control.TableColumn","javafx.scene.control.TableView",},new String[]{},new String[]{},"/ensemble/samples/concurrency/task/TaskApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_33 = new SampleInfo("Task","A sample showing use of an an asynchronous Task to populate a table. ","/Concurrency/Task","/ensemble/samples/concurrency/task","ensemble.samples.concurrency.task.TaskApp","/ensemble/samples/concurrency/task/preview.png",new String[]{"/ensemble/samples/concurrency/task/DailySales.java","/ensemble/samples/concurrency/task/GetDailySalesTask.java","/ensemble/samples/concurrency/task/TaskApp.java",},new String[]{"javafx.collections.FXCollections","javafx.concurrent.Task","javafx.scene.control.ProgressIndicator","javafx.scene.control.TableColumn","javafx.scene.control.TableView",},new String[]{},new String[]{},"/ensemble/samples/concurrency/task/TaskApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_34 = new SampleInfo("Accordion","An example of an accordion control. You can use accordion controls to define individual panes and  display them one at a time. ","/Controls/Accordion","/ensemble/samples/controls/accordion","ensemble.samples.controls.accordion.AccordionApp","/ensemble/samples/controls/accordion/preview.png",new String[]{"/ensemble/samples/controls/accordion/AccordionApp.java",},new String[]{"javafx.scene.control.Accordion",},new String[]{},new String[]{"/Controls/Toggle Button","/Controls/Toolbar/ToolBar",},"/ensemble/samples/controls/accordion/AccordionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_35 = new SampleInfo("Check Box","An example of CheckBoxes in various states. ","/Controls/Check Box","/ensemble/samples/controls/checkbox","ensemble.samples.controls.checkbox.CheckBoxApp","/ensemble/samples/controls/checkbox/preview.png",new String[]{"/ensemble/samples/controls/checkbox/CheckBoxApp.java",},new String[]{"javafx.scene.control.CheckBox",},new String[]{},new String[]{"/Controls/Radiobutton/Radio Button",},"/ensemble/samples/controls/checkbox/CheckBoxApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     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[]{});
@@ -53,29 +53,29 @@
     private static final SampleInfo SAMPLE_46 = new SampleInfo("TreeView","An implementation of the TreeView control displaying an expandable tree root node. ","/Controls/TreeView","/ensemble/samples/controls/treeview","ensemble.samples.controls.treeview.TreeViewApp","/ensemble/samples/controls/treeview/preview.png",new String[]{"/ensemble/samples/controls/treeview/TreeViewApp.java",},new String[]{"javafx.scene.control.TreeView",},new String[]{},new String[]{},"/ensemble/samples/controls/treeview/TreeViewApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_47 = new SampleInfo("Colored Buttons","An example of Buttons with different background colors. ","/Controls/Button/Colored Buttons","/ensemble/samples/controls/button/colorbutton","ensemble.samples.controls.button.colorbutton.ColorButtonApp","/ensemble/samples/controls/button/colorbutton/preview.png",new String[]{"/ensemble/samples/controls/button/colorbutton/ColorButtonApp.java",},new String[]{"javafx.scene.control.Button",},new String[]{},new String[]{"/Controls/Button/Graphic Button",},"/ensemble/samples/controls/button/colorbutton/ColorButtonApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_48 = new SampleInfo("Graphic Button","A button with an embedded image. ","/Controls/Button/Graphic Button","/ensemble/samples/controls/button/graphicbutton","ensemble.samples.controls.button.graphicbutton.GraphicButtonApp","/ensemble/samples/controls/button/graphicbutton/preview.png",new String[]{"/ensemble/samples/shared-resources/icon-48x48.png","/ensemble/samples/controls/button/graphicbutton/GraphicButtonApp.java",},new String[]{"javafx.scene.control.Button",},new String[]{},new String[]{"/Controls/Button/Colored Buttons",},"/ensemble/samples/controls/button/graphicbutton/GraphicButtonApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_49 = new SampleInfo("Pill Button","This sample demonstrates styling toggle buttons with CSS. ","/Controls/Button/Pill Button","/ensemble/samples/controls/button/pillbutton","ensemble.samples.controls.button.pillbutton.PillButtonApp","/ensemble/samples/controls/button/pillbutton/preview.png",new String[]{"/ensemble/samples/controls/button/pillbutton/PillButton.css","/ensemble/samples/controls/button/pillbutton/PillButton.css.good","/ensemble/samples/controls/button/pillbutton/PillButtonApp.java",},new String[]{"javafx.scene.control.ToggleButton",},new String[]{},new String[]{"/Controls/Button/Toggle Button",},"/ensemble/samples/controls/button/pillbutton/PillButtonApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_49 = new SampleInfo("Pill Button","This sample demonstrates styling toggle buttons with CSS. ","/Controls/Button/Pill Button","/ensemble/samples/controls/button/pillbutton","ensemble.samples.controls.button.pillbutton.PillButtonApp","/ensemble/samples/controls/button/pillbutton/preview.png",new String[]{"/ensemble/samples/controls/button/pillbutton/PillButtonApp.java","/ensemble/samples/controls/button/pillbutton/PillButton.css",},new String[]{"javafx.scene.control.ToggleButton",},new String[]{},new String[]{"/Controls/Button/Toggle Button",},"/ensemble/samples/controls/button/pillbutton/PillButtonApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_50 = new SampleInfo("HorizontalListView","A sample showing an implementation of the ListView control, in which a list of items is displayed in a horizontal row. ListView is a powerful multi-row 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 non-homogenous row heights. ","/Controls/Listview/HorizontalListView","/ensemble/samples/controls/listview/horizontallistview","ensemble.samples.controls.listview.horizontallistview.HorizontalListViewApp","/ensemble/samples/controls/listview/horizontallistview/preview.png",new String[]{"/ensemble/samples/controls/listview/horizontallistview/HorizontalListViewApp.java",},new String[]{"javafx.scene.control.ListView","javafx.scene.control.SelectionModel",},new String[]{},new String[]{"/Controls/Listview/ListViewCellFactory","/Controls/Listview/Simple ListView",},"/ensemble/samples/controls/listview/horizontallistview/HorizontalListViewApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_51 = new SampleInfo("ListViewCellFactory","A simple implementation of the ListView control that uses a CellFactory to customize the ListView cell contents. Positive values in the list are green, and negative values are red and enclosed in parentheses. Zero values are black. ","/Controls/Listview/ListViewCellFactory","/ensemble/samples/controls/listview/listviewcellfactory","ensemble.samples.controls.listview.listviewcellfactory.ListViewCellFactoryApp","/ensemble/samples/controls/listview/listviewcellfactory/preview.png",new String[]{"/ensemble/samples/controls/listview/listviewcellfactory/ListViewCellFactoryApp.java","/ensemble/samples/controls/listview/listviewcellfactory/MoneyFormatCell.java",},new String[]{"javafx.scene.control.ListView","javafx.scene.control.SelectionModel",},new String[]{},new String[]{"/Controls/Listview/HorizontalListView","/Controls/Listview/Simple ListView",},"/ensemble/samples/controls/listview/listviewcellfactory/ListViewCellFactoryApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     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/HiddenSplitPane.css","/ensemble/samples/controls/splitpane/hiddensplitpane/HiddenSplitPaneApp.java",},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/tab_16.png","/ensemble/samples/controls/tab/tabpane/TabPaneApp.java",},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 control to a table column and to enable editing of first/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","/ensemble/samples/controls/table/tablecellfactory/EditingCell.java","/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_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_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/InsetText.css","/ensemble/samples/controls/text/insettext/InsetTextApp.java",},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[]{});
-    private static final SampleInfo SAMPLE_59 = new SampleInfo("Search Box","A sample that demonstrates use of CSS to create a search box. ","/Controls/Text/Search Box","/ensemble/samples/controls/text/searchbox","ensemble.samples.controls.text.searchbox.SearchBoxApp","/ensemble/samples/controls/text/searchbox/preview.png",new String[]{"/ensemble/samples/controls/text/searchbox/SearchBox.css","/ensemble/samples/controls/text/searchbox/SearchBox.java","/ensemble/samples/controls/text/searchbox/SearchBoxApp.java",},new String[]{"javafx.scene.control.TextField",},new String[]{},new String[]{},"/ensemble/samples/controls/text/searchbox/SearchBoxApp.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[]{});
+    private static final SampleInfo SAMPLE_59 = new SampleInfo("Search Box","A sample that demonstrates use of CSS to create a search box. ","/Controls/Text/Search Box","/ensemble/samples/controls/text/searchbox","ensemble.samples.controls.text.searchbox.SearchBoxApp","/ensemble/samples/controls/text/searchbox/preview.png",new String[]{"/ensemble/samples/controls/text/searchbox/SearchBox.java","/ensemble/samples/controls/text/searchbox/SearchBoxApp.java","/ensemble/samples/controls/text/searchbox/SearchBox.css",},new String[]{"javafx.scene.control.TextField",},new String[]{},new String[]{},"/ensemble/samples/controls/text/searchbox/SearchBoxApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_60 = new SampleInfo("Simple Label","A simple implementation of the Label control, with an image to the left of the label. ","/Controls/Text/Simple Label","/ensemble/samples/controls/text/simplelabel","ensemble.samples.controls.text.simplelabel.SimpleLabelApp","/ensemble/samples/controls/text/simplelabel/preview.png",new String[]{"/ensemble/samples/shared-resources/icon-48x48.png","/ensemble/samples/controls/text/simplelabel/SimpleLabelApp.java",},new String[]{"javafx.scene.control.Label",},new String[]{},new String[]{"/Controls/Text/Advanced Label","/Controls/Button/Graphic Button","/Controls/Text/Inset Text",},"/ensemble/samples/controls/text/simplelabel/SimpleLabelApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_61 = new SampleInfo("Text Field","Demonstrates a TextField control that allows you to enter text. ","/Controls/Text/Text Field","/ensemble/samples/controls/text/textfield","ensemble.samples.controls.text.textfield.TextFieldApp","/ensemble/samples/controls/text/textfield/preview.png",new String[]{"/ensemble/samples/controls/text/textfield/TextFieldApp.java",},new String[]{"javafx.scene.control.TextField",},new String[]{},new String[]{},"/ensemble/samples/controls/text/textfield/TextFieldApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_62 = new SampleInfo("Text Validator","A sample that demonstrates text validation. If the value in the TextField is a small number, the field becomes yellow. If the value in the TextField is not a number, the field becomes red. ","/Controls/Text/Text Validator","/ensemble/samples/controls/text/textvalidator","ensemble.samples.controls.text.textvalidator.TextValidatorApp","/ensemble/samples/controls/text/textvalidator/preview.png",new String[]{"/ensemble/samples/controls/text/textvalidator/TextInputValidatorPane.java","/ensemble/samples/controls/text/textvalidator/TextValidatorApp.java","/ensemble/samples/controls/text/textvalidator/ValidationEvent.java","/ensemble/samples/controls/text/textvalidator/ValidationResult.java","/ensemble/samples/controls/text/textvalidator/Validator.java","/ensemble/samples/controls/text/textvalidator/ValidatorPane.java","/ensemble/samples/controls/text/textvalidator/Validators.css",},new String[]{"javafx.scene.control.TextField",},new String[]{},new String[]{"/Controls/Text/Text Field",},"/ensemble/samples/controls/text/textvalidator/TextValidatorApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_63 = new SampleInfo("Styled Tool Bar","A sample that shows three ToolBars, two of which are styled specifically with a separate CSS style sheet. ","/Controls/Toolbar/Styled Tool Bar","/ensemble/samples/controls/toolbar/styledtoolbar","ensemble.samples.controls.toolbar.styledtoolbar.StyledToolBarApp","/ensemble/samples/controls/toolbar/styledtoolbar/preview.png",new String[]{"/ensemble/samples/controls/toolbar/styledtoolbar/StyledToolBar.css","/ensemble/samples/controls/toolbar/styledtoolbar/StyledToolBarApp.java",},new String[]{"javafx.scene.control.ToolBar",},new String[]{},new String[]{"/Controls/Toolbar/Tool Bar",},"/ensemble/samples/controls/toolbar/styledtoolbar/StyledToolBarApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    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","/ensemble/samples/controls/toolbar/toolbar/ToolBarApp.java.orig","/ensemble/samples/controls/toolbar/toolbar/ToolBarApp.java.save",},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/Login.css","/ensemble/samples/fxml/fxmldemo/Login.fxml","/ensemble/samples/fxml/fxmldemo/LoginController.java","/ensemble/samples/fxml/fxmldemo/Profile.fxml","/ensemble/samples/fxml/fxmldemo/ProfileController.java","/ensemble/samples/fxml/fxmldemo/User.java",},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_63 = new SampleInfo("Styled Tool Bar","A sample that shows three ToolBars, two of which are styled specifically with a separate CSS style sheet. ","/Controls/Toolbar/Styled Tool Bar","/ensemble/samples/controls/toolbar/styledtoolbar","ensemble.samples.controls.toolbar.styledtoolbar.StyledToolBarApp","/ensemble/samples/controls/toolbar/styledtoolbar/preview.png",new String[]{"/ensemble/samples/controls/toolbar/styledtoolbar/StyledToolBarApp.java","/ensemble/samples/controls/toolbar/styledtoolbar/StyledToolBar.css",},new String[]{"javafx.scene.control.ToolBar",},new String[]{},new String[]{"/Controls/Toolbar/Tool Bar",},"/ensemble/samples/controls/toolbar/styledtoolbar/StyledToolBarApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    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_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[]{});
-    private static final SampleInfo SAMPLE_71 = new SampleInfo("Display Shelf","A display shelf of images using the PerspectiveTransform effect. ","/Graphics/Display Shelf","/ensemble/samples/graphics/displayshelf","ensemble.samples.graphics.displayshelf.DisplayShelfApp","/ensemble/samples/graphics/displayshelf/preview.png",new String[]{"/ensemble/samples/graphics/displayshelf/DisplayShelf.java","/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/shared-resources/Animal8.jpg","/ensemble/samples/shared-resources/Animal9.jpg","/ensemble/samples/shared-resources/Animal10.jpg","/ensemble/samples/shared-resources/Animal11.jpg","/ensemble/samples/shared-resources/Animal12.jpg","/ensemble/samples/shared-resources/Animal13.jpg","/ensemble/samples/shared-resources/Animal14.jpg","/ensemble/samples/graphics/displayshelf/DisplayShelfApp.java","/ensemble/samples/graphics/displayshelf/PerspectiveImage.java",},new String[]{"javafx.scene.effect.PerspectiveTransform","javafx.scene.effect.Reflection","javafx.scene.control.ScrollBar","javafx.scene.input.MouseEvent","javafx.scene.input.KeyEvent",},new String[]{},new String[]{},"/ensemble/samples/graphics/displayshelf/DisplayShelfApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_71 = new SampleInfo("Display Shelf","A display shelf of images using the PerspectiveTransform effect. ","/Graphics/Display Shelf","/ensemble/samples/graphics/displayshelf","ensemble.samples.graphics.displayshelf.DisplayShelfApp","/ensemble/samples/graphics/displayshelf/preview.png",new String[]{"/ensemble/samples/graphics/displayshelf/DisplayShelf.java","/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/shared-resources/Animal8.jpg","/ensemble/samples/shared-resources/Animal9.jpg","/ensemble/samples/shared-resources/Animal10.jpg","/ensemble/samples/shared-resources/Animal11.jpg","/ensemble/samples/shared-resources/Animal12.jpg","/ensemble/samples/shared-resources/Animal13.jpg","/ensemble/samples/shared-resources/Animal14.jpg","/ensemble/samples/graphics/displayshelf/DisplayShelfApp.java","/ensemble/samples/graphics/displayshelf/PerspectiveImage.java","/ensemble/samples/graphics/displayshelf/DisplayShelf.css",},new String[]{"javafx.scene.effect.PerspectiveTransform","javafx.scene.effect.Reflection","javafx.scene.control.ScrollBar","javafx.scene.input.MouseEvent","javafx.scene.input.KeyEvent",},new String[]{},new String[]{},"/ensemble/samples/graphics/displayshelf/DisplayShelfApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_72 = new SampleInfo("Puzzle Pieces","A sample in which an image is broken into pieces to create a jigsaw puzzle. ","/Graphics/Puzzle Pieces","/ensemble/samples/graphics/puzzle","ensemble.samples.graphics.puzzle.PuzzlePiecesApp","/ensemble/samples/graphics/puzzle/preview.png",new String[]{"/ensemble/samples/graphics/puzzle/Desk.java","/ensemble/samples/graphics/puzzle/Piece.java","/ensemble/samples/shared-resources/PuzzlePieces-picture.jpg","/ensemble/samples/graphics/puzzle/PuzzlePiecesApp.java",},new String[]{"javafx.scene.shape.Path","javafx.scene.image.Image","javafx.scene.image.ImageView","javafx.scene.control.Button","javafx.scene.layout.Pane","javafx.scene.input.MouseEvent","javafx.scene.effect.DropShadow",},new String[]{},new String[]{},"/ensemble/samples/graphics/puzzle/PuzzlePiecesApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_73 = new SampleInfo("Stopwatch","An animated stopwatch. Click the green button to start the stopwatch and click the red button to stop it. ","/Graphics/Stopwatch","/ensemble/samples/graphics/stopwatch","ensemble.samples.graphics.stopwatch.StopWatchApp","/ensemble/samples/graphics/stopwatch/preview.png",new String[]{"/ensemble/samples/graphics/stopwatch/Dial.java","/ensemble/samples/graphics/stopwatch/DigitalClock.java","/ensemble/samples/graphics/stopwatch/StopWatchApp.java","/ensemble/samples/graphics/stopwatch/StopWatchButton.java","/ensemble/samples/shared-resources/stopwatch.png","/ensemble/samples/graphics/stopwatch/Watch.java",},new String[]{"javafx.scene.effect.DropShadow","javafx.scene.effect.GaussianBlur","javafx.scene.effect.Light","javafx.scene.effect.Lighting","javafx.scene.image.Image","javafx.scene.image.ImageView","javafx.scene.shape.Circle","javafx.scene.Group","javafx.scene.shape.Ellipse","javafx.scene.shape.Rectangle","javafx.scene.text.Font","javafx.scene.text.Text","javafx.scene.text.TextAlignment","javafx.scene.text.TextBoundsType","javafx.scene.transform.Rotate","javafx.util.Duration",},new String[]{},new String[]{},"/ensemble/samples/graphics/stopwatch/StopWatchApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_74 = new SampleInfo("Drop Shadow","A sample that demonstrates how a drop shadow effect is affected by various settings. ","/Graphics/Effects/Drop Shadow","/ensemble/samples/graphics/effects/dropshadow","ensemble.samples.graphics.effects.dropshadow.DropShadowApp","/ensemble/samples/graphics/effects/dropshadow/preview.png",new String[]{"/ensemble/samples/graphics/effects/dropshadow/DropShadowApp.java",},new String[]{"javafx.scene.effect.DropShadow","javafx.scene.effect.Effect",},new String[]{},new String[]{},"/ensemble/samples/graphics/effects/dropshadow/DropShadowApp.java",new PlaygroundProperty[]{new PlaygroundProperty("dropShadow","radius","min","0","max","20","name","Drop Shadow Radius"),new PlaygroundProperty("dropShadow","offsetX","min","-10","max","10","name","Drop Shadow Offset X"),new PlaygroundProperty("dropShadow","offsetY","min","-10","max","10","name","Drop Shadow Offset Y"),new PlaygroundProperty("dropShadow","radius","min","0","max","1","name","Drop Shadow Spread"),new PlaygroundProperty("dropShadow","color","name","Drop Shadow Color"),},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",},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","/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_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[]{});
@@ -115,12 +115,12 @@
     private static final SampleInfo SAMPLE_108 = new SampleInfo("TilePane","An example of a TilePane layout. ","/Layout/TilePane","/ensemble/samples/layout/tilepane","ensemble.samples.layout.tilepane.TilePaneApp","/ensemble/samples/layout/tilepane/preview.png",new String[]{"/ensemble/samples/shared-resources/icon-48x48.png","/ensemble/samples/layout/tilepane/TilePaneApp.java",},new String[]{"javafx.scene.layout.TilePane",},new String[]{},new String[]{"/Graphics/Images/Image Creation",},"/ensemble/samples/layout/tilepane/TilePaneApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     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/AlphaMediaPlayer.css","/ensemble/samples/media/alphamediaplayer/AlphaMediaPlayerApp.java","/ensemble/samples/media/alphamediaplayer/PlanetaryPlayerPane.java",},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_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_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/OverlayMediaPlayer.css","/ensemble/samples/media/overlaymediaplayer/OverlayMediaPlayerApp.java","/ensemble/samples/media/overlaymediaplayer/PlayerPane.java",},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/StreamingMediaPlayer.css","/ensemble/samples/media/streamingmediaplayer/StreamingMediaPlayerApp.java",},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_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_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","/ensemble/samples/scenegraph/events/gestureevent/GestureEventApp.java.save",},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_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[]{});
@@ -130,7 +130,7 @@
     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[]{});
     private static final SampleInfo SAMPLE_125 = new SampleInfo("SwingInterop","A sample that invokes SwingInterop to run in a separate JVM.  SwingInterop shows how to embed JavaFX components, like Chart and WebView components, in a Swing application. ","/Swing/SwingInterop","/ensemble/samples/swing/swinginterop","ensemble.samples.swing.swinginterop.SwingInteropApp","/ensemble/samples/swing/swinginterop/preview.png",new String[]{"/ensemble/samples/swing/swinginterop/ProcessListener.java","/ensemble/samples/swing/swinginterop/SampleTableModel.java","/ensemble/samples/swing/swinginterop/SwingInterop.java","/ensemble/samples/swing/swinginterop/SwingInteropApp.java","/ensemble/samples/swing/swinginterop/SwingInteropService.java","/ensemble/samples/swing/swinginterop/SwingInteropTask.java",},new String[]{"javafx.application.Application","javafx.stage.Stage","javafx.scene.Scene","javafx.scene.chart.BarChart","javafx.scene.chart.CategoryAxis","javafx.scene.chart.Chart","javafx.scene.chart.NumberAxis","javafx.scene.chart.XYChart","javafx.scene.web.WebEngine","javafx.scene.web.WebView",},new String[]{},new String[]{},"/ensemble/samples/swing/swinginterop/SwingInteropApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_126 = new SampleInfo("HTML Editor","A sample that demonstrates the HTML Editor. You can make changes to the example text, and the resulting generated HTML is displayed. ","/Web/HTML Editor","/ensemble/samples/web/htmleditor","ensemble.samples.web.htmleditor.HTMLEditorApp","/ensemble/samples/web/htmleditor/preview.png",new String[]{"/ensemble/samples/web/htmleditor/HTMLEditorApp.java","/ensemble/samples/web/htmleditor/HTMLEditorApp.java.orig","/ensemble/samples/web/htmleditor/HTMLEditorApp.java.save",},new String[]{"javafx.scene.web.HTMLEditor",},new String[]{},new String[]{"controls/text/SimpleLabel",},"/ensemble/samples/web/htmleditor/HTMLEditorApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{ConditionalFeature.WEB,});
+    private static final SampleInfo SAMPLE_126 = new SampleInfo("HTML Editor","A sample that demonstrates the HTML Editor. You can make changes to the example text, and the resulting generated HTML is displayed. ","/Web/HTML Editor","/ensemble/samples/web/htmleditor","ensemble.samples.web.htmleditor.HTMLEditorApp","/ensemble/samples/web/htmleditor/preview.png",new String[]{"/ensemble/samples/web/htmleditor/HTMLEditorApp.java",},new String[]{"javafx.scene.web.HTMLEditor",},new String[]{},new String[]{"controls/text/SimpleLabel",},"/ensemble/samples/web/htmleditor/HTMLEditorApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{ConditionalFeature.WEB,});
     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,};
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/controls/table/tablecellfactory/CheckBoxTableCell.java	Tue Aug 06 10:13:00 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2008, 2013 Oracle and/or its affiliates.
- * All rights reserved. Use is subject to license terms.
- *
- * This file is available and licensed under the following license:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the distribution.
- *  - Neither the name of Oracle Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package ensemble.samples.controls.table.tablecellfactory;
-
-import javafx.beans.property.BooleanProperty;
-import javafx.beans.value.ObservableValue;
-import javafx.geometry.Pos;
-import javafx.scene.control.CheckBox;
-import javafx.scene.control.TableCell;
-
-public class CheckBoxTableCell<S, T> extends TableCell<S, T> {
-       private final CheckBox checkBox;
-        private ObservableValue<T> ov;
-
-        public CheckBoxTableCell() {
-            this.checkBox = new CheckBox();
-            this.checkBox.setAlignment(Pos.CENTER);
-
-            setAlignment(Pos.CENTER);
-            setGraphic(checkBox);    
-        }
-        @Override public void updateItem(T item, boolean empty) {
-            super.updateItem(item, empty);
-            if (empty) {
-                setText(null);
-                setGraphic(null);
-            } else {
-                setGraphic(checkBox);
-                if (ov instanceof BooleanProperty) {
-                    checkBox.selectedProperty().unbindBidirectional((BooleanProperty) ov);
-                }
-                ov = getTableColumn().getCellObservableValue(getIndex());
-                if (ov instanceof BooleanProperty) {
-                    checkBox.selectedProperty().bindBidirectional((BooleanProperty) ov);
-                }
-            }
-        }
-        
-}
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/controls/table/tablecellfactory/EditingCell.java	Tue Aug 06 10:13:00 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2008, 2013 Oracle and/or its affiliates.
- * All rights reserved. Use is subject to license terms.
- *
- * This file is available and licensed under the following license:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the distribution.
- *  - Neither the name of Oracle Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package ensemble.samples.controls.table.tablecellfactory;
-
-import javafx.event.EventHandler;
-import javafx.scene.control.TableCell;
-import javafx.scene.control.TextField;
-import javafx.scene.input.KeyCode;
-import javafx.scene.input.KeyEvent;
-
-public class EditingCell extends TableCell<Person, String> {
-
-    private TextField textField;
-
-    public EditingCell() {
-    }
-
-    @Override
-    public void startEdit() {
-        super.startEdit();
-        if (textField == null) {
-            createTextField();
-        }
-        setText(null);
-        setGraphic(textField);
-        textField.selectAll();
-    }
-
-    @Override
-    public void cancelEdit() {
-        super.cancelEdit();
-        setText((String) getItem());
-        setGraphic(null);
-    }
-
-    @Override
-    public void updateItem(String item, boolean empty) {
-        super.updateItem(item, empty);
-        if (empty) {
-            setText(null);
-            setGraphic(null);
-        } else {
-            if (isEditing()) {
-                if (textField != null) {
-                    textField.setText(getString());
-                }
-                setText(null);
-                setGraphic(textField);
-            } else {
-                setText(getString());
-                setGraphic(null);
-            }
-        }
-    }
-
-    private void createTextField() {
-        textField = new TextField(getString());
-        textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
-        textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
-            @Override
-            public void handle(KeyEvent t) {
-                if (t.getCode() == KeyCode.ENTER) {
-                    commitEdit(textField.getText());
-                } else if (t.getCode() == KeyCode.ESCAPE) {
-                    cancelEdit();
-                }
-            }
-        });
-    }
-
-    private String getString() {
-        return getItem() == null ? "" : getItem().toString();
-    }
-}
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/controls/table/tablecellfactory/TableCellFactoryApp.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/controls/table/tablecellfactory/TableCellFactoryApp.java	Tue Aug 06 14:14:24 2013 -0700
@@ -43,13 +43,15 @@
 import javafx.scene.control.TableView;
 import javafx.scene.control.cell.CheckBoxTableCell;
 import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.control.cell.TextFieldTableCell;
 import javafx.stage.Stage;
-import javafx.util.Callback;
+import javafx.util.StringConverter;
 
 /**
- *  A simple table that uses cell factories to add a control to a table
- * column and to enable editing of first/last name and email.
- * 
+ * 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.
+ *
  * @sampleName TableCellFactory
  * @preview preview.png
  * @see javafx.scene.control.TableCell
@@ -67,43 +69,39 @@
                 new Person(true, "Ethan", "Williams", "ethan.williams@example.com"),
                 new Person(true, "Emma", "Jones", "emma.jones@example.com"),
                 new Person(false, "Michael", "Brown", "michael.brown@example.com"));
+        StringConverter<Object> sc = new StringConverter<Object>() {
+            @Override
+            public String toString(Object t) {
+                return t == null ? null : t.toString();
+            }
+
+            @Override
+            public Object fromString(String string) {
+                return string;
+            }
+        };
         //"Invited" column
-        TableColumn invitedCol = new TableColumn<Person, Boolean>();
+        TableColumn invitedCol = new TableColumn<>();
         invitedCol.setText("Invited");
-        invitedCol.setMinWidth(50);
+        invitedCol.setMinWidth(70);
         invitedCol.setCellValueFactory(new PropertyValueFactory("invited"));
-        invitedCol.setCellFactory(new Callback<TableColumn<Person, Boolean>, TableCell<Person, Boolean>>() {
-
-            public TableCell<Person, Boolean> call(TableColumn<Person, Boolean> p) {
-                return new CheckBoxTableCell<Person, Boolean>();
-            }
-        });
+        invitedCol.setCellFactory(CheckBoxTableCell.forTableColumn(invitedCol));
         //"First Name" column
         TableColumn firstNameCol = new TableColumn();
         firstNameCol.setText("First");
         firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName"));
+        firstNameCol.setCellFactory(TextFieldTableCell.forTableColumn(sc));
         //"Last Name" column
         TableColumn lastNameCol = new TableColumn();
         lastNameCol.setText("Last");
         lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName"));
+        lastNameCol.setCellFactory(TextFieldTableCell.forTableColumn(sc));
         //"Email" column
         TableColumn emailCol = new TableColumn();
         emailCol.setText("Email");
         emailCol.setMinWidth(200);
         emailCol.setCellValueFactory(new PropertyValueFactory("email"));
-
-        //Set cell factory for cells that allow editing
-        Callback<TableColumn, TableCell> cellFactory =
-                new Callback<TableColumn, TableCell>() {
-
-                    public TableCell call(TableColumn p) {
-                        return new EditingCell();
-                    }
-                };
-        emailCol.setCellFactory(cellFactory);
-        firstNameCol.setCellFactory(cellFactory);
-        lastNameCol.setCellFactory(cellFactory);
-
+        emailCol.setCellFactory(TextFieldTableCell.forTableColumn(sc));
         //Set handler to update ObservableList properties. Applicable if cell is edited
         updateObservableListProperties(emailCol, firstNameCol, lastNameCol);
 
@@ -113,10 +111,10 @@
         tableView.setEditable(true);
         tableView.getColumns().addAll(invitedCol, firstNameCol, lastNameCol, emailCol);
         return tableView;
+    }
 
-    }
-   
-    @Override public void start(Stage primaryStage) throws Exception {
+    @Override
+    public void start(Stage primaryStage) throws Exception {
         primaryStage.setScene(new Scene(createContent()));
         primaryStage.show();
     }
@@ -127,30 +125,32 @@
     public static void main(String[] args) {
         launch(args);
     }
-    
- private void updateObservableListProperties(TableColumn emailCol, TableColumn firstNameCol,
+
+    private void updateObservableListProperties(TableColumn emailCol, TableColumn firstNameCol,
             TableColumn lastNameCol) {
         //Modifying the email property in the ObservableList
         emailCol.setOnEditCommit(new EventHandler<CellEditEvent<Person, String>>() {
-            @Override public void handle(CellEditEvent<Person, String> t) {
+            @Override
+            public void handle(CellEditEvent<Person, String> t) {
                 ((Person) t.getTableView().getItems().get(
                         t.getTablePosition().getRow())).setEmail(t.getNewValue());
             }
         });
         //Modifying the firstName property in the ObservableList
         firstNameCol.setOnEditCommit(new EventHandler<CellEditEvent<Person, String>>() {
-            @Override public void handle(CellEditEvent<Person, String> t) {
+            @Override
+            public void handle(CellEditEvent<Person, String> t) {
                 ((Person) t.getTableView().getItems().get(
                         t.getTablePosition().getRow())).setFirstName(t.getNewValue());
             }
         });
         //Modifying the lastName property in the ObservableList
         lastNameCol.setOnEditCommit(new EventHandler<CellEditEvent<Person, String>>() {
-            @Override public void handle(CellEditEvent<Person, String> t) {
+            @Override
+            public void handle(CellEditEvent<Person, String> t) {
                 ((Person) t.getTableView().getItems().get(
                         t.getTablePosition().getRow())).setLastName(t.getNewValue());
             }
         });
-    }   
-    
+    }
 }
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/scenegraph/node/customnode/MyNode.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/scenegraph/node/customnode/MyNode.java	Tue Aug 06 14:14:24 2013 -0700
@@ -31,10 +31,10 @@
  */
 package ensemble.samples.scenegraph.node.customnode;
 
-import javafx.scene.Parent;
+import javafx.scene.Group;
 import javafx.scene.control.Label;
 
-public class MyNode extends Parent {
+public class MyNode extends Group {
 
     private Label text;
 
--- a/apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/area/curvefitted/CurveFittedAreaChart.css	Tue Aug 06 10:13:00 2013 -0700
+++ b/apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/area/curvefitted/CurveFittedAreaChart.css	Tue Aug 06 14:14:24 2013 -0700
@@ -30,12 +30,12 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 .chart {
-    -fx-background-image: url("/ensemble/samples/shared-resources/Curve-fitted-background.png");
+    -fx-background-image: url("../../../shared-resources/Curve-fitted-background.png");
     -fx-padding: 15 25 15 15;
 }
 .chart-plot-background {
     -fx-background-color: red;
-    -fx-background-image: url("/ensemble/samples/shared-resources/Curve-fitted-chart-background.png"), url("/ensemble/samples/shared-resources/Curve-fitted-graph-gridlines.png");
+    -fx-background-image: url("../../../shared-resources/Curve-fitted-chart-background.png"), url("../../../shared-resources/Curve-fitted-graph-gridlines.png");
     -fx-background-size: cover, auto;
     -fx-background-repeat: no-repeat, repeat;
     -fx-background-position: 0% 0%, 0% 100%;
--- a/apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/text/searchbox/SearchBox.css	Tue Aug 06 10:13:00 2013 -0700
+++ b/apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/text/searchbox/SearchBox.css	Tue Aug 06 14:14:24 2013 -0700
@@ -34,7 +34,7 @@
     -fx-background-insets: 1;
     -fx-background-radius: 15;
     -fx-padding: -9 5 -11 0;
-    -fx-border-image-source: url("/ensemble/samples/shared-resources/search-box.png");
+    -fx-border-image-source: url("../../../shared-resources/search-box.png");
     -fx-border-image-slice: 12 12 12 22 fill;
     -fx-border-image-width: 12 12 12 22;
     -fx-border-image-repeat: stretch; 
@@ -48,8 +48,8 @@
 }
 .search-box .button {
     -fx-background-color: null;
-    -fx-background-image: url("/ensemble/samples/shared-resources/search-clear.png");
+    -fx-background-image: url("../../../shared-resources/search-clear.png");
 }
 .search-box .button:hover {
-    -fx-background-image: url("/ensemble/samples/shared-resources/search-clear-over.png");
+    -fx-background-image: url("../../../shared-resources/search-clear-over.png");
 }
\ No newline at end of file
--- a/apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/alphamediaplayer/AlphaMediaPlayer.css	Tue Aug 06 10:13:00 2013 -0700
+++ b/apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/alphamediaplayer/AlphaMediaPlayer.css	Tue Aug 06 14:14:24 2013 -0700
@@ -52,7 +52,7 @@
     -fx-background-insets: 1 0 -1 0, 0, 1;
     -fx-background-radius: 2.5, 2.5, 1.5;
     -fx-padding: 0.208333em; 
-    -fx-background-image: url("/ensemble/samples/shared-resources/slider.png");
+    -fx-background-image: url("../../shared-resources/slider.png");
     -fx-background-image-width: 10;
     -fx-background-image-slice: 0 fill;
 }
@@ -62,7 +62,7 @@
     -fx-background-insets: 0, 1, 2;
     -fx-background-radius: 1.0em; /* makes sure this remains circular */
     -fx-padding: 0.583333em; /* 7 */
-    -fx-border-image-source: url("/ensemble/samples/shared-resources/thumb_default.png");
+    -fx-border-image-source: url("../../shared-resources/thumb_default.png");
     -fx-border-image-width: 10;
     -fx-border-image-slice: 0 fill;
 }
@@ -71,7 +71,7 @@
     -fx-color: null;
     -fx-background-color: null;
     -fx-border-color: null;
-    -fx-border-image-source: url("/ensemble/samples/shared-resources/thumb_pressed.png");
+    -fx-border-image-source: url("../../shared-resources/thumb_pressed.png");
     -fx-border-image-width: 10;
     -fx-border-image-slice: 0 fill;
     -fx-background-insets: -1.4, 0, 1, 2;
@@ -82,68 +82,68 @@
     -fx-color: null;
     -fx-background-color: null;
     -fx-border-color: null;
-    -fx-border-image-source: url("/ensemble/samples/shared-resources/thumb_hover.png");
+    -fx-border-image-source: url("../../shared-resources/thumb_hover.png");
     -fx-border-image-width: 10;
     -fx-border-image-slice: 0 fill;
 }
 
 #back-button {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_default_back.png");
+    -fx-graphic: url("../../shared-resources/button_default_back.png");
 }
 
 #back-button:hover {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_hover_back.png");
+    -fx-graphic: url("../../shared-resources/button_hover_back.png");
 }
 
 #back-button:armed {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_pressed_back.png");
+    -fx-graphic: url("../../shared-resources/button_pressed_back.png");
 }
 
 #stop-button {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_default_stop.png");
+    -fx-graphic: url("../../shared-resources/button_default_stop.png");
 }
 
 #stop-button:hover {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_hover_stop.png");
+    -fx-graphic: url("../../shared-resources/button_hover_stop.png");
 }
 
 #stop-button:armed {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_pressed_stop.png");
+    -fx-graphic: url("../../shared-resources/button_pressed_stop.png");
 }
 
 #play-button {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_default_play.png");
+    -fx-graphic: url("../../shared-resources/button_default_play.png");
 }
 
 #play-button:hover {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_hover_play.png");
+    -fx-graphic: url("../../shared-resources/button_hover_play.png");
 }
 
 #play-button:armed {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_pressed_play.png");
+    -fx-graphic: url("../../shared-resources/button_pressed_play.png");
 }
 
 #pause-button {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_default_pause.png");
+    -fx-graphic: url("../../shared-resources/button_default_pause.png");
 }
 
 #pause-button:hover {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_hover_pause.png");
+    -fx-graphic: url("../../shared-resources/button_hover_pause.png");
 }
 
 #pause-button:armed {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_pressed_pause.png");
+    -fx-graphic: url("../../shared-resources/button_pressed_pause.png");
 }
 
 #forward-button {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_default_forward.png");
+    -fx-graphic: url("../../shared-resources/button_default_forward.png");
 }
 
 #forward-button:hover {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_hover_forward.png");
+    -fx-graphic: url("../../shared-resources/button_hover_forward.png");
 }
 
 #forward-button:armed {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_pressed_forward.png");
+    -fx-graphic: url("../../shared-resources/button_pressed_forward.png");
 }
 
--- a/apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/overlaymediaplayer/OverlayMediaPlayer.css	Tue Aug 06 10:13:00 2013 -0700
+++ b/apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/overlaymediaplayer/OverlayMediaPlayer.css	Tue Aug 06 14:14:24 2013 -0700
@@ -52,7 +52,7 @@
     -fx-background-insets: 1 0 -1 0, 0, 1;
     -fx-background-radius: 2.5, 2.5, 1.5;
     -fx-padding: 0.208333em; 
-    -fx-background-image: url("/ensemble/samples/shared-resources/slider.png");
+    -fx-background-image: url("../../shared-resources/slider.png");
     -fx-background-image-width: 10;
     -fx-background-image-slice: 0 fill;
 }
@@ -62,7 +62,7 @@
     -fx-background-insets: 0, 1, 2;
     -fx-background-radius: 1.0em; /* makes sure this remains circular */
     -fx-padding: 0.583333em; /* 7 */
-    -fx-border-image-source: url("/ensemble/samples/shared-resources/thumb_default.png");
+    -fx-border-image-source: url("../../shared-resources/thumb_default.png");
     -fx-border-image-width: 10;
     -fx-border-image-slice: 0 fill;
 }
@@ -71,7 +71,7 @@
     -fx-color: null;
     -fx-background-color: null;
     -fx-border-color: null;
-    -fx-border-image-source: url("/ensemble/samples/shared-resources/thumb_pressed.png");
+    -fx-border-image-source: url("../../shared-resources/thumb_pressed.png");
     -fx-border-image-width: 10;
     -fx-border-image-slice: 0 fill;
     -fx-background-insets: -1.4, 0, 1, 2;
@@ -82,68 +82,68 @@
     -fx-color: null;
     -fx-background-color: null;
     -fx-border-color: null;
-    -fx-border-image-source: url("/ensemble/samples/shared-resources/thumb_hover.png");
+    -fx-border-image-source: url("../../shared-resources/thumb_hover.png");
     -fx-border-image-width: 10;
     -fx-border-image-slice: 0 fill;
 }
 
 #back-button {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_default_back.png");
+    -fx-graphic: url("../../shared-resources/button_default_back.png");
 }
 
 #back-button:hover {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_hover_back.png");
+    -fx-graphic: url("../../shared-resources/button_hover_back.png");
 }
 
 #back-button:armed {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_pressed_back.png");
+    -fx-graphic: url("../../shared-resources/button_pressed_back.png");
 }
 
 #stop-button {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_default_stop.png");
+    -fx-graphic: url("../../shared-resources/button_default_stop.png");
 }
 
 #stop-button:hover {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_hover_stop.png");
+    -fx-graphic: url("../../shared-resources/button_hover_stop.png");
 }
 
 #stop-button:armed {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_pressed_stop.png");
+    -fx-graphic: url("../../shared-resources/button_pressed_stop.png");
 }
 
 #play-button {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_default_play.png");
+    -fx-graphic: url("../../shared-resources/button_default_play.png");
 }
 
 #play-button:hover {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_hover_play.png");
+    -fx-graphic: url("../../shared-resources/button_hover_play.png");
 }
 
 #play-button:armed {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_pressed_play.png");
+    -fx-graphic: url("../../shared-resources/button_pressed_play.png");
 }
 
 #pause-button {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_default_pause.png");
+    -fx-graphic: url("../../shared-resources/button_default_pause.png");
 }
 
 #pause-button:hover {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_hover_pause.png");
+    -fx-graphic: url("../../shared-resources/button_hover_pause.png");
 }
 
 #pause-button:armed {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_pressed_pause.png");
+    -fx-graphic: url("../../shared-resources/button_pressed_pause.png");
 }
 
 #forward-button {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_default_forward.png");
+    -fx-graphic: url("../../shared-resources/button_default_forward.png");
 }
 
 #forward-button:hover {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_hover_forward.png");
+    -fx-graphic: url("../../shared-resources/button_hover_forward.png");
 }
 
 #forward-button:armed {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_pressed_forward.png");
+    -fx-graphic: url("../../shared-resources/button_pressed_forward.png");
 }
 
--- a/apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/streamingmediaplayer/StreamingMediaPlayer.css	Tue Aug 06 10:13:00 2013 -0700
+++ b/apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/streamingmediaplayer/StreamingMediaPlayer.css	Tue Aug 06 14:14:24 2013 -0700
@@ -52,7 +52,7 @@
     -fx-background-insets: 1 0 -1 0, 0, 1;
     -fx-background-radius: 2.5, 2.5, 1.5;
     -fx-padding: 0.208333em; 
-    -fx-background-image: url("/ensemble/samples/shared-resources/slider.png");
+    -fx-background-image: url("../../shared-resources/slider.png");
     -fx-background-image-width: 10;
     -fx-background-image-slice: 0 fill;
 }
@@ -62,7 +62,7 @@
     -fx-background-insets: 0, 1, 2;
     -fx-background-radius: 1.0em; /* makes sure this remains circular */
     -fx-padding: 0.583333em; /* 7 */
-    -fx-border-image-source: url("/ensemble/samples/shared-resources/thumb_default.png");
+    -fx-border-image-source: url("../../shared-resources/thumb_default.png");
     -fx-border-image-width: 10;
     -fx-border-image-slice: 0 fill;
 }
@@ -71,7 +71,7 @@
     -fx-color: null;
     -fx-background-color: null;
     -fx-border-color: null;
-    -fx-border-image-source: url("/ensemble/samples/shared-resources/thumb_pressed.png");
+    -fx-border-image-source: url("../../shared-resources/thumb_pressed.png");
     -fx-border-image-width: 10;
     -fx-border-image-slice: 0 fill;
     -fx-background-insets: -1.4, 0, 1, 2;
@@ -82,68 +82,68 @@
     -fx-color: null;
     -fx-background-color: null;
     -fx-border-color: null;
-    -fx-border-image-source: url("/ensemble/samples/shared-resources/thumb_hover.png");
+    -fx-border-image-source: url("../../shared-resources/thumb_hover.png");
     -fx-border-image-width: 10;
     -fx-border-image-slice: 0 fill;
 }
 
 #back-button {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_default_back.png");
+    -fx-graphic: url("../../shared-resources/button_default_back.png");
 }
 
 #back-button:hover {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_hover_back.png");
+    -fx-graphic: url("../../shared-resources/button_hover_back.png");
 }
 
 #back-button:armed {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_pressed_back.png");
+    -fx-graphic: url("../../shared-resources/button_pressed_back.png");
 }
 
 #stop-button {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_default_stop.png");
+    -fx-graphic: url("../../shared-resources/button_default_stop.png");
 }
 
 #stop-button:hover {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_hover_stop.png");
+    -fx-graphic: url("../../shared-resources/button_hover_stop.png");
 }
 
 #stop-button:armed {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_pressed_stop.png");
+    -fx-graphic: url("../../shared-resources/button_pressed_stop.png");
 }
 
 #play-button {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_default_play.png");
+    -fx-graphic: url("../../shared-resources/button_default_play.png");
 }
 
 #play-button:hover {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_hover_play.png");
+    -fx-graphic: url("../../shared-resources/button_hover_play.png");
 }
 
 #play-button:armed {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_pressed_play.png");
+    -fx-graphic: url("../../shared-resources/button_pressed_play.png");
 }
 
 #pause-button {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_default_pause.png");
+    -fx-graphic: url("../../shared-resources/button_default_pause.png");
 }
 
 #pause-button:hover {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_hover_pause.png");
+    -fx-graphic: url("../../shared-resources/button_hover_pause.png");
 }
 
 #pause-button:armed {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_pressed_pause.png");
+    -fx-graphic: url("../../shared-resources/button_pressed_pause.png");
 }
 
 #forward-button {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_default_forward.png");
+    -fx-graphic: url("../../shared-resources/button_default_forward.png");
 }
 
 #forward-button:hover {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_hover_forward.png");
+    -fx-graphic: url("../../shared-resources/button_hover_forward.png");
 }
 
 #forward-button:armed {
-    -fx-graphic: url("/ensemble/samples/shared-resources/button_pressed_forward.png");
+    -fx-graphic: url("../../shared-resources/button_pressed_forward.png");
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/toys/FX8-3DFeatures/src/fx83dfeatures/LightMotion.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,276 @@
+/*
+ * 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 java.nio.ByteBuffer;
+import javafx.animation.Interpolator;
+import javafx.animation.KeyFrame;
+import javafx.animation.KeyValue;
+import javafx.animation.RotateTransition;
+import javafx.animation.Timeline;
+import javafx.application.Application;
+import static javafx.application.Application.launch;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.ObservableList;
+import javafx.event.EventHandler;
+import javafx.geometry.Point3D;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.PerspectiveCamera;
+import javafx.scene.PointLight;
+import javafx.scene.Scene;
+import javafx.scene.image.PixelFormat;
+import javafx.scene.image.WritableImage;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.PhongMaterial;
+import javafx.scene.shape.Cylinder;
+import javafx.scene.shape.Sphere;
+import javafx.scene.transform.Rotate;
+import javafx.stage.Stage;
+import javafx.util.Duration;
+
+public class LightMotion extends Application {
+
+    final Color light1Color = Color.PALEGOLDENROD;
+    final Color light2Color = Color.ORANGERED;
+    Timeline stationLightTL;
+    Timeline movingLightTL;
+    RotateTransition rotTrans;
+    Group sphereGroup;
+    Cylinder cylinder;
+    int light1Count = 0;
+    int light2Count = 0;
+    int counterS = 0;
+    int counterC = 0;
+
+    private Scene buildScene() {
+        PhongMaterial material = new PhongMaterial();
+        material.setDiffuseColor(Color.LIGHTGRAY);
+        material.setSpecularColor(Color.rgb(30, 30, 30));
+
+        Sphere sphere = new Sphere(100);
+        sphere.setMaterial(material);
+        sphereGroup = new Group(sphere);
+        sphereGroup.setTranslateX(400);
+        sphereGroup.setTranslateY(100);
+        sphereGroup.setTranslateZ(50);
+
+        cylinder = new Cylinder(200, 400);
+        cylinder.setTranslateX(400);
+        cylinder.setTranslateY(500);
+        cylinder.setTranslateZ(50);
+
+        cylinder.setMaterial(material);
+
+        // Create first light group and light
+        final VisibleLight lightGroup1 = new VisibleLight(light1Color);
+        lightGroup1.setTranslateX(700);
+        lightGroup1.setTranslateY(200);
+        lightGroup1.setTranslateZ(-200);
+
+        // Animate the color of the first light
+        DoubleProperty t = new SimpleDoubleProperty(0);
+        t.addListener(new ChangeListener<Number>() {
+            @Override
+            public void changed(ObservableValue<? extends Number> observable,
+                    Number oldValue, Number newValue) {
+
+                double t = newValue.doubleValue();
+                Color c = Color.WHITE.interpolate(Color.GREEN, t);
+                lightGroup1.setColor(c);
+            }
+        });
+
+        KeyValue kv1 = new KeyValue(t, 1.0, Interpolator.EASE_BOTH);
+        KeyFrame kf1 = new KeyFrame(Duration.seconds(2), kv1);
+        stationLightTL = new Timeline(kf1);
+        stationLightTL.setAutoReverse(true);
+        stationLightTL.setCycleCount(Timeline.INDEFINITE);
+
+        // Create second light group and light  
+        final VisibleLight lightGroup2 = new VisibleLight(light2Color);
+        lightGroup2.setTranslateX(-300);
+        lightGroup2.setTranslateY(300);
+        lightGroup2.setTranslateZ(-100);
+
+
+        // Animate the position of the second light
+        final Group movingLight = new Group(lightGroup2);
+        movingLight.setTranslateX(400);
+        final Rotate rot = new Rotate(0, Rotate.Y_AXIS);
+        movingLight.getTransforms().add(rot);
+        KeyValue kv = new KeyValue(rot.angleProperty(), 360.0);
+        KeyFrame kf = new KeyFrame(Duration.seconds(7), kv);
+        movingLightTL = new Timeline(kf);
+        movingLightTL.setCycleCount(Timeline.INDEFINITE);
+
+        // Animate cylinder
+        rotTrans = new RotateTransition(Duration.seconds(35), cylinder);
+        rotTrans.setAutoReverse(true);
+        rotTrans.setAxis(new Point3D(2, 1, 0).normalize());
+        rotTrans.setInterpolator(Interpolator.EASE_BOTH);
+        rotTrans.setCycleCount(Timeline.INDEFINITE);
+        rotTrans.setByAngle(360);
+
+        Group root = new Group();
+
+        PerspectiveCamera camera = new PerspectiveCamera();
+        camera.setTranslateZ(-10);
+        root.getChildren().addAll(sphereGroup, cylinder, lightGroup1, movingLight, camera);
+        Scene scene = new Scene(root, 800, 800, true);
+        scene.setCamera(camera);
+        scene.setFill(Color.rgb(10, 10, 40));
+
+        scene.setOnKeyTyped(new EventHandler<KeyEvent>() {
+            public void handle(KeyEvent e) {
+                switch (e.getCharacter()) {
+                    case "[":
+                        if (stationLightTL.getStatus() == Timeline.Status.RUNNING) {
+                            stationLightTL.pause();
+                        } else {
+                            stationLightTL.play();
+                        }
+                        break;
+                    case "]":
+                        if (movingLightTL.getStatus() == Timeline.Status.RUNNING) {
+                            movingLightTL.pause();
+                        } else {
+                            movingLightTL.play();
+                        }
+                        break;
+                    case "\\":
+                        if (rotTrans.getStatus() == Timeline.Status.RUNNING) {
+                            rotTrans.pause();
+                        } else {
+                            rotTrans.play();
+                        }
+                        break;
+                    case "c":
+                        lightGroup1.addScope(cylinder);
+                        lightGroup2.addScope(cylinder);
+                        break;
+                    case "C":
+                        System.err.println("C = " + counterC++ + ". Removing cylinder from lights");
+                        lightGroup1.removeScope(cylinder);
+                        lightGroup2.removeScope(cylinder);
+                        break;
+                    case "s":
+                        lightGroup1.addScope(sphereGroup);
+                        lightGroup2.addScope(sphereGroup);
+                        break;
+                    case "S":
+                        System.err.println("S = " + counterS++ + ". Removing sphere from lights");
+                        lightGroup1.removeScope(sphereGroup);
+                        lightGroup2.removeScope(sphereGroup);
+                        break;
+                }
+            }
+        });
+        return scene;
+    }
+
+    @Override
+    public void start(Stage primaryStage) {
+        Scene scene = buildScene();
+        primaryStage.setTitle("FX8 Light Motion");
+        primaryStage.setScene(scene);
+        primaryStage.show();
+        System.err.println("Both cylinder and sphere need to be added to lights"
+                +" first before removing them from lights can work.");
+    }
+
+    public static void main(String[] args) {
+        launch(args);
+    }
+
+    private class VisibleLight extends Group {
+
+        private PhongMaterial material;
+        private PointLight pointLight;
+        private Sphere lightShape;
+
+        private void makeConstantImage(WritableImage img, Color color) {
+            int w = (int) img.getWidth();
+            int h = (int) img.getHeight();
+            ByteBuffer scanline = ByteBuffer.allocate(3 * w);
+            byte r = (byte) ((int) Math.round(color.getRed() * 255.0));
+            byte g = (byte) ((int) Math.round(color.getGreen() * 255.0));
+            byte b = (byte) ((int) Math.round(color.getBlue() * 255.0));
+            for (int i = 0; i < w; i++) {
+                scanline.put(r);
+                scanline.put(g);
+                scanline.put(b);
+            }
+            scanline.rewind();
+            img.getPixelWriter().setPixels(0, 0, w, w, PixelFormat.getByteRgbInstance(), scanline, 0);
+        }
+
+        VisibleLight(Color color) {
+            pointLight = new PointLight();
+            material = new PhongMaterial(Color.BLACK);
+            material.setDiffuseMap(null);
+            material.setBumpMap(null);
+            material.setSpecularMap(null);
+            material.setSpecularColor(Color.TRANSPARENT);
+            setColor(color);
+
+            lightShape = new Sphere(50);
+            lightShape.setScaleX(0.2);
+            lightShape.setScaleY(0.2);
+            lightShape.setScaleZ(0.2);
+            lightShape.setMaterial(material);
+
+            this.getChildren().addAll(pointLight, lightShape);
+        }
+
+        final void setColor(Color color) {
+            pointLight.setColor(color);
+            WritableImage selfIllumMap = new WritableImage(64, 64);
+            makeConstantImage(selfIllumMap, color);
+            material.setSelfIlluminationMap(selfIllumMap);
+        }
+
+        final void addScope(Node node) {
+            ObservableList scope = pointLight.getScope();
+            if (scope.isEmpty()) {
+                scope.add(lightShape);
+            }
+            if ((node != null) && (!scope.contains(node))) {
+                scope.add(node);
+            }
+        }
+
+        final void removeScope(Node node) {
+            ObservableList scope = pointLight.getScope();
+            if (node != null) {
+                scope.remove(node);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/toys/FX8-3DFeatures/src/fx83dfeatures/SimpleMovingCamera.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,142 @@
+/*
+ * 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.animation.Timeline;
+import javafx.animation.TranslateTransition;
+import javafx.application.Application;
+import javafx.event.EventHandler;
+import javafx.scene.*;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.PhongMaterial;
+import javafx.scene.shape.*;
+import javafx.stage.Stage;
+import javafx.util.Duration;
+
+public class SimpleMovingCamera extends Application {
+
+    PointLight pointLight;
+    Sphere sphere;
+    PhongMaterial material;
+    PerspectiveCamera camera;    
+    Group cameraGroup;
+    TranslateTransition transTrans;
+    double fovValue;
+    double rotateCamera = 0.0;
+    double translateCamera = 0.0;
+    
+
+    private Scene buildScene() {
+        material = new PhongMaterial();
+        material.setDiffuseColor(Color.GOLD);
+        material.setSpecularColor(Color.rgb(30, 30, 30));
+        sphere = new Sphere(300);
+        sphere.setTranslateX(400);
+        sphere.setTranslateY(400);
+        sphere.setTranslateZ(20);
+        sphere.setMaterial(material);
+
+        sphere.setDrawMode(DrawMode.FILL);
+
+        pointLight = new PointLight(Color.ANTIQUEWHITE);
+        pointLight.setTranslateX(150);
+        pointLight.setTranslateY(-100);
+        pointLight.setTranslateZ(-1000);
+
+        camera = createCamera();
+        cameraGroup = new Group(camera);
+        Group root = new Group(sphere, pointLight, cameraGroup);
+
+        Scene scene = new Scene(root, 800, 800, true);
+        scene.setFill(Color.GRAY);
+        scene.setCamera(camera);
+        System.err.println("Camera FOV = " + (fovValue = camera.getFieldOfView()));
+        
+        transTrans = new TranslateTransition(Duration.seconds(5), cameraGroup);
+        transTrans.setAutoReverse(true);
+        transTrans.setCycleCount(Timeline.INDEFINITE);
+        transTrans.setByZ(-400);
+
+        scene.setOnKeyTyped(new EventHandler<KeyEvent>() {
+            @Override
+            public void handle(KeyEvent e) {
+                switch (e.getCharacter()) {
+                    case "[":
+                        fovValue -= 2.0;
+                        if (fovValue < 10.0) {
+                            fovValue = 10.0;
+                        }
+                        camera.setFieldOfView(fovValue);
+                        break;
+                    case "]":
+                        fovValue += 2.0;
+                        if (fovValue > 60.0) {
+                            fovValue = 60.0;
+                        }
+                        camera.setFieldOfView(fovValue);
+                        break;
+                    case "r":
+                        rotateCamera += 5.0;
+                        if (rotateCamera > 360.0) {
+                            rotateCamera = 0.0;
+                        }
+                        camera.setRotate(rotateCamera);
+                        break;
+                    case "t":
+                        if (transTrans.getStatus() == Timeline.Status.RUNNING) {
+                            transTrans.pause();
+                        } else {
+                            transTrans.play();
+                        }
+                        break;
+                }
+            }
+        });
+        return scene;
+    }
+
+    private PerspectiveCamera createCamera() {
+        PerspectiveCamera perspectiveCamera = new PerspectiveCamera(true);
+        perspectiveCamera.setTranslateX(400);
+        perspectiveCamera.setTranslateY(400);
+        perspectiveCamera.setTranslateZ(-1500);
+        perspectiveCamera.setFarClip(2000);
+        return perspectiveCamera;
+    }
+
+    @Override
+    public void start(Stage primaryStage) {
+        Scene scene = buildScene();
+        primaryStage.setTitle("SimpleMovingCamera");
+        primaryStage.setScene(scene);
+        primaryStage.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/SimpleMovingCameraSubScene.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,165 @@
+/*
+ * 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.animation.Timeline;
+import javafx.animation.TranslateTransition;
+import javafx.application.Application;
+import javafx.event.EventHandler;
+import javafx.scene.*;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.PhongMaterial;
+import javafx.scene.shape.*;
+import javafx.stage.Stage;
+import javafx.util.Duration;
+
+public class SimpleMovingCameraSubScene extends Application {
+
+    PointLight pointLight;
+    Sphere sphere;
+    PhongMaterial material;
+    PerspectiveCamera camera;
+    PerspectiveCamera subSceneCamera;
+    Group cameraGroup;
+    TranslateTransition transTrans;
+    double fovValue;
+    double rotateCamera = 0.0;
+    double translateCamera = 0.0;
+    
+    private SubScene buildSubScene() {
+        PhongMaterial ssMaterial = new PhongMaterial();
+        ssMaterial.setDiffuseColor(Color.SILVER);
+        ssMaterial.setSpecularColor(Color.rgb(30, 30, 30));
+        Sphere ssSphere = new Sphere(300);
+        ssSphere.setTranslateX(200);
+        ssSphere.setTranslateY(100);
+        ssSphere.setTranslateZ(1000);
+        ssSphere.setMaterial(ssMaterial);
+
+        ssSphere.setDrawMode(DrawMode.FILL);
+        
+        subSceneCamera = new PerspectiveCamera();
+
+        Group root = new Group(ssSphere);
+
+        SubScene subScene = new SubScene(root, 400, 200, true, true);
+        subScene.setCamera(subSceneCamera);
+        subScene.setFill(Color.BLACK);
+        return subScene;
+    }
+
+    private Scene buildScene() {
+        material = new PhongMaterial();
+        material.setDiffuseColor(Color.GOLD);
+        material.setSpecularColor(Color.rgb(30, 30, 30));
+        sphere = new Sphere(300);
+        sphere.setTranslateX(400);
+        sphere.setTranslateY(400);
+        sphere.setTranslateZ(20);
+        sphere.setMaterial(material);
+
+        sphere.setDrawMode(DrawMode.FILL);
+
+        pointLight = new PointLight(Color.ANTIQUEWHITE);
+        pointLight.setTranslateX(150);
+        pointLight.setTranslateY(-100);
+        pointLight.setTranslateZ(-1000);
+        
+        camera = createCamera();
+        cameraGroup = new Group(camera);
+
+        Group root = new Group(buildSubScene(), sphere, pointLight, cameraGroup);
+
+        Scene scene = new Scene(root, 800, 800, true);
+        scene.setFill(Color.GRAY);
+        scene.setCamera(camera);
+        System.err.println("Camera FOV = " + (fovValue = camera.getFieldOfView()));
+        
+        transTrans = new TranslateTransition(Duration.seconds(5), cameraGroup);
+        transTrans.setAutoReverse(true);
+        transTrans.setCycleCount(Timeline.INDEFINITE);
+        transTrans.setByZ(-400);
+
+        scene.setOnKeyTyped(new EventHandler<KeyEvent>() {
+            @Override
+            public void handle(KeyEvent e) {
+                switch (e.getCharacter()) {
+                    case "[":
+                        fovValue -= 2.0;
+                        if (fovValue < 10.0) {
+                            fovValue = 10.0;
+                        }
+                        subSceneCamera.setFieldOfView(fovValue);
+                        break;
+                    case "]":
+                        fovValue += 2.0;
+                        if (fovValue > 60.0) {
+                            fovValue = 60.0;
+                        }
+                        subSceneCamera.setFieldOfView(fovValue);
+                        break;
+                    case "r":
+                        rotateCamera += 5.0;
+                        if (rotateCamera > 360.0) {
+                            rotateCamera = 0.0;
+                        }
+                        subSceneCamera.setRotate(rotateCamera);
+                        break;
+                    case "t":
+                        if (transTrans.getStatus() == Timeline.Status.RUNNING) {
+                            transTrans.pause();
+                        } else {
+                            transTrans.play();
+                        }
+                        break;
+                }
+            }
+        });
+        return scene;
+    }
+
+    private PerspectiveCamera createCamera() {
+        PerspectiveCamera perspectiveCamera = new PerspectiveCamera(true);
+        perspectiveCamera.setTranslateX(400);
+        perspectiveCamera.setTranslateY(400);
+        perspectiveCamera.setTranslateZ(-1500);
+        perspectiveCamera.setFarClip(2000);
+        return perspectiveCamera;
+    }
+
+    @Override
+    public void start(Stage primaryStage) {
+        Scene scene = buildScene();
+        primaryStage.setTitle("SimpleMovingCameraSubScene");
+        primaryStage.setScene(scene);
+        primaryStage.show();
+    }
+
+    public static void main(String[] args) {
+        launch(args);
+    }
+}
--- a/build.gradle	Tue Aug 06 10:13:00 2013 -0700
+++ b/build.gradle	Tue Aug 06 14:14:24 2013 -0700
@@ -833,6 +833,22 @@
     }
 }
 
+// Task to check whether jfxrt.jar is present in the JDK
+task checkJfxrtJar {
+    doLast {
+        def jfxrtFile = new File("$JAVA_HOME/jre/lib/ext/jfxrt.jar");
+        if (jfxrtFile.exists()) {
+            if (BUILD_CLOSED) {
+                fail("$jfxrtFile must be removed before building closed sdk")
+            } else {
+                logger.warn("****************************************************************")
+                logger.warn("$jfxrtFile may interfere with testing or running applications against locally build jfxrt.jar")
+                logger.warn("****************************************************************")
+            }
+        }
+    }
+}
+
 task updateCacheIfNeeded() {
     // an empty task we can add to as needed for UPDATE_STUB_CACHE
 }
@@ -1702,7 +1718,9 @@
 
 task jfxrt()
 
-task sdk()
+task sdk() {
+    dependsOn(checkJfxrtJar)
+}
 
 // this is empty, allowing us to depend on the task, which may have other
 // real intances added later.
@@ -1862,9 +1880,6 @@
                 }
                 if (COMPILE_WEBKIT) {
                     from ("modules/web/build/libs/${library('jfxwebkit')}")
-                    if (IS_WINDOWS) {
-                        from ("modules/web/src/main/native/WebKitBuild/import/runtime")
-                    }
                 } else {
                     if (t.name == "android") {
                         //don't copy anything, use built in webkit.
@@ -2220,7 +2235,7 @@
 
     task copyClassesFromBinaryStub << {
         copy {
-            from zipTree(BINARY_STUB.getSingleFile())
+            from zipTree(rootProject.BINARY_STUB.getSingleFile())
             into "$buildDir/classes/main"
             include("javafx/scene/web/**",
                 "com/sun/javafx/scene/web/**",
--- a/buildSrc/android.gradle	Tue Aug 06 10:13:00 2013 -0700
+++ b/buildSrc/android.gradle	Tue Aug 06 14:14:24 2013 -0700
@@ -162,7 +162,7 @@
             )
             destinationDir = file("modules/web/build/classes/android")
             dependencyCacheDir = file("modules/web/build/dependency-cache")
-            source file("${closedDir}/javafx-android/webnode/src")
+            source file("modules/web/src/android/java")
         }
 
         def jarWebJavaAndroid = task("jarWebJavaAndroid",
@@ -287,7 +287,7 @@
 ]
 ANDROID.surface.compiler = compiler
 ANDROID.surface.linker = linker
-ANDROID.surface.lib = "glass-lens-android"
+ANDROID.surface.lib = "glass_lens_android"
 ANDROID.surface.ccFlags = [ccFlags, ccWarnFlags, ccArchFlags, ccOptFlags,
     ccDebugFlags, ccDefaultIncludeFlags, "-Isrc/main/native-glass/lens"].flatten()
 ANDROID.surface.linkFlags = [linkFlags, "-ldl", "-landroid", "-llog"].flatten()
@@ -299,8 +299,7 @@
     "com/sun/webkit/NativeWebView.class"
 ]
 ANDROID.webview.nativeSource = [
-    //file("modules/web/src/android/native/native_webview.c")
-    file("${closedDir}/javafx-android/webnode/jni/native_webview.c")
+    file("modules/web/src/android/native/native_webview.c")
 ]
 ANDROID.webview.compiler = compiler
 ANDROID.webview.linker = linker
@@ -316,12 +315,11 @@
     "com/sun/webkit/NativeWebView.class"
 ]
 ANDROID.dvkwebview.nativeSource = [
-    //file("modules/web/src/android/native/android_webview.c")
-    file("${closedDir}/javafx-android/webnode/jni/android_webview.c")
+    file("modules/web/src/android/native/android_webview.c")
 ]
 ANDROID.dvkwebview.compiler = compiler
 ANDROID.dvkwebview.linker = linker
-ANDROID.dvkwebview.lib = "android-webview"
+ANDROID.dvkwebview.lib = "android_webview"
 ANDROID.dvkwebview.ccFlags = [ccFlags, ccWarnFlags, ccArchFlags, ccOptFlags,
     ccDebugFlags, ccDefaultIncludeFlags].flatten()
 ANDROID.dvkwebview.linkFlags = [linkFlags, "-ldl", "-llog"].flatten()
@@ -342,7 +340,7 @@
     file("modules/graphics/src/main/native-glass/lens/wm/screen/androidScreen.c")]
 ANDROID.glass.eglfb.compiler = compiler
 ANDROID.glass.eglfb.linker = linker
-ANDROID.glass.eglfb.lib = "glass-lens-eglfb"
+ANDROID.glass.eglfb.lib = "glass_lens_eglfb"
 ANDROID.glass.eglfb.ccFlags = [ccFlags, ccWarnFlags, ccArchFlags, ccOptFlags,
     ccDebugFlags, ccDefaultIncludeFlags].flatten()
 ANDROID.glass.eglfb.linkFlags = [linkFlags, "-ldl", "-landroid", "-llog"].flatten()
@@ -355,7 +353,7 @@
     ccDebugFlags, ccDefaultIncludeFlags].flatten()
 ANDROID.prism.linker = linker
 ANDROID.prism.linkFlags = [linkFlags].flatten()
-ANDROID.prism.lib = "prism-common"
+ANDROID.prism.lib = "prism_common"
 
 ANDROID.prismSW = [:]
 ANDROID.prismSW.javahInclude = ["com/sun/pisces/**/*"]
@@ -365,7 +363,7 @@
     ccDebugFlags, ccDefaultIncludeFlags].flatten()
 ANDROID.prismSW.linker = linker
 ANDROID.prismSW.linkFlags = [linkFlags].flatten()
-ANDROID.prismSW.lib = "prism-sw"
+ANDROID.prismSW.lib = "prism_sw"
 
 ANDROID.decora = [:]
 ANDROID.decora.compiler = compiler
@@ -373,7 +371,7 @@
     ccDebugFlags, ccDefaultIncludeFlags].flatten()
 ANDROID.decora.linker = linker
 ANDROID.decora.linkFlags = [linkFlags].flatten()
-ANDROID.decora.lib = "decora-sse"
+ANDROID.decora.lib = "decora_sse"
 
 ANDROID.iio = [:]
 ANDROID.iio.javahInclude = ["com/sun/javafx/iio/**/*"]
@@ -385,7 +383,7 @@
     ccDebugFlags, ccDefaultIncludeFlags].flatten()
 ANDROID.iio.linker = linker
 ANDROID.iio.linkFlags = [linkFlags].flatten()
-ANDROID.iio.lib = "javafx-iio"
+ANDROID.iio.lib = "javafx_iio"
 
 ANDROID.prismES2 = [:]
 ANDROID.prismES2.variants = ["eglfb"]
@@ -401,7 +399,7 @@
     ccDebugFlags, ccDefaultIncludeFlags, "-DIS_EGLFB"].flatten()
 ANDROID.prismES2.eglfb.linker = linker
 ANDROID.prismES2.eglfb.linkFlags = [linkFlags, "-ldl", "-llog", "-lGLESv2", "-lEGL"].flatten()
-ANDROID.prismES2.eglfb.lib = "prism-es2-eglfb"
+ANDROID.prismES2.eglfb.lib = "prism_es2_eglfb"
 
 ANDROID.font = [:]
 ANDROID.font.javahInclude = [
@@ -413,7 +411,7 @@
     ccDebugFlags, ccDefaultIncludeFlags].flatten()
 ANDROID.font.linker = linker
 ANDROID.font.linkFlags = [linkFlags].flatten()
-ANDROID.font.lib = "javafx-font"
+ANDROID.font.lib = "javafx_font"
 
 ANDROID.fontT2K = [:]
 ANDROID.fontT2K.javahInclude = ["com/sun/javafx/font/t2k/**/*"]
@@ -426,4 +424,4 @@
     ccArchFlags, ccOptFlags, ccDebugFlags, ccDefaultIncludeFlags].flatten()
 ANDROID.fontT2K.linker = linker
 ANDROID.fontT2K.linkFlags = [linkFlags, "-lstdc++"].flatten()
-ANDROID.fontT2K.lib = "javafx-font-t2k"
\ No newline at end of file
+ANDROID.fontT2K.lib = "javafx_font_t2k"
--- a/buildSrc/ios.gradle	Tue Aug 06 10:13:00 2013 -0700
+++ b/buildSrc/ios.gradle	Tue Aug 06 14:14:24 2013 -0700
@@ -44,8 +44,10 @@
 
 defineProperty("USE_LIPO", "false")
 defineProperty("GENERATE_SYMBOLS", "false")
+defineProperty("BUILD_IOS_TOOLS", "true")
 if (USE_LIPO instanceof String) IOS.useLipo = Boolean.parseBoolean(USE_LIPO)
 if (GENERATE_SYMBOLS instanceof String) IOS.generateSymbols = Boolean.parseBoolean(GENERATE_SYMBOLS)
+if (BUILD_IOS_TOOLS instanceof String) ext.BUILD_IOS_TOOLS = Boolean.parseBoolean(BUILD_IOS_TOOLS)
 
 IOS.generateSymbolsExcludes = [
     "libprism_sw.a",
--- a/modules/graphics/src/android/java/com/oracle/dalvik/FXActivity.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/android/java/com/oracle/dalvik/FXActivity.java	Tue Aug 06 14:14:24 2013 -0700
@@ -102,6 +102,14 @@
         System.loadLibrary(ANDROID_WEBVIEW);
     }
 
+    @Override
+    protected void onDestroy() {
+        android.os.Process.killProcess(android.os.Process.myPid());
+        super.onDestroy();
+    }
+    
+    
+
     public static FXActivity getInstance() {
         return instance;
     }
@@ -157,6 +165,11 @@
         mView.requestFocus();
         imm.hideSoftInputFromWindow(mView.getWindowToken(), 0);
     }
+    
+    private void shutdown() {
+        Log.e(TAG, "VM SHUTDOWN");
+        finish();
+    }
 
     private void installJVMIfNeeded() {
         new InstallerTask().execute();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/android/java/com/oracle/dalvik/FXActivity.java.jfx78	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,333 @@
+package com.oracle.dalvik;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.Map.Entry;
+import java.util.Properties;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Configuration;
+import android.graphics.PixelFormat;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.FrameLayout;
+
+public class FXActivity extends Activity implements SurfaceHolder.Callback, SurfaceHolder.Callback2 {
+
+	private static final String TAG = "FXActivity";
+	
+	private static final String JAVAFX_APPLICATION_APPLICATION = "javafx.application.Application";
+
+	private static final String COM_SUN_JAVAFX_APPLICATION_LAUNCHERIMPL = "com.sun.javafx.application.LauncherImpl";
+
+	private static final String LAUNCH_APPLICATION_METHOD = "launchApplication";
+
+	private static final String MAIN_METHOD = "main";
+
+	private static final Class[] LAUNCH_APPLICATION_ARGS = new Class[] {
+			Class.class, Class.class, (new String[0]).getClass() };
+
+	private static final Class[] MAIN_METHOD_ARGS = new Class[] { 
+			(new String[0]).getClass() };
+
+//	private static final String JFX_APPLICATION_ATTRIBUTE = "JavaFX-Application-Class";
+    private static final String META_DATA_MAIN_CLASS = "main.class";
+	private static final String JFX_PRELOADER_ATTRIBUTE = "preloader.class";
+//	private static final String JFX_MAIN_ATTRIBUTE = "main.class";
+    private static final String GLASS_LENS_ANDROID = "glass_lens_android";
+	
+
+	private static int orientation;		
+//	private static FXActivity instance;
+	private static boolean fxApplicationLaunched = false;
+	private static boolean fxApplicationLaunching = false;
+	
+    private static FXActivity instance;
+    private static FrameLayout mViewGroup;
+    private static SurfaceView mView;
+
+    private String            appDataDir;
+    private String            storageDir;    
+    private NativePipeReader  reader;
+    private InputMethodManager imm;   
+    private String ldPath;
+    
+	public FXActivity() {
+		super();
+		
+		Properties userProperties = new Properties();
+//		try {
+//			userProperties.load(FXActivity.class.getResourceAsStream("/javafx.platform.properties"));
+//			for(Entry<Object, Object> e:userProperties.entrySet()) {
+//				System.setProperty((String)e.getKey(), (String)e.getValue());
+//			}
+//			System.getProperties().list(System.out);
+//			
+//		} catch (IOException e) {
+//			e.printStackTrace();
+//		}
+	}
+	
+//	public static FXActivity getInstance() {
+//		if (instance == null) {
+//			System.err.println("Activity not initialized.");
+//		}
+//		return instance;
+//	}
+	
+	@Override
+	public void onCreate(final Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		
+		//DEBUGGING
+		//Debug.waitForDebugger();										
+		//DEBUGGING
+		
+//        FXActivity.instance = this;    
+        
+        getWindow().requestFeature(Window.FEATURE_NO_TITLE);
+        getWindow().setSoftInputMode(
+                WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
+                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
+        getWindow().setFormat(PixelFormat.RGBA_8888);
+
+        imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+
+        mView = new FXActivity.InternalSurfaceView(this);
+        mView.getHolder().addCallback(this);        
+        mViewGroup = new FrameLayout(this);
+        mViewGroup.addView(mView);
+        setContentView(mViewGroup);
+        instance = this;        
+        System.loadLibrary(GLASS_LENS_ANDROID);
+//        System.loadLibrary(ANDROID_WEBVIEW);
+        
+        //AndroidViewGroup is FrameLayout and holds GLSurfaceView. 
+//        setContentView(AndroidViewGroup.getInstance());
+    	
+        //launch main class
+    	launchFXApplication();
+	}
+	
+    public static FXActivity getInstance() {
+        return instance;
+    }
+
+    public String getLDPath() {
+        if (appDataDir == null) {
+            appDataDir = this.getApplicationInfo().dataDir;
+        }
+        if (ldPath == null) {
+            ldPath = appDataDir + "/lib";
+        }
+        return ldPath;
+    }
+
+    public static ViewGroup getViewGroup() {
+        return mViewGroup;
+    }    
+	
+    @Override
+    public void surfaceCreated(SurfaceHolder holder) {
+            _surfaceChanged(holder.getSurface());
+    }
+
+    @Override
+    public void surfaceChanged(SurfaceHolder holder, int format, int width,
+                    int height) {
+            _surfaceChanged(holder.getSurface(), format, width, height);
+
+    }
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {
+            _surfaceChanged(null);
+    }
+
+    @Override
+    public void surfaceRedrawNeeded(SurfaceHolder holder) {
+            _surfaceRedrawNeeded(holder.getSurface());		
+    }
+
+    private native void _surfaceChanged(Surface surface);
+
+    private native void _surfaceChanged(Surface surface, int format, int width, int height);
+
+    private native void _surfaceRedrawNeeded(Surface surface);
+
+    private void showIME() {
+        mView.requestFocus();
+        imm.showSoftInput(mView, 0);
+    }
+
+    private void hideIME() {
+        mView.requestFocus();
+        imm.hideSoftInputFromWindow(mView.getWindowToken(), 0);
+    }
+    
+	@Override
+	public void onConfigurationChanged(Configuration newConfig) {
+		super.onConfigurationChanged(newConfig);
+//		if (newConfig.orientation != FXActivity.orientation) {
+//			Log.d(TAG, "orientation has changed");
+//			AndroidApplication.getInstance().notifyScreenSettingsChanged();
+//		}
+	}
+	
+	@Override
+	protected void onStart() {
+		super.onStart();
+		Log.d("onStart", "Activity started");
+//		Configuration startingConfiguration = getResources().getConfiguration();
+//		orientation = startingConfiguration.orientation;
+	}
+	
+	@Override
+	protected void onPause() {		
+		super.onPause();
+		Log.d("onPause", "Activity paused");
+	}
+	
+	@Override
+	protected void onResume() {
+		super.onResume();
+		Log.d("onResume", "Activity resumed");
+	}
+	
+	@Override
+	protected void onStop() {
+		super.onStop();
+		Log.d("onStop", "Activity stoped");
+	}
+	
+	@Override
+	protected void onRestart() {
+		super.onRestart();
+		Log.d("onRestart", "Activity re-started");
+	}
+	
+	public void launchFXApplication() {
+	    try {
+			final Class applicationClass = resolveApplicationClass();
+			final Class preloaderClass = resolvePreloaderClass();
+			final Class javafxApplicationClass = Class.forName(JAVAFX_APPLICATION_APPLICATION);
+			final Class javafxLauncherClass = Class.forName(COM_SUN_JAVAFX_APPLICATION_LAUNCHERIMPL);
+	
+			final Method launchMethod = javafxLauncherClass.getMethod(
+					LAUNCH_APPLICATION_METHOD, LAUNCH_APPLICATION_ARGS);
+						
+			
+			new Thread(new Runnable() {
+				public void run() {
+					fxApplicationLaunching = true;					
+					try {
+						if (javafxApplicationClass.isAssignableFrom(applicationClass)) {
+							launchMethod.invoke(null, new Object[] {
+									applicationClass, preloaderClass,
+									new String[] {} });
+						} else {
+							Method mainMethod = applicationClass.getMethod(
+									MAIN_METHOD, MAIN_METHOD_ARGS);
+							mainMethod.invoke(null,
+									new Object[] { new String[] {} });
+						}
+					} catch (Exception e) {
+						e.printStackTrace();
+					}
+					fxApplicationLaunched = true;
+					fxApplicationLaunching = false;
+				}
+			}, "Prelauncher Thread").start();
+	
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+    }
+    
+    private Bundle getMetadata() {
+        try {
+            ActivityInfo ai = FXActivity.this.getPackageManager().getActivityInfo(
+                    getIntent().getComponent(), PackageManager.GET_META_DATA);
+            return ai.metaData;
+
+        } catch(NameNotFoundException e) {
+            throw new RuntimeException("Error getting activity info", e);
+        }
+    }
+    
+    private Class resolveApplicationClass()
+			throws NameNotFoundException, ClassNotFoundException {
+
+		Class clazz = null;
+//		String applicationClassName = getPackageManager().getActivityInfo(
+//				new ComponentName(this, getClass()),
+//				PackageManager.GET_META_DATA).metaData
+//				.getString(JFX_APPLICATION_ATTRIBUTE);
+        String applicationClassName = getMetadata().getString(META_DATA_MAIN_CLASS);
+
+//		if (applicationClassName == null) {
+//			applicationClassName = getPackageManager().getActivityInfo(
+//					new ComponentName(this, getClass()),
+//					PackageManager.GET_META_DATA).metaData
+//					.getString(JFX_MAIN_ATTRIBUTE);
+//		}
+		if (applicationClassName != null && applicationClassName.length() > 0) {
+			clazz = Class.forName(applicationClassName);
+		}
+		return clazz;
+	}
+
+	private Class resolvePreloaderClass()
+			throws NameNotFoundException, ClassNotFoundException {
+
+		Class clazz = null;
+//		String className = getPackageManager().getActivityInfo(
+//				new ComponentName(this, getClass()),
+//				PackageManager.GET_META_DATA).metaData
+//				.getString(JFX_PRELOADER_ATTRIBUTE);
+
+        String className = getMetadata().getString(JFX_PRELOADER_ATTRIBUTE);
+		if (className != null && className.length() > 0) {
+			clazz = Class.forName(className);
+		}
+		return clazz;
+	}
+    
+    class InternalSurfaceView extends SurfaceView {
+
+        public InternalSurfaceView(Context context) {
+            super(context);
+            setFocusableInTouchMode(true);
+        }
+
+        @Override
+        public boolean dispatchTouchEvent(MotionEvent event) {
+            onTouchEventNative(event.getAction(), (int) event.getX(), (int) event.getY());
+            return true;
+        }
+
+        @Override
+        public boolean dispatchKeyEvent(KeyEvent event) {
+            onKeyEventNative(event.getAction(), event.getKeyCode(), event.getCharacters());
+            return true;
+        }
+
+        private native void onTouchEventNative(int action, int absx, int absy);
+
+        private native void onKeyEventNative(int action, int keycode, String characters);
+
+    }
+}
--- a/modules/graphics/src/android/java/com/oracle/dalvik/MainActivity.java	Tue Aug 06 10:13:00 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,258 +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.
- */
-package com.oracle.dalvik;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.util.ArrayList;
-import java.util.List;
-
-import android.app.Activity;
-import android.app.NativeActivity;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.ColorDrawable;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-
-
-public class MainActivity extends NativeActivity {
-
-    public static final String  TAG     = "MainActivity";
-    private static final String TAG_JVM = "JVM";
-    private static final String JAR     = ".jar";
-
-    private static final String META_DATA_MAIN_CLASS = "main.class";
-    private static final String META_DATA_JVM_ARGS   = "jvm.args";
-    private static final String META_DATA_APP_ARGS   = "app.args";
-    private static final String META_DATA_DEBUG_PORT = "debug.port";
-
-    private String                  appDataDir;
-    private String                  storageDir;    
-    private NativePipeReader        reader;
-    
-    private ViewGroup mViewGroup;
-    private View      mView;
-
-    static {
-        // load npr and vmlauncher
-        System.loadLibrary("vmlauncher");
-    }
-        
-    private NativePipeReader.OnTextReceivedListener textListener = 
-            new NativePipeReader.OnTextReceivedListener() {
-                public void onTextReceived(String text) {
-                    Log.v(TAG_JVM, text);
-                }
-            };
-
-    private void initDirInfo() {
-        appDataDir = this.getApplicationInfo().dataDir;
-        storageDir = appDataDir + "/storage";
-    }
-
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        getWindow().setFormat(PixelFormat.RGBA_8888);
-        getWindow().setSoftInputMode(
-                WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
-              | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
-
-        mViewGroup = (ViewGroup)getWindow().getDecorView()
-                    .findViewById(Window.ID_ANDROID_CONTENT);
-        mView = mViewGroup.getChildAt(0);
-        mView.setFocusableInTouchMode(true);
-
-        reader = NativePipeReader.getDefaultReader(textListener);
-        reader.start();
-        initDirInfo();
-        installJVMIfNeeded();
-    }
-
-    @Override
-    public boolean dispatchKeyEvent(KeyEvent event) {
-    	if (event.getAction() == KeyEvent.ACTION_MULTIPLE) {
-    		if (event.getKeyCode() == KeyEvent.KEYCODE_UNKNOWN) {
-    			Log.w(TAG, "KeyEvent (MULTIPLE) :" + event.getCharacters());
-    			Log.w(TAG, "Predictive text (T9) not supported!");
-    		}
-    	}
-    	return super.dispatchKeyEvent(event);
-    }
-    
-    private void installJVMIfNeeded() {
-        new InstallerTask().execute();
-    }
-
-    private void runJVM() {
-        Log.i(TAG, "Launch JVM + application");
-        JvmArgs args = new JvmArgs(appDataDir);
-        VMLauncher.initialize(args.getJavaHome());
-        VMLauncher.runOnDebugPort(args.getDebugPort(),
-                                  args.getArgArray());
-    }
-
-    private class InstallerTask extends AsyncTask<Void, Void, Void> {
-        protected Void doInBackground(Void... args) {
-           Log.i(TAG, "Installing JVM");
-            AppDataInstaller installer = 
-                new AppDataInstaller(storageDir,
-                                     MainActivity.this.getApplicationContext().getAssets());
-            installer.install();
-            return null;
-        }
-        protected void onPostExecute(Void result) {
-           Log.i(TAG, "JVM Installed");
-            runJVM();
-        }
-    }
-
-
-    private class JvmArgs {
-        private List<String> argList = new ArrayList<String>();
-        private String javaHome;
-
-        public JvmArgs(String appDir) {
-            String jvmRunCommand =
-                   "-Djava.library.path="
-                     + appDir + "/lib|"
-                     + "-Djava.home="
-                     + appDir + "/storage/jvm|"
-                     + "-Dsun.boot.library.path="
-                     + appDir + "/storage/jvm/lib|"
-                     + "-cp|"
-                     + getClasspath(appDir)
-                     + "|"                                         
-                     + "-Djavafx.platform=android|"
-                     + "-Djavafx.runtime.path="
-                     + appDir +"/storage/lib|"
-                     + getCustomJVMArgs()
-                     + "|"
-                     + getMainClass()
-                     + "|"
-                     + getApplicationArgs();
-
-            createArgList(jvmRunCommand);
-        }
-
-        private String[] listFiles(String dir, final String suffix) {
-           File dirf = new File(dir);
-           if (!dirf.exists()) {
-               return new String[]{};
-           }
-           String[] files = dirf.list(new FilenameFilter() {           
-               @Override
-               public boolean accept(File dir, String filename) {      
-                   return filename.endsWith(suffix);
-               }
-           });
-           return files;
-       }
-
-       private String getClasspath(String appDir) {
-           final String libDir = appDir + "/storage/lib/";
-           String[] libfiles = listFiles(libDir, JAR);
-           if (libfiles.length == 0) {
-               return "";
-           }
-           StringBuilder sb = new StringBuilder();
-           for(String file: libfiles) {
-               sb.append(libDir);
-               sb.append(file);
-               sb.append(File.pathSeparatorChar);
-           }
-           int len = sb.length();
-           return sb.substring(0, len - 1);
-       }
-
-       private String getMainClass() {
-           return getMetadata().getString(META_DATA_MAIN_CLASS);
-       }
-
-       private String getCustomJVMArgs() {
-           return getMetadata().getString(META_DATA_JVM_ARGS);
-       }
-
-       private String getApplicationArgs() {
-           return getMetadata().getString(META_DATA_APP_ARGS);
-       }
-
-       private int getDebugPort() {            
-           return getMetadata().getInt(META_DATA_DEBUG_PORT, 0);
-       }
-
-       private Bundle getMetadata() {
-           try {
-               ActivityInfo ai = MainActivity.this.getPackageManager().getActivityInfo(
-                       getIntent().getComponent(), PackageManager.GET_META_DATA);
-               return ai.metaData;
-               
-           } catch(NameNotFoundException e) {
-               throw new RuntimeException("Error getting activity info", e);
-           }
-       }
-
-        public void createArgList(String args) {
-            if (args != null) {
-                String sep = (args.contains("|")) ? "\\|" : " ";
-                for (String arg : args.split(sep)) {
-                    arg = arg.trim();
-                    if (arg.length() > 0) {
-                        this.argList.add(arg);
-                        if (javaHome == null) {
-                            String[] pair = arg.split("\\=");
-                            Log.v(TAG, "arg = " + arg);
-                            Log.v(TAG, "pair.length = " + pair.length);
-                            if (pair.length == 2) {
-                                if ("-Djava.home".equals(pair[0])) {
-                                    Log.v(TAG, "Setting javaHome to " + pair[1]);
-                                    javaHome = pair[1];
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        public String[] getArgArray() {
-            return argList.toArray(new String[0]);
-        }
-
-        public String getJavaHome() {
-           return javaHome;
-        }
-
-   }
-}
--- a/modules/graphics/src/android/java/com/oracle/dalvik/NativePipeReader.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/android/java/com/oracle/dalvik/NativePipeReader.java	Tue Aug 06 14:14:24 2013 -0700
@@ -65,6 +65,8 @@
     private Handler handler;
 
     public NativePipeReader(Client client) {
+        super("NativePipeReader");
+        setDaemon(true);
         this.client = client;
         this.handler = new Handler();    
     }
--- a/modules/graphics/src/android/java/com/oracle/dalvik/VMLauncher.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/android/java/com/oracle/dalvik/VMLauncher.java	Tue Aug 06 14:14:24 2013 -0700
@@ -95,7 +95,8 @@
     }
 
     private VMLauncher(String[] args) {
-        super("JVM");
+        super("VMLauncher");
+        setDaemon(true);
         this.args = args;
     }
 
--- a/modules/graphics/src/main/java/com/sun/glass/ui/Application.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/Application.java	Tue Aug 06 14:14:24 2013 -0700
@@ -41,7 +41,8 @@
 
 public abstract class Application {
 
-    protected String name;
+    private final static String DEFAULT_NAME = "java";
+    protected String name = DEFAULT_NAME;
 
     public static class EventHandler {
         // currently used only on Mac OS X
@@ -146,7 +147,7 @@
         // on Mac OS X - use NSBundle info, which can be overriden by -Xdock:name
         // on Windows - TODO
         // on Linux - TODO
-        application.name = "java"; // default
+        //application.name = DEFAULT_NAME; // default
         try {
             application.runLoop(new Runnable() {
                 @Override public void run() {
@@ -169,10 +170,50 @@
         // The eventThread is null at this point, no need to check it
     }
     
+    /**
+     * Gets the name for the application.  The application name may
+     * be used to identify the application in the user interface or
+     * as part of the platform specific path used to store application
+     * data.
+     * 
+     * This is a hint and may not be used on some platforms.
+     * 
+     * @return the application name
+     */
     public String getName() {
         checkEventThread();
         return name;
     }
+    
+    /**
+     * Sets the name for the application.  The application name may
+     * be used to identify the application in the user interface or
+     * as part of the platform specific path used to store application
+     * data.
+     * 
+     * This is a hint and may not be used on some platforms.
+     * 
+     * @param name the new application name
+     */
+    public void setName(String name) {
+        checkEventThread();
+        this.name = name == null ? DEFAULT_NAME : name;
+    }
+
+    /**
+     * Gets a platform specific path that can be used to store
+     * application data.  The application name typically appears
+     * as part of the path.
+     * 
+     * On some platforms, the path may not yet exist and the caller
+     * will need to create it.
+     * 
+     * @return the platform specific path for the application data
+     */
+    public String getDataDirectory() {
+        checkEventThread();
+        return System.getProperty("user.home") + File.separator + "." + name + File.separator;
+    }
 
     private void notifyWillFinishLaunching() {
         EventHandler handler = getEventHandler();
--- a/modules/graphics/src/main/java/com/sun/glass/ui/lens/LensTouchInputSupport.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/lens/LensTouchInputSupport.java	Tue Aug 06 14:14:24 2013 -0700
@@ -33,11 +33,35 @@
 import com.sun.glass.ui.Application;
 import com.sun.glass.ui.View;
 
-import java.util.LinkedList;
-import java.util.Hashtable;
+import java.lang.Integer;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
 
 final class LensTouchInputSupport {
 
+    private static final int touchTapRadius;
+    private static final int touchReleasePendingTimeout;
+
+    static {
+        touchTapRadius = AccessController.doPrivileged(
+        new PrivilegedAction<Integer>() {
+            @Override
+            public Integer run() {
+                return Integer.getInteger("lens.touchTapRadius", 20);
+            }
+        });
+
+        touchReleasePendingTimeout = AccessController.doPrivileged(
+        new PrivilegedAction<Integer>() {
+            @Override
+            public Integer run() {
+                return Integer.getInteger("lens.touchReleasePendingTimeout", 50);
+            }
+        });
+    }
+
+
     private final static GestureSupport gestures = new GestureSupport(false);
     private final static TouchInputSupport touches =
         new TouchInputSupport(gestures.createTouchCountListener(), false);
--- a/modules/graphics/src/main/java/com/sun/glass/ui/mac/MacApplication.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/mac/MacApplication.java	Tue Aug 06 14:14:24 2013 -0700
@@ -292,4 +292,14 @@
     public String getRemoteLayerServerName() {
         return _getRemoteLayerServerName();
     }
+    
+    private native String _getDataDirectory();
+    public String getDataDirectory() {
+        checkEventThread();
+        String baseDirectory = _getDataDirectory();
+        if (baseDirectory == null || baseDirectory.length() == 0) {
+            return super.getDataDirectory();
+        }
+        return baseDirectory + File.separator + name + File.separator;
+    }
 }
--- a/modules/graphics/src/main/java/com/sun/glass/ui/win/WinApplication.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/win/WinApplication.java	Tue Aug 06 14:14:24 2013 -0700
@@ -247,4 +247,17 @@
     }
 
     @Override native protected boolean _supportsUnifiedWindows();
+    
+    public String getDataDirectory() {
+        checkEventThread();
+        String baseDirectory = AccessController.doPrivileged(new PrivilegedAction<String>() {
+            @Override public String run() {
+                return System.getenv("APPDATA");
+            }
+        });
+        if (baseDirectory == null || baseDirectory.length() == 0) {
+            return super.getDataDirectory();
+        }
+        return baseDirectory + File.separator + name + File.separator;
+    }
 }
--- a/modules/graphics/src/main/java/com/sun/javafx/application/LauncherImpl.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/application/LauncherImpl.java	Tue Aug 06 14:14:24 2013 -0700
@@ -767,6 +767,7 @@
                     app = c.newInstance();
                     // Set startup parameters
                     ParametersImpl.registerParameters(app, new ParametersImpl(args));
+                    PlatformImpl.setApplicationName(appClass);
                 } catch (Throwable t) {
                     System.err.println("Exception in Application constructor");
                     constructorError = t;
--- a/modules/graphics/src/main/java/com/sun/javafx/application/PlatformImpl.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/application/PlatformImpl.java	Tue Aug 06 14:14:24 2013 -0700
@@ -98,6 +98,23 @@
     }
 
     /**
+     * Sets the name of the this application based on the Application class.
+     * This method is called by the launcher or by the deploy code, and is not
+     * called from the FX Application Thread, so we need to do it in a runLater.
+     * We do not need to wait for the result since it will complete before the
+     * Application start() method is called regardless.
+     *
+     * @param appClass the Application class.
+     */
+    public static void setApplicationName(final Class appClass) {
+        runLater(new Runnable() {
+            @Override public void run() {
+                com.sun.glass.ui.Application.GetApplication().setName(appClass.getName());
+            }
+        });
+    }
+
+    /**
      * Return whether or not focus navigation between controls is context-
      * sensitive.
      * @return true if the context-sensitive algorithm for focus navigation is
--- a/modules/graphics/src/main/java/com/sun/javafx/font/PrismFontStrike.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/PrismFontStrike.java	Tue Aug 06 14:14:24 2013 -0700
@@ -27,6 +27,7 @@
 
 import java.util.HashMap;
 import java.util.Map;
+
 import com.sun.javafx.geom.Path2D;
 import com.sun.javafx.geom.Shape;
 import com.sun.javafx.geom.transform.Affine2D;
@@ -154,7 +155,8 @@
     protected abstract Glyph createGlyph(int glyphCode);
 
     protected Glyph createGlyph(GlyphList gl, int gi) {
-        return createGlyph(gl.getGlyphCode(gi));
+        int glyphCode = gl.getGlyphCode(gi) & CompositeGlyphMapper.GLYPHMASK;
+        return createGlyph(glyphCode);
     }
 
     public Glyph getGlyph(int glyphCode) {
@@ -167,7 +169,7 @@
     }
 
     public Glyph getGlyph(GlyphList gl, int gi) {
-        int glyphCode = gl.getGlyphCode(gi);
+        int glyphCode = gl.getGlyphCode(gi) & CompositeGlyphMapper.GLYPHMASK;
         Glyph glyph = glyphMap.get(glyphCode);
         if (glyph == null) {
             glyph = createGlyph(gl, gi);
--- a/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWFontFile.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWFontFile.java	Tue Aug 06 14:14:24 2013 -0700
@@ -126,9 +126,9 @@
         DWRITE_GLYPH_METRICS metrics = fontFace.GetDesignGlyphMetrics((short)gc, false);
         int[] bb = new int[4];
         bb[0] = metrics.leftSideBearing;
-        bb[1] = metrics.topSideBearing;
+        bb[1] = metrics.verticalOriginY - metrics.advanceHeight + metrics.bottomSideBearing;
         bb[2] = metrics.advanceWidth - metrics.rightSideBearing;
-        bb[3] = metrics.verticalOriginY;
+        bb[3] = metrics.verticalOriginY - metrics.topSideBearing;
         return bb;
     }
 
--- a/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWFontStrike.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWFontStrike.java	Tue Aug 06 14:14:24 2013 -0700
@@ -25,6 +25,7 @@
 
 package com.sun.javafx.font.directwrite;
 
+import com.sun.javafx.font.CompositeGlyphMapper;
 import com.sun.javafx.font.DisposerRecord;
 import com.sun.javafx.font.FontStrikeDesc;
 import com.sun.javafx.font.Glyph;
@@ -105,7 +106,7 @@
         Point2D offset = (Point2D)((TextRun)gl).getGlyphData(gi);
         float advanceOffset = offset != null ? offset.x : 0;
         float ascenderOffset = offset != null ? offset.y : 0;
-        int gc = gl.getGlyphCode(gi);
+        int gc = gl.getGlyphCode(gi) & CompositeGlyphMapper.GLYPHMASK;
         if (PrismFontFactory.debugFonts) {
             if (advanceOffset != 0 || ascenderOffset != 0) {
                 System.err.println("Setting glyph[" + Integer.toHexString(gc) +
--- a/modules/graphics/src/main/java/com/sun/javafx/image/PixelUtils.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/image/PixelUtils.java	Tue Aug 06 14:14:24 2013 -0700
@@ -27,6 +27,7 @@
 
 import com.sun.javafx.image.impl.ByteBgra;
 import com.sun.javafx.image.impl.ByteBgraPre;
+import com.sun.javafx.image.impl.ByteIndexed;
 import com.sun.javafx.image.impl.ByteRgb;
 import com.sun.javafx.image.impl.General;
 import com.sun.javafx.image.impl.IntArgb;
@@ -95,6 +96,8 @@
                 return ByteBgraPre.getter;
             case BYTE_RGB:
                 return ByteRgb.getter;
+            case BYTE_INDEXED:
+                return ByteIndexed.createGetter(pf);
             case INT_ARGB:
             case INT_ARGB_PRE:
                 // Impossible
@@ -219,6 +222,11 @@
             } else if (dst ==       ByteBgraPre.setter) {
                 return    ByteRgb.ToByteBgraPreConverter;
             }
+        } else if (src instanceof ByteIndexed.Getter) {
+            if (dst == ByteBgra.setter || dst == ByteBgraPre.setter) {
+                return ByteIndexed.createToByteBgraAny((BytePixelGetter) src,
+                                                       (BytePixelSetter) dst);
+            }
         }
         return General.create((BytePixelGetter) src, (BytePixelSetter) dst);
     }
@@ -244,6 +252,11 @@
             } else if (dst ==       IntArgbPre.setter) {
                 return    ByteRgb.ToIntArgbPreConverter;
             }
+        } else if (src instanceof ByteIndexed.Getter) {
+            if (dst == IntArgb.setter || dst == IntArgbPre.setter) {
+                return ByteIndexed.createToIntArgbAny((BytePixelGetter) src,
+                                                      (IntPixelSetter)  dst);
+            }
         }
         return General.create((BytePixelGetter) src, (IntPixelSetter) dst);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/javafx/image/impl/ByteIndexed.java	Tue Aug 06 14:14:24 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 com.sun.javafx.image.impl;
+
+import com.sun.javafx.image.AlphaType;
+import com.sun.javafx.image.BytePixelGetter;
+import com.sun.javafx.image.BytePixelSetter;
+import com.sun.javafx.image.ByteToBytePixelConverter;
+import com.sun.javafx.image.ByteToIntPixelConverter;
+import com.sun.javafx.image.IntPixelSetter;
+import com.sun.javafx.image.PixelSetter;
+import com.sun.javafx.tk.Toolkit;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import javafx.scene.image.PixelFormat;
+
+public class ByteIndexed {
+    public static BytePixelGetter createGetter(PixelFormat<ByteBuffer> pf) {
+        return new Getter(pf);
+    }
+
+    public static ByteToBytePixelConverter
+        createToByteBgraAny(BytePixelGetter src,
+                            BytePixelSetter dst)
+    {
+        return new ToByteBgraAnyConverter(src, dst);
+    }
+
+    public static ByteToIntPixelConverter
+        createToIntArgbAny(BytePixelGetter src,
+                           IntPixelSetter dst)
+    {
+        return new ToIntArgbAnyConverter(src, dst);
+    }
+
+    public static class Getter implements BytePixelGetter {
+        PixelFormat<ByteBuffer> theFormat;
+        private int precolors[];
+        private int nonprecolors[];
+
+        Getter(PixelFormat<ByteBuffer> pf) {
+            theFormat = pf;
+        }
+
+        int[] getPreColors() {
+            if (precolors == null) {
+                precolors = Toolkit.getImageAccessor().getPreColors(theFormat);
+            }
+            return precolors;
+        }
+
+        int[] getNonPreColors() {
+            if (nonprecolors == null) {
+                nonprecolors = Toolkit.getImageAccessor().getNonPreColors(theFormat);
+            }
+            return nonprecolors;
+        }
+
+        @Override
+        public AlphaType getAlphaType() {
+            return theFormat.isPremultiplied()
+                    ? AlphaType.PREMULTIPLIED
+                    : AlphaType.NONPREMULTIPLIED;
+        }
+
+        @Override
+        public int getNumElements() {
+            return 1;
+        }
+
+        @Override
+        public int getArgb(byte[] arr, int offset) {
+            return getNonPreColors()[arr[offset] & 0xff];
+        }
+
+        @Override
+        public int getArgbPre(byte[] arr, int offset) {
+            return getPreColors()[arr[offset] & 0xff];
+        }
+
+        @Override
+        public int getArgb(ByteBuffer buf, int offset) {
+            return getNonPreColors()[buf.get(offset) & 0xff];
+        }
+
+        @Override
+        public int getArgbPre(ByteBuffer buf, int offset) {
+            return getPreColors()[buf.get(offset) & 0xff];
+        }
+    }
+
+    static int[] getColors(BytePixelGetter getter, PixelSetter setter) {
+        ByteIndexed.Getter big = (ByteIndexed.Getter) getter;
+        return (setter.getAlphaType() == AlphaType.PREMULTIPLIED)
+                ? big.getPreColors()
+                : big.getNonPreColors();
+    }
+
+    public static class ToByteBgraAnyConverter extends BaseByteToByteConverter {
+        public ToByteBgraAnyConverter(BytePixelGetter getter, BytePixelSetter setter) {
+            super(getter, setter);
+        }
+
+        @Override
+        void doConvert(byte[] srcarr, int srcoff, int srcscanbytes,
+                       byte[] dstarr, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            int colors[] = getColors(getGetter(), getSetter());
+
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int argb = colors[srcarr[srcoff + x] & 0xff];
+                    dstarr[dstoff++] = (byte) (argb      );
+                    dstarr[dstoff++] = (byte) (argb >>  8);
+                    dstarr[dstoff++] = (byte) (argb >> 16);
+                    dstarr[dstoff++] = (byte) (argb >> 24);
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            int colors[] = getColors(getGetter(), getSetter());
+
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int argb = colors[srcbuf.get(srcoff + x) & 0xff];
+                    dstbuf.put(dstoff    , (byte) (argb      ));
+                    dstbuf.put(dstoff + 1, (byte) (argb >>  8));
+                    dstbuf.put(dstoff + 2, (byte) (argb >> 16));
+                    dstbuf.put(dstoff + 3, (byte) (argb >> 24));
+                    dstoff += 4;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+
+    public static class ToIntArgbAnyConverter extends BaseByteToIntConverter {
+        public ToIntArgbAnyConverter(BytePixelGetter getter, IntPixelSetter setter) {
+            super(getter, setter);
+        }
+
+        @Override
+        void doConvert(byte[] srcarr, int srcoff, int srcscanbytes,
+                       int[]  dstarr, int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            int colors[] = getColors(getGetter(), getSetter());
+
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    dstarr[dstoff + x] = colors[srcarr[srcoff + x] & 0xff];
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanints;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       IntBuffer  dstbuf, int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            int colors[] = getColors(getGetter(), getSetter());
+
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    dstbuf.put(dstoff + x, colors[srcbuf.get(srcoff + x) & 0xff]);
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanints;
+            }
+        }
+    }
+}
--- a/modules/graphics/src/main/java/com/sun/javafx/scene/text/TextLayout.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/scene/text/TextLayout.java	Tue Aug 06 14:14:24 2013 -0700
@@ -40,7 +40,9 @@
     static final int FLAGS_HAS_EMBEDDED     = 1 << 5;
     static final int FLAGS_WRAPPED          = 1 << 6;
     static final int FLAGS_RTL_BASE         = 1 << 7;
-    static final int FLAGS_LAST             = 1 << 8;
+    static final int FLAGS_CACHED_UNDERLINE      = 1 << 8;
+    static final int FLAGS_CACHED_STRIKETHROUGH  = 1 << 9;
+    static final int FLAGS_LAST             = 1 << 10;
 
     static final int ANALYSIS_MASK = FLAGS_LAST - 1;
 
@@ -138,6 +140,13 @@
     public BaseBounds getBounds(TextSpan filter, BaseBounds bounds);
 
     /**
+     * Returns the visual bounds of the layout using glyph bounding box
+     *
+     * @return the visual bounds
+     */
+    public BaseBounds getVisualBounds(int type);
+    
+    /**
      * Returns the lines of text layout.
      * 
      * @return the text lines
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGBox.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGBox.java	Tue Aug 06 14:14:24 2013 -0700
@@ -25,23 +25,11 @@
 
 package com.sun.javafx.sg.prism;
 
-import com.sun.prism.Graphics;
-
 /**
  * TODO: 3D - Need documentation
  */
 public class NGBox extends NGShape3D {
 
-    private NGTriangleMesh mesh;
-
-    @Override
-    protected void renderMeshView(Graphics g) {
-        if (getMesh() == null) {
-            setMesh(mesh);
-        }
-        super.renderMeshView(g);
-    }
-
     public void updateMesh(NGTriangleMesh mesh) {
         this.mesh = mesh;
         invalidate();
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGCylinder.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGCylinder.java	Tue Aug 06 14:14:24 2013 -0700
@@ -25,23 +25,11 @@
 
 package com.sun.javafx.sg.prism;
 
-import com.sun.prism.Graphics;
-
 /**
  * TODO: 3D - Need documentation
  */
 public class NGCylinder extends NGShape3D {
 
-    private NGTriangleMesh mesh;
-
-    @Override
-    protected void renderMeshView(Graphics g) {
-        if (getMesh() == null) {
-            setMesh(mesh);
-        }
-        super.renderMeshView(g);
-    }
-
     public void updateMesh(NGTriangleMesh mesh) {
         this.mesh = mesh;
         invalidate();
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGNode.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGNode.java	Tue Aug 06 14:14:24 2013 -0700
@@ -1548,6 +1548,9 @@
             }
         }
 
+        // save current depth test state
+        boolean prevDepthTest = g.isDepthTest();
+
         // Apply Depth test for this node
         // (note that this will only be used if we have a depth buffer for the
         // surface to which we are rendering)
@@ -1604,6 +1607,9 @@
                          myx, myy, myz, myt,
                          mzx, mzy, mzz, mzt);
         
+        // restore previous depth test state
+        g.setDepthTest(prevDepthTest);
+
         if (PULSE_LOGGING_ENABLED) PULSE_LOGGER.renderIncrementCounter("Nodes rendered");
     }
 
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGRegion.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGRegion.java	Tue Aug 06 14:14:24 2013 -0700
@@ -42,7 +42,6 @@
 import javafx.scene.layout.CornerRadii;
 import javafx.scene.paint.Color;
 import javafx.scene.paint.LinearGradient;
-import javafx.scene.paint.RadialGradient;
 import javafx.scene.shape.StrokeLineCap;
 import javafx.scene.shape.StrokeLineJoin;
 import javafx.scene.shape.StrokeType;
@@ -89,6 +88,16 @@
     private static final RegionImageCache CACHE = new RegionImageCache();
 
     /**
+     * Indicates the cached image can be sliced vertically.
+     */
+    private static final int CACHE_SLICE_V = 0x1;
+
+    /**
+     * Indicates the cached image can be sliced horizontally.
+     */
+    private static final int CACHE_SLICE_H = 0x2;
+
+    /**
      * The background to use for drawing. Since this is an immutable object, I can simply refer to
      * its fields / methods directly when rendering. I will make sure this is not ever null at
      * the time that we do the sync, so that the code in this class can assume non-null.
@@ -148,18 +157,18 @@
     private float width, height;
 
     /**
+     * Determined when a background is set on the region, this flag indicates whether this
+     * background can be cached. As of this time, the only backgrounds which can be cached
+     * are those where there are only solid fills or linear gradients.
+     */
+    private int cacheMode;
+
+    /**
      * Simple Helper Function for cleanup.
      */
     static Paint getPlatformPaint(javafx.scene.paint.Paint paint) {
         return (Paint)Toolkit.getPaintAccessor().getPlatformPaint(paint);
     }
-    
-    /**
-     * Determined when a background is set on the region, this flag indicates whether this
-     * background can be cached. As of this time, the only backgrounds which can be cached
-     * are those where there are only solid fills or vertical linear gradients.
-     */
-    private boolean backgroundCanBeCached;
 
     // We create a class instance of a no op. Effect internally to handle 3D
     // transform if user didn't use Effect for 3D Transformed Region. This will
@@ -240,23 +249,31 @@
         background = b == null ? Background.EMPTY : (Background) b;
 
         final List<BackgroundFill> fills = background.getFills();
-        backgroundCanBeCached = !PrismSettings.disableRegionCaching && !fills.isEmpty() && (shape == null || cacheShape);
-        if (backgroundCanBeCached) {
-            for (int i=0, max=fills.size(); i<max && backgroundCanBeCached; i++) {
+        cacheMode = 0;
+        if (!PrismSettings.disableRegionCaching && !fills.isEmpty() && (shape == null || cacheShape)) {
+            cacheMode = CACHE_SLICE_H | CACHE_SLICE_V;
+            for (int i=0, max=fills.size(); i<max && cacheMode != 0; i++) {
                 // We need to now inspect the paint to determine whether we can use a cache for this background.
                 // If a shape is being used, we don't care about gradients (we cache 'em both), but for a rectangle
                 // fill we omit these (so we can do 3-patch scaling). An ImagePattern is deadly to either
                 // (well, only deadly to a shape if it turns out to be a writable image).
                 final BackgroundFill fill = fills.get(i);
                 javafx.scene.paint.Paint paint = fill.getFill();
-                if ((shape == null && paint instanceof RadialGradient) || paint instanceof javafx.scene.paint.ImagePattern) {
-                    backgroundCanBeCached = false;
-                }
-                if (shape == null && paint instanceof LinearGradient) {
-                    LinearGradient linear = (LinearGradient) paint;
-                    if (linear.getStartX() != linear.getEndX()) {
-                        backgroundCanBeCached = false;
+                if (shape == null) {
+                    if (paint instanceof LinearGradient) {
+                        LinearGradient linear = (LinearGradient) paint;
+                        if (linear.getStartX() != linear.getEndX()) {
+                            cacheMode &= ~CACHE_SLICE_H;
+                        }
+                        if (linear.getStartY() != linear.getEndY()) {
+                            cacheMode &= ~CACHE_SLICE_V;
+                        }
+                    } else if (!(paint instanceof Color)) {
+                        //Either radial gradient or image pattern
+                        cacheMode = 0;
                     }
+                } else if (paint instanceof javafx.scene.paint.ImagePattern) {
+                    cacheMode = 0;
                 }
             }
         }
@@ -498,7 +515,7 @@
 
                 // RT-25013: We need to make sure that we do not use a cached image in the case of a
                 // scaled region, or things won't look right (they'll looked scaled instead of vector-resized).
-                final boolean cache = backgroundCanBeCached && g.getTransformNoClone().isTranslateOrIdentity();
+                final boolean cache = cacheMode != 0 && g.getTransformNoClone().isTranslateOrIdentity();
                 RTTexture cached = cache ? CACHE.getImage(g.getAssociatedScreen(), textureWidth, textureHeight, background, shape) : null;
                 if (cached != null) {
                     cached.lock();
@@ -620,7 +637,6 @@
             }
         } else if (width > 0 && height > 0) {
             if (!background.isEmpty()) {
-                final Insets outsets = background.getOutsets();
                 // cacheWidth is the width of the region used within the cached image. For example,
                 // perhaps normally the width of a region is 200px. But instead I will render the
                 // region as though it is 20px wide instead into the cached image. 20px in this
@@ -631,184 +647,159 @@
                 if (backgroundInsets == null) updateBackgroundInsets();
                 final double leftInset = backgroundInsets.getLeft() + 1;
                 final double rightInset = backgroundInsets.getRight() + 1;
-                int cacheWidth = (int) (leftInset + rightInset);
+                final double topInset = backgroundInsets.getTop() + 1;
+                final double bottomInset = backgroundInsets.getBottom() + 1;
+
                 // If the insets are too large, then we want to use the width of the region instead of the
                 // computed cacheWidth. RadioButton enters this case
-                cacheWidth = Math.min(cacheWidth, roundUp(width));
+                int cacheWidth = roundUp(width);
+                if ((cacheMode & CACHE_SLICE_H) != 0) {
+                    cacheWidth = Math.min(cacheWidth, (int) (leftInset + rightInset));
+                }
+                int cacheHeight = roundUp(height);
+                if ((cacheMode & CACHE_SLICE_V) != 0) {
+                    cacheHeight = Math.min(cacheHeight, (int) (topInset + bottomInset));
+                }
+
+                final Insets outsets = background.getOutsets();
+                final int outsetsLeft = roundUp(outsets.getLeft());
+                final int outsetsTop = roundUp(outsets.getTop());
+                final int outsetsRight = roundUp(outsets.getRight());
+                final int outsetsBottom = roundUp(outsets.getRight());
+
                 // The textureWidth / textureHeight is the width/height of the actual image. This needs to be rounded
                 // up to the next whole pixel value.
-                final int textureWidth = cacheWidth + roundUp(outsets.getLeft()) + roundUp(outsets.getRight()),
-                          textureHeight = roundUp(height) + roundUp(outsets.getTop()) + roundUp(outsets.getBottom());
+                final int textureWidth = outsetsLeft + cacheWidth + outsetsRight;
+                final int textureHeight = outsetsTop + cacheHeight + outsetsBottom;
 
                 // See if we have a cached representation for this region background already.
                 // RT-25013: We need to make sure that we do not use a cached image in the case of a
                 // scaled region, or things won't look right (they'll looked scaled instead of vector-resized).
-                // RT_25049: Need to only use the cache for pixel aligned regions or the result
+                // RT-25049: Need to only use the cache for pixel aligned regions or the result
                 // will not look the same as though drawn by vector
                 final boolean cache =
-                        height < 256 &&
                         background.getFills().size() > 1 && // Not worth the overhead otherwise
-                        (width - (int)width == 0) &&
-                        backgroundCanBeCached &&
+                        width == (int)width &&
+                        height == (int)height &&
+                        cacheMode != 0 &&
                         g.getTransformNoClone().isTranslateOrIdentity();
-                RTTexture cached = cache ? CACHE.getImage(g.getAssociatedScreen(), textureWidth, textureHeight, background) : null;
-                if (cached != null) {
-                    cached.lock();
-                    if (cached.isSurfaceLost()) {
-                        cached = null;
+                RTTexture cached = null;
+                if (cache && CACHE.isImageCachable(textureWidth, textureHeight)) {
+                    cached = CACHE.getImage(g.getAssociatedScreen(), textureWidth, textureHeight, background);
+                    if (cached != null) {
+                        cached.lock();
+                        if (cached.isSurfaceLost()) {
+                            cached = null;
+                        }
                     }
-                }
-                // If there is not a cached texture already, then we need to render everything
-                if (cached == null) {
-                    // We will here check to see if we CAN cache the region background. If not, then
-                    // we will render as normal. If we can cache it, however, then we will setup a
-                    // texture and swizzle rendering onto the RTTexture's graphics, and then at the
-                    // end do 3-patch from the texture onto the graphics object we were passed.
-                    Graphics old = null;
-                    float oldWidth = width;
-                    if (cache && CACHE.isImageCachable(textureWidth, textureHeight)) {
-                        old = g;
-                        width = cacheWidth;
-                        cached = g.getResourceFactory().createRTTexture(textureWidth, textureHeight,
-                                                                        WrapMode.CLAMP_TO_ZERO);
+                    if (cached == null) {
+                        cached = g.getResourceFactory().createRTTexture(textureWidth, textureHeight, WrapMode.CLAMP_TO_ZERO);
                         cached.contentsUseful();
-                        g = cached.createGraphics();
+                        CACHE.setImage(cached, g.getAssociatedScreen(), textureWidth, textureHeight, background);
+                        if (PulseLogger.PULSE_LOGGING_ENABLED) {
+                            PulseLogger.PULSE_LOGGER.renderIncrementCounter("Region background image cached");
+                        }
+
+                        Graphics cacheGraphics = cached.createGraphics();
                         // Have to move the origin such that when rendering to x=0, we actually end up rendering
                         // at x=outsets.getLeft(). Otherwise anything rendered to the left of the origin would be lost
                         // Round up to the nearest pixel
-                        g.translate(roundUp(outsets.getLeft()), roundUp(outsets.getTop()));
-                        CACHE.setImage(cached, old.getAssociatedScreen(), textureWidth, textureHeight, background);
-                        if (PulseLogger.PULSE_LOGGING_ENABLED) {
-                            PulseLogger.PULSE_LOGGER.renderIncrementCounter("Region background image cached");
-                        }
+                        cacheGraphics.translate(outsetsLeft, outsetsTop);
+
+                        //rendering backgrounds to the cache
+                        renderBackgrounds(cacheGraphics, cacheWidth, cacheHeight);
                     }
-
-                    // Paint in order each BackgroundFill.
-                    final List<BackgroundFill> fills = background.getFills();
-                    for (int i = 0, max = fills.size(); i < max; i++) {
-                        final BackgroundFill fill = fills.get(i);
-                        final Insets insets = fill.getInsets();
-                        final float t = (float) insets.getTop(),
-                                l = (float) insets.getLeft(),
-                                b = (float) insets.getBottom(),
-                                r = (float) insets.getRight();
-                        // w and h is the width and height of the area to be filled (width and height less insets)
-                        float w = width - l - r;
-                        float h = height - t - b;
-                        // Only setup and paint for those areas which have positive width and height. This means, if
-                        // the insets are such that the right edge is left of the left edge, then we have a negative
-                        // width and will not paint it. TODO we need to document this fact (RT-26924)
-                        if (w > 0 && h > 0) {
-                            // Could optimize this such that if paint is transparent then we go no further.
-                            final Paint paint = getPlatformPaint(fill.getFill());
-                            g.setPaint(paint);
-                            final CornerRadii radii = fill.getRadii();
-                            // This is a workaround for RT-28435 so we use path rasterizer for small radius's We are
-                            // keeping old rendering. We do not apply workaround when using Caspian or Embedded
-                            if (radii.isUniform() &&
-                                    !(!PlatformImpl.isCaspian() && !PlatformUtil.isEmbedded() && radii.getTopLeftHorizontalRadius() > 0 && radii.getTopLeftHorizontalRadius() <= 4)) {
-                                // If the radii is uniform then we know every corner matches, so we can do some
-                                // faster rendering paths.
-                                float tlhr = (float) radii.getTopLeftHorizontalRadius();
-                                float tlvr = (float) radii.getTopLeftVerticalRadius();
-                                if (tlhr == 0 && tlvr == 0) {
-                                    // The edges are square, so we can do a simple fill rect
-                                    g.fillRect(l, t, w, h);
-                                } else {
-                                    // Fix the horizontal and vertical radii if they are percentage based
-                                    if (radii.isTopLeftHorizontalRadiusAsPercentage()) tlhr = tlhr * width;
-                                    if (radii.isTopLeftVerticalRadiusAsPercentage()) tlvr = tlvr * height;
-                                    // The edges are rounded, so we need to compute the arc width and arc height
-                                    // and fill a round rect
-                                    float arcWidth = tlhr + tlhr;
-                                    float arcHeight = tlvr + tlvr;
-                                    // If the arc width and arc height are so large as to exceed the width / height of
-                                    // the region, then we clamp to the width / height of the region (which will give
-                                    // the look of a circle on that corner)
-                                    if (arcWidth > w) arcWidth = w;
-                                    if (arcHeight > h) arcHeight = h;
-                                    g.fillRoundRect(l, t, w, h, arcWidth, arcHeight);
-                                }
-                            } else {
-                                // The edges are not uniform, so we have to render each edge independently
-                                // TODO document the issue number which will give us a fast path for rendering
-                                // non-uniform corners, and that we want to implement that instead of createPath2
-                                // below in such cases. (RT-26979)
-                                g.fill(createPath(t, l, b, r, normalize(radii)));
-                            }
-                        }
-                    }
-
-                    // If old != null then that means we were rendering into the "cached" texture, and
-                    // therefore need to reset the graphics and width (because above we had changed
-                    // graphics to point to the cached texture's graphics, and we had changed the
-                    // width to be only big enough for the smallest texture we could save).
-                    if (old != null) {
-                        g = old;
-                        width = oldWidth;
-                    }
+                } else {
+                    // no cache, rendering backgrounds directly to graphics
+                    renderBackgrounds(g, width, height);
                 }
 
                 // cached might not be null if either there was a cached image, or we just created one.
                 // In either case, we need to now render from the cached texture to the graphics
                 if (cached != null) {
-                    final double dstWidth = width + roundUp(outsets.getLeft()) + roundUp(outsets.getRight());
-                    if (cached.getContentWidth() == dstWidth) {
-                        // If the destination width is the same as the content width of the cached image,
-                        // then we can just draw the cached image directly, no need for 3-patch rendering
-                        final float dstX1 = -roundUp(outsets.getLeft());
-                        final float dstY1 = -roundUp(outsets.getTop());
-                        final float dstX2 = (width + roundUp(outsets.getRight()));
-                        final float dstY2 = (height + roundUp(outsets.getBottom()));
+                    final boolean sameWidth = cacheWidth == width;
+                    final boolean sameHeight = cacheHeight == height;
+                    final float dstX1 = -outsetsLeft;
+                    final float dstY1 = -outsetsTop;
+                    final float dstX2 = width + outsetsRight;
+                    final float dstY2 = height + outsetsBottom;
+                    final float srcX1 = 0f;
+                    final float srcY1 = 0f;
+                    final float srcX2 = srcX1 + textureWidth;
+                    final float srcY2 = srcY1 + textureHeight;
 
-                        final float srcX1 = 0f;
-                        final float srcY1 = 0f;
-                        final float srcX2 = srcX1 + textureWidth;
-                        final float srcY2 = srcY1 + textureHeight;
-
+                    if (sameWidth && sameHeight) {
                         g.drawTexture(cached, dstX1, dstY1, dstX2, dstY2, srcX1, srcY1, srcX2, srcY2);
-
-                        if (PulseLogger.PULSE_LOGGING_ENABLED) {
-                            PulseLogger.PULSE_LOGGER.renderIncrementCounter("Cached Region background image used");
-                        }
-                    } else {
-                        // We do 3-patch rendering, because our height is fixed (ie: the same background but at
-                        // different heights will have different cached images)
-                        final float dstX1 = -roundUp(outsets.getLeft());
-                        final float dstY1 = -roundUp(outsets.getTop());
-                        final float dstX2 = (width + roundUp(outsets.getRight()));
-                        final float dstY2 = (height + roundUp(outsets.getBottom()));
-
-                        final float srcX1 = 0f;
-                        final float srcY1 = 0f;
-                        final float srcX2 = srcX1 + textureWidth;
-                        final float srcY2 = srcY1 + textureHeight;
-
-                        final float right = (float) (rightInset + roundUp(outsets.getRight())),
-                        left = (float) (leftInset + roundUp(outsets.getLeft()));
+                    } else if (sameHeight) {
+                        // We do 3-patch rendering fixed height
+                        final float left = (float) (leftInset + outsetsLeft);
+                        final float right = (float) (rightInset + outsetsRight);
 
                         final float dstLeftX = dstX1 + left;
                         final float dstRightX = dstX2 - right;
                         final float srcLeftX = srcX1 + left;
                         final float srcRightX = srcX2 - right;
 
-//                        System.out.println("\noutsets=" + outsets + ", width=" + width + ", height=" + height + ", contentX=" + cached.getContentX() + ", contentY=" + cached.getContentY());
-//                        System.out.println("dstX1=" + dstX1 + ", dstY1=" + dstY1 + ", dstLeftX=" + dstLeftX + ", dstY2=" + dstY2 + ", srcX1=" + srcX1 + ", srcY1=" + srcY1 + ", srcLeftX=" + srcLeftX + ", srcY2=" + srcY2);
-//                        System.out.println("dstLeftX=" + dstLeftX + ", dstY1=" + dstY1 + ", dstRightX=" + dstRightX + ", dstY2=" + dstY2 + ", srcLeftX=" + srcLeftX + ", srcY1=" + srcY1 + ", srcRightX=" + srcRightX + ", srcY2=" + srcY2);
-//                        System.out.println("dstRightX=" + dstRightX + ", dstY1=" + dstY1 + ", dstX2=" + dstX2 + ", dstY2=" + dstY2 + ", srcRightX=" + srcRightX + ", srcY1=" + srcY1 + ", srcX2=" + srcX2 + ", srcY2=" + srcY2);
-
                         // These assertions must hold, or rendering artifacts are highly likely to occur
                         assert dstX1 != dstLeftX;
                         assert dstLeftX != dstRightX;
                         assert dstRightX != dstX2;
 
-                        g.drawTexture(cached, dstX1, dstY1, dstLeftX, dstY2, srcX1, srcY1, srcLeftX, srcY2);
-                        g.drawTexture(cached, dstLeftX, dstY1, dstRightX, dstY2, srcLeftX, srcY1, srcRightX, srcY2);
-                        g.drawTexture(cached, dstRightX, dstY1, dstX2, dstY2, srcRightX, srcY1, srcX2, srcY2);
+                        g.drawTexture3SliceH(cached,
+                                             dstX1, dstY1, dstX2, dstY2,
+                                             srcX1, srcY1, srcX2, srcY2,
+                                             dstLeftX, dstRightX, srcLeftX, srcRightX);
+                    } else if (sameWidth) {
+                        // We do 3-patch rendering fixed width
+                        final float top = (float) (topInset + outsetsTop);
+                        final float bottom = (float) (bottomInset + outsetsBottom);
 
-                        if (PulseLogger.PULSE_LOGGING_ENABLED) {
-                            PulseLogger.PULSE_LOGGER.renderIncrementCounter("Cached Region background image used");
-                        }
+                        final float dstTopY = dstY1 + top;
+                        final float dstBottomY = dstY2 - bottom;
+                        final float srcTopY = srcY1 + top;
+                        final float srcBottomY = srcY2 - bottom;
+
+                        // These assertions must hold, or rendering artifacts are highly likely to occur
+                        assert dstY1 != dstTopY;
+                        assert dstTopY != dstBottomY;
+                        assert dstBottomY != dstY2;
+
+                        g.drawTexture3SliceV(cached,
+                                             dstX1, dstY1, dstX2, dstY2,
+                                             srcX1, srcY1, srcX2, srcY2,
+                                             dstTopY, dstBottomY, srcTopY, srcBottomY);
+                    } else {
+                        // We do 9-patch rendering
+                        final float left = (float) (leftInset + outsetsLeft);
+                        final float top = (float) (topInset + outsetsTop);
+                        final float right = (float) (rightInset + outsetsRight);
+                        final float bottom = (float) (bottomInset + outsetsBottom);
+
+                        final float dstLeftX = dstX1 + left;
+                        final float dstRightX = dstX2 - right;
+                        final float srcLeftX = srcX1 + left;
+                        final float srcRightX = srcX2 - right;
+                        final float dstTopY = dstY1 + top;
+                        final float dstBottomY = dstY2 - bottom;
+                        final float srcTopY = srcY1 + top;
+                        final float srcBottomY = srcY2 - bottom;
+
+                        // These assertions must hold, or rendering artifacts are highly likely to occur
+                        assert dstY1 != dstTopY;
+                        assert dstTopY != dstBottomY;
+                        assert dstBottomY != dstY2;
+                        assert dstX1 != dstLeftX;
+                        assert dstLeftX != dstRightX;
+                        assert dstRightX != dstX2;
+
+                        g.drawTexture9Slice(cached,
+                                            dstX1, dstY1, dstX2, dstY2,
+                                            srcX1, srcY1, srcX2, srcY2,
+                                            dstLeftX, dstTopY, dstRightX, dstBottomY,
+                                            srcLeftX, srcTopY, srcRightX, srcBottomY);
+                    }
+                    if (PulseLogger.PULSE_LOGGING_ENABLED) {
+                        PulseLogger.PULSE_LOGGER.renderIncrementCounter("Cached Region background image used");
                     }
                     cached.unlock();
                 }
@@ -1016,7 +1007,7 @@
                             } else {
                                 // We do not have uniform radii, so we need to create a path that represents
                                 // the stroke and then draw that.
-                                g.draw(createPath(t, l, b, r, radii));
+                                g.draw(createPath(width, height, t, l, b, r, radii));
                             }
                         }
                     } else if (radii.isUniform() && radius == 0) {
@@ -1249,6 +1240,63 @@
         super.renderContent(g);
     }
 
+    private void renderBackgrounds(Graphics g, float width, float height) {
+        final List<BackgroundFill> fills = background.getFills();
+        for (int i = 0, max = fills.size(); i < max; i++) {
+            final BackgroundFill fill = fills.get(i);
+            final Insets insets = fill.getInsets();
+            final float t = (float) insets.getTop(),
+                    l = (float) insets.getLeft(),
+                    b = (float) insets.getBottom(),
+                    r = (float) insets.getRight();
+            // w and h is the width and height of the area to be filled (width and height less insets)
+            float w = width - l - r;
+            float h = height - t - b;
+            // Only setup and paint for those areas which have positive width and height. This means, if
+            // the insets are such that the right edge is left of the left edge, then we have a negative
+            // width and will not paint it. TODO we need to document this fact (RT-26924)
+            if (w > 0 && h > 0) {
+                // Could optimize this such that if paint is transparent then we go no further.
+                final Paint paint = getPlatformPaint(fill.getFill());
+                g.setPaint(paint);
+                final CornerRadii radii = fill.getRadii();
+                // This is a workaround for RT-28435 so we use path rasterizer for small radius's We are
+                // keeping old rendering. We do not apply workaround when using Caspian or Embedded
+                if (radii.isUniform() &&
+                        !(!PlatformImpl.isCaspian() && !PlatformUtil.isEmbedded() && radii.getTopLeftHorizontalRadius() > 0 && radii.getTopLeftHorizontalRadius() <= 4)) {
+                    // If the radii is uniform then we know every corner matches, so we can do some
+                    // faster rendering paths.
+                    float tlhr = (float) radii.getTopLeftHorizontalRadius();
+                    float tlvr = (float) radii.getTopLeftVerticalRadius();
+                    if (tlhr == 0 && tlvr == 0) {
+                        // The edges are square, so we can do a simple fill rect
+                        g.fillRect(l, t, w, h);
+                    } else {
+                        // Fix the horizontal and vertical radii if they are percentage based
+                        if (radii.isTopLeftHorizontalRadiusAsPercentage()) tlhr = tlhr * width;
+                        if (radii.isTopLeftVerticalRadiusAsPercentage()) tlvr = tlvr * height;
+                        // The edges are rounded, so we need to compute the arc width and arc height
+                        // and fill a round rect
+                        float arcWidth = tlhr + tlhr;
+                        float arcHeight = tlvr + tlvr;
+                        // If the arc width and arc height are so large as to exceed the width / height of
+                        // the region, then we clamp to the width / height of the region (which will give
+                        // the look of a circle on that corner)
+                        if (arcWidth > w) arcWidth = w;
+                        if (arcHeight > h) arcHeight = h;
+                        g.fillRoundRect(l, t, w, h, arcWidth, arcHeight);
+                    }
+                } else {
+                    // The edges are not uniform, so we have to render each edge independently
+                    // TODO document the issue number which will give us a fast path for rendering
+                    // non-uniform corners, and that we want to implement that instead of createPath2
+                    // below in such cases. (RT-26979)
+                    g.fill(createPath(width, height, t, l, b, r, normalize(radii)));
+                }
+            }
+        }
+    }
+
     private int roundUp(double d) {
         return (d - (int)d) == 0 ? (int) d : (int) (d + 1);
     }
@@ -1451,7 +1499,7 @@
     }
 
     /** Creates a rounded rectangle path with our width and height, different corner radii, offset with given offsets */
-    private Path2D createPath(float t, float l, float bo, float ro, CornerRadii radii) {
+    private Path2D createPath(float width, float height, float t, float l, float bo, float ro, CornerRadii radii) {
         float r = width - ro;
         float b = height - bo;
         // TODO have to teach this method how to handle vertical radii (RT-26941)
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGShape3D.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGShape3D.java	Tue Aug 06 14:14:24 2013 -0700
@@ -46,7 +46,7 @@
     protected boolean materialDirty = false;
     protected boolean drawModeDirty = false;
     protected boolean cullFaceDirty = false;
-    private NGTriangleMesh mesh;
+    protected NGTriangleMesh mesh;
     private MeshView meshView;
 
     public void setMaterial(NGPhongMaterial material) {
@@ -67,7 +67,8 @@
     }
 
     protected void invalidate() {
-        setMesh(null);
+        meshView = null;
+        visualsChanged();
     }
 
     protected void renderMeshView(Graphics g) {
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGSphere.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGSphere.java	Tue Aug 06 14:14:24 2013 -0700
@@ -25,23 +25,11 @@
 
 package com.sun.javafx.sg.prism;
 
-import com.sun.prism.Graphics;
-
 /**
  * TODO: 3D - Need documentation
  */
 public class NGSphere extends NGShape3D {
 
-    private NGTriangleMesh mesh;
-    
-    @Override
-    protected void renderMeshView(Graphics g) {
-        if (getMesh() == null) {
-            setMesh(mesh);
-        }
-        super.renderMeshView(g);
-    }
-
     public void updateMesh(NGTriangleMesh mesh) {
         this.mesh = mesh;
         invalidate();
--- a/modules/graphics/src/main/java/com/sun/javafx/text/PrismTextLayout.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/text/PrismTextLayout.java	Tue Aug 06 14:14:24 2013 -0700
@@ -53,7 +53,9 @@
 public class PrismTextLayout implements TextLayout {
     private static final BaseTransform IDENTITY = BaseTransform.IDENTITY_TRANSFORM;
     private static final int X_MIN_INDEX = 0;
+    private static final int Y_MIN_INDEX = 1;
     private static final int X_MAX_INDEX = 2;
+    private static final int Y_MAX_INDEX = 3;
 
     private char[] text;
     private TextSpan[] spans;   /* Rich text  (null for single font text) */
@@ -62,7 +64,8 @@
     private TextLine[] lines;
     private TextRun[] runs;
     private int runCount;
-    private BaseBounds bounds;
+    private BaseBounds logicalBounds;
+    private RectBounds visualBounds;
     private float layoutWidth, layoutHeight;
     private float wrapWidth, spacing;
     private LayoutCache layoutCache;
@@ -70,7 +73,7 @@
     private int flags;
 
     public PrismTextLayout() {
-        bounds = new RectBounds();
+        logicalBounds = new RectBounds();
     }
 
     private void reset() {
@@ -81,9 +84,10 @@
     }
 
     private void relayout() {
-        bounds.makeEmpty();
+        logicalBounds.makeEmpty();
+        visualBounds = null;
         layoutWidth = layoutHeight = 0;
-        flags &= ~FLAGS_WRAPPED;
+        flags &= ~(FLAGS_WRAPPED | FLAGS_CACHED_UNDERLINE | FLAGS_CACHED_STRIKETHROUGH);
         lines = null;
         shape = null;
     }
@@ -220,7 +224,7 @@
 
     public BaseBounds getBounds() {
         ensureLayout();
-        return bounds;
+        return logicalBounds;
     }
 
     public BaseBounds getBounds(TextSpan filter, BaseBounds bounds) {
@@ -724,14 +728,14 @@
         if (run.getAscent() == 0) {
             Metrics m = strike.getMetrics();
 
-            /* The implementation of the center bounds mode is to assure the
+            /* The implementation of the center layoutBounds mode is to assure the
              * layout has the same number of pixels above and bellow the cap
              * height.
              */
             if ((flags & BOUNDS_MASK) == BOUNDS_CENTER) {
                 float ascent = m.getAscent();
                 /* Segoe UI has a very large internal leading area, applying the
-                 * center bounds heuristics on it would result in several pixels
+                 * center layoutBounds heuristics on it would result in several pixels
                  * being added to the descent. The final results would be
                  * overly large and visually unappealing. The fix is to reduce
                  * the ascent before applying the algorithm. */
@@ -1177,7 +1181,7 @@
             }
 
             computeSideBearings(line);
-
+            
             /* Set run location */
             float runX = lineX;
             TextRun[] lineRuns = line.getRuns();
@@ -1188,17 +1192,104 @@
                 runX += run.getWidth();
             }
             if (i + 1 < lines.length) {
-                lineY = Math.max(lineY, lineY + bounds.getHeight() + spacing);
+                lineY = Math.max(lineY, lineY + bounds.getHeight() + spacing);                
             } else {
                 lineY += (bounds.getHeight() - line.getLeading());
             }
         }
         float ascent = lines[0].getBounds().getMinY();
         layoutHeight = lineY;
-        bounds = bounds.deriveWithNewBounds(0, ascent, 0, layoutWidth,
+        logicalBounds = logicalBounds.deriveWithNewBounds(0, ascent, 0, layoutWidth,
                                             layoutHeight + ascent, 0);
     }
 
+    @Override
+    public BaseBounds getVisualBounds(int type) {
+        ensureLayout();
+
+        /* Not defined for rich text */
+        if (strike == null) {
+            return null;
+        }
+        
+        boolean underline = (type & TYPE_UNDERLINE) != 0;
+        boolean hasUnderline = (flags & FLAGS_CACHED_UNDERLINE) != 0;
+        boolean strikethrough = (type & TYPE_STRIKETHROUGH) != 0;
+        boolean hasStrikethrough = (flags & FLAGS_CACHED_STRIKETHROUGH) != 0;
+        if (visualBounds != null && underline == hasUnderline
+                && strikethrough == hasStrikethrough) {
+            /* Return last cached value */
+            return visualBounds;
+        }
+        
+        flags &= ~(FLAGS_CACHED_STRIKETHROUGH | FLAGS_CACHED_UNDERLINE);
+        if (underline) flags |= FLAGS_CACHED_UNDERLINE;
+        if (strikethrough) flags |= FLAGS_CACHED_STRIKETHROUGH;
+        visualBounds = new RectBounds();
+
+        float xMin = Float.POSITIVE_INFINITY;
+        float yMin = Float.POSITIVE_INFINITY;
+        float xMax = Float.NEGATIVE_INFINITY;
+        float yMax = Float.NEGATIVE_INFINITY;
+        float bounds[] = new float[4];
+        FontResource fr = strike.getFontResource();
+        Metrics metrics = strike.getMetrics();
+        float size = strike.getSize();
+        for (int i = 0; i < lines.length; i++) {
+            TextLine line = lines[i];
+            TextRun[] runs = line.getRuns();
+            for (int j = 0; j < runs.length; j++) {
+                TextRun run = runs[j];
+                Point2D pt = run.getLocation();
+                if (run.isLinebreak()) continue;
+                int glyphCount = run.getGlyphCount();
+                for (int gi = 0; gi < glyphCount; gi++) {
+                    int gc = run.getGlyphCode(gi);
+                    if (gc != CharToGlyphMapper.INVISIBLE_GLYPH_ID) {
+                        fr.getGlyphBoundingBox(run.getGlyphCode(gi), size, bounds);
+                        if (bounds[X_MIN_INDEX] != bounds[X_MAX_INDEX]) {
+                            float glyphX = pt.x + run.getPosX(gi);
+                            float glyphY = pt.y + run.getPosY(gi);
+                            float glyphMinX = glyphX + bounds[X_MIN_INDEX];
+                            float glyphMinY = glyphY - bounds[Y_MAX_INDEX];
+                            float glyphMaxX = glyphX + bounds[X_MAX_INDEX];
+                            float glyphMaxY = glyphY - bounds[Y_MIN_INDEX];
+                            if (glyphMinX < xMin) xMin = glyphMinX;
+                            if (glyphMinY < yMin) yMin = glyphMinY;
+                            if (glyphMaxX > xMax) xMax = glyphMaxX;
+                            if (glyphMaxY > yMax) yMax = glyphMaxY;
+                        }
+                    }
+                }
+                if (underline) {
+                    float underlineMinX = pt.x;
+                    float underlineMinY = pt.y + metrics.getUnderLineOffset();
+                    float underlineMaxX = underlineMinX + run.getWidth();
+                    float underlineMaxY = underlineMinY + metrics.getUnderLineThickness();
+                    if (underlineMinX < xMin) xMin = underlineMinX;
+                    if (underlineMinY < yMin) yMin = underlineMinY;
+                    if (underlineMaxX > xMax) xMax = underlineMaxX;
+                    if (underlineMaxY > yMax) yMax = underlineMaxY;
+                }
+                if (strikethrough) {
+                    float strikethroughMinX = pt.x;
+                    float strikethroughMinY = pt.y + metrics.getStrikethroughOffset();
+                    float strikethroughMaxX = strikethroughMinX + run.getWidth();
+                    float strikethroughMaxY = strikethroughMinY + metrics.getStrikethroughThickness();
+                    if (strikethroughMinX < xMin) xMin = strikethroughMinX;
+                    if (strikethroughMinY < yMin) yMin = strikethroughMinY;
+                    if (strikethroughMaxX > xMax) xMax = strikethroughMaxX;
+                    if (strikethroughMaxY > yMax) yMax = strikethroughMaxY;
+                }
+            }
+        }
+        
+        if (xMin < xMax && yMin < yMax) {
+            visualBounds.setBounds(xMin, yMin, xMax, yMax);
+        }
+        return visualBounds;
+    }
+
     private void computeSideBearings(TextLine line) {
         TextRun[] runs = line.getRuns();
         if (runs.length == 0) return;
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/DummyToolkit.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/DummyToolkit.java	Tue Aug 06 14:14:24 2013 -0700
@@ -95,7 +95,7 @@
     }
 
     @Override
-    public TKStage createTKPopupStage(StageStyle stageStyle, TKStage owner, AccessControlContext acc) {
+    public TKStage createTKPopupStage(TKStage owner, AccessControlContext acc) {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/Toolkit.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/Toolkit.java	Tue Aug 06 14:14:24 2013 -0700
@@ -31,6 +31,7 @@
 import javafx.scene.Scene;
 import javafx.scene.effect.BlurType;
 import javafx.scene.image.Image;
+import javafx.scene.image.PixelFormat;
 import javafx.scene.image.WritableImage;
 import javafx.scene.input.Dragboard;
 import javafx.scene.input.InputMethodRequests;
@@ -55,6 +56,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.ByteBuffer;
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -273,7 +275,7 @@
     public abstract TKStage createTKStage(StageStyle stageStyle, boolean primary,
             Modality modality, TKStage owner, boolean rtl, AccessControlContext acc);
 
-    public abstract TKStage createTKPopupStage(StageStyle stageStyle, TKStage owner, AccessControlContext acc);
+    public abstract TKStage createTKPopupStage(TKStage owner, AccessControlContext acc);
     public abstract TKStage createTKEmbeddedStage(HostInterface host, AccessControlContext acc);
 
     /**
@@ -856,6 +858,8 @@
     public interface ImageAccessor {
         public boolean isAnimation(Image image);
         public ReadOnlyObjectProperty<PlatformImage>getImageProperty(Image image);
+        public int[] getPreColors(PixelFormat<ByteBuffer> pf);
+        public int[] getNonPreColors(PixelFormat<ByteBuffer> pf);
     }
 
     private static ImageAccessor imageAccessor = null;
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/PopupScene.java	Tue Aug 06 10:13:00 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2011, 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.tk.quantum;
-
-final class PopupScene extends ViewScene {
-
-    public PopupScene(boolean depthBuffer, boolean antiAliasing) {
-        super(depthBuffer, antiAliasing);
-    }
-
-    private PopupStage getPopupStage() {
-        return (PopupStage)getStage();
-    }
-
-    @Override
-    public void sceneChanged() {
-        PopupStage popupStage = getPopupStage();
-        if (popupStage != null) {
-            GlassStage ownerStage = popupStage.getOwner();
-            GlassScene ownerScene = ownerStage.getScene();
-            if (ownerScene != null) {
-                ownerScene.sceneChanged();
-            }
-        }
-        super.sceneChanged();
-    }
-}
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/PopupStage.java	Tue Aug 06 10:13:00 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2008, 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.tk.quantum;
-
-import javafx.stage.Modality;
-import javafx.stage.StageStyle;
-
-import com.sun.glass.ui.Application;
-import com.sun.glass.ui.Screen;
-import com.sun.glass.ui.Window;
-
-import com.sun.javafx.tk.TKScene;
-import com.sun.javafx.tk.TKStage;
-
-import java.security.AccessControlContext;
-
-final class PopupStage extends WindowStage  {
-
-    public PopupStage(final TKStage owner) {
-        super(StageStyle.TRANSPARENT, false, Modality.NONE, owner);
-    }
-
-    @Override
-    protected void initPlatformWindow() {
-        Application app = Application.GetApplication();
-        GlassStage ownerStage = getOwner();
-        Window owner = (ownerStage instanceof WindowStage) ?
-                       ((WindowStage)ownerStage).getPlatformWindow() :
-                       null;
-        platformWindow = app.createWindow(owner, Screen.getMainScreen(),
-                                          Window.TRANSPARENT | Window.POPUP);
-        platformWindow.setFocusable(false);
-
-        super.initPlatformWindow();
-    }
-
-    @Override
-    public TKScene createTKScene(boolean depthBuffer, boolean antiAliasing, AccessControlContext acc) {
-        PopupScene scene =  new PopupScene(depthBuffer, antiAliasing);
-        scene.setSecurityContext(acc);
-        return scene;
-    }
-
-    public void setResizable(final boolean resizable) {
-        // no-op
-    }
-
-    public void setTitle(final String title) {
-        // no-op
-    }
-}
-
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/QuantumToolkit.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/QuantumToolkit.java	Tue Aug 06 14:14:24 2013 -0700
@@ -237,61 +237,6 @@
 
     @Override public boolean init() {
         /*
-         * The below no longer applies with for jfx 8.0 on jdk 8.0. But leaving
-         * the check and comments to avoid breaking jfx running with older
-         * versions of jdk.
-         *
-         * AWT headful trips up glass, and is used in various places throughout
-         * prism, such as J2DFontFactory and BufferedImageTools, but only
-         * required AWT in a headless capacity.
-         *
-         * AWT headful interferes with glass and is used in various places throughout
-         * prism, such as J2DFontFactory and BufferedImageTools, but the only
-         * required AWT is in a headless capacity.
-         *
-         * It is assumed that we don't need AWT headful, and if it is needed
-         * then AWT is already initialized before this property is set.  In that
-         * case the code below is harmless.
-         *
-         * Further Consideration and Dependencies:
-         * - This fix introduces a order dependency in Swing/AWT and FX interop
-         * mode on Mac. Now Swing/AWT must be initialization before FX.
-         *
-         * - On Mac this causes the warning message "Process manager already
-         * initialized -- can't fully enable headless mode."
-         *
-         * - On Windows AWT headful does not cause problems.
-         *
-         * - This Mac specific fix should be removed as soon as possible.
-         * Once RT-12452 has been implemented, then we should be able to do
-         * just that.  Introducing a long term restriction on Mac only, is worse
-         * then adding universal platform restriction.
-         */
-        if (PlatformUtil.isMac()) {
-            String version = AccessController.doPrivileged(new PrivilegedAction<String>() {
-                @Override public String run() {
-                    return System.getProperty("os.version");
-                }
-            });
-            if (version.startsWith("10.4") || version.startsWith("10.5")) {
-                throw new RuntimeException("JavaFX requires Mac OSX 10.6 or higher to run");
-            }
-            String javaVersion = AccessController.doPrivileged(new PrivilegedAction<String>() {
-                @Override public String run() {
-                    return System.getProperty("java.version");
-                }
-            });
-            // We only support 1.6 and higher no need to check older versions
-            if (javaVersion.startsWith("1.6") || javaVersion.startsWith("1.7")) {
-                AccessController.doPrivileged(new PrivilegedAction<Void>() {
-                    @Override public Void run() {
-                        System.setProperty("java.awt.headless", "true");
-                        return null;
-                    }
-                });
-            }
-        }
-        /*
          * Glass Mac, X11 need Application.setDeviceDetails to happen prior to Glass Application.Run
          */
         renderer = QuantumRenderer.getInstance();
@@ -571,8 +516,11 @@
     @Override public TKStage createTKStage(StageStyle stageStyle,
             boolean primary, Modality modality, TKStage owner, boolean rtl, AccessControlContext acc) {
         assertToolkitRunning();
-        WindowStage stage = new WindowStage(stageStyle, primary, modality, owner);
+        WindowStage stage = new WindowStage(stageStyle, modality, owner);
         stage.setSecurityContext(acc);
+        if (primary) {
+            stage.setIsPrimary();
+        }
         stage.setRTL(rtl);
         stage.init(systemMenu);
         return stage;
@@ -618,11 +566,13 @@
         eventLoop.leave(rval);
     }
 
-    @Override public TKStage createTKPopupStage(StageStyle stageStyle, TKStage owner,
+    @Override public TKStage createTKPopupStage(TKStage owner,
                                                 AccessControlContext acc) {
         assertToolkitRunning();
-        WindowStage stage = new PopupStage(owner).init(systemMenu);
+        WindowStage stage = new WindowStage(StageStyle.TRANSPARENT, null, owner);
         stage.setSecurityContext(acc);
+        stage.setIsPopup();
+        stage.init(systemMenu);
         return stage;
     }
 
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/ViewPainter.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/ViewPainter.java	Tue Aug 06 14:14:24 2013 -0700
@@ -186,7 +186,8 @@
                     g.setClipRect(dirtyRect);
                     g.setClipRectIndex(i);
 
-                    if (g.isDepthTest()) {
+                    // Disable occlusion culling if depth buffer is enabled for the scene.
+                    if (sceneState.getScene().getDepthBuffer()) {
                         doPaint(g, null);
                     } else {
                         doPaint(g, root.getRenderRoot(NODE_PATH, dirtyRegion, i, tx, projTx));
@@ -204,6 +205,10 @@
             if (PrismSettings.showCull) {
                  root.drawCullBits(g);
             }
+
+            // save current depth test state
+            boolean prevDepthTest = g.isDepthTest();
+
             g.setDepthTest(false);
             if (status == DirtyRegionContainer.DTR_OK) {
                 g.setPaint(new Color(1, 0, 0, .3f));
@@ -216,6 +221,10 @@
                 g.setPaint(new Color(1, 0, 0, .3f));
                 g.fillRect(0, 0, width, height);
             }
+
+            // restore previous depth test state
+            g.setDepthTest(prevDepthTest);
+
         }
 
         if (SystemProperties.isDebug()) {
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/WindowStage.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/WindowStage.java	Tue Aug 06 14:14:24 2013 -0700
@@ -69,6 +69,7 @@
     private boolean transparent = false;
     private boolean isPrimaryStage = false;
     private boolean isAppletStage = false; // true if this is an embedded applet window
+    private boolean isPopupStage = false;
     private boolean isInFullScreen = false;
 
     // A flag to indicate whether a call was generated from
@@ -93,22 +94,29 @@
         return appletWindow;
     }
 
-    public WindowStage(final StageStyle stageStyle, final boolean isPrimary, Modality modality, TKStage owner) {
+    public WindowStage(final StageStyle stageStyle, Modality modality, TKStage owner) {
+        this.style = stageStyle;
+        this.owner = (GlassStage)owner;
+        this.modality = modality;
+
         transparent = stageStyle == StageStyle.TRANSPARENT;
+        if (owner == null) {
+            if (this.modality == Modality.WINDOW_MODAL) {
+                this.modality = Modality.NONE;
+            }
+        }
+    }
 
-        this.style = stageStyle;
-        this.isPrimaryStage = isPrimary;
-        if (null != appletWindow && isPrimary) {
+    final void setIsPrimary() {
+        isPrimaryStage = true;
+        if (appletWindow != null) {
             // this is an embedded applet stage
             isAppletStage = true;
         }
-        if (owner == null) {
-            if (modality == Modality.WINDOW_MODAL) {
-                modality = Modality.NONE;
-            }
-        }
-        this.owner = (GlassStage)owner;
-        this.modality = modality;
+    }
+
+    final void setIsPopup() {
+        isPopupStage = true;
     }
 
     // Called by QuantumToolkit, so we can override initPlatformWindow in subclasses
@@ -122,34 +130,47 @@
         return this;
     }
 
-    protected void initPlatformWindow() {
+    private void initPlatformWindow() {
         if (platformWindow == null) {
             Application app = Application.GetApplication();
-            Window ownerWindow = null;
-            if (owner instanceof WindowStage) {
-                ownerWindow = ((WindowStage)owner).platformWindow;
-            }
-            int windowMask = rtl ? Window.RIGHT_TO_LEFT : 0;
             if (isPrimaryStage && (null != appletWindow)) {
                 platformWindow = app.createWindow(appletWindow.getGlassWindow().getNativeWindow());
-            } else if (style == StageStyle.DECORATED || style == StageStyle.UNIFIED) {
-                windowMask |= Window.TITLED | Window.CLOSABLE | Window.MINIMIZABLE |
-                        Window.MAXIMIZABLE;
-                if (style == StageStyle.UNIFIED && app.supportsUnifiedWindows()) {
-                    windowMask |= Window.UNIFIED;
+            } else {
+                Window ownerWindow = null;
+                if (owner instanceof WindowStage) {
+                    ownerWindow = ((WindowStage)owner).platformWindow;
+                }
+                boolean resizable = false;
+                boolean focusable = true;
+                int windowMask = rtl ? Window.RIGHT_TO_LEFT : 0;
+                if (isPopupStage) { // TODO: make it a stage style?
+                    windowMask |= Window.TRANSPARENT | Window.POPUP;
+                    focusable = false;
+                } else {
+                    switch (style) {
+                        case UNIFIED:
+                            if (app.supportsUnifiedWindows()) {
+                                windowMask |= Window.UNIFIED;
+                            }
+                            // fall through
+                        case DECORATED:
+                            windowMask |=
+                                    Window.TITLED | Window.CLOSABLE | Window.MINIMIZABLE | Window.MAXIMIZABLE;
+                            resizable = true;
+                            break;
+                        case UTILITY:
+                            windowMask |=  Window.TITLED | Window.UTILITY | Window.CLOSABLE;
+                            break;
+                        default:
+                            windowMask |=
+                                    (transparent ? Window.TRANSPARENT : Window.UNTITLED) | Window.CLOSABLE;
+                            break;
+                    }
                 }
                 platformWindow =
                         app.createWindow(ownerWindow, Screen.getMainScreen(), windowMask);
-                platformWindow.setResizable(true);
-            } else if (style == StageStyle.UTILITY) {
-                windowMask |=  Window.TITLED | Window.UTILITY | Window.CLOSABLE;
-                platformWindow =
-                        app.createWindow(ownerWindow, Screen.getMainScreen(), windowMask);
-            } else {
-                windowMask |= (transparent ? Window.TRANSPARENT : Window.UNTITLED) |
-                        Window.CLOSABLE;
-                platformWindow =
-                        app.createWindow(ownerWindow, Screen.getMainScreen(), windowMask);
+                platformWindow.setResizable(resizable);
+                platformWindow.setFocusable(focusable);
             }
         }
         platformWindows.put(platformWindow, this);
--- a/modules/graphics/src/main/java/com/sun/prism/Graphics.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/Graphics.java	Tue Aug 06 14:14:24 2013 -0700
@@ -153,6 +153,19 @@
     public void drawTexture(Texture tex,
                             float dx1, float dy1, float dx2, float dy2,
                             float sx1, float sy1, float sx2, float sy2);
+    public void drawTexture3SliceH(Texture tex,
+                                   float dx1, float dy1, float dx2, float dy2,
+                                   float sx1, float sy1, float sx2, float sy2,
+                                   float dh1, float dh2, float sh1, float sh2);
+    public void drawTexture3SliceV(Texture tex,
+                                   float dx1, float dy1, float dx2, float dy2,
+                                   float sx1, float sy1, float sx2, float sy2,
+                                   float dv1, float dv2, float sv1, float sv2);
+    public void drawTexture9Slice(Texture tex,
+                                  float dx1, float dy1, float dx2, float dy2,
+                                  float sx1, float sy1, float sx2, float sy2,
+                                  float dh1, float dv1, float dh2, float dv2,
+                                  float sh1, float sv1, float sh2, float sv2);
     public void drawTextureVO(Texture tex,
                               float topopacity, float botopacity,
                               float dx1, float dy1, float dx2, float dy2,
--- a/modules/graphics/src/main/java/com/sun/prism/d3d/D3DContext.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/d3d/D3DContext.java	Tue Aug 06 14:14:24 2013 -0700
@@ -191,6 +191,7 @@
         long resourceHandle = ((D3DRenderTarget)target).getResourceHandle();
         int res = nSetRenderTarget(pContext, resourceHandle);
         validate(res);
+        resetLastClip(state);
 
         this.camera = camera;
         this.depthTest = depthTest;
--- a/modules/graphics/src/main/java/com/sun/prism/impl/BaseGraphics.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/BaseGraphics.java	Tue Aug 06 14:14:24 2013 -0700
@@ -402,6 +402,165 @@
                                           tx1, ty1, tx2, ty2);
     }
 
+    @Override
+    public void drawTexture3SliceH(Texture tex,
+                                   float dx1, float dy1, float dx2, float dy2,
+                                   float sx1, float sy1, float sx2, float sy2,
+                                   float dh1, float dh2, float sh1, float sh2)
+    {
+        BaseTransform xform = isSimpleTranslate ? IDENT : getTransformNoClone();
+        PixelFormat format = tex.getPixelFormat();
+        if (format == PixelFormat.BYTE_ALPHA) {
+            // Note that we treat this as a paint operation, using the
+            // given texture as the alpha mask; perhaps it would be better
+            // to treat this as a separate operation from drawTexture(), but
+            // overloading drawTexture() seems like an equally valid option.
+            context.validatePaintOp(this, xform, tex, dx1, dy1, dx2-dx1, dy2-dy1);
+        } else {
+            context.validateTextureOp(this, xform, tex, format);
+        }
+        if (isSimpleTranslate) {
+            // The validatePaintOp bounds above needed to use the original
+            // coordinates (prior to any translation below) for relative
+            // paint processing.
+            dx1 += transX;
+            dy1 += transY;
+            dx2 += transX;
+            dy2 += transY;
+            dh1 += transX;
+         // dv1 += transY;
+            dh2 += transX;
+         // dv2 += transY;
+        }
+
+        float pw = tex.getPhysicalWidth();
+        float ph = tex.getPhysicalHeight();
+        float cx1 = tex.getContentX();
+        float cy1 = tex.getContentY();
+        float tx1 = (cx1 + sx1) / pw;
+        float ty1 = (cy1 + sy1) / ph;
+        float tx2 = (cx1 + sx2) / pw;
+        float ty2 = (cy1 + sy2) / ph;
+        float th1 = (cx1 + sh1) / pw;
+     // float tv1 = (cy1 + sv1) / ph;
+        float th2 = (cx1 + sh2) / pw;
+     // float tv2 = (cy1 + sv2) / ph;
+
+        VertexBuffer vb = context.getVertexBuffer();
+        vb.addQuad(dx1, dy1, dh1, dy2, tx1, ty1, th1, ty2);
+        vb.addQuad(dh1, dy1, dh2, dy2, th1, ty1, th2, ty2);
+        vb.addQuad(dh2, dy1, dx2, dy2, th2, ty1, tx2, ty2);
+    }
+
+    @Override
+    public void drawTexture3SliceV(Texture tex,
+                                   float dx1, float dy1, float dx2, float dy2,
+                                   float sx1, float sy1, float sx2, float sy2,
+                                   float dv1, float dv2, float sv1, float sv2)
+    {
+        BaseTransform xform = isSimpleTranslate ? IDENT : getTransformNoClone();
+        PixelFormat format = tex.getPixelFormat();
+        if (format == PixelFormat.BYTE_ALPHA) {
+            // Note that we treat this as a paint operation, using the
+            // given texture as the alpha mask; perhaps it would be better
+            // to treat this as a separate operation from drawTexture(), but
+            // overloading drawTexture() seems like an equally valid option.
+            context.validatePaintOp(this, xform, tex, dx1, dy1, dx2-dx1, dy2-dy1);
+        } else {
+            context.validateTextureOp(this, xform, tex, format);
+        }
+        if (isSimpleTranslate) {
+            // The validatePaintOp bounds above needed to use the original
+            // coordinates (prior to any translation below) for relative
+            // paint processing.
+            dx1 += transX;
+            dy1 += transY;
+            dx2 += transX;
+            dy2 += transY;
+         // dh1 += transX;
+            dv1 += transY;
+         // dh2 += transX;
+            dv2 += transY;
+        }
+
+        float pw = tex.getPhysicalWidth();
+        float ph = tex.getPhysicalHeight();
+        float cx1 = tex.getContentX();
+        float cy1 = tex.getContentY();
+        float tx1 = (cx1 + sx1) / pw;
+        float ty1 = (cy1 + sy1) / ph;
+        float tx2 = (cx1 + sx2) / pw;
+        float ty2 = (cy1 + sy2) / ph;
+     // float th1 = (cx1 + sh1) / pw;
+        float tv1 = (cy1 + sv1) / ph;
+     // float th2 = (cx1 + sh2) / pw;
+        float tv2 = (cy1 + sv2) / ph;
+
+        VertexBuffer vb = context.getVertexBuffer();
+        vb.addQuad(dx1, dy1, dx2, dv1, tx1, ty1, tx2, tv1);
+        vb.addQuad(dx1, dv1, dx2, dv2, tx1, tv1, tx2, tv2);
+        vb.addQuad(dx1, dv2, dx2, dy2, tx1, tv2, tx2, ty2);
+    }
+
+    @Override
+    public void drawTexture9Slice(Texture tex,
+                                  float dx1, float dy1, float dx2, float dy2,
+                                  float sx1, float sy1, float sx2, float sy2,
+                                  float dh1, float dv1, float dh2, float dv2,
+                                  float sh1, float sv1, float sh2, float sv2)
+    {
+        BaseTransform xform = isSimpleTranslate ? IDENT : getTransformNoClone();
+        PixelFormat format = tex.getPixelFormat();
+        if (format == PixelFormat.BYTE_ALPHA) {
+            // Note that we treat this as a paint operation, using the
+            // given texture as the alpha mask; perhaps it would be better
+            // to treat this as a separate operation from drawTexture(), but
+            // overloading drawTexture() seems like an equally valid option.
+            context.validatePaintOp(this, xform, tex, dx1, dy1, dx2-dx1, dy2-dy1);
+        } else {
+            context.validateTextureOp(this, xform, tex, format);
+        }
+        if (isSimpleTranslate) {
+            // The validatePaintOp bounds above needed to use the original
+            // coordinates (prior to any translation below) for relative
+            // paint processing.
+            dx1 += transX;
+            dy1 += transY;
+            dx2 += transX;
+            dy2 += transY;
+            dh1 += transX;
+            dv1 += transY;
+            dh2 += transX;
+            dv2 += transY;
+        }
+
+        float pw = tex.getPhysicalWidth();
+        float ph = tex.getPhysicalHeight();
+        float cx1 = tex.getContentX();
+        float cy1 = tex.getContentY();
+        float tx1 = (cx1 + sx1) / pw;
+        float ty1 = (cy1 + sy1) / ph;
+        float tx2 = (cx1 + sx2) / pw;
+        float ty2 = (cy1 + sy2) / ph;
+        float th1 = (cx1 + sh1) / pw;
+        float tv1 = (cy1 + sv1) / ph;
+        float th2 = (cx1 + sh2) / pw;
+        float tv2 = (cy1 + sv2) / ph;
+
+        VertexBuffer vb = context.getVertexBuffer();
+        vb.addQuad(dx1, dy1, dh1, dv1, tx1, ty1, th1, tv1);
+        vb.addQuad(dh1, dy1, dh2, dv1, th1, ty1, th2, tv1);
+        vb.addQuad(dh2, dy1, dx2, dv1, th2, ty1, tx2, tv1);
+
+        vb.addQuad(dx1, dv1, dh1, dv2, tx1, tv1, th1, tv2);
+        vb.addQuad(dh1, dv1, dh2, dv2, th1, tv1, th2, tv2);
+        vb.addQuad(dh2, dv1, dx2, dv2, th2, tv1, tx2, tv2);
+
+        vb.addQuad(dx1, dv2, dh1, dy2, tx1, tv2, th1, ty2);
+        vb.addQuad(dh1, dv2, dh2, dy2, th1, tv2, th2, ty2);
+        vb.addQuad(dh2, dv2, dx2, dy2, th2, tv2, tx2, ty2);
+    }
+
     public void drawTextureVO(Texture tex,
                               float topopacity, float botopacity,
                               float dx1, float dy1, float dx2, float dy2,
--- a/modules/graphics/src/main/java/com/sun/prism/impl/GlyphCache.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/GlyphCache.java	Tue Aug 06 14:14:24 2013 -0700
@@ -26,6 +26,7 @@
 package com.sun.prism.impl;
 
 import com.sun.javafx.font.CharToGlyphMapper;
+import com.sun.javafx.font.CompositeGlyphMapper;
 import com.sun.javafx.font.FontResource;
 import com.sun.javafx.font.FontStrike;
 import com.sun.javafx.font.Glyph;
@@ -38,12 +39,14 @@
 import com.sun.prism.Texture;
 import com.sun.prism.impl.shape.MaskData;
 import com.sun.prism.paint.Color;
+
 import java.nio.ByteBuffer;
 import java.util.HashMap;
 import java.util.WeakHashMap;
 
 import static com.sun.javafx.logging.PulseLogger.PULSE_LOGGING_ENABLED;
 import static com.sun.javafx.logging.PulseLogger.PULSE_LOGGER;
+
 import com.sun.prism.ResourceFactory;
 import com.sun.prism.Texture.WrapMode;
 
@@ -133,7 +136,7 @@
         boolean subPixel = strike.isSubPixelGlyph();
         float subPixelX = 0;
         for (int gi = 0; gi < len; gi++) {
-            int gc = gl.getGlyphCode(gi);
+            int gc = gl.getGlyphCode(gi) & CompositeGlyphMapper.GLYPHMASK;
 
             // If we have a supplementary character, then a special
             // glyph is inserted in the list, which is one we skip
--- a/modules/graphics/src/main/java/com/sun/prism/impl/ps/BaseShaderContext.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/ps/BaseShaderContext.java	Tue Aug 06 14:14:24 2013 -0700
@@ -167,6 +167,10 @@
         private boolean lastState3D = false;
     }
 
+    protected void resetLastClip(State state) {
+        state.lastClip = null;
+    }
+
     protected abstract State updateRenderTarget(RenderTarget target, NGCamera camera,
                                                 boolean depthTest);
 
--- a/modules/graphics/src/main/java/com/sun/prism/impl/ps/BaseShaderGraphics.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/ps/BaseShaderGraphics.java	Tue Aug 06 14:14:24 2013 -0700
@@ -141,6 +141,73 @@
         }
     }
 
+    @Override
+    public void drawTexture3SliceH(Texture tex,
+                                   float dx1, float dy1, float dx2, float dy2,
+                                   float sx1, float sy1, float sx2, float sy2,
+                                   float dh1, float dh2, float sh1, float sh2)
+    {
+        if (!(tex instanceof MultiTexture)) {
+            super.drawTexture3SliceH(tex,
+                                     dx1, dy1, dx2, dy2,
+                                     sx1, sy1, sx2, sy2,
+                                     dh1, dh2, sh1, sh2);
+            return;
+        }
+        MultiTexture mtex = (MultiTexture) tex;
+        drawMultiTexture(mtex, dx1, dy1, dh1, dy2, sx1, sy1, sh1, sy2);
+        drawMultiTexture(mtex, dh1, dy1, dh2, dy2, sh1, sy1, sh2, sy2);
+        drawMultiTexture(mtex, dh2, dy1, dx2, dy2, sh2, sy1, sx2, sy2);
+    }
+
+    @Override
+    public void drawTexture3SliceV(Texture tex,
+                                   float dx1, float dy1, float dx2, float dy2,
+                                   float sx1, float sy1, float sx2, float sy2,
+                                   float dv1, float dv2, float sv1, float sv2)
+    {
+        if (!(tex instanceof MultiTexture)) {
+            super.drawTexture3SliceV(tex,
+                                     dx1, dy1, dx2, dy2,
+                                     sx1, sy1, sx2, sy2,
+                                     dv1, dv2, sv1, sv2);
+            return;
+        }
+        MultiTexture mtex = (MultiTexture) tex;
+        drawMultiTexture(mtex, dx1, dy1, dx2, dv1, sx1, sy1, sx2, sv1);
+        drawMultiTexture(mtex, dx1, dv1, dx2, dv2, sx1, sv1, sx2, sv2);
+        drawMultiTexture(mtex, dx1, dv2, dx2, dy2, sx1, sv2, sx2, sy2);
+    }
+
+    @Override
+    public void drawTexture9Slice(Texture tex,
+                                  float dx1, float dy1, float dx2, float dy2,
+                                  float sx1, float sy1, float sx2, float sy2,
+                                  float dh1, float dv1, float dh2, float dv2,
+                                  float sh1, float sv1, float sh2, float sv2)
+    {
+        if (!(tex instanceof MultiTexture)) {
+            super.drawTexture9Slice(tex,
+                                    dx1, dy1, dx2, dy2,
+                                    sx1, sy1, sx2, sy2,
+                                    dh1, dv1, dh2, dv2,
+                                    sh1, sv1, sh2, sv2);
+            return;
+        }
+        MultiTexture mtex = (MultiTexture) tex;
+        drawMultiTexture(mtex, dx1, dy1, dh1, dv1, sx1, sy1, sh1, sv1);
+        drawMultiTexture(mtex, dh1, dy1, dh2, dv1, sh1, sy1, sh2, sv1);
+        drawMultiTexture(mtex, dh2, dy1, dx2, dv1, sh2, sy1, sx2, sv1);
+
+        drawMultiTexture(mtex, dx1, dv1, dh1, dv2, sx1, sv1, sh1, sv2);
+        drawMultiTexture(mtex, dh1, dv1, dh2, dv2, sh1, sv1, sh2, sv2);
+        drawMultiTexture(mtex, dh2, dv1, dx2, dv2, sh2, sv1, sx2, sv2);
+
+        drawMultiTexture(mtex, dx1, dv2, dh1, dy2, sx1, sv2, sh1, sy2);
+        drawMultiTexture(mtex, dh1, dv2, dh2, dy2, sh1, sv2, sh2, sy2);
+        drawMultiTexture(mtex, dh2, dv2, dx2, dy2, sh2, sv2, sx2, sy2);
+    }
+
     private static float calculateScaleFactor(float contentDim, float physicalDim) {
         if (contentDim == physicalDim) {
             return 1f;
--- a/modules/graphics/src/main/java/com/sun/prism/j2d/J2DPrismGraphics.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/j2d/J2DPrismGraphics.java	Tue Aug 06 14:14:24 2013 -0700
@@ -963,6 +963,48 @@
                 null);
     }
 
+    @Override
+    public void drawTexture3SliceH(Texture tex,
+                                   float dx1, float dy1, float dx2, float dy2,
+                                   float sx1, float sy1, float sx2, float sy2,
+                                   float dh1, float dh2, float sh1, float sh2)
+    {
+        drawTexture(tex, dx1, dy1, dh1, dy2, sx1, sy1, sh1, sy2);
+        drawTexture(tex, dh1, dy1, dh2, dy2, sh1, sy1, sh2, sy2);
+        drawTexture(tex, dh2, dy1, dx2, dy2, sh2, sy1, sx2, sy2);
+    }
+
+    @Override
+    public void drawTexture3SliceV(Texture tex,
+                                   float dx1, float dy1, float dx2, float dy2,
+                                   float sx1, float sy1, float sx2, float sy2,
+                                   float dv1, float dv2, float sv1, float sv2)
+    {
+        drawTexture(tex, dx1, dy1, dx2, dv1, sx1, sy1, sx2, sv1);
+        drawTexture(tex, dx1, dv1, dx2, dv2, sx1, sv1, sx2, sv2);
+        drawTexture(tex, dx1, dv2, dx2, dy2, sx1, sv2, sx2, sy2);
+    }
+
+    @Override
+    public void drawTexture9Slice(Texture tex,
+                                  float dx1, float dy1, float dx2, float dy2,
+                                  float sx1, float sy1, float sx2, float sy2,
+                                  float dh1, float dv1, float dh2, float dv2,
+                                  float sh1, float sv1, float sh2, float sv2)
+    {
+        drawTexture(tex, dx1, dy1, dh1, dv1, sx1, sy1, sh1, sv1);
+        drawTexture(tex, dh1, dy1, dh2, dv1, sh1, sy1, sh2, sv1);
+        drawTexture(tex, dh2, dy1, dx2, dv1, sh2, sy1, sx2, sv1);
+
+        drawTexture(tex, dx1, dv1, dh1, dv2, sx1, sv1, sh1, sv2);
+        drawTexture(tex, dh1, dv1, dh2, dv2, sh1, sv1, sh2, sv2);
+        drawTexture(tex, dh2, dv1, dx2, dv2, sh2, sv1, sx2, sv2);
+
+        drawTexture(tex, dx1, dv2, dh1, dy2, sx1, sv2, sh1, sy2);
+        drawTexture(tex, dh1, dv2, dh2, dy2, sh1, sv2, sh2, sy2);
+        drawTexture(tex, dh2, dv2, dx2, dy2, sh2, sv2, sx2, sy2);
+    }
+
     public void drawTextureRaw(Texture tex,
                                float dx1, float dy1, float dx2, float dy2,
                                float tx1, float ty1, float tx2, float ty2)
--- a/modules/graphics/src/main/java/com/sun/prism/sw/SWGraphics.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/sw/SWGraphics.java	Tue Aug 06 14:14:24 2013 -0700
@@ -902,6 +902,48 @@
         }
     }
 
+    @Override
+    public void drawTexture3SliceH(Texture tex,
+                                   float dx1, float dy1, float dx2, float dy2,
+                                   float sx1, float sy1, float sx2, float sy2,
+                                   float dh1, float dh2, float sh1, float sh2)
+    {
+        drawTexture(tex, dx1, dy1, dh1, dy2, sx1, sy1, sh1, sy2);
+        drawTexture(tex, dh1, dy1, dh2, dy2, sh1, sy1, sh2, sy2);
+        drawTexture(tex, dh2, dy1, dx2, dy2, sh2, sy1, sx2, sy2);
+    }
+
+    @Override
+    public void drawTexture3SliceV(Texture tex,
+                                   float dx1, float dy1, float dx2, float dy2,
+                                   float sx1, float sy1, float sx2, float sy2,
+                                   float dv1, float dv2, float sv1, float sv2)
+    {
+        drawTexture(tex, dx1, dy1, dx2, dv1, sx1, sy1, sx2, sv1);
+        drawTexture(tex, dx1, dv1, dx2, dv2, sx1, sv1, sx2, sv2);
+        drawTexture(tex, dx1, dv2, dx2, dy2, sx1, sv2, sx2, sy2);
+    }
+
+    @Override
+    public void drawTexture9Slice(Texture tex,
+                                  float dx1, float dy1, float dx2, float dy2,
+                                  float sx1, float sy1, float sx2, float sy2,
+                                  float dh1, float dv1, float dh2, float dv2,
+                                  float sh1, float sv1, float sh2, float sv2)
+    {
+        drawTexture(tex, dx1, dy1, dh1, dv1, sx1, sy1, sh1, sv1);
+        drawTexture(tex, dh1, dy1, dh2, dv1, sh1, sy1, sh2, sv1);
+        drawTexture(tex, dh2, dy1, dx2, dv1, sh2, sy1, sx2, sv1);
+
+        drawTexture(tex, dx1, dv1, dh1, dv2, sx1, sv1, sh1, sv2);
+        drawTexture(tex, dh1, dv1, dh2, dv2, sh1, sv1, sh2, sv2);
+        drawTexture(tex, dh2, dv1, dx2, dv2, sh2, sv1, sx2, sv2);
+
+        drawTexture(tex, dx1, dv2, dh1, dy2, sx1, sv2, sh1, sy2);
+        drawTexture(tex, dh1, dv2, dh2, dy2, sh1, sv2, sh2, sy2);
+        drawTexture(tex, dh2, dv2, dx2, dy2, sh2, sv2, sx2, sy2);
+    }
+
     private void computeScaleAndPixelCorrection(float[] target, float dv1, float dv2, float sv1, float sv2) {
         final float dv_diff = dv2 - dv1;
         float scale = dv_diff / (sv2 - sv1);
--- a/modules/graphics/src/main/java/javafx/scene/Camera.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/Camera.java	Tue Aug 06 14:14:24 2013 -0700
@@ -287,13 +287,12 @@
     }
 
     private void markOwnerDirty() {
-        // if the camera is part of the scene/subScene, we don't need to notify
-        // the owner as the camera will be added to its dirty list as usual
-
-        if (ownerScene != null && ownerScene != getScene()) {
+        // if the camera is part of the scene/subScene, we will need to notify
+        // the owner to mark the entire scene/subScene dirty.
+        if (ownerScene != null) {
             ownerScene.markCameraDirty();
         }
-        if (ownerSubScene != null && ownerSubScene != getSubScene()) {
+        if (ownerSubScene != null) {
             ownerSubScene.markContentDirty();
         }
     }
--- a/modules/graphics/src/main/java/javafx/scene/LightBase.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/LightBase.java	Tue Aug 06 14:14:24 2013 -0700
@@ -170,12 +170,12 @@
                         for (Node node : c.getRemoved()) {
                             // Update the removed nodes
                             if (node instanceof Parent || node instanceof Shape3D) {
-                                node.impl_markDirty(DirtyBits.NODE_CONTENTS);
+                                markChildrenDirty(node);
                             }
                         }
                         for (Node node : c.getAddedSubList()) {
                             if (node instanceof Parent || node instanceof Shape3D) {
-                                node.impl_markDirty(DirtyBits.NODE_CONTENTS);
+                                markChildrenDirty(node);
                             }
                         }
                     }
@@ -203,6 +203,45 @@
         }
     }
 
+    private void markOwnerDirty() {
+        // if the light is part of the scene/subScene, we will need to notify
+        // the owner to mark the entire scene/subScene dirty.
+        SubScene subScene = getSubScene();
+        if (subScene != null) {
+            subScene.markContentDirty();
+        } else {
+            Scene scene = getScene();
+            if (scene != null) {
+                scene.setNeedsRepaint();
+            }
+        }
+    }
+
+    private void markChildrenDirty(Node node) {
+        if (node instanceof Shape3D) {
+            // Dirty using a lightweight DirtyBits.NODE_DRAWMODE bit   
+            ((Shape3D) node).impl_markDirty(DirtyBits.NODE_DRAWMODE);
+        } else if (node instanceof Parent) {
+            for (Node child : ((Parent) node).getChildren()) {
+                markChildrenDirty(child);
+            }
+        }
+    }
+
+    @Override
+    protected void impl_markDirty(DirtyBits dirtyBit) {
+        super.impl_markDirty(dirtyBit);
+        if ((scope == null) || getScope().isEmpty()) {
+            // This light affect the entire scene/subScene
+            markOwnerDirty();
+        } else {                
+            ObservableList<Node> tmpScope = getScope();            
+            for (int i = 0, max = tmpScope.size(); i < max; i++) {
+                markChildrenDirty(tmpScope.get(i));
+            }
+        }
+    }
+
     /**
      * @treatAsPrivate implementation detail
      * @deprecated This is an internal API that is not intended for use and will be removed in the next version
@@ -218,12 +257,13 @@
             peer.setLightOn(isLightOn());
 
             if (scope != null) {
-                if (getScope().isEmpty()) {
+                ObservableList<Node> tmpScope = getScope();
+                if (tmpScope.isEmpty()) {
                     peer.setScope(null);
                 } else {
-                    Object ngList[] = new Object[getScope().size()];
-                    for (int i = 0; i < scope.size(); i++) {
-                        Node n = scope.get(i);
+                    Object ngList[] = new Object[tmpScope.size()];
+                    for (int i = 0; i < tmpScope.size(); i++) {
+                        Node n = tmpScope.get(i);
                         ngList[i] = n.impl_getPeer();
                     }
                     peer.setScope(ngList);
--- a/modules/graphics/src/main/java/javafx/scene/Node.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/Node.java	Tue Aug 06 14:14:24 2013 -0700
@@ -1064,9 +1064,6 @@
                         impl_markDirty(DirtyBits.NODE_VISIBLE);
                         impl_geomChanged();
                         updateTreeVisible();
-                        if (getClip() != null) {
-                            getClip().updateTreeVisible();
-                        }
                         if (getParent() != null) {
                             // notify the parent of the potential change in visibility
                             // of this node, since visibility affects bounds of the
@@ -7601,11 +7598,23 @@
         }
     }
 
+    void markDirtyLayoutBranch() {
+        Parent p = getParent();
+        while (p != null && p.layoutFlag == LayoutFlags.CLEAN) {
+            p.setLayoutFlag(LayoutFlags.DIRTY_BRANCH);
+            if (p.isSceneRoot()) {
+                Toolkit.getToolkit().requestNextPulse();
+            }
+            p = p.getParent();
+        }
+
+    }
+
     private void updateTreeVisible() {
         boolean isTreeVisible = isVisible();
         if (isTreeVisible) {
             final Parent p = getParent();
-            isTreeVisible = p != null ? getParent().impl_isTreeVisible() :
+            isTreeVisible = p != null ? p.impl_isTreeVisible() :
                     clipParent != null ? clipParent.impl_isTreeVisible() :
                     getSubScene() == null || getSubScene().impl_isTreeVisible();
         }
@@ -7620,6 +7629,9 @@
             treeVisible = value;
             updateCanReceiveFocus();
             focusSetDirty(getScene());
+            if (getClip() != null) {
+                getClip().updateTreeVisible();
+            }
             if (treeVisible && !impl_isDirtyEmpty()) {
                 // The node hasn't been synchronized while invisible, so
                 // synchronize now
--- a/modules/graphics/src/main/java/javafx/scene/Parent.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/Parent.java	Tue Aug 06 14:14:24 2013 -0700
@@ -324,6 +324,10 @@
                 }
             }
 
+            if (geomChanged) {
+                impl_geomChanged();
+            }
+
             //
             // Note that the styles of a child do not affect the parent or
             // its siblings. Thus, it is only necessary to reapply css to
@@ -347,10 +351,6 @@
                 requestLayout();
             }
 
-            if (geomChanged) {
-                impl_geomChanged();
-            }
-
             // Note the starting index at which we need to update the
             // PGGroup on the next update, and mark the children dirty
             c.reset();
@@ -831,30 +831,21 @@
     private double minWidthCache = -1;
     private double minHeightCache = -1;
 
-    private void setLayoutFlag(LayoutFlags flag) {
+    void setLayoutFlag(LayoutFlags flag) {
         if (needsLayout != null) {
             needsLayout.set(flag == LayoutFlags.NEEDS_LAYOUT);
         }
         layoutFlag = flag;
     }
 
-    private void markDirtyLayoutBranch() {
-        Parent parent = getParent();
-        while (parent != null && parent.layoutFlag == LayoutFlags.CLEAN) {
-            parent.setLayoutFlag(LayoutFlags.DIRTY_BRANCH);
-            if (parent.sceneRoot) {
-                Toolkit.getToolkit().requestNextPulse();
-            }
-            parent = parent.getParent();
-        }
-
-    }
-
     private void markDirtyLayout(boolean local) {
         setLayoutFlag(LayoutFlags.NEEDS_LAYOUT);
         if (local || layoutRoot) {
             if (sceneRoot) {
                 Toolkit.getToolkit().requestNextPulse();
+                if (getSubScene() != null) {
+                    getSubScene().setDirtyLayout(this);
+                }
             } else {
                 markDirtyLayoutBranch();
             }
@@ -1065,6 +1056,8 @@
                     final Node child = children.get(i);
                     if (child instanceof Parent) {
                         ((Parent)child).layout();
+                    } else if (child instanceof SubScene) {
+                        ((SubScene)child).layoutPass();
                     }
                 }
                 setLayoutFlag(LayoutFlags.CLEAN);
@@ -1106,6 +1099,10 @@
         layoutRoot = !isManaged() || sceneRoot;
     }
 
+    final boolean isSceneRoot() {
+        return sceneRoot;
+    }
+
     /***********************************************************************
      *                                                                     *
      *                         Stylesheet Handling                         *
--- a/modules/graphics/src/main/java/javafx/scene/Scene.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/Scene.java	Tue Aug 06 14:14:24 2013 -0700
@@ -980,6 +980,7 @@
     // Used by the camera
     void markCameraDirty() {
         markDirty(DirtyBits.CAMERA_DIRTY);
+        setNeedsRepaint();
     }
 
     /**
--- a/modules/graphics/src/main/java/javafx/scene/SubScene.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/SubScene.java	Tue Aug 06 14:14:24 2013 -0700
@@ -475,7 +475,7 @@
 
         // TODO deal with clip node
 
-        dirtyNodes = dirtyLayout = false;
+        dirtyNodes = false;
         if (isDirty()) {
             NGSubScene peer = impl_getPeer();
             final Camera cam = getEffectiveCamera();
@@ -591,6 +591,7 @@
         if (!dirtyLayout && p != null && p.getSubScene() == this &&
                 this.getScene() != null) {
             dirtyLayout = true;
+            markDirtyLayoutBranch();
             markDirty(SubSceneDirtyBits.CONTENT_DIRTY);
         }
     }
@@ -604,6 +605,16 @@
         }
     }
 
+    void layoutPass() {
+        if (dirtyLayout) {
+            Parent r = getRoot();
+            if (r != null) {
+                r.layout();
+            }
+            dirtyLayout = false;
+        }
+    }
+
     private enum SubSceneDirtyBits {
         SIZE_DIRTY,
         FILL_DIRTY,
--- a/modules/graphics/src/main/java/javafx/scene/image/Image.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/image/Image.java	Tue Aug 06 14:14:24 2013 -0700
@@ -122,6 +122,16 @@
             {
                 return image.acc_platformImageProperty();
             }
+
+            @Override
+            public int[] getPreColors(PixelFormat<ByteBuffer> pf) {
+                return ((PixelFormat.IndexedPixelFormat) pf).getPreColors();
+            }
+
+            @Override
+            public int[] getNonPreColors(PixelFormat<ByteBuffer> pf) {
+                return ((PixelFormat.IndexedPixelFormat) pf).getNonPreColors();
+            }
         });
     }
 
--- a/modules/graphics/src/main/java/javafx/scene/image/PixelFormat.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/image/PixelFormat.java	Tue Aug 06 14:14:24 2013 -0700
@@ -37,6 +37,9 @@
  */
 public abstract class PixelFormat<T extends Buffer> {
     /**
+     * An enum describing the in-array storage format of a single pixel
+     * managed by a {@link PixelFormat}.
+     * 
      * @since JavaFX 2.2
      */
     public enum Type {
@@ -84,44 +87,203 @@
         this.type = type;
     }
 
+    /**
+     * Returns a {@code WritablePixelFormat} instance describing a pixel
+     * layout with the pixels stored in 32-bit integers with the
+     * <b>non-premultiplied</b> components stored in order, from MSb to LSb:
+     * alpha, red, green, blue.
+     * <p>
+     * Pixels in this format can be decoded using the following sample code:
+     * <pre>
+     *     int pixel = array[rowstart + x];
+     * 
+     *     int alpha = ((pixel >> 24) & 0xff);
+     *     int red   = ((pixel >> 16) & 0xff);
+     *     int green = ((pixel >>  8) & 0xff);
+     *     int blue  = ((pixel      ) & 0xff);
+     * </pre>
+     * 
+     * @return a {@code WritabelPixelFormat<IntBuffer>} describing the
+     *         indicated pixel format
+     */
     public static WritablePixelFormat<IntBuffer> getIntArgbInstance() {
         return WritablePixelFormat.IntArgb.INSTANCE;
     }
 
+    /**
+     * Returns a {@code WritablePixelFormat} instance describing a pixel
+     * layout with the pixels stored in 32-bit integers with the
+     * <b>premultiplied</b> components stored in order, from MSb to LSb:
+     * alpha, red, green, blue.
+     * <p>
+     * Pixels in this format can be decoded using the following sample code:
+     * <pre>
+     *     int pixel = array[rowstart + x];
+     * 
+     *     int alpha = ((pixel >> 24) & 0xff);
+     *     int red   = ((pixel >> 16) & 0xff);
+     *     int green = ((pixel >>  8) & 0xff);
+     *     int blue  = ((pixel      ) & 0xff);
+     * </pre>
+     * 
+     * @return a {@code WritabelPixelFormat<IntBuffer>} describing the
+     *         indicated pixel format
+     */
     public static WritablePixelFormat<IntBuffer> getIntArgbPreInstance() {
         return WritablePixelFormat.IntArgbPre.INSTANCE;
     }
 
+    /**
+     * Returns a {@code WritablePixelFormat} instance describing a pixel
+     * layout with the pixels stored in adjacent bytes with the
+     * <b>non-premultiplied</b> components stored in order of increasing index:
+     * blue, green, red, alpha.
+     * <p>
+     * Pixels in this format can be decoded using the following sample code:
+     * <pre>
+     *     int i = rowstart + x * 4;
+     * 
+     *     int blue  = (array[i+0] & 0xff);
+     *     int green = (array[i+1] & 0xff);
+     *     int red   = (array[i+2] & 0xff);
+     *     int alpha = (array[i+3] & 0xff);
+     * </pre>
+     * 
+     * @return a {@code WritablePixelFormat<ByteBuffer>} describing the
+     *         indicated pixel format
+     */
     public static WritablePixelFormat<ByteBuffer> getByteBgraInstance() {
         return WritablePixelFormat.ByteBgra.INSTANCE;
     }
 
+    /**
+     * Returns a {@code WritablePixelFormat} instance describing a pixel
+     * layout with the pixels stored in adjacent bytes with the
+     * <b>premultiplied</b> components stored in order of increasing index:
+     * blue, green, red, alpha.
+     * <p>
+     * Pixels in this format can be decoded using the following sample code:
+     * <pre>
+     *     int i = rowstart + x * 4;
+     * 
+     *     int blue  = (array[i+0] & 0xff);
+     *     int green = (array[i+1] & 0xff);
+     *     int red   = (array[i+2] & 0xff);
+     *     int alpha = (array[i+3] & 0xff);
+     * </pre>
+     * 
+     * @return a {@code WritablePixelFormat<ByteBuffer>} describing the
+     *         indicated pixel format
+     */
     public static WritablePixelFormat<ByteBuffer> getByteBgraPreInstance() {
         return WritablePixelFormat.ByteBgraPre.INSTANCE;
     }
 
+    /**
+     * Returns a {@code PixelFormat} instance describing a pixel
+     * layout with the pixels stored in adjacent bytes with the
+     * color components stored in order of increasing index:
+     * red, green, blue.
+     * <p>
+     * Pixels in this format can be decoded using the following sample code:
+     * <pre>
+     *     int i = rowstart + x * 3;
+     * 
+     *     int red   = (array[i+0] & 0xff);
+     *     int green = (array[i+1] & 0xff);
+     *     int blue  = (array[i+2] & 0xff);
+     * </pre>
+     * 
+     * @return a {@code PixelFormat<ByteBuffer>} describing the
+     *         indicated pixel format
+     */
     public static PixelFormat<ByteBuffer> getByteRgbInstance() {
         return ByteRgb.instance;
     }
 
+    /**
+     * Creates a {@code PixelFormat} instance describing a pixel layout
+     * with the pixels stored as single bytes representing an index
+     * into the specified lookup table of <b>premultiplied</b> color
+     * values in the {@link Type#INT_ARGB_PRE INT_ARGB_PRE} format.
+     * <p>
+     * Pixels in this format can be decoded using the following sample code:
+     * <pre>
+     *     int pixel = array[rowstart + x] & 0xff;
+     *     int argb  = colors[pixel];
+     * 
+     *     int alpha = ((argb >> 24) & 0xff);
+     *     int red   = ((argb >> 16) & 0xff);
+     *     int green = ((argb >>  8) & 0xff);
+     *     int blue  = ((argb      ) & 0xff);
+     * </pre>
+     * 
+     * @param colors an {@code int[]} array of 32-bit color values in
+     *               the {@link Type#INT_ARGB_PRE INT_ARGB_PRE} format
+     * @return a {@code PixelFormat<ByteBuffer>} describing the indicated
+     *         pixel format with the specified list of premultiplied colors
+     */
     public static PixelFormat<ByteBuffer>
         createByteIndexedPremultipliedInstance(int colors[])
     {
         return IndexedPixelFormat.createByte(colors, true);
     }
 
+    /**
+     * Creates a {@code PixelFormat} instance describing a pixel layout
+     * with the pixels stored as single bytes representing an index
+     * into the specified lookup table of <b>non-premultiplied</b> color
+     * values in the {@link Type#INT_ARGB INT_ARGB} format.
+     * <p>
+     * Pixels in this format can be decoded using the following sample code:
+     * <pre>
+     *     int pixel = array[rowstart + x] & 0xff;
+     *     int argb  = colors[pixel];
+     * 
+     *     int alpha = ((argb >> 24) & 0xff);
+     *     int red   = ((argb >> 16) & 0xff);
+     *     int green = ((argb >>  8) & 0xff);
+     *     int blue  = ((argb      ) & 0xff);
+     * </pre>
+     * 
+     * @param colors an {@code int[]} array of 32-bit color values in
+     *               the {@link Type#INT_ARGB INT_ARGB} format
+     * @return a {@code PixelFormat<ByteBuffer>} describing the indicated
+     *         pixel format with the specified list of non-premultiplied colors
+     */
     public static PixelFormat<ByteBuffer>
         createByteIndexedInstance(int colors[])
     {
         return IndexedPixelFormat.createByte(colors, false);
     }
 
+    /**
+     * Returns the enum representing the storage format of the pixels
+     * managed by this {@code PixelFormat} object.
+     * 
+     * @return the {@code Type} enum of the pixels
+     */
     public Type getType() {
         return type;
     }
 
+    /**
+     * Returns true iff this {@code PixelFormat} object can convert
+     * color information into a pixel representation.
+     * 
+     * @return true iff this {@code PixelFormat} can convert colors to
+     *         pixel data
+     */
     public abstract boolean isWritable();
 
+    /**
+     * Returns true iff the color components decoded (or encoded) by this
+     * format are pre-multiplied by the alpha component for more efficient
+     * blending calculations.
+     * 
+     * @return true iff the managed color components are premultiplied
+     *         by alpha
+     */
     public abstract boolean isPremultiplied();
 
     static int NonPretoPre(int nonpre) {
@@ -151,8 +313,9 @@
     }
 
     /**
-     * Reads a 32-bit integer representation of the color from the buffer
-     * at the specified coordinates.
+     * Reads pixel data from the buffer at the specified coordinates and
+     * converts it to a 32-bit integer representation of the color in the
+     * {@link Type#INT_ARGB INT_ARGB} format.
      * The 32-bit integer will contain the 4 color components in separate
      * 8-bit fields in ARGB order from the most significant byte to the least
      * significant byte.
@@ -167,6 +330,15 @@
      * integer and indexed formats, or 3 or 4 in the case of the byte
      * formats), but some images may have further padding between rows for
      * alignment or other purposes.
+     * <p>
+     * The color components can be extracted from the returned integer using
+     * the following sample code:
+     * <pre>
+     *     int alpha = ((retval >> 24) & 0xff);
+     *     int red   = ((retval >> 16) & 0xff);
+     *     int green = ((retval >>  8) & 0xff);
+     *     int blue  = ((retval      ) & 0xff);
+     * </pre>
      * 
      * @param buf the buffer of pixel data
      * @param x the X coordinate of the pixel to be read
@@ -174,7 +346,7 @@
      * @param scanlineStride the number of buffer elements between the
      *        start of adjacent pixel rows in the buffer
      * @return a 32-bit value with the color of the pixel in a format
-     *         similar to the {@code Type.INT_ARGB} pixel format
+     *         similar to the {@link Type#INT_ARGB INT_ARGB} pixel format
      */
     public abstract int getArgb(T buf, int x, int y, int scanlineStride);
 
@@ -235,7 +407,7 @@
             return premult;
         }
 
-        private int[] getPreColors() {
+        int[] getPreColors() {
             if (precolors == null) {
                 int colors[] = new int[nonprecolors.length];
                 for (int i = 0; i < colors.length; i++) {
@@ -246,7 +418,7 @@
             return precolors;
         }
 
-        private int[] getNonPreColors() {
+        int[] getNonPreColors() {
             if (nonprecolors == null) {
                 int colors[] = new int[precolors.length];
                 for (int i = 0; i < colors.length; i++) {
--- a/modules/graphics/src/main/java/javafx/scene/image/WritablePixelFormat.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/image/WritablePixelFormat.java	Tue Aug 06 14:14:24 2013 -0700
@@ -48,7 +48,8 @@
     }
 
     /**
-     * Stores a 32-bit integer representation of the color in the buffer
+     * Stores the appropriate pixel data that represents the specified
+     * 32-bit integer representation of a color in the buffer
      * at the specified coordinates.
      * The 32-bit integer will contain the 4 color components in separate
      * 8-bit fields in ARGB order from the most significant byte to the least
@@ -64,6 +65,15 @@
      * integer and indexed formats, or 3 or 4 in the case of the byte
      * formats), but some images may have further padding between rows for
      * alignment or other purposes.
+     * <p>
+     * Color components can be composed into an integer using the following
+     * sample code:
+     * <pre>
+     *     int argb = ((alpha &lt;&lt; 24) |
+     *                 (red   &lt;&lt; 16) |
+     *                 (green &lt;&lt;  8) |
+     *                 (blue       );
+     * </pre>
      * 
      * @param buf the buffer of pixel data
      * @param x the X coordinate of the pixel to be read
--- a/modules/graphics/src/main/java/javafx/scene/text/Text.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/text/Text.java	Tue Aug 06 14:14:24 2013 -0700
@@ -161,10 +161,6 @@
 
     private void checkOrientation() {
         if (!isSpan()) {
-            /* Using impl_transformsChanged to detect for orientation change.
-             * This can be improved if EffectiveNodeOrientation becomes a
-             * property. See http://javafx-jira.kenai.com/browse/RT-26140
-             */
             NodeOrientation orientation = getEffectiveNodeOrientation();
             boolean rtl =  orientation == NodeOrientation.RIGHT_TO_LEFT;
             int dir = rtl ? TextLayout.DIRECTION_RTL : TextLayout.DIRECTION_LTR;
@@ -252,17 +248,17 @@
     private boolean spanBoundsInvalid = true;
 
     void layoutSpan(GlyphList[] runs) {
-        /* Sometimes a property change in the text node will causes layout in 
-         * text flow. In this case all the dirty bits are already clear and no 
-         * extra work is necessary. Other times the layout is caused by changes  
+        /* Sometimes a property change in the text node will causes layout in
+         * text flow. In this case all the dirty bits are already clear and no
+         * extra work is necessary. Other times the layout is caused by changes
          * in the text flow object (wrapping width and text alignment for example).
-         * In the second case the dirty bits must be set here using 
-         * needsTextLayout(). Note that needsTextLayout() uses impl_geomChanged() 
+         * In the second case the dirty bits must be set here using
+         * needsTextLayout(). Note that needsTextLayout() uses impl_geomChanged()
          * which causes another (undesired) layout request in the parent.
-         * In general this is not a problem because shapes are not resizable and 
+         * In general this is not a problem because shapes are not resizable and
          * region do not propagate layout changes to the parent.
          * This is a special case where a shape is resized by the parent during
-         * layoutChildren().  See TextFlow#requestLayout() for information how 
+         * layoutChildren().  See TextFlow#requestLayout() for information how
          * text flow deals with this situation.
          */
         needsTextLayout();
@@ -332,7 +328,7 @@
         int type = TextLayout.TYPE_TEXT;
         if (isStrikethrough()) type |= TextLayout.TYPE_STRIKETHROUGH;
         if (isUnderline()) type |= TextLayout.TYPE_UNDERLINE;
-        
+
         TextSpan filter = null;
         if (isSpan()) {
             /* Spans are always relative to the top */
@@ -349,7 +345,14 @@
     }
 
     private BaseBounds getVisualBounds() {
-        return getShape().getBounds();
+        if (impl_mode == NGShape.Mode.FILL || getStrokeType() == StrokeType.INSIDE) {
+            int type = TextLayout.TYPE_TEXT;
+            if (isStrikethrough()) type |= TextLayout.TYPE_STRIKETHROUGH;
+            if (isUnderline()) type |= TextLayout.TYPE_UNDERLINE;
+            return getTextLayout().getVisualBounds(type);
+        } else {
+            return getShape().getBounds();
+        }
     }
 
     private BaseBounds getLogicalBounds() {
@@ -542,7 +545,7 @@
     }
 
     public final TextBoundsType getBoundsType() {
-        return boundsType == null ? 
+        return boundsType == null ?
             DEFAULT_BOUNDS_TYPE : boundsTypeProperty().get();
     }
 
@@ -671,7 +674,7 @@
      * has no effect.
      *
      * @defaultValue TextAlignment.LEFT
-     */   
+     */
     public final ObjectProperty<TextAlignment> textAlignmentProperty() {
         return getTextAttribute().textAlignmentProperty();
     }
@@ -802,8 +805,8 @@
     }
 
     /**
-     * Shape of selection in local coordinates. 
-     * 
+     * Shape of selection in local coordinates.
+     *
      * @treatAsPrivate implementation detail
      * @deprecated This is an internal API that is not intended
      * for use and will be removed in the next version
@@ -820,7 +823,7 @@
      */
     @Deprecated
     public final void setImpl_selectionStart(int value) {
-        if (value == -1 && 
+        if (value == -1 &&
                 (attributes == null || attributes.impl_selectionStart == null)) {
             return;
         }
@@ -841,7 +844,7 @@
     }
 
     /**
-     * Selection start index in the content. 
+     * Selection start index in the content.
      * set to {@code -1} to unset selection.
      *
      * @treatAsPrivate implementation detail
@@ -860,7 +863,7 @@
      */
     @Deprecated
     public final void setImpl_selectionEnd(int value) {
-        if (value == -1 && 
+        if (value == -1 &&
                 (attributes == null || attributes.impl_selectionEnd == null)) {
             return;
         }
@@ -881,7 +884,7 @@
     }
 
     /**
-     * Selection end index in the content. 
+     * Selection end index in the content.
      * set to {@code -1} to unset selection.
      *
      * @treatAsPrivate implementation detail
@@ -915,7 +918,7 @@
 
     /**
      * Shape of caret in local coordinates.
-     * 
+     *
      * @treatAsPrivate implementation detail
      * @deprecated This is an internal API that is not intended
      * for use and will be removed in the next version
@@ -932,7 +935,7 @@
      */
     @Deprecated
     public final void setImpl_caretPosition(int value) {
-        if (value == -1 && 
+        if (value == -1 &&
                 (attributes == null || attributes.impl_caretPosition == null)) {
             return;
         }
@@ -953,9 +956,9 @@
     }
 
     /**
-     * caret index in the content. 
+     * caret index in the content.
      * set to {@code -1} to unset caret.
-     * 
+     *
      * @treatAsPrivate implementation detail
      * @deprecated This is an internal API that is not intended
      * for use and will be removed in the next version
@@ -987,7 +990,7 @@
     public final boolean isImpl_caretBias() {
         if (attributes == null || attributes.impl_caretBias == null) {
             return DEFAULT_CARET_BIAS;
-        } 
+        }
         return getTextAttribute().isImpl_caretBias();
     }
 
@@ -1164,9 +1167,19 @@
             if (getTextInternal().length() == 0 || impl_mode == NGShape.Mode.EMPTY) {
                 return bounds.makeEmpty();
             }
-
-            /* Let the super class compute the bounds using shape */
-            return super.impl_computeGeomBounds(bounds, tx);
+            if (impl_mode == NGShape.Mode.FILL || getStrokeType() == StrokeType.INSIDE) {
+                /* Optimize for FILL and INNER STROKE: save the cost of shaping each glyph */
+                BaseBounds visualBounds = getVisualBounds();
+                float x = visualBounds.getMinX() + (float) getX();
+                float yadj = getYAdjustment(visualBounds);
+                float y = visualBounds.getMinY() + yadj + (float) getY();
+                bounds.deriveWithNewBounds(x, y, 0, x + visualBounds.getWidth(),
+                        y + visualBounds.getHeight(), 0);
+                return tx.transform(bounds, bounds);
+            } else {
+                /* Let the super class compute the bounds using shape */
+                return super.impl_computeGeomBounds(bounds, tx);
+            }
         }
 
         BaseBounds textBounds = getLogicalBounds();
@@ -1331,8 +1344,8 @@
 
             @Override
             public boolean isSettable(Text node) {
-                return node.attributes == null || 
-                       node.attributes.textOrigin == null || 
+                return node.attributes == null ||
+                       node.attributes.textOrigin == null ||
                       !node.attributes.textOrigin.isBound();
             }
 
@@ -1429,8 +1442,8 @@
      *
      * @since JavaFX 8.0
      */
-    
-    
+
+
     @Override
     public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
         return getClassCssMetaData();
@@ -1498,7 +1511,7 @@
             accText = new AccessibleText(this);
         return (AccessibleProvider)accText ;
     }
-    
+
     /***************************************************************************
      *                                                                         *
      *                       Seldom Used Properties                            *
@@ -1506,14 +1519,14 @@
      **************************************************************************/
 
     private TextAttribute attributes;
-    
+
     private TextAttribute getTextAttribute() {
         if (attributes == null) {
             attributes = new TextAttribute();
         }
         return attributes;
     }
-    
+
     private static final VPos DEFAULT_TEXT_ORIGIN = VPos.BASELINE;
     private static final TextBoundsType DEFAULT_BOUNDS_TYPE = TextBoundsType.LOGICAL;
     private static final boolean DEFAULT_UNDERLINE = false;
@@ -1525,7 +1538,7 @@
     private static final int DEFAULT_SELECTION_END = -1;
     private static final Color DEFAULT_SELECTION_FILL= Color.WHITE;
     private static final boolean DEFAULT_CARET_BIAS = true;
-    
+
     private final class TextAttribute {
 
         private ObjectProperty<VPos> textOrigin;
@@ -1549,7 +1562,7 @@
             }
             return textOrigin;
         }
-        
+
         private BooleanProperty underline;
 
         public final boolean isUnderline() {
@@ -1574,7 +1587,7 @@
             }
             return underline;
         }
-        
+
         private BooleanProperty strikethrough;
 
         public final boolean isStrikethrough() {
@@ -1599,7 +1612,7 @@
             }
             return strikethrough;
         }
-        
+
         private ObjectProperty<TextAlignment> textAlignment;
 
         public final TextAlignment getTextAlignment() {
@@ -1631,7 +1644,7 @@
             }
             return textAlignment;
         }
-        
+
         private DoubleProperty lineSpacing;
 
         public final double getLineSpacing() {
@@ -1669,7 +1682,7 @@
                         {bind(fontProperty());}
                         @Override protected double computeValue() {
                             /* This method should never be used for spans.
-                             * If it is, it will still returns the ascent 
+                             * If it is, it will still returns the ascent
                              * for the first line in the layout */
                             BaseBounds bounds = getLogicalBounds();
                             return -bounds.getMinY();
@@ -1706,7 +1719,7 @@
         @Deprecated
         public final ObjectProperty<Paint> impl_selectionFillProperty() {
             if (selectionFill == null) {
-                selectionFill = 
+                selectionFill =
                     new ObjectPropertyBase<Paint>(DEFAULT_SELECTION_FILL) {
                         @Override public Object getBean() { return Text.this; }
                         @Override public String getName() { return "impl_selectionFill"; }
@@ -1729,7 +1742,7 @@
         @Deprecated
         public final IntegerProperty impl_selectionStartProperty() {
             if (impl_selectionStart == null) {
-                impl_selectionStart = 
+                impl_selectionStart =
                     new IntegerPropertyBase(DEFAULT_SELECTION_START) {
                         @Override public Object getBean() { return Text.this; }
                         @Override public String getName() { return "impl_selectionStart"; }
@@ -1752,7 +1765,7 @@
         @Deprecated
         public final IntegerProperty impl_selectionEndProperty() {
             if (impl_selectionEnd == null) {
-                impl_selectionEnd = 
+                impl_selectionEnd =
                     new IntegerPropertyBase(DEFAULT_SELECTION_END) {
                         @Override public Object getBean() { return Text.this; }
                         @Override public String getName() { return "impl_selectionEnd"; }
@@ -1791,7 +1804,7 @@
             }
             return impl_caretShape;
         }
-        
+
         @Deprecated
         private IntegerProperty impl_caretPosition;
 
@@ -1808,7 +1821,7 @@
             }
             return impl_caretPosition;
         }
-        
+
         @Deprecated
         private BooleanProperty impl_caretBias;
 
--- a/modules/graphics/src/main/java/javafx/scene/text/TextFlow.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/text/TextFlow.java	Tue Aug 06 14:14:24 2013 -0700
@@ -29,18 +29,21 @@
 import java.util.Collections;
 import java.util.List;
 
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
 import javafx.beans.property.DoubleProperty;
 import javafx.beans.property.ObjectProperty;
 import javafx.geometry.HPos;
 import javafx.geometry.Insets;
+import javafx.geometry.NodeOrientation;
 import javafx.geometry.Orientation;
 import javafx.geometry.VPos;
 import javafx.scene.Node;
 import javafx.scene.layout.Pane;
-
 import javafx.css.StyleableDoubleProperty;
 import javafx.css.StyleableObjectProperty;
 import javafx.css.CssMetaData;
+
 import com.sun.javafx.css.converters.EnumConverter;
 import com.sun.javafx.css.converters.SizeConverter;
 import com.sun.javafx.geom.BaseBounds;
@@ -51,6 +54,7 @@
 import com.sun.javafx.scene.text.TextLayoutFactory;
 import com.sun.javafx.scene.text.TextSpan;
 import com.sun.javafx.tk.Toolkit;
+
 import javafx.css.Styleable;
 import javafx.css.StyleableProperty;
 
@@ -62,19 +66,19 @@
  * A single {@link Text} node can span over several lines due to wrapping and
  * the visual location of {@link Text} node can differ from the logical location
  * due to bidi reordering.
- * 
+ *
  * <p>
- * Any other Node, rather than Text, will be treated as embedded object in the 
+ * Any other Node, rather than Text, will be treated as embedded object in the
  * text layout. It will be inserted in the content using its preferred width,
  * height, and baseline offset.
- * 
+ *
  * <p>
  * When a {@link Text} node is inside of a TextFlow some its properties are ignored.
  * 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.
- * 
+ *
  * <p>
  * The wrapping width of the layout is determined by the region's current width.
  * It can be specified by the application by setting the textflow's preferred
@@ -151,11 +155,16 @@
      */
     public TextFlow() {
         super();
+        effectiveNodeOrientationProperty().addListener(new InvalidationListener() {
+            @Override public void invalidated(Observable observable) {
+                checkOrientation();
+            }
+        });
     }
 
     /**
      * Creates a TextFlow layout with the given children.
-     * 
+     *
      * @param children children.
      */
     public TextFlow(Node... children) {
@@ -163,6 +172,21 @@
         getChildren().addAll(children);
     }
 
+    private void checkOrientation() {
+        NodeOrientation orientation = getEffectiveNodeOrientation();
+        boolean rtl =  orientation == NodeOrientation.RIGHT_TO_LEFT;
+        int dir = rtl ? TextLayout.DIRECTION_RTL : TextLayout.DIRECTION_LTR;
+        TextLayout layout = getTextLayout();
+        if (layout.setDirection(dir)) {
+            requestLayout();
+        }
+    }
+
+    @Override
+    public boolean usesMirroring() {
+        return false;
+    }
+
     @Override protected void setWidth(double value) {
         if (value != getWidth()) {
             TextLayout layout = getTextLayout();
@@ -229,7 +253,7 @@
         * The content does not need to set when:
         *  the width/height changes in the region
         *  the insets changes in the region
-        * 
+        *
         * Unfortunately, it is not possible to know what change invoked request
         * layout. The solution is to always reset the content in the text
         * layout and rely on it to preserve itself if the new content equals to
@@ -423,7 +447,7 @@
       * @treatAsPrivate implementation detail
       */
      private static class StyleableProperties {
-         
+
          private static final
              CssMetaData<TextFlow, TextAlignment> TEXT_ALIGNMENT =
                  new CssMetaData<TextFlow,TextAlignment>("-fx-text-alignment",
@@ -457,7 +481,7 @@
          static {
             final List<CssMetaData<? extends Styleable, ?>> styleables =
                 new ArrayList<CssMetaData<? extends Styleable, ?>>(Pane.getClassCssMetaData());
-            styleables.add(TEXT_ALIGNMENT); 
+            styleables.add(TEXT_ALIGNMENT);
             styleables.add(LINE_SPACING);
             STYLEABLES = Collections.unmodifiableList(styleables);
          }
@@ -471,12 +495,6 @@
         return StyleableProperties.STYLEABLES;
     }
 
-    /**
-     * {@inheritDoc}
-     *
-     */
-    
-    
     @Override
     public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
         return getClassCssMetaData();
--- a/modules/graphics/src/main/java/javafx/stage/PopupWindow.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/stage/PopupWindow.java	Tue Aug 06 14:14:24 2013 -0700
@@ -432,7 +432,7 @@
         Toolkit toolkit = Toolkit.getToolkit();
         if (visible && (impl_peer == null)) {
             // Setup the peer
-            impl_peer = toolkit.createTKPopupStage(StageStyle.TRANSPARENT, getOwnerWindow().impl_getPeer(), acc);
+            impl_peer = toolkit.createTKPopupStage(getOwnerWindow().impl_getPeer(), acc);
             peerListener = new PopupWindowPeerListener(PopupWindow.this);
         }
     }
--- a/modules/graphics/src/main/jsl-decora/InvertMask.jsl	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/jsl-decora/InvertMask.jsl	Tue Aug 06 14:14:24 2013 -0700
@@ -27,10 +27,14 @@
 private float[] getOffset() {
     float xoff = getEffect().getOffsetX();
     float yoff = getEffect().getOffsetY();
-    return new float[] {
-        xoff / getInputNativeBounds(0).width,
-        yoff / getInputNativeBounds(0).height,
-    };
+    float offsets[] = new float[] { xoff, yoff };
+    try {
+        getInputTransform(0).inverseDeltaTransform(offsets, 0, offsets, 0, 1);
+    } catch (Exception e) {
+    }
+    offsets[0] /= getInputNativeBounds(0).width;
+    offsets[1] /= getInputNativeBounds(0).height;
+    return offsets;
 }
 >>
 
--- a/modules/graphics/src/main/native-glass/gtk/glass_gtkcompat.cpp	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/glass_gtkcompat.cpp	Tue Aug 06 14:14:24 2013 -0700
@@ -209,15 +209,20 @@
 
 gboolean
 glass_gdk_mouse_devices_grab(GdkWindow *gdkWindow) {
-    return glass_gdk_mouse_devices_grab_with_cursor(gdkWindow, NULL);
+    return glass_gdk_mouse_devices_grab_with_cursor(gdkWindow, NULL, TRUE);
 }
 
 gboolean
 glass_gdk_mouse_devices_grab_with_cursor(GdkWindow *gdkWindow, GdkCursor *cursor) {
+    return glass_gdk_mouse_devices_grab_with_cursor(gdkWindow, cursor, TRUE);
+}
+
+gboolean
+glass_gdk_mouse_devices_grab_with_cursor(GdkWindow *gdkWindow, GdkCursor *cursor, gboolean owner_events) {
     if (disableGrab) {
         return TRUE;
     }
-    GdkGrabStatus status = gdk_pointer_grab(gdkWindow, TRUE, (GdkEventMask)
+    GdkGrabStatus status = gdk_pointer_grab(gdkWindow, owner_events, (GdkEventMask)
                                             (GDK_POINTER_MOTION_MASK
                                                 | GDK_POINTER_MOTION_HINT_MASK
                                                 | GDK_BUTTON_MOTION_MASK
--- a/modules/graphics/src/main/native-glass/gtk/glass_gtkcompat.h	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/glass_gtkcompat.h	Tue Aug 06 14:14:24 2013 -0700
@@ -112,6 +112,7 @@
 
 gboolean glass_gdk_mouse_devices_grab(GdkWindow * gdkWindow);
 gboolean glass_gdk_mouse_devices_grab_with_cursor(GdkWindow * gdkWindow, GdkCursor *cursor);
+gboolean glass_gdk_mouse_devices_grab_with_cursor(GdkWindow * gdkWindow, GdkCursor *cursor, gboolean owner_events);
 void glass_gdk_mouse_devices_ungrab();
 
 void glass_gdk_master_pointer_grab(GdkWindow *window, GdkCursor *cursor);
--- a/modules/graphics/src/main/native-glass/gtk/glass_window.cpp	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/glass_window.cpp	Tue Aug 06 14:14:24 2013 -0700
@@ -46,6 +46,7 @@
 #include <algorithm>
 
 WindowContext * WindowContextBase::sm_grab_window = NULL;
+WindowContext * WindowContextBase::sm_mouse_drag_window = NULL;
 
 GdkWindow* WindowContextBase::get_gdk_window(){
     return gdk_window;
@@ -114,6 +115,10 @@
 }
 
 void WindowContextBase::process_destroy() {
+    if (WindowContextBase::sm_mouse_drag_window == this) {
+        ungrab_mouse_drag_focus();
+    }
+
     if (WindowContextBase::sm_grab_window == this) {
         ungrab_focus();
     }
@@ -209,7 +214,7 @@
     }
 
     jint button = gtk_button_number_to_mouse_button(event->button);
-    
+
     if (jview && button != com_sun_glass_events_MouseEvent_BUTTON_NONE) {
         mainEnv->CallVoidMethod(jview, jViewNotifyMouse,
                 press ? com_sun_glass_events_MouseEvent_DOWN : com_sun_glass_events_MouseEvent_UP,
@@ -230,6 +235,16 @@
         }
     }
 
+    // Upper layers expects from us Windows behavior:
+    // all mouse events should be delivered to window where drag begins 
+    // and no exit/enter event should be reported during this drag.
+    // We can grab mouse pointer for these needs.
+    if (press) {
+        grab_mouse_drag_focus();
+    } else if ((event->state & MOUSE_BUTTONS_MASK)
+            && !(state & MOUSE_BUTTONS_MASK)) { // all buttons released
+        ungrab_mouse_drag_focus();
+    }
 }
 
 void WindowContextBase::process_mouse_motion(GdkEventMotion* event) {
@@ -300,19 +315,21 @@
     if (jview) {
         guint state = event->state;
         if (enter) { // workaround for RT-21590
-            state &= ~(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK);
+            state &= ~MOUSE_BUTTONS_MASK;
         }
 
-        is_mouse_entered = enter;
-        mainEnv->CallVoidMethod(jview, jViewNotifyMouse,
-                enter ? com_sun_glass_events_MouseEvent_ENTER : com_sun_glass_events_MouseEvent_EXIT,
-                com_sun_glass_events_MouseEvent_BUTTON_NONE,
-                (jint) event->x, (jint) event->y,
-                (jint) event->x_root, (jint) event->y_root,
-                gdk_modifier_mask_to_glass(state),
-                JNI_FALSE,
-                JNI_FALSE);
-        CHECK_JNI_EXCEPTION(mainEnv)
+        if (enter != is_mouse_entered) {
+            is_mouse_entered = enter;
+            mainEnv->CallVoidMethod(jview, jViewNotifyMouse,
+                    enter ? com_sun_glass_events_MouseEvent_ENTER : com_sun_glass_events_MouseEvent_EXIT,
+                    com_sun_glass_events_MouseEvent_BUTTON_NONE,
+                    (jint) event->x, (jint) event->y,
+                    (jint) event->x_root, (jint) event->y_root,
+                    gdk_modifier_mask_to_glass(state),
+                    JNI_FALSE,
+                    JNI_FALSE);
+            CHECK_JNI_EXCEPTION(mainEnv)
+        }
     }
 }
 
@@ -468,8 +485,27 @@
     return TRUE;
 }
 
+bool WindowContextBase::grab_mouse_drag_focus() {
+    if (glass_gdk_mouse_devices_grab_with_cursor(
+            gdk_window, gdk_window_get_cursor(gdk_window), FALSE)) {
+        WindowContextBase::sm_mouse_drag_window = this;
+        return true;
+    } else {
+        return false;
+    }
+}
+
+void WindowContextBase::ungrab_mouse_drag_focus() {
+    WindowContextBase::sm_mouse_drag_window = NULL;
+    glass_gdk_mouse_devices_ungrab();
+    if (WindowContextBase::sm_grab_window) {
+        WindowContextBase::sm_grab_window->grab_focus();
+    }
+}
+
 bool WindowContextBase::grab_focus() {
-    if (glass_gdk_mouse_devices_grab(gdk_window)) {
+    if (WindowContextBase::sm_mouse_drag_window
+            || glass_gdk_mouse_devices_grab(gdk_window)) {
         WindowContextBase::sm_grab_window = this;
         return true;
     } else {
@@ -478,7 +514,9 @@
 }
 
 void WindowContextBase::ungrab_focus() {
-    glass_gdk_mouse_devices_ungrab();
+    if (!WindowContextBase::sm_mouse_drag_window) {
+        glass_gdk_mouse_devices_ungrab();
+    }
     WindowContextBase::sm_grab_window = NULL;
 
     if (jwindow) {
@@ -488,7 +526,10 @@
 }
 
 void WindowContextBase::set_cursor(GdkCursor* cursor) {
-    if (WindowContextBase::sm_grab_window) {
+    if (WindowContextBase::sm_mouse_drag_window) {
+        glass_gdk_mouse_devices_grab_with_cursor(
+                WindowContextBase::sm_mouse_drag_window->get_gdk_window(), cursor, FALSE);
+    } else if (WindowContextBase::sm_grab_window) {
         glass_gdk_mouse_devices_grab_with_cursor(
                 WindowContextBase::sm_grab_window->get_gdk_window(), cursor);
     }
--- a/modules/graphics/src/main/native-glass/gtk/glass_window.h	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/glass_window.h	Tue Aug 06 14:14:24 2013 -0700
@@ -59,6 +59,8 @@
     int right;
 };
 
+static const guint MOUSE_BUTTONS_MASK = (guint) (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK);
+
 enum BoundsType {
     BOUNDSTYPE_CONTENT,
     BOUNDSTYPE_WINDOW
@@ -119,7 +121,9 @@
     virtual void request_focus() = 0;
     virtual void set_focusable(bool)= 0;
     virtual bool grab_focus() = 0;
+    virtual bool grab_mouse_drag_focus() = 0;
     virtual void ungrab_focus() = 0;
+    virtual void ungrab_mouse_drag_focus() = 0;
     virtual void set_title(const char*) = 0;
     virtual void set_alpha(double) = 0;
     virtual void set_enabled(bool) = 0;
@@ -188,7 +192,24 @@
 
     bool is_mouse_entered;
 
-    static WindowContext * sm_grab_window;
+    /*
+     * sm_grab_window points to WindowContext holding a mouse grab.
+     * It is mostly used for popup windows.
+     */
+    static WindowContext* sm_grab_window;
+    
+    /*
+     * sm_mouse_drag_window points to a WindowContext from which a mouse drag started.
+     * This WindowContext holding a mouse grab during this drag. After releasing
+     * all mouse buttons sm_mouse_drag_window becomes NULL and sm_grab_window's
+     * mouse grab should be restored if present.
+     *
+     * This is done in order to mimic Windows behavior:
+     * All mouse events should be delivered to a window from which mouse drag
+     * started, until all mouse buttons released. No mouse ENTER/EXIT events
+     * should be reported during this drag.
+     */
+    static WindowContext* sm_mouse_drag_window;
 public:
     bool isEnabled();
     bool hasIME();
@@ -208,7 +229,9 @@
     bool is_visible();
     bool set_view(jobject);
     bool grab_focus();
+    bool grab_mouse_drag_focus();
     void ungrab_focus();
+    void ungrab_mouse_drag_focus();
     void set_cursor(GdkCursor*);
     void set_level(int) {}
     void set_background(float, float, float);
--- a/modules/graphics/src/main/native-glass/lens/android/android.c	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/native-glass/lens/android/android.c	Tue Aug 06 14:14:24 2013 -0700
@@ -54,7 +54,6 @@
 #define KEY_ACTION_MULTIPLE 2
 
 JavaVM *dalvikVM;
-JNIEnv *glass_env;
 JNIEnv *dalvik_env;
 
 ANativeWindow *window;
@@ -62,41 +61,36 @@
 int32_t height;
 int32_t format;
 
-static JavaVM* (*_glass_application_getVM)();
-
-static void (*_glass_application_notifyWindowEvent_resize)(
-        JNIEnv *env,
+static void (*_notifyWindowEvent_resize)(
         ANativeWindow *window,
         int eventType,
         int width,
         int height);
 
-static void (*_lens_wm_notifyTouchEvent)(
-        JNIEnv *env,
-        jint state,
+static void (*_notifyTouchEvent)(
+        int state,
         int id,
+        int sendAlsoButtonEvent,
         int xabs,
         int yabs);
 
-static void (*_lens_wm_notifyMotionEvent)(
-        JNIEnv *env,
+static void (*_notifyMotionEvent)(
         int mousePosX,
         int mousePosY,
         int isTouch,
         int touchId);
 
-static void (*_lens_wm_notifyButtonEvent)(
-        JNIEnv *env,
-        jboolean pressed,
+static void (*_notifyButtonEvent)(
+        int pressed,
         int button,
-        int xabs, int yabs);
+        int xabs,
+        int yabs);
 
-static void (*_glass_application_notifyKeyEvent)(
-        JNIEnv *env,
+static void (*_notifyKeyEvent)(
         NativeWindow window,
         int eventType,
         int jfxKeyCode,
-        jboolean isRepeatEvent);
+        int isRepeatEvent);
 
 static NativeWindow(*_glass_window_getFocusedWindow)();
 
@@ -117,6 +111,7 @@
 jmethodID jFXActivity_getLDPath;
 jmethodID jFXActivity_showIME;
 jmethodID jFXActivity_hideIME;
+jmethodID jFXActivity_shutdown;
 
 void init_ids(JNIEnv *env) {
     jFXActivityClass =
@@ -130,6 +125,10 @@
     jFXActivity_hideIME = (*env)->GetMethodID(env, jFXActivityClass,
             "hideIME", "()V");
     CHECK_EXCEPTION(env);
+    
+    jFXActivity_shutdown = (*env)->GetMethodID(env, jFXActivityClass,
+            "shutdown", "()V");
+    CHECK_EXCEPTION(env);
 
     jFXActivity_getInstance = (*env)->GetStaticMethodID(env, jFXActivityClass,
             "getInstance", "()Lcom/oracle/dalvik/FXActivity;");
@@ -159,12 +158,11 @@
         THROW_RUNTIME_EXCEPTION(env, "dlopen failed with error: %s", dlerror());
         return;
     }
-    _glass_application_getVM = GET_SYMBOL(env, libglass, "glass_application_GetVM");
-    _glass_application_notifyWindowEvent_resize = GET_SYMBOL(env, libglass, "glass_application_notifyWindowEvent_resize");
-    _lens_wm_notifyTouchEvent = GET_SYMBOL(env, libglass, "lens_wm_notifyTouchEvent");
-    _lens_wm_notifyMotionEvent = GET_SYMBOL(env, libglass, "lens_wm_notifyMotionEvent");
-    _lens_wm_notifyButtonEvent = GET_SYMBOL(env, libglass, "lens_wm_notifyButtonEvent");
-    _glass_application_notifyKeyEvent = GET_SYMBOL(env, libglass, "glass_application_notifyKeyEvent");
+    _notifyWindowEvent_resize = GET_SYMBOL(env, libglass, "notifyWindowEvent_resize");
+    _notifyTouchEvent = GET_SYMBOL(env, libglass, "notifyTouchEvent");
+    _notifyMotionEvent = GET_SYMBOL(env, libglass, "notifyMotionEvent");
+    _notifyButtonEvent = GET_SYMBOL(env, libglass, "notifyButtonEvent");
+    _notifyKeyEvent = GET_SYMBOL(env, libglass, "notifyKeyEvent");
     _glass_window_getFocusedWindow = GET_SYMBOL(env, libglass, "glass_window_getFocusedWindow");
     _glass_inputEvents_getJavaKeycodeFromPlatformKeyCode = GET_SYMBOL(env, libglass,
             "glass_inputEvents_getJavaKeycodeFromPlatformKeyCode");
@@ -219,23 +217,15 @@
 (JNIEnv *ignore, jobject view, jint action, jint absx, jint absy) {
     LOGV(TAG, "Touch event: [%s, x: %i, y: %i]\n", describe_touch_action(action), absx, absy);
 
-    JNIEnv *genv = get_glass_JNIEnv();
-    if (!genv) return;
-
     int fxstate = to_jfx_touch_action(action);
     if (!fxstate) {
         LOGE(TAG, "Can't handle this state yet. Ignoring. (Probably multitouch)");
         return;
     }
     if (fxstate == com_sun_glass_events_TouchEvent_TOUCH_MOVED) {
-        (*_lens_wm_notifyMotionEvent)(genv, absx, absy, 1, 0);
+        (*_notifyMotionEvent)(absx, absy, 1, 0);
     } else {
-        (*_lens_wm_notifyTouchEvent)(genv, fxstate, 0, absx, absy);
-        //send also mouse event
-        (*_lens_wm_notifyButtonEvent)(genv,
-                (fxstate == com_sun_glass_events_TouchEvent_TOUCH_PRESSED),
-                com_sun_glass_events_MouseEvent_BUTTON_LEFT,
-                absx, absy);
+        (*_notifyTouchEvent)(fxstate, 0, 1, absx, absy);
     }
 }
 
@@ -246,26 +236,13 @@
  */
 JNIEXPORT void JNICALL Java_com_oracle_dalvik_FXActivity_00024InternalSurfaceView_onKeyEventNative
 (JNIEnv *ignore, jobject view, jint action, jint keyCode) {
-    JNIEnv *genv = get_glass_JNIEnv();
-    if (!genv) return;
-
+    
+    LOGV(TAG, "Key event: [action: %s, keyCode: %i]\n", describe_key_action(action), keyCode);
     int jfxaction = to_jfx_key_action(action);
     int jfxKeyCode = (*_glass_inputEvents_getJavaKeycodeFromPlatformKeyCode)(
             translate_to_linux_keycode(keyCode));
     NativeWindow window = (*_glass_window_getFocusedWindow)();
-    (*_glass_application_notifyKeyEvent)(genv, window, jfxaction, jfxKeyCode, 0);
-}
-
-JNIEnv *get_glass_JNIEnv() {
-    if (!glass_env) {
-        JavaVM *glass_vm = (*_glass_application_getVM)();
-        if (glass_vm == NULL) {
-            LOGV(TAG, "Ignoring event!");
-            return NULL;
-        }
-        (*glass_vm)->AttachCurrentThread(glass_vm, (JNIEnv **) &glass_env, NULL);
-    }
-    return glass_env;
+    (*_notifyKeyEvent)(window, jfxaction, jfxKeyCode, 0);
 }
 
 ANativeWindow *ANDROID_getNativeWindow() {
@@ -276,12 +253,21 @@
     JNIEnv *env;
     (*dalvikVM)->AttachCurrentThread(dalvikVM, (JNIEnv **) &env, NULL);
     (*env)->CallVoidMethod(env, jFXActivity, jFXActivity_showIME);
+    (*dalvikVM)->DetachCurrentThread(dalvikVM);
 }
 
 void ANDROID_hideIME() {
     JNIEnv *env;
     (*dalvikVM)->AttachCurrentThread(dalvikVM, (JNIEnv **) &env, NULL);
     (*env)->CallVoidMethod(env, jFXActivity, jFXActivity_hideIME);
+    (*dalvikVM)->DetachCurrentThread(dalvikVM);
+}
+
+void ANDROID_shutdown() {
+    JNIEnv *env;
+    (*dalvikVM)->AttachCurrentThread(dalvikVM, (JNIEnv **) &env, NULL);
+    (*env)->CallVoidMethod(env, jFXActivity, jFXActivity_shutdown);
+    (*dalvikVM)->DetachCurrentThread(dalvikVM);
 }
 
 int32_t translate_to_linux_keycode(int32_t androidKeyCode) {
@@ -343,6 +329,17 @@
     }
 }
 
+char *describe_key_action(int action) {
+    switch(action) {
+        case KEY_ACTION_DOWN:
+            return "KEY_ACTION_DOWN";
+        case KEY_ACTION_UP:
+            return "KEY_ACTION_UP";
+        case KEY_ACTION_MULTIPLE:
+            return "KEY_ACTION_MULTIPLE";
+    }
+}
+
 char *describe_touch_action(int state) {
     switch (state) {
         case TOUCH_ACTION_DOWN:
@@ -365,6 +362,4 @@
     }
 }
 
-#endif /* ANDROID_NDK */
-
-
+#endif /* ANDROID_NDK */
\ No newline at end of file
--- a/modules/graphics/src/main/native-glass/lens/android/android.h	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/native-glass/lens/android/android.h	Tue Aug 06 14:14:24 2013 -0700
@@ -78,8 +78,6 @@
 
 void init_functions(JNIEnv *);
 
-JNIEnv *get_glass_JNIEnv();
-
 char *describe_touch_action(int);
 
 int to_jfx_touch_action(int);
--- a/modules/graphics/src/main/native-glass/lens/input/android/androidInput.c	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/native-glass/lens/input/android/androidInput.c	Tue Aug 06 14:14:24 2013 -0700
@@ -31,6 +31,7 @@
 static ANativeWindow* (*_ANDROID_getNativeWindow)();
 static void (*_ANDROID_showIME)();
 static void (*_ANDROID_hideIME)();
+static void (*_ANDROID_shutdown)();
 
 
 void init_functions(JNIEnv *env) {
@@ -41,6 +42,7 @@
     _ANDROID_getNativeWindow = GET_SYMBOL(env, libglass, "ANDROID_getNativeWindow");
     _ANDROID_showIME = GET_SYMBOL(env, libglass, "ANDROID_showIME");
     _ANDROID_hideIME = GET_SYMBOL(env, libglass, "ANDROID_hideIME");
+    _ANDROID_shutdown = GET_SYMBOL(env, libglass, "ANDROID_shutdown");
 }
 
 ANativeWindow *getAndroidNativeWindow() {
@@ -68,4 +70,17 @@
     (*_ANDROID_hideIME)();
 }
 
+JNIEXPORT void JNICALL Java_com_sun_glass_ui_android_Activity_shutdown
+(JNIEnv *env, jclass clazz) {
+    android_shutdown();
+}
+
+void android_shutdown() {
+    if (!_ANDROID_shutdown) {
+        init_functions(NULL);
+    }
+    GLASS_LOG_FINE("Send shutdown");
+    (*_ANDROID_shutdown)();
+}
+
 #endif /* ANDROID_NDK */
--- a/modules/graphics/src/main/native-glass/lens/input/android/androidInput.h	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/native-glass/lens/input/android/androidInput.h	Tue Aug 06 14:14:24 2013 -0700
@@ -42,8 +42,10 @@
 #define THROW_RUNTIME_EXCEPTION(ENV, MESSAGE, ...)                          \
     char error_msg[256];                                                    \
     sprintf(error_msg, MESSAGE, __VA_ARGS__);                               \
-    (*ENV)->ThrowNew(ENV,                                                   \
-        (*ENV)->FindClass(ENV, "java/lang/RuntimeException"), error_msg);
+    if (env) {                                                              \
+      (*ENV)->ThrowNew(ENV,                                                 \
+          (*ENV)->FindClass(ENV, "java/lang/RuntimeException"), error_msg); \
+    }                                                                       
 
 #ifdef DEBUG
     // This method is good for early debug, but is unneeded for general use
@@ -65,6 +67,7 @@
 
 ANativeWindow *getAndroidNativeWindow();
 
+void android_shutdown();
     
 #ifdef	__cplusplus
 }
--- a/modules/graphics/src/main/native-glass/lens/input/android/androidLens.c	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/native-glass/lens/input/android/androidLens.c	Tue Aug 06 14:14:24 2013 -0700
@@ -26,7 +26,20 @@
 
 #include "wm/LensWindowManager.h"
 #include "com_sun_glass_ui_lens_LensApplication.h"
+#include "LensCommon.h"
+#include "com_sun_glass_events_TouchEvent.h"
+#include "com_sun_glass_events_MouseEvent.h"
+#include "com_sun_glass_events_KeyEvent.h"
 #include "androidLens.h"
+#include "androidInput.h"
+
+#define ATTACH_JNI_THREAD()  \
+    JNIEnv *env;                                                        \
+    JavaVM *vm = glass_application_GetVM();                             \
+    (*vm)->AttachCurrentThreadAsDaemon(vm, (JNIEnv **) &env, NULL);     
+
+#define DETACH_JNI_THREAD()  \
+    (*vm)->DetachCurrentThread(vm);
 
 jboolean lens_input_initialize(JNIEnv *env) {
     uint32_t flags = 0;
@@ -35,9 +48,91 @@
     return JNI_TRUE;
 }
 
-void lens_input_shutdown() {    
-    JavaVM *glass_vm = glass_application_GetVM();
-    (*glass_vm)->DetachCurrentThread(glass_vm);    
+void lens_input_shutdown() {
+    android_shutdown();    
+}
+
+void notifyWindowEvent_resize(
+        ANativeWindow *window,
+        int eventType,
+        int width,
+        int height) {
+   
+   ATTACH_JNI_THREAD();
+   glass_application_notifyWindowEvent_resize(env,
+        window,
+        eventType,
+        width,
+        height);
+   DETACH_JNI_THREAD();
+}
+
+void notifyTouchEvent(
+        int state,
+        int id,
+        int sendAlsoButtonEvent,
+        int xabs,
+        int yabs) {
+    
+   ATTACH_JNI_THREAD();
+   lens_wm_notifyTouchEvent(env,
+           state,
+           id,
+           xabs,
+           yabs);
+                   
+   if (sendAlsoButtonEvent) {
+        lens_wm_notifyButtonEvent(env,
+                (state == com_sun_glass_events_TouchEvent_TOUCH_PRESSED),
+                com_sun_glass_events_MouseEvent_BUTTON_LEFT,
+                xabs,
+                yabs);
+   }
+   DETACH_JNI_THREAD();
+}
+
+void notifyMotionEvent(
+        int mousePosX,
+        int mousePosY,
+        int isTouch,
+        int touchId) {
+   
+   ATTACH_JNI_THREAD();
+   lens_wm_notifyMotionEvent(env,
+           mousePosX,
+           mousePosY,
+           isTouch,
+           touchId);
+   DETACH_JNI_THREAD();
+}
+
+void _notifyButtonEvent(
+        int pressed,
+        int button,
+        int xabs, int yabs) {
+   
+   ATTACH_JNI_THREAD();
+   lens_wm_notifyButtonEvent(env,
+           pressed,
+           button,
+           xabs,
+           yabs);
+   DETACH_JNI_THREAD();
+}
+
+void _notifyKeyEvent(
+        NativeWindow window,
+        int eventType,
+        int jfxKeyCode,
+        int isRepeatEvent) {
+    
+   ATTACH_JNI_THREAD();
+   glass_application_notifyKeyEvent(env,
+           window,
+           eventType,
+           jfxKeyCode,
+           isRepeatEvent);
+   DETACH_JNI_THREAD();
 }
 
 #endif
\ No newline at end of file
--- a/modules/graphics/src/main/native-glass/lens/input/udev/udevInput.c	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/native-glass/lens/input/udev/udevInput.c	Tue Aug 06 14:14:24 2013 -0700
@@ -221,8 +221,10 @@
 static int newMousePosY = 0;
 
 // Touch
-static const int gTapRadius = 20;//pixels
-static const int gReleasePendingTimeout = 100;//pixels
+#define LENS_MAX_TAP_RADIUS 1000
+#define LENS_MAX_TAP_RELEASE_PENDING_TIMEOUT 1000
+static int gTapRadius = 20;//pixels
+static int gTapReleasePendingTimeout = 50;//milis
 
 
 //JNI
@@ -322,6 +324,35 @@
 
     GLASS_LOG_FINE("screen size=%ix%i", screenWidth, screenHeight);
 
+    //Set tap radius/timeout
+    const char* className = "com/sun/glass/ui/lens/LensTouchInputSupport";
+    jclass lensTouchInputSupport = (*env)->FindClass(env, className);
+    if (lensTouchInputSupport != NULL) {
+        jfieldID radiusVar = (*env)->GetStaticFieldID(env,lensTouchInputSupport, "touchTapRadius", "I");
+        jfieldID timeoutVar = (*env)->GetStaticFieldID(env,lensTouchInputSupport, "touchReleasePendingTimeout", "I");
+
+        if (radiusVar != NULL && timeoutVar != NULL) {
+            int confRadius = (*env)->GetStaticIntField(env, lensTouchInputSupport, radiusVar);
+            int confTimeout = (*env)->GetStaticIntField(env, lensTouchInputSupport, timeoutVar);
+
+            if (confRadius >= 0 && confRadius <= LENS_MAX_TAP_RADIUS && 
+                confTimeout >= 0 && confTimeout <= LENS_MAX_TAP_RELEASE_PENDING_TIMEOUT) 
+            {
+                gTapRadius = confRadius;
+                gTapReleasePendingTimeout = confTimeout;
+                GLASS_LOG_FINEST("Tap radius: %d tap timeout : %d", gTapRadius, gTapReleasePendingTimeout);
+            } else {
+                GLASS_LOG_SEVERE("Out of bound value/s: tap radius: %d  tap release timeout : %d", confRadius, confTimeout);
+            }
+            
+        } else {
+            GLASS_LOG_SEVERE("Could not find static vars in %s", className);
+        }
+
+    } else {
+        GLASS_LOG_SEVERE("Could not find %s", className);
+    }
+
     lens_wm_setPointerPosition(screenWidth / 2, screenHeight / 2);
 
     glass_application_request_native_event_loop(env, &lens_input_eventLoop, NULL);
@@ -1392,6 +1423,9 @@
     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) {
@@ -1429,7 +1463,14 @@
             if (device->isTouch && mouseState->touchState == TOUCH_TAPPING) {
                 mouseState->touchState = TOUCH_RELEASING;
                 mouseState->releaseEvent = mouseState->pendingInputEvents[keyEventIndex];
-                lens_input_eventLoop_triggerTimeout(device, gReleasePendingTimeout, lens_input_pointerEvents_handleTimeout);
+                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);
+                }
             }
         }
     }
--- a/modules/graphics/src/main/native-glass/mac/GlassApplication.m	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/main/native-glass/mac/GlassApplication.m	Tue Aug 06 14:14:24 2013 -0700
@@ -998,3 +998,27 @@
     [NSApp unhideAllApplications:NSApp];
 }
 
+/*
+ * Class:     com_sun_glass_ui_mac_MacApplication
+ * Method:    _getDataDirectory
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_com_sun_glass_ui_mac_MacApplication__1getDataDirectory
+(JNIEnv * env, jobject japplication)
+{
+    jstring string = nil;
+    
+    GLASS_ASSERT_MAIN_JAVA_THREAD(env);
+    GLASS_POOL_ENTER;
+    {
+    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
+    if (paths && [paths count] > 0) {
+        string = (*env)->NewStringUTF(jEnv, [[paths lastObject] UTF8String]);
+    }
+    }
+    GLASS_POOL_EXIT;
+    GLASS_CHECK_EXCEPTION(env);
+    
+    return string;
+}
+
--- a/modules/graphics/src/stub/java/com/sun/javafx/pgstub/StubTextLayout.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/stub/java/com/sun/javafx/pgstub/StubTextLayout.java	Tue Aug 06 14:14:24 2013 -0700
@@ -152,4 +152,9 @@
         return new PathElement[0];
     }
 
+    @Override
+    public BaseBounds getVisualBounds(int type) {
+        return new RectBounds();
+    }
+
 }
--- a/modules/graphics/src/stub/java/com/sun/javafx/pgstub/StubToolkit.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/stub/java/com/sun/javafx/pgstub/StubToolkit.java	Tue Aug 06 14:14:24 2013 -0700
@@ -124,7 +124,7 @@
     }
 
     @Override
-    public TKStage createTKPopupStage(StageStyle stageStyle, TKStage owner, AccessControlContext acc) {
+    public TKStage createTKPopupStage(TKStage owner, AccessControlContext acc) {
         return new StubPopupStage();
     }
 
--- a/modules/graphics/src/stub/java/javafx/scene/NodeTest.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/stub/java/javafx/scene/NodeTest.java	Tue Aug 06 14:14:24 2013 -0700
@@ -25,13 +25,18 @@
 
 package javafx.scene;
 
+import com.sun.javafx.geom.BoxBounds;
 import com.sun.javafx.geom.PickRay;
+import com.sun.javafx.geom.transform.BaseTransform;
+import com.sun.javafx.pgstub.StubToolkit;
 import com.sun.javafx.scene.DirtyBits;
 import com.sun.javafx.scene.input.PickResultChooser;
 import com.sun.javafx.sg.prism.NGGroup;
 import com.sun.javafx.sg.prism.NGNode;
+import com.sun.javafx.sg.prism.NGRectangle;
 import com.sun.javafx.test.objects.TestScene;
 import com.sun.javafx.test.objects.TestStage;
+import com.sun.javafx.tk.Toolkit;
 import javafx.beans.property.*;
 import javafx.geometry.BoundingBox;
 import javafx.geometry.Bounds;
@@ -50,6 +55,7 @@
 import java.lang.reflect.Method;
 import java.util.Comparator;
 import javafx.scene.layout.AnchorPane;
+import javafx.stage.Stage;
 
 import static org.junit.Assert.*;
 /**
@@ -1339,4 +1345,48 @@
         assertEquals(10, r.getLayoutY(), 1e-10);
 
     }
+
+    @Test
+    public void clipShouldUpdateAfterParentVisibilityChange() {
+
+        final Group root = new Group();
+        Scene scene = new Scene(root, 300, 300);
+
+        final Group parent = new Group();
+        parent.setVisible(false);
+
+        final Circle circle = new Circle(100, 100, 100);
+        parent.getChildren().add(circle);
+
+        final Rectangle clip = new Rectangle(100, 100) {
+            @Override protected NGNode impl_createPeer() {
+                return new MockClip();
+            }
+        };
+        circle.setClip(clip);
+
+        root.getChildren().add(parent);
+        parent.setVisible(true);
+
+        Stage stage = new Stage();
+        stage.setScene(scene);
+        stage.show();
+
+        ((StubToolkit) Toolkit.getToolkit()).firePulse();
+
+        clip.setWidth(300);
+
+        ((StubToolkit) Toolkit.getToolkit()).firePulse();
+
+        assertEquals(300, ((MockClip) clip.impl_getPeer()).w, 1e-10);
+    }
+
+    private class MockClip extends NGRectangle {
+        double w = 0;
+
+        @Override public void updateRectangle(float x, float y, float width,
+                float height, float arcWidth, float arcHeight) {
+            w = width;
+        }
+    }
 }
--- a/modules/graphics/src/stub/java/javafx/scene/ParentTest.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/stub/java/javafx/scene/ParentTest.java	Tue Aug 06 14:14:24 2013 -0700
@@ -28,12 +28,8 @@
 import com.sun.javafx.pgstub.StubToolkit;
 import com.sun.javafx.sg.prism.NGGroup;
 import com.sun.javafx.tk.Toolkit;
-import java.util.concurrent.atomic.AtomicBoolean;
 import javafx.beans.InvalidationListener;
 import javafx.beans.Observable;
-import javafx.beans.value.ChangeListener;
-import javafx.beans.value.ObservableValue;
-import javafx.geometry.Bounds;
 import javafx.scene.shape.Rectangle;
 import javafx.stage.Stage;
 import org.junit.After;
@@ -579,40 +575,6 @@
     }
 
     @Test
-    public void newChildInvalidatesLayoutWhenLayoutBoundsAreValidatedImmediately() {
-        Group root = new Group();
-        final AtomicBoolean layoutCalled = new AtomicBoolean();
-        final AtomicBoolean testReady = new AtomicBoolean();
-        LGroup sub = new LGroup() {
-
-            @Override
-            protected void layoutChildren() {
-                if (testReady.get()) {
-                    assertAndClear(true);
-                    layoutCalled.set(true);
-                }
-            }
-
-        };
-        root.getChildren().add(sub);
-        root.getLayoutBounds(); // validate
-        sub.getBoundsInParent(); // validate
-
-        root.layoutBoundsProperty().addListener(new ChangeListener<Bounds>() {
-
-            @Override
-            public void changed(ObservableValue<? extends Bounds> observable, Bounds oldValue, Bounds newValue) {
-                // ChangeListener will immediately validate the bounds
-            }
-        });
-        sub.clear();
-
-        testReady.set(true);
-        sub.getChildren().add(new Rectangle());
-        assertTrue(layoutCalled.get());
-    }
-
-    @Test
     public void testChildrenPermutationInvalidatesManagedChildrenAndLayout() {
         LGroup root = new LGroup();
         Rectangle r1 = new Rectangle();
--- a/modules/graphics/src/stub/java/javafx/scene/SubSceneTest.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/stub/java/javafx/scene/SubSceneTest.java	Tue Aug 06 14:14:24 2013 -0700
@@ -28,6 +28,7 @@
 import com.sun.javafx.sg.prism.NGCamera;
 import com.sun.javafx.sg.prism.NGSubScene;
 import com.sun.javafx.tk.Toolkit;
+import javafx.scene.layout.Pane;
 import org.junit.Test;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
@@ -227,4 +228,22 @@
             fail("It didn't allow to 'share' camera with myslef");
         }
     }
+
+    @Test
+    public void testLayout() {
+        Pane pane = new Pane();
+        pane.setPrefWidth(100);
+
+        SubScene sub = new SubScene(new Group(pane), 500, 500);
+        Scene scene = new Scene(new Group(sub), 600, 600);
+
+        scene.getRoot().layout();
+        assertEquals(100, pane.getWidth(), 1e-10);
+
+        pane.setPrefWidth(110);
+        scene.getRoot().layout();
+        assertEquals(110, pane.getWidth(), 1e-10);
+
+
+    }
 }
--- a/modules/graphics/src/test/java/com/sun/javafx/sg/prism/TestGraphics.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/graphics/src/test/java/com/sun/javafx/sg/prism/TestGraphics.java	Tue Aug 06 14:14:24 2013 -0700
@@ -118,6 +118,18 @@
     public void drawTexture(Texture tex, float dx1, float dy1, float dx2, float dy2, float sx1, float sy1, float sx2, float sy2) {
     }
 
+    @Override
+    public void drawTexture3SliceH(Texture tex, float dx1, float dy1, float dx2, float dy2, float sx1, float sy1, float sx2, float sy2, float dh1, float dh2, float sh1, float sh2) {
+    }
+
+    @Override
+    public void drawTexture3SliceV(Texture tex, float dx1, float dy1, float dx2, float dy2, float sx1, float sy1, float sx2, float sy2, float dv1, float dv2, float sv1, float sv2) {
+    }
+
+    @Override
+    public void drawTexture9Slice(Texture tex, float dx1, float dy1, float dx2, float dy2, float sx1, float sy1, float sx2, float sy2, float dh1, float dv1, float dh2, float dv2, float sh1, float sv1, float sh2, float sv2) {
+    }
+
     public void sync() {
     }
 
--- a/modules/swt/src/main/java/javafx/embed/swt/FXCanvas.java	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/swt/src/main/java/javafx/embed/swt/FXCanvas.java	Tue Aug 06 14:14:24 2013 -0700
@@ -224,6 +224,7 @@
         PlatformImpl.startup(new Runnable() {
             @Override
             public void run() {
+                Application.GetApplication().setName(Display.getAppName());
             }
         });
     }
--- a/modules/web/.classpath	Tue Aug 06 10:13:00 2013 -0700
+++ b/modules/web/.classpath	Tue Aug 06 14:14:24 2013 -0700
@@ -3,11 +3,13 @@
   <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
   <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
   <classpathentry kind="src" exported="true" path="src/main/java"/>
+  <!--
   <classpathentry kind="src" exported="true" path="src/test/java">
   <attributes>
       <attribute name="optional" value="true"/>
     </attributes>
   </classpathentry>
+  -->
   <classpathentry kind="src" exported="true" path="src/main/resources">
   <attributes>
       <attribute name="optional" value="true"/>
@@ -23,16 +25,11 @@
       <attribute name="optional" value="true"/>
     </attributes>
   </classpathentry>
-  <classpathentry kind="src" exported="true" path="/controls"/>
-  <classpathentry kind="src" exported="true" path="/media"/>
   <classpathentry exported="true" kind="src" path="/javafx-ui-desktop">
     <attributes>
       <attribute name="optional" value="true"/>
     </attributes>
   </classpathentry>
-  <classpathentry kind="lib" exported="true" path="../../../caches/sdk/rt/lib/ext/jfxrt.jar">
-    <attributes>
-      <attribute name="optional" value="true"/>
-    </attributes>
-  </classpathentry>
+  <classpathentry kind="src" exported="true" path="/controls"/>
+  <classpathentry kind="src" exported="true" path="/media"/>
 </classpath>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web/src/android/java/com/sun/javafx/scene/web/Debugger.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,100 @@
+/*
+ * 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.javafx.scene.web;
+
+import javafx.util.Callback;
+
+/**
+ * An object that can be used to debug a web page loaded into
+ * a {@link WebEngine}.
+ */
+public interface Debugger {
+
+    /**
+     * Determines whether the debugger is enabled.
+     * A debugger's {@link #sendMessage} method may only be called
+     * while the debugger is enabled.
+     * The message callback object registered with a debugger is only called
+     * while the debugger is enabled.
+     * @return {@code true} if the debugger is enabled,
+     *         {@code false} otherwise.
+     */
+    boolean isEnabled();
+
+    /**
+     * Enables or disables the debugger.
+     * A debugger's {@link #sendMessage} method may only be called
+     * while the debugger is enabled.
+     * The message callback object registered with a debugger is only called
+     * while the debugger is enabled.
+     * <p>
+     * This method has no effect
+     * if the {@code enabled} parameter is {@code true}
+     * and the debugger is already enabled,
+     * or if the {@code enabled} parameter is {@code false}
+     * and the debugger is already disabled.
+     * @param enabled specifies whether the debugger should be enabled
+     *        or disabled.
+     */
+    void setEnabled(boolean enabled);
+
+    /**
+     * Sends a message to the debugger.
+     * The message is a text string in the format specified by
+     * the WebKit Remote Debugging Protocol.
+     * <p>
+     * This method may only be called while the debugger is enabled.
+     * @param message the message to be sent to the debugger.
+     *        May not be {@code null}.
+     * @throws IllegalStateException if the debugger is not enabled.
+     * @throws NullPointerException if {@code message} is {@code null}.
+     */
+    void sendMessage(String message);
+
+    /**
+     * Returns the message callback object registered with the debugger.
+     * The debugger calls the message callback object's
+     * {@link Callback#call} method to deliver a message to
+     * the debugger frontend.
+     * The message passed to the message callback is a text string
+     * in the format specified by the WebKit Remote Debugging Protocol.
+     * @return the message callback object registered with the debugger,
+     *         or {@code null} if there is no such object.
+     */
+    Callback<String,Void> getMessageCallback();
+
+    /**
+     * Registers a message callback object with the debugger.
+     * The debugger calls the message callback object's
+     * {@link Callback#call} method to deliver a message to
+     * the debugger frontend.
+     * The message passed to the message callback is a text string
+     * in the format specified by the WebKit Remote Debugging Protocol.
+     * @param callback the message callback object to be registered with
+     *        the debugger. May be {@code null}.
+     */
+    void setMessageCallback(Callback<String,Void> callback);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web/src/android/java/com/sun/javafx/scene/web/skin/HTMLEditorSkin.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,58 @@
+/*
+ * 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.javafx.scene.web.skin;
+
+import javafx.scene.web.HTMLEditor;
+import javafx.scene.Node;
+import javafx.scene.control.Skin;
+
+public class HTMLEditorSkin implements Skin<HTMLEditor> {
+    
+    private String text;
+    private final HTMLEditor editor;
+    
+    public HTMLEditorSkin(HTMLEditor editor) {
+        this.editor = editor;
+    }
+    
+    public String getHTMLText() {
+        return text;
+    }
+    
+    public void setHTMLText(String text) {
+        this.text = text;
+    }
+    
+    public HTMLEditor getSkinnable() {
+        return editor;
+    }
+    
+    public Node getNode() {
+        return editor;
+    }
+    
+    public void dispose() {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web/src/android/java/com/sun/javafx/sg/prism/NGWebView.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,101 @@
+/*
+ * 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.javafx.sg.prism;
+
+import com.sun.javafx.geom.BaseBounds;
+import com.sun.javafx.geom.RectBounds;
+import java.util.logging.Logger;
+import com.sun.prism.Graphics;
+import com.sun.prism.paint.Color;
+import com.sun.webkit.WebPage;
+
+public final class NGWebView extends NGGroup {
+
+    private final static Logger log =
+        Logger.getLogger(NGWebView.class.getName());
+    private volatile WebPage page;
+    private volatile float width, height;
+    private static final Color VERY_LIGHT_RED = new Color(1, 0, 0, .3f);
+
+    public void setPage(WebPage page) {
+        this.page = page;
+    }
+
+    public void resize(float w, float h) {
+        if (width != w || height != h) {
+            width = w;
+            height = h;
+            geometryChanged();
+        }
+    }
+
+    // Invoked on JavaFX User Thread.
+    public void update() {
+    }
+
+    public void requestRender() {
+        visualsChanged();
+    }
+    private final float[] src = new float[]{0.0f, 0.0f};
+    private final float[] dest = new float[]{0.0f, 0.0f};
+    private final RectBounds destBounds = new RectBounds();
+
+    @Override
+    protected void doRender(Graphics g) {
+        renderContent(g);
+    }
+
+    @Override
+    public void setTransformedBounds(BaseBounds bounds, boolean byTransformChangeOnly) {
+        super.setTransformedBounds(bounds, byTransformChangeOnly);
+    }
+
+    // Invoked on Render Thread.
+    @Override
+    protected void renderContent(Graphics g) {
+//        g.setPaint(VERY_LIGHT_RED);
+//        g.fillRect(transformedBounds.getMinX(),
+//                transformedBounds.getMinY(),
+//                transformedBounds.getWidth(),
+//                transformedBounds.getHeight());
+
+        g.getTransformNoClone().
+                transform(transformedBounds, destBounds);
+        page.moveAndResize(
+                destBounds.getMinX(),
+                destBounds.getMinY(),
+                destBounds.getWidth(),
+                destBounds.getHeight());
+    }
+
+    @Override public boolean hasOverlappingContents() {
+        return false;
+    }
+    
+    @Override protected boolean hasVisuals() {
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web/src/android/java/com/sun/javafx/webkit/Accessor.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011, 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.webkit;
+
+import javafx.beans.InvalidationListener;
+import javafx.scene.Node;
+import javafx.scene.web.WebEngine;
+import javafx.scene.web.WebView;
+import com.sun.webkit.WebPage;
+
+public abstract class Accessor {
+
+    public static interface PageAccessor {
+        public WebPage getPage(WebEngine w);
+    }
+
+    private static PageAccessor pageAccessor;
+
+    public static void setPageAccessor(PageAccessor instance) {
+        Accessor.pageAccessor = instance;
+    }
+
+    public static WebPage getPageFor(WebEngine w) {
+        return pageAccessor.getPage(w);
+    }
+
+    public abstract WebEngine getEngine();
+    public abstract WebView getView();
+    public abstract WebPage getPage();
+    public abstract void addChild(Node child);
+    public abstract void removeChild(Node child);
+    public abstract void addViewListener(InvalidationListener l);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web/src/android/java/com/sun/javafx/webkit/prism/PrismInvoker.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,106 @@
+/*
+ * 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.javafx.webkit.prism;
+
+import com.sun.javafx.tk.RenderJob;
+import com.sun.javafx.tk.Toolkit;
+import com.sun.webkit.Invoker;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.ReentrantLock;
+
+public final class PrismInvoker extends Invoker {
+
+    private final AtomicBoolean isToolkitRunning = new AtomicBoolean(true);
+
+    public PrismInvoker() {
+        Toolkit.getToolkit().addShutdownHook(new Runnable() {
+            public void run() {
+                isToolkitRunning.set(false);
+            }
+        });
+    }
+
+    /*
+     * No synchronization b/w Event (User) & Render threads is required
+     * because FX synchronizes pulse and render operations itself.
+     */
+    @Override protected boolean lock(ReentrantLock lock) {
+        return false;
+    }
+
+    @Override protected boolean unlock(ReentrantLock lock) {
+        return false;
+    }
+
+    @Override protected boolean isEventThread() {
+        return isEventThreadPrivate();
+    }
+
+    private static boolean isEventThreadPrivate() {
+        return Toolkit.getToolkit().isFxUserThread();
+    }
+
+    @Override protected void checkEventThread() {
+        Toolkit.getToolkit().checkFxUserThread();
+    }
+
+    @Override public void invokeOnEventThread(final Runnable r) {
+        if (isEventThread()) {
+            r.run();
+        } else {
+            Toolkit.getToolkit().defer(r);
+        }
+    }
+
+    @Override public void postOnEventThread(final Runnable r) {
+        if (isToolkitRunning.get()) {
+            Toolkit.getToolkit().defer(r);
+        }
+    }
+
+    static void invokeOnRenderThread(final Runnable r) {
+        Toolkit.getToolkit().addRenderJob(new RenderJob(r));
+    }
+
+    static void runOnRenderThread(final Runnable r) {
+        if (Thread.currentThread().getName().startsWith("QuantumRenderer")) {
+            r.run();
+        } else {
+            FutureTask<Void> f = new FutureTask<Void>(r, null);
+            Toolkit.getToolkit().addRenderJob(new RenderJob(f));
+            try {
+                // block until job is complete
+                f.get();
+            } catch (ExecutionException ex) {
+                throw new AssertionError(ex);
+            } catch (InterruptedException ex) {
+                // ignore; recovery is impossible
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web/src/android/java/com/sun/webkit/BackForwardList.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 2011, 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.webkit;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.sun.webkit.event.WCChangeEvent;
+import com.sun.webkit.event.WCChangeListener;
+import com.sun.webkit.graphics.WCImage;
+
+import static com.sun.webkit.network.URLs.newURL;
+
+public final class BackForwardList {
+
+    public static final class Entry {
+        /**
+         * Native pointer to the HistoryItem object.
+         * If 0, the corresponding object has already been destroyed.
+         */
+        private long pitem = 0;
+
+        // Native pointer to the Page object.
+        private long ppage = 0;
+
+        private Entry[] children;
+        private URL url;
+        private String title;
+        private Date lastVisitedDate;
+        private WCImage icon;
+        private String target;
+        private boolean isTargetItem;
+
+        // Only called from the native code.
+        private Entry(long pitem, long ppage) {
+            this.pitem = pitem;
+            this.ppage = ppage;
+
+            // When the Entry is disposed its fields may be
+            // left uninitialized. As the Entry may still
+            // be referenced from a global history, the fields
+            // should get their initial values here.
+            getURL();
+            getTitle();
+            getLastVisitedDate();
+            getIcon();
+            getTarget();
+            isTargetItem();
+            getChildren();
+        }
+
+        // Only called from the native code.
+        private void notifyItemDestroyed() {
+            pitem = 0;
+        }
+        
+        // Called from the native code as well.
+        private void notifyItemChanged() {
+            for (WCChangeListener l : listenerList) {
+                l.stateChanged(new WCChangeEvent(this));
+            }
+        }
+
+        public URL getURL() {
+            try {
+                return (pitem == 0 ? url : (url = newURL(""/*bflItemGetURL(pitem)*/)));
+            } catch (MalformedURLException ex) {
+                return url = null;
+            }
+        }
+
+        public String getTitle() {
+            return (pitem == 0 ? title : (title = ""/*bflItemGetTitle(pitem)*/));
+        }
+
+        public WCImage getIcon() {
+            return (pitem == 0 ? icon : (icon = null /*bflItemGetIcon(pitem)*/));
+        }
+
+        public String getTarget() {
+            return (pitem == 0 ? target : (target = "" /*bflItemGetTarget(pitem)*/));
+        }
+
+        public Date getLastVisitedDate() {
+            return lastVisitedDate == null ? null : (Date)lastVisitedDate.clone();
+        }
+        
+        private void updateLastVisitedDate() {
+            lastVisitedDate = new Date(System.currentTimeMillis());
+            notifyItemChanged();
+        }
+
+        public boolean isTargetItem() {
+            return (pitem == 0 ? isTargetItem : (isTargetItem = false /*bflItemIsTargetItem(pitem)*/));
+        }
+
+        public Entry[] getChildren() {
+            return (pitem == 0 ? children : (children = null /*bflItemGetChildren(pitem, ppage)*/));
+        }
+
+        @Override
+        public String toString() {
+            return "url=" + getURL() +
+                    ",title=" + getTitle() +
+                    ",date=" + getLastVisitedDate();
+        }
+        
+        
+        private final List<WCChangeListener> listenerList =
+            new LinkedList<WCChangeListener>();
+        
+        public void addChangeListener(WCChangeListener l) {
+            if (l == null)
+                return;
+            listenerList.add(l);
+        }
+
+        public void removeChangeListener(WCChangeListener l) {
+            if (l == null)
+                return;            
+            listenerList.remove(l);
+        }
+    }
+
+    private final WebPage page;
+    private final List<WCChangeListener> listenerList =
+        new LinkedList<WCChangeListener>();
+    
+    BackForwardList(WebPage page) {
+        this.page = page;
+        
+        // WebKit doesn't set a page's visiting date. We do it here as workaround.
+        // This way it works for page reload as well.
+        page.addLoadListenerClient(new LoadListenerClient() {
+            @Override public void dispatchLoadEvent(long frame,
+                                                    int state,
+                                                    String url,
+                                                    String contentType,
+                                                    double progress,
+                                                    int errorCode)
+            {
+                if (state == LoadListenerClient.DOCUMENT_AVAILABLE) {
+                    Entry entry = getCurrentEntry();
+                    if (entry != null) {
+                        entry.updateLastVisitedDate();
+                    }
+                }
+            }
+
+            @Override public void dispatchResourceLoadEvent(long frame,
+                                                            int state,
+                                                            String url,
+                                                            String contentType,
+                                                            double progress,
+                                                            int errorCode)
+            {}
+        });
+    }
+
+    public int size() {
+//        return bflSize(page.getPage());
+        return 0;
+    }
+
+    public int getMaximumSize() {
+//        return bflGetMaximumSize(page.getPage());
+        return 0;
+    }
+
+    public void setMaximumSize(int size) {
+//        bflSetMaximumSize(page.getPage(), size);
+    }
+
+    public int getCurrentIndex() {
+//        return bflGetCurrentIndex(page.getPage());
+        return 0;
+    }
+
+    public boolean isEmpty() {
+//        return size() == 0;
+        return true;
+    }
+
+    public void setEnabled(boolean flag) {
+//        bflSetEnabled(page.getPage(), flag);
+    }
+
+    public boolean isEnabled() {
+//        return bflIsEnabled(page.getPage());
+        return false;
+    }
+
+     public Entry get(int index) {
+//        Entry host = (Entry)bflGet(page.getPage(), index);
+//        return host;
+         return null;
+    }
+
+    public Entry getCurrentEntry() {
+        return get(getCurrentIndex());
+    }
+
+    public int indexOf(Entry e) {
+//        return bflIndexOf(page.getPage(), e.pitem, false);
+        return 0;
+    }
+
+    public boolean contains(Entry e) {
+        return indexOf(e) >= 0;
+    }
+
+    public Entry[] toArray() {
+        int size = size();
+        Entry[] entries = new Entry[size];
+        for (int i = 0; i < size; i++) {
+            entries[i] = get(i);
+        }
+        return entries;
+    }
+
+    public void setCurrentIndex(int index) {
+//        if (bflSetCurrentIndex(page.getPage(), index) < 0) {
+//            throw new IllegalArgumentException("invalid index: " + index);
+//        }
+    }
+
+    private boolean canGoBack(int index) {
+        return index > 0;
+    }
+
+    public boolean canGoBack() {
+        return canGoBack(getCurrentIndex());
+    }
+
+    public boolean goBack() {
+        int index = getCurrentIndex();
+        if (canGoBack(index)) {
+            setCurrentIndex(index - 1);
+            return true;
+        }
+        return false;
+    }
+
+    private boolean canGoForward(int index) {
+        return index < (size() - 1);
+    }
+
+    public boolean canGoForward() {
+        return canGoForward(getCurrentIndex());
+    }
+
+    public boolean goForward() {
+        int index = getCurrentIndex();
+        if (canGoForward(index)) {
+            setCurrentIndex(index + 1);
+            return true;
+        }
+        return false;
+    }
+
+    public void addChangeListener(WCChangeListener l) {
+        if (l == null) {
+            return;
+        }
+        if (listenerList.isEmpty()) {
+//            bflSetHostObject(page.getPage(), this);
+        }
+        listenerList.add(l);
+    }
+
+    public void removeChangeListener(WCChangeListener l) {
+        if (l == null) {
+            return;
+        }
+        listenerList.remove(l);
+        if (listenerList.isEmpty()) {
+//            bflSetHostObject(page.getPage(), null);
+        }
+    }
+
+    public WCChangeListener[] getChangeListeners() {
+        return listenerList.toArray(new WCChangeListener[0]);
+    }
+
+    // Only called from the native code.
+    private void notifyChanged() {
+        for (WCChangeListener l : listenerList) {
+            l.stateChanged(new WCChangeEvent(this));
+        }
+    }
+    
+//    native private static String bflItemGetURL(long item);
+//    native private static String bflItemGetTitle(long item);
+//    native private static WCImage bflItemGetIcon(long item);
+//    native private static long bflItemGetLastVisitedDate(long item);
+//    native private static boolean bflItemIsTargetItem(long item);
+//    native private static Entry[] bflItemGetChildren(long item, long page);
+//    native private static String bflItemGetTarget(long item);
+//
+//    native private static int bflSize(long page);
+//    native private static int bflGetMaximumSize(long page);
+//    native private static void bflSetMaximumSize(long page, int size);
+//    native private static int bflGetCurrentIndex(long page);
+//    native private static int bflIndexOf(long page, long item, boolean reverse);
+//    native private static void bflSetEnabled(long page, boolean flag);
+//    native private static boolean bflIsEnabled(long page);
+//    native private static Object bflGet(long page, int index);
+//    native private static int bflSetCurrentIndex(long page, int index);
+//    native private static void bflSetHostObject(long page, Object host);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web/src/android/java/com/sun/webkit/Disposer.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2011, 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.webkit;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * This class is used for registering and disposing the native
+ * data associated with java objects.
+ *
+ * The object can register itself by calling the addRecord method and
+ * providing a descendant of the DisposerRecord class with overridden
+ * dispose() method.
+ *
+ * When the object becomes unreachable, the dispose() method
+ * of the associated DisposerRecord object will be called.
+ *
+ * @see DisposerRecord
+ */
+public final class Disposer implements Runnable {
+    private static final ReferenceQueue queue = new ReferenceQueue();
+    private static final Disposer disposerInstance = new Disposer();
+    private static final Set<WeakDisposerRecord> records =
+            new HashSet<WeakDisposerRecord>();
+
+    static {
+        Thread t = new Thread(disposerInstance, "Disposer");
+        t.setDaemon(true);
+        t.setPriority(Thread.MAX_PRIORITY);
+        t.start();
+    }
+
+    /**
+     * Registers the object and the native data for later disposal.
+     * @param target Object to be registered
+     * @param rec the associated DisposerRecord object
+     * @see DisposerRecord
+     */
+    public static void addRecord(Object target, DisposerRecord rec) {
+        disposerInstance.add(target, rec);
+    }
+
+    /**
+     * Performs the actual registration of the target object to be disposed.
+     * @param target Object to be registered
+     * @param rec the associated DisposerRecord object
+     * @see DisposerRecord
+     */
+    private synchronized void add(Object target, DisposerRecord rec) {
+        records.add(new WeakDisposerRecord(target, rec));
+    }
+
+    public void run() {
+        while (true) {
+            try {
+                WeakDisposerRecord obj = (WeakDisposerRecord) queue.remove();
+                obj.clear();
+                DisposerRunnable.getInstance().enqueue(obj);
+            } catch (Exception e) {
+                System.out.println("Exception while removing reference: " + e);
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private static final class DisposerRunnable implements Runnable {
+        private static final DisposerRunnable theInstance = new DisposerRunnable();
+
+        private static DisposerRunnable getInstance() {
+            return theInstance;
+        }
+
+        private boolean isRunning = false;
+        private final Object disposerLock = new Object();
+        private final LinkedBlockingQueue<WeakDisposerRecord> disposerQueue
+                = new LinkedBlockingQueue<WeakDisposerRecord>();
+
+        private void enqueueAll(Collection<WeakDisposerRecord> objs) {
+            synchronized (disposerLock) {
+                disposerQueue.addAll(objs);
+                if (!isRunning) {
+                    Invoker.getInvoker().invokeOnEventThread(this);
+                    isRunning = true;
+                }
+            }
+        }
+
+        private void enqueue(WeakDisposerRecord obj) {
+            enqueueAll(Arrays.asList(obj));
+        }
+
+        @Override public void run() {
+            while (true) {
+                WeakDisposerRecord obj;
+                synchronized (disposerLock) {
+                    obj = disposerQueue.poll();
+                    if (obj == null) {
+                        isRunning = false;
+                        break;
+                    }
+                }
+                // Check if the object has not yet been removed & disposed.
+                if (records.contains(obj)) {
+                    records.remove(obj);
+                    obj.dispose();
+                }
+            }
+        }
+    }
+
+    public static class WeakDisposerRecord
+        extends WeakReference
+        implements DisposerRecord
+    {
+        protected WeakDisposerRecord(Object referent) {
+            super(referent, Disposer.queue);
+            this.record = null;
+        }
+
+        private WeakDisposerRecord(Object referent, DisposerRecord record) {
+            super(referent, Disposer.queue);
+            this.record = record;
+        }
+
+        private final DisposerRecord record;
+
+        @Override
+        public void dispose() {
+            record.dispose();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web/src/android/java/com/sun/webkit/DisposerRecord.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011, 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.webkit;
+
+/**
+ * This class is used to hold the resource to be
+ * disposed.
+ */
+public interface DisposerRecord {
+    public void dispose();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web/src/android/java/com/sun/webkit/InspectorClient.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011, 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.webkit;
+
+public interface InspectorClient {
+    boolean sendMessageToFrontend(String message);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web/src/android/java/com/sun/webkit/Invoker.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+package com.sun.webkit;
+
+//import com.sun.webkit.perf.PerfLogger;
+import java.util.concurrent.locks.ReentrantLock;
+
+public abstract class Invoker {
+    private static Invoker instance;
+
+//    private static final PerfLogger locksLog = PerfLogger.getLogger("Locks");
+
+    public static synchronized void setInvoker(Invoker invoker) {
+        instance = invoker;
+    }
+
+    public static synchronized Invoker getInvoker() {
+        return instance;
+    }
+
+    /*
+     * Acquires the lock if it's not yet held by the current thread.
+     *
+     * @returns {@code true} if the lock has been acquired, otherwise {@code false}
+     */
+    protected boolean lock(ReentrantLock lock) {
+        if (lock.getHoldCount() == 0) {
+
+            lock.lock();
+//            locksLog.resumeCount(isEventThread() ? "EventThread" : "RenderThread");
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * Releases the lock if it's held by the current thread.
+     *
+     * @returns {@code true} if the lock has been released, otherwise {@code false}
+     */
+    protected boolean unlock(ReentrantLock lock) {
+        if (lock.getHoldCount() != 0) {
+
+//            locksLog.suspendCount(isEventThread() ? "EventThread" : "RenderThread");
+            lock.unlock();
+            return true;
+        }
+        return false;
+    }
+
+    protected abstract boolean isEventThread();
+
+    /**
+     * Throws {@link IllegalStateException} if the current thread is not
+     * the event thread.
+     * @throws IllegalStateException if the current thread is not the event
+     *         thread
+     */
+    protected void checkEventThread() {
+        if (!isEventThread()) {
+            throw new IllegalStateException("Current thread is not event thread"
+                    + ", current thread: " + Thread.currentThread().getName());
+        }
+    }
+
+    public abstract void invokeOnEventThread(Runnable r);
+
+    public abstract void postOnEventThread(Runnable r);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web/src/android/java/com/sun/webkit/LoadListenerClient.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2011, 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.webkit;
+
+public interface LoadListenerClient {
+    public final static int PAGE_STARTED = 0;
+    public final static int PAGE_FINISHED = 1;
+    public final static int PAGE_REDIRECTED = 2;
+    public final static int LOAD_FAILED = 5;
+    public final static int LOAD_STOPPED = 6;
+    public final static int CONTENT_RECEIVED = 10;
+    public final static int TITLE_RECEIVED = 11;
+    public final static int ICON_RECEIVED = 12;
+    public final static int CONTENTTYPE_RECEIVED = 13;
+    public final static int DOCUMENT_AVAILABLE = 14;
+    public final static int RESOURCE_STARTED = 20;
+    public final static int RESOURCE_REDIRECTED = 21;
+    public final static int RESOURCE_FINISHED = 22;
+    public final static int RESOURCE_FAILED = 23;
+    public final static int PROGRESS_CHANGED = 30;
+
+
+    // -- Error Code values
+    /**
+     * An error code indicating that the host name couldn't be resolved.
+     */
+    public final static int UNKNOWN_HOST = 1;
+    /**
+     * An error code indicating that the URL was malformed or illegal.
+     */
+    public final static int MALFORMED_URL = 2;
+    /**
+     * An error code indicating that the SSL handshake failed.
+     */
+    public final static int SSL_HANDSHAKE = 3;
+    /**
+     * An error code indicating that the connection was refused by the server.
+     */
+    public final static int CONNECTION_REFUSED = 4;
+    /**
+     * An error code indicating that the connection was reset by the server.
+     */
+    public final static int CONNECTION_RESET = 5;
+    /**
+     * An error code indicating that there was no route to the host.
+     */
+    public final static int NO_ROUTE_TO_HOST = 6;
+    /**
+     * An error code indicating that the connection timed out.
+     */
+    public final static int CONNECTION_TIMED_OUT = 7;
+    /**
+     * An error code indicating that the client was denied permission
+     * to initiate connection to the server.
+     */
+    public final static int PERMISSION_DENIED = 8;
+    /**
+     * An error code indicating that the server response was invalid.
+     */
+    public final static int INVALID_RESPONSE = 9;
+    /**
+     * An error code indicating that too many redirects were encountered
+     * while processing the request.
+     */
+    public final static int TOO_MANY_REDIRECTS = 10;
+    /**
+     * An error code indicating that the requested local file was not found.
+     */
+    public final static int FILE_NOT_FOUND = 11;
+    /**
+     * An error code indicating that an unknown error occurred.
+     */
+    public final static int UNKNOWN_ERROR = 99;
+
+
+    public void dispatchLoadEvent(long frame, int state,
+                                  String url, String contentType,
+                                  double progress, int errorCode);
+
+    public void dispatchResourceLoadEvent(long frame, int state,
+                                          String url, String contentType,
+                                          double progress, int errorCode);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web/src/android/java/com/sun/webkit/NativeWebView.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,113 @@
+/*
+ * 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.webkit;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class NativeWebView {
+
+    private static List<NativeWebView> views = new ArrayList<NativeWebView>();
+    private int id;
+    private WebPage page;
+
+    public NativeWebView(WebPage page) {
+        id = _createAndroidWebView();
+        this.page = page;
+        views.add(this);
+    }
+
+    public void moveToTop() {
+        _moveToTop(this.id);
+    }
+
+    public void moveAndResize(int x, int y, int width, int height) {
+        _moveAndResize(this.id, x, y, width, height);
+    }
+
+    public void setVisible(boolean visible) {
+        _setVisible(this.id, visible);
+    }
+
+    void loadUrl(String url) {
+        _loadUrl(this.id, url);
+    }
+
+    void loadContent(String content, String contentType) {
+        _loadContent(this.id, content, contentType);
+    }
+
+    void setEncoding(String encoding) {
+        _setEncoding(this.id, encoding);
+    }
+
+    void dispose() {        
+        _dispose(this.id);
+        views.remove(this);
+    }
+
+    private static NativeWebView getViewByID(int id) {
+        for (NativeWebView wvp : views) {
+            if (id == wvp.id) {
+                return wvp;
+            }
+        }
+        System.err.println("Accesing nonexisting/disposed NativewWebView id: " + id);
+        return null;
+    }
+
+    static void fire_load_event(final int id, final int frameID, final int state,
+            final String url, final String contenType,
+            final int progress, final int errorCode) {
+        final NativeWebView nwv = NativeWebView.getViewByID(id);
+        if (nwv == null) {            
+            return;
+        }
+        Invoker.getInvoker().invokeOnEventThread(new Runnable() {
+            @Override
+            public void run() {
+                double dprogress = progress / 100.0;
+                nwv.page.fireLoadEvent(frameID, state, url, contenType, dprogress, errorCode);
+            }
+        });
+    }
+
+    private native void _moveAndResize(int id, int x, int y, int width, int height);
+
+    private native void _setVisible(int id, boolean visible);
+
+    private native int _createAndroidWebView();
+
+    private native void _moveToTop(int id);
+
+    private native void _loadUrl(int id, String url);
+
+    private native void _dispose(int id);
+
+    private native void _loadContent(int id, String content, String contentType);
+
+    private native void _setEncoding(int id, String encoding);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web/src/android/java/com/sun/webkit/Timer.java	Tue Aug 06 14:14:24 2013 -0700
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2011, 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.webkit;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+