changeset 1657:3baf54f57be7 2.2.40-b30

Automated merge with ssh://jfxsrc.us.oracle.com//javafx/2.2.25/MASTER/jfx/rt
author kcr
date Tue, 18 Jun 2013 12:21:58 -0700
parents b97dbe3ddf77 862dcc768d3a
children ff55a1a6dfa5
files .hgtags
diffstat 61 files changed, 1680 insertions(+), 392 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Jun 06 08:14:21 2013 -0700
+++ b/.hgtags	Tue Jun 18 12:21:58 2013 -0700
@@ -50,11 +50,22 @@
 f99798608d247682245297b13e62188bd53642ef 2.2.3-b04
 46ea8d4fadd37870b08dd55e4b7757c81ddc6c35 2.2.3-b05
 693dc811b1668c5ac5bea098112e32c777411db5 2.2.4-b09
+218e7d2c04da1d8a33223018f83fe1b418215c6b 2.2.2-b02
+61b4df69e139e14bc3bcb02a1320f7e11c3d4ffa 2.2.2-b03
+81a022a16d363b75cf1db47b2287878a49f61d81 2.2.2-b04
+89c56c042f37e6769c4fa6b9f00fcaebce2fd25b 2.2.2-b05
+4747ac0eab73e4e33759a84a399412b4894f01e5 2.2.2-b06
+98d1e63be240748ece02a9a916eb93a9e4ce3f29 2.2.4-b06
+fd6ef0efba9030685b19cdc7ceb307df278552a2 2.2.4-b07
+86fef7811f51e9d1dc6c187a320e6bcde0f992d9 2.2.4-b08
+54c678a9f9b6ee118b01def45276c56a650c2a6e 2.2.4-b09
 264a190d4737425f23def97337b638f3a6c4f6b9 2.2.4-b10
 b819ec28c317950f6e732f8ca6a48368ce8ff504 2.2.4-b11
 92938e0a1a53593d68f27c6f8f0b66c906a90c1f 2.2.4-b12
 caa28b7ca6515d58476d566bcf5ce8fa4804a4f7 2.2.4-b13
+c3114e9f22159eea2cfd155b0567002045c2a979 2.2.6-b01
 8b11117967603e33ee1f5b3a0e1e97be8a088d40 2.2.5-b01
+fb4d0e99bed7e260b05e697d9b4b95f2981c2be1 2.2.6-b02
 8b11117967603e33ee1f5b3a0e1e97be8a088d40 2.2.4-b14
 1758a9b1b90c93e9f030d97e83bb700f2ee73200 2.2.5-b02
 868bef8eff555190981e3b009f65c01d9c8576d0 2.2.4-b15
@@ -62,11 +73,20 @@
 4492579af767585f8cd6ba88b9481a3e35da81bf 2.2.4-b16
 16e2b3c01e34f8cee013c266be366da240a858e7 2.2.5-b04
 c07a4dc990bbbd03e5a1ed1942dffbd9f14c3ea9 2.2.4-b17
+7d52ac515200059a59da8db49862bd75541f4672 2.2.6-b03
 3c0781f1cfb812207505e89ae7b2d15760438e7b 2.2.5-b05
 c3fa08afde13b637cc4d8f0234a94b595b76f86c 2.2.4-b18
+3617bc4b5d819d48ffd1a81e3ab87d6554919816 2.2.6-b04
 419dca88d4a313bb9739dc96e9cb2c146056488c 2.2.5-b06
 25445fc9f47864d97f325eac40c219167b8c2f52 2.2.4-b30
 25445fc9f47864d97f325eac40c219167b8c2f52 2.2.4-b19
+6feb25f693a2349a3ccc6df5712765b144233c64 2.2.6-b05
+096f6f6dcf27ae02ba734fe2d6622274c878a5ee 2.2.6-b06
+9c2427b8c3abc07abfe22e8842791066a1a557da 2.2.6-b07
+33c4f3579933f302d1c20c92b12d6c84df36a940 2.2.6-b08
+69afe259d0fe59737a501da407e4561403b3876a 2.2.6-b09
+7fe83fb6c034cb8d26d5f78183cbbac1ff0ad904 2.2.6-b10
+ef5361831b35685662a102de81ab9c5ed739d95b 2.2.6-b11
 bce12e7b181095ec9d47e2a441d04254578b37b1 2.2.5-b07
 04349a3e9d6f86e7824d843011c25b71c2d5e894 2.2.5-b08
 d0b5f394ced4549600c5da5114f0bf93ec1d82ec 2.2.5-b09
@@ -77,6 +97,7 @@
 e34cb5b6d09c45290566a32b56ec8e117c9d37a2 2.2.5-b11
 88f3edfa7aa49f0b72793c28157ada37e70da50d 2.2.5-b19
 efce9ea9515ec66fb51d3e095a85e20b007fba42 2.2.5-b20
+0920ee3d8395775b37c699d75096de9ca5a60b0e 2.2.6-b12
 5e032c33c475a3abdaee7faffcdda6958c3289db 2.2.21-b01
 33989ed2b6c6d1d99fda890b7a1f4575ef8a4730 2.2.7-b01
 bb75727a0429e9ca86f8c8ab5664cb0ff79993e9 2.2.21-b02
@@ -97,6 +118,14 @@
 b46fbd1f74f9afbab72507c39b328f8496561284 2.2.25-b04
 e9ae09d6479cac9e051bd0719ffbea02dd658a77 2.2.21-b10
 d651a3591ddd854a0c93a2d0a1308f7cd9e5bef9 2.2.21-b11
+5b271a5061319322e6a6ddc00d48c9136b78ffbf 2.2.40-b22
+c786344bbe4d887e518a3372e25cb2397ffc4157 2.2.40-b23
+5df591c88735dc74f78e4a77258230dfd1ef45bc 2.2.40-b24
+4ea478033cedd674d1abc1a21dd3cedfd7579615 2.2.40-b25
+8deb0a9394635cd4665535f705ace305b795669f 2.2.40-b26
+2ed8cef9d3d09eae510a72b55cd3e7991a4cd778 2.2.40-b27
+fac50f983ffa837ce5cc7e4661a87c7ee037e5c6 2.2.40-b28
+6b5ccbc93d06d53d299022b0c957e4a720e21014 2.2.40-b29
 e1197ad035b8bdc63da4f4d50ee708c47108a6d7 2.2.25-b05
 a3b7e0235380e7977a0585196155cd7879cdfa0f 2.2.25-b06
 4671ef10126f47198c0afe7854de12d25171dd84 2.2.25-b07
--- a/javafx-ui-charts/src/javafx/scene/chart/PieChart.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-charts/src/javafx/scene/chart/PieChart.java	Tue Jun 18 12:21:58 2013 -0700
@@ -309,6 +309,12 @@
     }
 
     // -------------- METHODS --------------------------------------------------
+
+    @Override public void requestLayout() {
+        super.requestLayout();
+        // RT-22986 PieChart legend resize issue
+        if (legend != null) legend.requestLayout();
+    }
     
     private void dataNameChanged(Data item) {
 
--- a/javafx-ui-charts/src/javafx/scene/chart/StackedAreaChart.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-charts/src/javafx/scene/chart/StackedAreaChart.java	Tue Jun 18 12:21:58 2013 -0700
@@ -42,6 +42,7 @@
 import com.sun.javafx.charts.Legend;
 import com.sun.javafx.charts.Legend.LegendItem;
 import com.sun.javafx.css.StyleableProperty;
+import javafx.scene.paint.Color;
 
 /**
  * StackedAreaChart is a variation of {@link AreaChart} that displays trends of the 
@@ -383,15 +384,15 @@
             Series<X, Y> series = getData().get(seriesIndex);
             aggregateData.clear();
             // copy currentSeriesData accumulated in the previous iteration to aggregate.
-            for(DataPointInfo data : currentSeriesData) {
+            for(DataPointInfo<X,Y> data : currentSeriesData) {
                 data.partOf = PartOf.PREVIOUS;
                 aggregateData.add(data);
             }
             currentSeriesData.clear(); 
             // now copy actual data of the current series. 
             for(Data<X, Y> item = series.begin; item != null; item = item.next) {
-                DataPointInfo itemInfo = new DataPointInfo(item, getXAxis().toNumericValue(item.getXValue()), 
-                        getYAxis().toNumericValue(item.getYValue()), PartOf.CURRENT);
+                DataPointInfo<X,Y> itemInfo = new DataPointInfo(item, item.getXValue(), 
+                        item.getYValue(), PartOf.CURRENT);
                 aggregateData.add(itemInfo);
             }
             DoubleProperty seriesYAnimMultiplier = seriesYMultiplierMap.get(series);
@@ -409,30 +410,26 @@
             int lastCurrentIndex = findPreviousCurrent(aggregateData, aggregateData.size());
             // Iterate over the aggregate data : this process accumulates data points
             // cumulatively from the bottom to top of stack
-            for (DataPointInfo dataInfo : aggregateData) {
+            for (DataPointInfo<X,Y> dataInfo : aggregateData) {
                 if (dataIndex == lastCurrentIndex) lastCurrent = true;
                 if (dataIndex == firstCurrentIndex) firstCurrent = true;
                 double x = 0;
                 double y = 0;
-                double itemX = 0;
-                double itemY = 0;
-                DataPointInfo currentDataPoint = new DataPointInfo();
-                DataPointInfo dropDownDataPoint = new DataPointInfo(true);
+                DataPointInfo<X,Y> currentDataPoint = new DataPointInfo();
+                DataPointInfo<X,Y> dropDownDataPoint = new DataPointInfo(true);
                 Data<X,Y> item = dataInfo.dataItem;
                 if (dataInfo.partOf.equals(PartOf.CURRENT)) { // handle data from current series
                     int pIndex = findPreviousPrevious(aggregateData, dataIndex); 
                     int nIndex = findNextPrevious(aggregateData, dataIndex);
-                    DataPointInfo prevPoint;
-                    DataPointInfo nextPoint;
-                    if (pIndex == -1 || (nIndex == -1 && !(aggregateData.get(pIndex).x == dataInfo.x))) {
+                    DataPointInfo<X,Y> prevPoint;
+                    DataPointInfo<X,Y> nextPoint;
+                    if (pIndex == -1 || (nIndex == -1 && !(aggregateData.get(pIndex).x.equals(dataInfo.x)))) {
                         if (firstCurrent) {
                             // Need to add the drop down point.
                             item = new Data(dataInfo.x, 0);
                             x = getXAxis().getDisplayPosition(item.getCurrentX());
                             y = getYAxis().getZeroPosition();
-                            itemX = getXAxis().toNumericValue(item.getXValue()); 
-                            itemY = getYAxis().toNumericValue(item.getYValue());
-                            dropDownDataPoint.setValues(item, itemX, itemY, x, y, PartOf.CURRENT, true, false);
+                            dropDownDataPoint.setValues(item, item.getXValue(), item.getYValue(), x, y, PartOf.CURRENT, true, false);
                             currentSeriesData.add(dropDownDataPoint);
                         } 
                         // And add current point.
@@ -440,32 +437,28 @@
                         x = getXAxis().getDisplayPosition(item.getCurrentX());
                         y = getYAxis().getDisplayPosition(
                                 getYAxis().toRealValue(getYAxis().toNumericValue(item.getCurrentY()) * seriesYAnimMultiplier.getValue()));
-                        itemX = getXAxis().toNumericValue(item.getXValue()); 
-                        itemY = getYAxis().toNumericValue(item.getYValue());
-                        currentDataPoint.setValues(item, itemX, itemY, x, y, PartOf.CURRENT, false, (firstCurrent) ? false : true);
+                        currentDataPoint.setValues(item, item.getXValue(), item.getYValue(), x, y, PartOf.CURRENT, false, (firstCurrent) ? false : true);
                         currentSeriesData.add(currentDataPoint);
                         if (dataIndex == lastCurrentIndex) {
                             // need to add drop down point
                             item = new Data(dataInfo.x, 0);
                             x = getXAxis().getDisplayPosition(item.getCurrentX());
                             y = getYAxis().getZeroPosition();
-                            itemX = getXAxis().toNumericValue(item.getXValue()); 
-                            itemY = getYAxis().toNumericValue(item.getYValue());
-                            dropDownDataPoint.setValues(item, itemX, itemY, x, y, PartOf.CURRENT, true, false);
+                            dropDownDataPoint.setValues(item, item.getXValue(), item.getYValue(), x, y, PartOf.CURRENT, true, false);
                             currentSeriesData.add(dropDownDataPoint);
                         }
                     } else {
                         prevPoint = aggregateData.get(pIndex);
-                        if (prevPoint.x == dataInfo.x) { // Need to add Y values
+                        if (prevPoint.x.equals(dataInfo.x)) { // Need to add Y values
                             // Check if prevPoint is a dropdown - as the stable sort preserves the order.
                             // If so, find the non dropdown previous point on previous series.
-                            DataPointInfo ddPoint = prevPoint;
+                            DataPointInfo<X,Y> ddPoint = prevPoint;
                             if (prevPoint.dropDown) {
                                 pIndex = findPreviousPrevious(aggregateData, pIndex);
-                                prevPoint = aggregateData.get(pIndex);
+                                prevPoint = (DataPointInfo<X,Y>)aggregateData.get(pIndex);
                                 // If lastCurrent - add this drop down
                             } 
-                            if (prevPoint.x == dataInfo.x) { // simply add
+                            if (prevPoint.x.equals(dataInfo.x)) { // simply add
                                 x = getXAxis().getDisplayPosition(item.getCurrentX());
                                 y = getYAxis().getDisplayPosition(
                                     getYAxis().toRealValue(getYAxis().toNumericValue(item.getCurrentY()) * seriesYAnimMultiplier.getValue()));
@@ -481,8 +474,8 @@
                             }
                         } else {
                             // interpolate 
-                            nextPoint = (nIndex == -1) ? null : aggregateData.get(nIndex);
-                            prevPoint = (pIndex == -1) ? null : aggregateData.get(pIndex);
+                            nextPoint = (nIndex == -1) ? null : (DataPointInfo<X,Y>)aggregateData.get(nIndex);
+                            prevPoint = (pIndex == -1) ? null : (DataPointInfo<X,Y>)aggregateData.get(pIndex);
                             x = getXAxis().getDisplayPosition(item.getCurrentX());
                             y = getYAxis().getDisplayPosition(
                                 getYAxis().toRealValue(getYAxis().toNumericValue(item.getCurrentY()) * seriesYAnimMultiplier.getValue()));
@@ -490,11 +483,15 @@
                                  double displayY = interpolate(prevPoint.displayX, 
                                         prevPoint.displayY, nextPoint.displayX, nextPoint.displayY, x);
                                  y+= -(getYAxis().getZeroPosition() - displayY);
-                                 double dataY = interpolate(prevPoint.x, prevPoint.y, nextPoint.x, nextPoint.y, dataInfo.x); 
+                                 double dataY = interpolate(getXAxis().toNumericValue(prevPoint.x), 
+                                         getYAxis().toNumericValue(prevPoint.y), 
+                                         getXAxis().toNumericValue(nextPoint.x), 
+                                         getYAxis().toNumericValue(nextPoint.y), 
+                                         getXAxis().toNumericValue(dataInfo.x)); 
                                  if (firstCurrent) {
                                      // now create the drop down point
                                      item = new Data(dataInfo.x, dataY);
-                                     dropDownDataPoint.setValues(item, dataInfo.x, dataY, x, displayY, PartOf.CURRENT, true, false);
+                                     dropDownDataPoint.setValues(item, dataInfo.x, getYAxis().toRealValue(dataY), x, displayY, PartOf.CURRENT, true, false);
                                      currentSeriesData.add(dropDownDataPoint);
                                  }
                                  // Add the current point
@@ -504,7 +501,7 @@
                                  if (dataIndex == lastCurrentIndex) {
                                      // add drop down point
                                      item = new Data(dataInfo.x, dataY);
-                                     dropDownDataPoint.setValues(item, dataInfo.x, dataY, x, displayY, PartOf.CURRENT, true, false);
+                                     dropDownDataPoint.setValues(item, dataInfo.x, getYAxis().toRealValue(dataY), x, displayY, PartOf.CURRENT, true, false);
                                      currentSeriesData.add(dropDownDataPoint);
                                  }
                                  // Note: add drop down if last current
@@ -519,11 +516,12 @@
                 } else { // handle data from Previous series.
                     int pIndex = findPreviousCurrent(aggregateData, dataIndex); 
                     int nIndex = findNextCurrent(aggregateData, dataIndex);
-                    DataPointInfo prevPoint;
-                    DataPointInfo nextPoint;
+                    DataPointInfo<X,Y> prevPoint;
+                    DataPointInfo<X,Y> nextPoint;
                     if (dataInfo.dropDown) {
-                        if (dataInfo.x <= aggregateData.get(firstCurrentIndex).x || 
-                                dataInfo.x > aggregateData.get(lastCurrentIndex).x) {
+                        if (getXAxis().toNumericValue(dataInfo.x) <= 
+                                getXAxis().toNumericValue(((DataPointInfo<X,Y>)aggregateData.get(firstCurrentIndex)).x) || 
+                                getXAxis().toNumericValue(dataInfo.x) > getXAxis().toNumericValue(((DataPointInfo<X,Y>)aggregateData.get(lastCurrentIndex)).x)) {
                             currentDataPoint.setValues(item, dataInfo.x, dataInfo.y, dataInfo.displayX, dataInfo.displayY, 
                                     PartOf.CURRENT, true, false);
                             currentDataPoint.dropDown = true;
@@ -535,18 +533,22 @@
                                     PartOf.CURRENT, true, false);
                             currentSeriesData.add(currentDataPoint);
                         } else {
-                            nextPoint = aggregateData.get(nIndex);
-                            if (nextPoint.x == dataInfo.x) {
+                            nextPoint = (DataPointInfo<X,Y>)aggregateData.get(nIndex);
+                            if (nextPoint.x.equals(dataInfo.x)) {
                                 // do nothing as the current point is already there.
                             } else {
                                 // interpolate on the current series.
-                                prevPoint = aggregateData.get(pIndex);
+                                prevPoint = (DataPointInfo<X,Y>)aggregateData.get(pIndex);
                                 x = getXAxis().getDisplayPosition(item.getCurrentX());
-                                double dataY = interpolate(prevPoint.x, prevPoint.y, nextPoint.x, nextPoint.y,  dataInfo.x);
+                                  double dataY = interpolate(getXAxis().toNumericValue(prevPoint.x), 
+                                         getYAxis().toNumericValue(prevPoint.y), 
+                                         getXAxis().toNumericValue(nextPoint.x), 
+                                         getYAxis().toNumericValue(nextPoint.y), 
+                                         getXAxis().toNumericValue(dataInfo.x)); 
                                 y = getYAxis().getDisplayPosition(
                                     getYAxis().toRealValue(dataY * seriesYAnimMultiplier.getValue()));
                                 y+= -(getYAxis().getZeroPosition() - dataInfo.displayY);
-                                currentDataPoint.setValues(new Data(dataInfo.x, dataY), dataInfo.x, dataY, x, y, PartOf.CURRENT, true, true);
+                                currentDataPoint.setValues(new Data(dataInfo.x, dataY), dataInfo.x, getYAxis().toRealValue(0), x, y, PartOf.CURRENT, true, true);
                                 currentSeriesData.add(currentDataPoint);
                             }
                         }
@@ -686,12 +688,12 @@
      * Helper class to hold data and display and other information for each 
      * data point
      */
-    final static class DataPointInfo {
-        double x;
-        double y;   
+    final static class DataPointInfo<X,Y> {
+        X x;
+        Y y;   
         double displayX;
         double displayY;
-        Data dataItem;
+        Data<X,Y> dataItem;
         PartOf partOf;
         boolean skipSymbol = false; // interpolated point - skip drawing symbol
         boolean lineTo = false; // should there be a lineTo to this point on SeriesLine.
@@ -699,8 +701,8 @@
         
         //----- Constructors --------------------
         DataPointInfo() {}
-        
-        DataPointInfo(Data item, double x, double y, PartOf partOf) {
+
+        DataPointInfo(Data<X,Y> item, X x, Y y, PartOf partOf) {
             this.dataItem = item;
             this.x = x;
             this.y = y;
@@ -711,7 +713,7 @@
             this.dropDown = dropDown;
         }
         
-        void setValues(Data item, double x, double y, double dx, double dy, 
+        void setValues(Data<X,Y> item, X x, Y y, double dx, double dy, 
                         PartOf partOf, boolean skipSymbol, boolean lineTo) {
             this.dataItem = item;
             this.x = x;
@@ -722,6 +724,14 @@
             this.skipSymbol = skipSymbol;
             this.lineTo = lineTo;
         }
+        
+        public final X getX() {
+            return x;
+        }
+        
+        public final Y getY() {
+            return y;
+        }
     }
 
     // To indicate if the data point belongs to the current or the previous series.
--- a/javafx-ui-charts/test/javafx/scene/chart/StackedAreaChartTest.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-charts/test/javafx/scene/chart/StackedAreaChartTest.java	Tue Jun 18 12:21:58 2013 -0700
@@ -28,21 +28,36 @@
     private Stage stage;
     StackedAreaChart<Number,Number> ac;
     final XYChart.Series<Number, Number> series1 = new XYChart.Series<Number, Number>();
-    
+    boolean useCategoryAxis = false;
+    final String[] countries = {"USA", "Italy", "France", "China", "India"};
     protected Chart createChart() {
-        final NumberAxis xAxis = new NumberAxis();
         final NumberAxis yAxis = new NumberAxis();
-        ac = new StackedAreaChart<Number,Number>(xAxis,yAxis);
-        xAxis.setLabel("X Axis");
-        yAxis.setLabel("Y Axis");
-        ac.setTitle("HelloStackedAreaChart");
-        // add starting data
         ObservableList<XYChart.Data> data = FXCollections.observableArrayList();
+        Axis xAxis;
+        if (useCategoryAxis) {
+            xAxis = new CategoryAxis();
+            ((CategoryAxis)xAxis).setCategories(FXCollections.observableArrayList(countries));
+            // add starting data
+        series1.getData().add(new XYChart.Data(countries[0], 10d));
+        series1.getData().add(new XYChart.Data(countries[1], 20d));
+        series1.getData().add(new XYChart.Data(countries[2], 15d));
+        series1.getData().add(new XYChart.Data(countries[3], 15d));
+        series1.getData().add(new XYChart.Data(countries[4], 10d));
+        } else {
+            xAxis = new NumberAxis();
+            ac = new StackedAreaChart<Number,Number>(xAxis,yAxis);
+            // add starting data
         series1.getData().add(new XYChart.Data(10d, 10d));
         series1.getData().add(new XYChart.Data(25d, 20d));
         series1.getData().add(new XYChart.Data(30d, 15d));
         series1.getData().add(new XYChart.Data(50d, 15d));
         series1.getData().add(new XYChart.Data(80d, 10d));
+        }
+        
+        xAxis.setLabel("X Axis");
+        yAxis.setLabel("Y Axis");
+        ac.setTitle("HelloStackedAreaChart");
+        
         return ac;
     }
     
@@ -140,4 +155,11 @@
             assertEquals(sb.toString(), "L206.0 197.0 L329.0 40.0 L412.0 276.0 L658.0 354.0 ");
         }
     }
+    
+    @Test 
+    public void testStackedAreaChartWithCategoryAxis() {
+        useCategoryAxis = true;
+        startApp();
+        useCategoryAxis = false;
+    }
 }
--- a/javafx-ui-charts/test/javafx/scene/chart/StackedBarChartTest.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-charts/test/javafx/scene/chart/StackedBarChartTest.java	Tue Jun 18 12:21:58 2013 -0700
@@ -55,6 +55,32 @@
     }
     
     @Test
+    public void testAddingAutoRangingCategoryAxis() {
+        CategoryAxis xAxis = new CategoryAxis();
+        String[] years = {"2007", "2008", "2009"};
+        NumberAxis yAxis = new NumberAxis();
+        ObservableList<StackedBarChart.Series> barChartData = FXCollections.observableArrayList(
+            new StackedBarChart.Series("Region 1", FXCollections.observableArrayList(
+               new StackedBarChart.Data(years[0], 567d),
+               new StackedBarChart.Data(years[1], 1292d),
+               new StackedBarChart.Data(years[2], 1292d)
+            )),
+            new StackedBarChart.Series("Region 2", FXCollections.observableArrayList(
+               new StackedBarChart.Data(years[0], 956),
+               new StackedBarChart.Data(years[1], 1665),
+               new StackedBarChart.Data(years[2], 2559)
+            ))
+        );
+        StackedBarChart sbc = new StackedBarChart(xAxis, yAxis, barChartData, 25.0d);
+        scene = new Scene(sbc,800,600);
+        stage = new Stage();
+        stage.setScene(scene);
+        stage.show();
+        pulse();
+         assertEquals(6, sbc.getPlotChildren().size());
+    }
+    
+    @Test
     public void testSeriesAdd() {
         startApp();
         sbc.getData().addAll(series1, series2, series3);
--- a/javafx-ui-common/src/com/sun/javafx/application/PlatformImpl.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/application/PlatformImpl.java	Tue Jun 18 12:21:58 2013 -0700
@@ -180,11 +180,12 @@
                                 return null;
                             }
                         }, acc);
-                        pendingRunnables.decrementAndGet();
-                        checkIdle();
                      } catch (Throwable t) {
                         System.err.println("Exception in runnable");
                         t.printStackTrace();
+                    } finally {
+                        pendingRunnables.decrementAndGet();
+                        checkIdle();
                     }
                 }
             });
--- a/javafx-ui-common/src/com/sun/javafx/css/CompoundSelector.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/CompoundSelector.java	Tue Jun 18 12:21:58 2013 -0700
@@ -334,14 +334,14 @@
         for (int n=0; n< relationships.size(); n++) os.writeByte(relationships.get(n).ordinal());
     }
 
-    public static CompoundSelector readBinary(final DataInputStream is, final String[] strings)
+    public static CompoundSelector readBinary(int version, final DataInputStream is, final String[] strings)
             throws IOException
     {
 
         final int nSelectors = is.readShort();
         final List<SimpleSelector> selectors = new ArrayList<SimpleSelector>();
         for (int n=0; n<nSelectors; n++) {
-            selectors.add((SimpleSelector)Selector.readBinary(is,strings));
+            selectors.add((SimpleSelector)Selector.readBinary(version, is,strings));
         }
 
         final int nRelationships = is.readShort();
--- a/javafx-ui-common/src/com/sun/javafx/css/Declaration.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/Declaration.java	Tue Jun 18 12:21:58 2013 -0700
@@ -81,6 +81,14 @@
         return important;
     }
 
+    /** Helper */
+    private Stylesheet.Origin getOrigin() {
+        Rule rule = getRule();
+        if (rule != null)  {
+            return rule.getOrigin();
+        }
+        return null;
+    }
     /** 
      * One declaration is the equal to another regardless of the Rule to which
      * the Declaration belongs. Only the property, value and importance are
@@ -98,15 +106,18 @@
             return false;
         }
         final Declaration other = (Declaration) obj;
+        if (this.important != other.important) {
+            return false;
+        }
+        if (this.getOrigin() != other.getOrigin()) {
+            return false;
+        }
         if ((this.property == null) ? (other.property != null) : !this.property.equals(other.property)) {
             return false;
         }
         if (this.parsedValue != other.parsedValue && (this.parsedValue == null || !this.parsedValue.equals(other.parsedValue))) {
             return false;
         }
-        if (this.important != other.important) {
-            return false;
-        }
         return true;
     }
 
@@ -135,11 +146,11 @@
         os.writeBoolean(important);
     }
 
-    static Declaration readBinary(DataInputStream is, String[] strings)
+    static Declaration readBinary(int version, DataInputStream is, String[] strings)
         throws IOException
     {
         final String propertyName = strings[is.readShort()];
-        final ParsedValue parsedValue = ParsedValue.readBinary(is,strings);
+        final ParsedValue parsedValue = ParsedValue.readBinary(version, is,strings);
         final boolean important = is.readBoolean();
         return new Declaration(propertyName, parsedValue, important);
     }
--- a/javafx-ui-common/src/com/sun/javafx/css/ParsedValue.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/ParsedValue.java	Tue Jun 18 12:21:58 2013 -0700
@@ -585,22 +585,22 @@
             os.writeByte(NULL_VALUE);
 
         } else {
-            throw new InternalError("cannot writeBinary " + this);
+            throw new IllegalArgumentException("cannot writeBinary " + value);
         }
     }
 
-    public static ParsedValue readBinary(DataInputStream is, String[] strings)
+    public static ParsedValue readBinary(int version, DataInputStream is, String[] strings)
             throws IOException {
 
         final boolean lookup = is.readBoolean();
         final boolean hasType = is.readBoolean();
 
-        final StyleConverter converter = (hasType) ? StyleConverter.readBinary(is, strings) : null;
+        final StyleConverter converter = (hasType) ? StyleConverter.readBinary(version, is, strings) : null;
 
         final int valType = is.readByte();
 
         if (valType == VALUE) {
-            final ParsedValue value = ParsedValue.readBinary(is, strings);
+            final ParsedValue value = ParsedValue.readBinary(version, is, strings);
             return new ParsedValue(value, converter, lookup);
 
         } else if (valType == VALUE_ARRAY) {
@@ -609,7 +609,7 @@
             for (int v=0; v<nVals; v++) {
                 int vtype = is.readByte();
                 if (vtype == VALUE) {
-                    values[v] = ParsedValue.readBinary(is, strings);
+                    values[v] = ParsedValue.readBinary(version, is, strings);
                 } else {
                     values[v] = null;
                 }
@@ -625,7 +625,7 @@
                 for (int v=0; v<nVals; v++) {
                     int vtype = is.readByte();
                     if (vtype == VALUE) {
-                        layers[l][v] = ParsedValue.readBinary(is, strings);
+                        layers[l][v] = ParsedValue.readBinary(version, is, strings);
                     } else {
                         layers[l][v] = null;
                     }
@@ -644,6 +644,23 @@
             final int nameIndex = is.readShort();
             final String ename = strings[nameIndex];
             
+            if (version == 2) {
+                // RT-31022
+                // Once upon a time, the enum's class name was added to the 
+                // StringStore and the class name's index was written to the
+                // stream. Then the writeShort of the class name's index was 
+                // removed but the binary css version wasn't incremented. 
+                // So if we're trying to read a version 2 stream, then we'll
+                // read this short value. If the stream is actually a the 
+                // version without this short value, then the data will get 
+                // out of sync with the deserialization code and an exception
+                // will be thrown, at which point we can try a different 
+                // version.
+                // 
+                int bad = is.readShort();
+                if (bad >= strings.length) throw new IllegalArgumentException("bad version " + version);
+            }
+            
             ParsedValue value = new ParsedValue(ename, converter, lookup);
             return value;
 
@@ -674,14 +691,14 @@
                 URL url = new URL(str);
                 return new ParsedValue(url, converter, lookup);
             } catch (MalformedURLException malf) {
-                throw new InternalError("Excpeption in Value.readBinary: " + malf);
+                throw new IllegalArgumentException("Excpeption in Value.readBinary: " + malf);
             }
 
         } else if (valType == NULL_VALUE) {
             return new ParsedValue(null, converter, lookup);
 
         } else {
-            throw new InternalError("unknown type: " + valType);
+            throw new IllegalArgumentException("unknown type: " + valType);
         }
     }
 
--- a/javafx-ui-common/src/com/sun/javafx/css/Rule.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/Rule.java	Tue Jun 18 12:21:58 2013 -0700
@@ -173,20 +173,20 @@
         }
     }
 
-    static Rule readBinary(DataInputStream is, String[] strings)
+    static Rule readBinary(int version, DataInputStream is, String[] strings)
             throws IOException
     {
         short nSelectors = is.readShort();
         List<Selector> selectors = new ArrayList<Selector>(nSelectors);
         for (int i = 0; i < nSelectors; i++) {
-            Selector s = Selector.readBinary(is, strings);
+            Selector s = Selector.readBinary(version, is, strings);
             selectors.add(s);
         }
 
         short nDeclarations = is.readShort();
         List<Declaration> declarations = new ArrayList<Declaration>(nDeclarations);
         for (int i = 0; i < nDeclarations; i++) {
-            Declaration d = Declaration.readBinary(is, strings);
+            Declaration d = Declaration.readBinary(version, is, strings);
             declarations.add(d);
         }
 
--- a/javafx-ui-common/src/com/sun/javafx/css/Selector.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/Selector.java	Tue Jun 18 12:21:58 2013 -0700
@@ -104,13 +104,13 @@
         }
     }
 
-    static Selector readBinary(DataInputStream is, String[] strings)
+    static Selector readBinary(int version, DataInputStream is, String[] strings)
         throws IOException {
         final int type = is.readByte();
         if (type == TYPE_SIMPLE)
-            return SimpleSelector.readBinary(is,strings);
+            return SimpleSelector.readBinary(version, is,strings);
         else
-            return CompoundSelector.readBinary(is,strings);
+            return CompoundSelector.readBinary(version, is,strings);
     }
 
     public static Selector createSelector(final String cssSelector) {
--- a/javafx-ui-common/src/com/sun/javafx/css/SimpleSelector.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/SimpleSelector.java	Tue Jun 18 12:21:58 2013 -0700
@@ -364,7 +364,7 @@
         for (String p : pseudoclasses)  os.writeShort(stringStore.addString(p));
     }
 
-    static SimpleSelector readBinary(final DataInputStream is, final String[] strings)
+    static SimpleSelector readBinary(int version, final DataInputStream is, final String[] strings)
         throws IOException
     {
         final String name = strings[is.readShort()];
--- a/javafx-ui-common/src/com/sun/javafx/css/StyleConverter.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/StyleConverter.java	Tue Jun 18 12:21:58 2013 -0700
@@ -92,7 +92,7 @@
     // map of StyleConverter class name to StyleConverter
     private static Map<String,StyleConverter> tmap;
 
-    public static StyleConverter readBinary(DataInputStream is, String[] strings)
+    public static StyleConverter readBinary(int version, DataInputStream is, String[] strings)
             throws IOException {
 
         int index = is.readShort();
@@ -101,7 +101,7 @@
         if (cname == null || cname.isEmpty()) return null;
         
         if (cname.startsWith("com.sun.javafx.css.converters.EnumConverter")) {
-            return com.sun.javafx.css.converters.EnumConverter.readBinary(is, strings);
+            return com.sun.javafx.css.converters.EnumConverter.readBinary(version, is, strings);
         } 
 
         // Make a new entry in tmap, if necessary
--- a/javafx-ui-common/src/com/sun/javafx/css/StyleHelper.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/StyleHelper.java	Tue Jun 18 12:21:58 2013 -0700
@@ -44,6 +44,8 @@
 import java.lang.ref.WeakReference;
 import java.util.*;
 import java.util.Map.Entry;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
 import javafx.beans.value.WritableValue;
 import javafx.scene.Parent;
 import javafx.scene.text.FontPosture;
@@ -861,11 +863,7 @@
                 calculatedValue = lookup(node, styleable, isUserSet, states, 
                         inlineStyles, node, cacheEntry, styleList);
 
-                if (fastpath) {
-                    // if userStyles is null and calculatedValue was null,
-                    // then the calculatedValue didn't come from the cache
-                    cacheEntry.put(property, calculatedValue);
-                }
+                cacheEntry.put(property, calculatedValue);
 
             }
 
@@ -1279,7 +1277,8 @@
             Node node, 
             ParsedValue value, 
             long states,
-            Map<String,CascadingStyle> userStyles, 
+            Map<String,CascadingStyle> inlineStyles,
+            ObjectProperty<Origin> whence,
             List<Style> styleList) {
         
         
@@ -1296,7 +1295,7 @@
                 final String sval = (String)val;
                 
                 CascadingStyle resolved = 
-                    resolveRef(node, sval, states, userStyles);
+                    resolveRef(node, sval, states, inlineStyles);
 
                 if (resolved != null) {
                     
@@ -1307,10 +1306,22 @@
                         }
                     }
                     
+                    // The origin of this parsed value is the greatest of 
+                    // any of the resolved reference. If a resolved reference
+                    // comes from an inline style, for example, then the value
+                    // calculated from the resolved lookup should have inline
+                    // as its origin. Otherwise, an inline style could be 
+                    // stored in shared cache.
+                    final Origin wOrigin = whence.get();
+                    final Origin rOrigin = resolved.getOrigin();
+                    if (rOrigin != null && (wOrigin == null ||  wOrigin.compareTo(rOrigin) < 0)) {
+                        whence.set(rOrigin);
+                    } 
+                    
                     // the resolved value may itself need to be resolved.
                     // For example, if the value "color" resolves to "base",
                     // then "base" will need to be resolved as well.
-                    return resolveLookups(node, resolved.getParsedValue(), states, userStyles, styleList);
+                    return resolveLookups(node, resolved.getParsedValue(), states, inlineStyles, whence, styleList);
                 }
             }
         }
@@ -1328,7 +1339,7 @@
                 for (int ll=0; ll<layers[l].length; ll++) {
                     if (layers[l][ll] == null) continue;
                     layers[l][ll].resolved = 
-                        resolveLookups(node, layers[l][ll], states, userStyles, styleList);
+                        resolveLookups(node, layers[l][ll], states, inlineStyles, whence, styleList);
                 }
             }
 
@@ -1338,7 +1349,7 @@
             for (int l=0; l<layer.length; l++) {
                 if (layer[l] == null) continue;
                 layer[l].resolved =
-                    resolveLookups(node, layer[l], states, userStyles, styleList);
+                    resolveLookups(node, layer[l], states, inlineStyles, whence, styleList);
             }
         }
 
@@ -1431,6 +1442,7 @@
         return sbuf.toString();
     }
     
+    
     private CalculatedValue calculateValue(
             final CascadingStyle style, 
             final Node node, 
@@ -1444,8 +1456,9 @@
         final ParsedValue cssValue = style.getParsedValue();
         if (cssValue != null && !("null").equals(cssValue.getValue())) {
         
+            ObjectProperty<Origin> whence = new SimpleObjectProperty<Origin>(style.getOrigin());
             final ParsedValue resolved = 
-                resolveLookups(node, cssValue, states, inlineStyles, styleList);
+                resolveLookups(node, cssValue, states, inlineStyles, whence, styleList);
             
             try {
                 // The computed value
@@ -1536,7 +1549,7 @@
                 else
                     val = styleable.getConverter().convert(resolved, font);
 
-                final Origin origin = style.getOrigin();
+                final Origin origin = whence.get();
                 return new CalculatedValue(val, origin, resolved.isNeedsFont());
                 
             } catch (ClassCastException cce) {
@@ -1950,7 +1963,7 @@
                 calculateValue(csShorthand, node, styleable, states, inlineStyles, 
                     originatingNode, cacheEntry, styleList);
             
-            if (origin == null || origin.compareTo(cv.origin) <= 0) {
+            if (cv != SKIP && (origin == null || origin.compareTo(cv.origin) <= 0)) {
                 
                 if (cv.value instanceof Font) {
                     Font f = (Font)cv.value;
@@ -2234,13 +2247,15 @@
                                              
                         final int start = styleList.size();
                         
-                        final Map<String, List<CascadingStyle>> smap = getStyleMap();
-                        if (smap == null) return;
+                        final Map<String, List<CascadingStyle>> smap = helper.getStyleMap();
+                        if (smap != null) {
 
-                        List<CascadingStyle> styles = smap.get(property);
-                        
-                        if (styles != null) {
-                            styleList.addAll(styles);
+                            List<CascadingStyle> styles = smap.get(property);
+
+                            if (styles != null) {
+                                styleList.addAll(styles);
+                            }
+
                         }
                         
                         List<CascadingStyle> inlineStyles = (inlineStyleMap != null) 
--- a/javafx-ui-common/src/com/sun/javafx/css/Stylesheet.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/Stylesheet.java	Tue Jun 18 12:21:58 2013 -0700
@@ -35,6 +35,8 @@
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import javafx.collections.ListChangeListener.Change;
 import javafx.collections.ObservableList;
 
@@ -54,6 +56,8 @@
  */
 final public class Stylesheet {
 
+    public final static int BINARY_CSS_VERSION = 3;
+            
     public enum Origin {
         USER_AGENT,
         USER,
@@ -174,7 +178,7 @@
 
     // protected for unit testing 
     /** @treatAsPrivate public to allow unit testing */
-    public void readBinary(DataInputStream is, String[] strings)
+    public void readBinary(int version, DataInputStream is, String[] strings)
         throws IOException 
     {
         final int index = is.readShort();
@@ -182,7 +186,7 @@
         final int nRules = is.readShort();
         List<Rule> persistedRules = new ArrayList<Rule>(nRules);
         for (int n=0; n<nRules; n++) {
-            persistedRules.add(Rule.readBinary(is,strings));
+            persistedRules.add(Rule.readBinary(version,is,strings));
         }
         this.rules.addAll(persistedRules);
         
@@ -205,14 +209,35 @@
             dataInputStream = new DataInputStream(bufferedInputStream);
             // read file version
             final int version = dataInputStream.readShort();
-            if (version != 2)
-                throw new IOException(url.toString() + " wrong file version. got "
-                        + version + " expected 2");
+            if (version > Stylesheet.BINARY_CSS_VERSION) {
+                throw new IOException(url.toString() + " wrong binary CSS version: "
+                        + version + ". Expected version less than or equal to" +
+                        Stylesheet.BINARY_CSS_VERSION);
+            }
             // read strings
             final String[] strings = StringStore.readBinary(dataInputStream);
             // read binary data
             stylesheet = new Stylesheet(url);
-            stylesheet.readBinary(dataInputStream,strings);
+ 
+            // RT-31022
+            if (version == 2) {
+                boolean retry = false;
+                try {
+                    
+                    dataInputStream.mark(Integer.MAX_VALUE);
+                    stylesheet.readBinary(version, dataInputStream, strings);
+
+                } catch (Exception e) {
+                    
+                    stylesheet = new Stylesheet(url);
+
+                    dataInputStream.reset();
+                    stylesheet.readBinary(Stylesheet.BINARY_CSS_VERSION, dataInputStream, strings);
+
+                }
+            } else {
+                stylesheet.readBinary(Stylesheet.BINARY_CSS_VERSION, dataInputStream, strings);
+            }
 
         } catch (FileNotFoundException fnfe) {
             // This comes from url.openStream() and is expected. 
@@ -221,18 +246,12 @@
             // TODO: User logger here
             System.err.println(ignored);
             ignored.printStackTrace(System.err);
-        } finally {
+        } finally { 
             try {
-                if (dataInputStream != null) {
-                    dataInputStream.close();
-                } else if (bufferedInputStream != null) {
-                    bufferedInputStream.close();
-                } else if (inputStream != null) {
-                    inputStream.close();
-                }
-            } catch(IOException ioe) {
+                if (dataInputStream != null) dataInputStream.close();
+            } catch (IOException ignored) {
             }
-        }
+       }
 
         // return stylesheet
         return stylesheet;
--- a/javafx-ui-common/src/com/sun/javafx/css/converters/EnumConverter.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/converters/EnumConverter.java	Tue Jun 18 12:21:58 2013 -0700
@@ -77,7 +77,7 @@
         os.writeShort(index);
     }
     
-    public static StyleConverter readBinary(DataInputStream is, String[] strings)
+    public static StyleConverter readBinary(int version, DataInputStream is, String[] strings)
             throws IOException {
     
         short index = is.readShort();
--- a/javafx-ui-common/src/com/sun/javafx/css/converters/FontConverter.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/converters/FontConverter.java	Tue Jun 18 12:21:58 2013 -0700
@@ -125,7 +125,27 @@
         @Override
         public FontPosture convert(ParsedValue<FontUnits.Style, FontPosture> value, Font font) {
 
-            final FontUnits.Style style = value.getValue();
+            // Testing for RT-31022 exposed a ClassCastException where value 
+            // wraps a String (e.g., "ITALIC", not a FontUnits.Style). 
+            final Object val = value.getValue();
+            
+            FontUnits.Style style = null;
+            
+            if (val instanceof String) {
+                try {
+                    String sval = ((String)val).toUpperCase();
+                    style = Enum.valueOf(FontUnits.Style.class, sval); 
+                } catch (IllegalArgumentException iae) {
+                    return FontPosture.REGULAR;
+                } catch (NullPointerException npe) {
+                    return FontPosture.REGULAR;
+                }
+                
+            } else if (val instanceof FontUnits.Style) {
+                style = (FontUnits.Style)val;
+            } else {
+                return FontPosture.REGULAR;
+            }
 
             if (FontUnits.Style.INHERIT != style) {
                 return style.toFontPosture();
@@ -163,8 +183,26 @@
         @Override
         public FontWeight convert(ParsedValue<FontUnits.Weight, FontWeight> value, Font font) {
 
-            final FontUnits.Weight weight = value.getValue();
-
+            // Testing for RT-31022 exposed a ClassCastException where value 
+            // wraps a String (e.g., "BOLD", not a FontUnits.Weight). 
+            final Object val = value.getValue();
+            
+            FontUnits.Weight weight = null;
+            if (val instanceof String) {
+                try {
+                    String sval = ((String)val).toUpperCase();
+                    weight = Enum.valueOf(FontUnits.Weight.class, Utils.stripQuotes(sval));
+                } catch (IllegalArgumentException iae) {
+                    return FontWeight.NORMAL;
+                } catch (NullPointerException npe) {
+                    return FontWeight.NORMAL;
+                }
+            } else if (val instanceof FontUnits.Weight) {
+                weight = (FontUnits.Weight)val;
+            } else {
+                return FontWeight.NORMAL;
+            }
+            
             if (FontUnits.Weight.INHERIT != weight
                     && FontUnits.Weight.BOLDER != weight
                     && FontUnits.Weight.LIGHTER != weight) {
--- a/javafx-ui-common/src/com/sun/javafx/css/parser/Css2Bin.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/parser/Css2Bin.java	Tue Jun 18 12:21:58 2013 -0700
@@ -75,7 +75,7 @@
         FileOutputStream fos = new FileOutputStream(outFile);
         DataOutputStream os = new DataOutputStream(fos);
         // write file version
-        os.writeShort(2);
+        os.writeShort(Stylesheet.BINARY_CSS_VERSION);
         // write strings
         stringStore.writeBinary(os);
         // write binary data
--- a/javafx-ui-common/src/com/sun/javafx/image/ByteToBytePixelConverter.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/image/ByteToBytePixelConverter.java	Tue Jun 18 12:21:58 2013 -0700
@@ -30,14 +30,92 @@
 public interface ByteToBytePixelConverter
     extends PixelConverter<ByteBuffer, ByteBuffer>
 {
+    /**
+     * Copies a rectangular region of data from the source array to the
+     * destination array using the following relationship:
+     * <pre>
+     * for each xy : 0 <= x,y < w,h {
+     *     int srcpos = y * srcscanbytes + x * srcbytesperpixel + srcoff;
+     *     int dstpos = y * dstscanbytes + x * dstbytesperpixel + dstoff;
+     *     for each j : 0 <= j < srcbytesperpixel {
+     *         load data from srcarr[srcpos + j];
+     *     }
+     *     convert data to destination pixel format
+     *     for each k : 0 <= k < dstbytesperpixel {
+     *         store data into dstarr[dstpos + k] = pixel data;
+     *     }
+     * }
+     * </pre>
+     * 
+     * @param srcarr the byte array containing the source data
+     * @param srcoff the index in the array of the first source pixel data
+     * @param srcscanbytes number of array indices between rows of data in the source
+     * @param dstbuf the byte array containing the destination data
+     * @param dstoff the index in the array of the first destination pixel data
+     * @param dstscanbytes number of array indices between rows of data in the destination
+     * @param w the number of pixels to process across before moving to the next row
+     * @param h the number of rows of pixels to process
+     */
     public void convert(byte       srcarr[], int srcoff, int srcscanbytes,
                         byte       dstarr[], int dstoff, int dstscanbytes,
                         int w, int h);
 
+    /**
+     * Copies a rectangular region of data from the source buffer to the
+     * destination array using the following relationship:
+     * <pre>
+     * for each xy : 0 <= x,y < w,h {
+     *     int srcpos = y * srcscanbytes + x * srcbytesperpixel + srcoff;
+     *     int dstpos = y * dstscanbytes + x * dstbytesperpixel + dstoff;
+     *     for each j : 0 <= j < srcbytesperpixel {
+     *         load data from srcbuf.get(srcpos + j);
+     *     }
+     *     convert data to destination pixel format
+     *     for each k : 0 <= k < dstbytesperpixel {
+     *         store data into dstarr[dstpos + k] = pixel data;
+     *     }
+     * }
+     * </pre>
+     * 
+     * @param srcbuf the nio buffer containing the source data
+     * @param srcoff the absolute location in the buffer of the first source pixel data
+     * @param srcscanbytes number of buffer elements between rows of data in the source
+     * @param dstbuf the byte array containing the destination data
+     * @param dstoff the index in the array of the first destination pixel data
+     * @param dstscanbytes number of array indices between rows of data in the destination
+     * @param w the number of pixels to process across before moving to the next row
+     * @param h the number of rows of pixels to process
+     */
     public void convert(ByteBuffer srcbuf,   int srcoff, int srcscanbytes,
                         byte       dstarr[], int dstoff, int dstscanbytes,
                         int w, int h);
 
+    /**
+     * Copies a rectangular region of data from the source array to the
+     * destination buffer using the following relationship:
+     * <pre>
+     * for each xy : 0 <= x,y < w,h {
+     *     int srcpos = y * srcscanbytes + x * srcbytesperpixel + srcoff;
+     *     int dstpos = y * dstscanbytes + x * dstbytesperpixel + dstoff;
+     *     for each j : 0 <= j < srcbytesperpixel {
+     *         load data from srcarr[srcpos + j];
+     *     }
+     *     convert data to destination pixel format
+     *     for each k : 0 <= k < dstbytesperpixel {
+     *         store data into dstbuf.put(dstpos + k, pixel data);
+     *     }
+     * }
+     * </pre>
+     * 
+     * @param srcarr the byte array containing the source data
+     * @param srcoff the index in the array of the first source pixel data
+     * @param srcscanbytes number of array indices between rows of data in the source
+     * @param dstbuf the nio buffer containing the destination data
+     * @param dstoff the absolute location in the buffer of the first destination pixel data
+     * @param dstscanbytes number of buffer elements between rows of data in the destination
+     * @param w the number of pixels to process across before moving to the next row
+     * @param h the number of rows of pixels to process
+     */
     public void convert(byte       srcarr[], int srcoff, int srcscanbytes,
                         ByteBuffer dstbuf,   int dstoff, int dstscanbytes,
                         int w, int h);
--- a/javafx-ui-common/src/com/sun/javafx/image/ByteToIntPixelConverter.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/image/ByteToIntPixelConverter.java	Tue Jun 18 12:21:58 2013 -0700
@@ -31,14 +31,92 @@
 public interface ByteToIntPixelConverter
     extends PixelConverter<ByteBuffer, IntBuffer>
 {
+    /**
+     * Copies a rectangular region of data from the source array to the
+     * destination array using the following relationship:
+     * <pre>
+     * for each xy : 0 <= x,y < w,h {
+     *     int srcpos = y * srcscanbytes + x * srcbytesperpixel + srcoff;
+     *     int dstpos = y * dstscanints  + x * dstintsperpixel  + dstoff;
+     *     for each j : 0 <= j < srcbytesperpixel {
+     *         load data from srcarr[srcpos + j];
+     *     }
+     *     convert data to destination pixel format
+     *     for each k : 0 <= k < dstintsperpixel {
+     *         store data into dstarry[dstpos + k] = pixel data;
+     *     }
+     * }
+     * </pre>
+     * 
+     * @param srcbuf the byte array containing the source data
+     * @param srcoff the index in the array of the first source pixel data
+     * @param srcscanbytes number of array indices between rows of data in the source
+     * @param dstbuf the int array containing the destination data
+     * @param dstoff the index in the array of the first destination pixel data
+     * @param dstscanints number of array indices between rows of data in the destination
+     * @param w the number of pixels to process across before moving to the next row
+     * @param h the number of rows of pixels to process
+     */
     public void convert(byte srcarr[], int srcoff, int srcscanbytes,
                         int  dstarr[], int dstoff, int dstscanints,
                         int w, int h);
 
+    /**
+     * Copies a rectangular region of data from the source buffer to the
+     * destination array using the following relationship:
+     * <pre>
+     * for each xy : 0 <= x,y < w,h {
+     *     int srcpos = y * srcscanbytes + x * srcbytesperpixel + srcoff;
+     *     int dstpos = y * dstscanints  + x * dstintsperpixel  + dstoff;
+     *     for each j : 0 <= j < srcbytesperpixel {
+     *         load data from srcbuf.get(srcpos + j);
+     *     }
+     *     convert data to destination pixel format
+     *     for each k : 0 <= k < dstintsperpixel {
+     *         store data into dstarry[dstpos + k] = pixel data;
+     *     }
+     * }
+     * </pre>
+     * 
+     * @param srcbuf the nio buffer containing the source data
+     * @param srcoff the absolute location in the buffer of the first source pixel data
+     * @param srcscanbytes number of buffer elements between rows of data in the source
+     * @param dstbuf the int array containing the destination data
+     * @param dstoff the index in the array of the first destination pixel data
+     * @param dstscanints number of array indices between rows of data in the destination
+     * @param w the number of pixels to process across before moving to the next row
+     * @param h the number of rows of pixels to process
+     */
     public void convert(ByteBuffer srcbuf,   int srcoff, int srcscanbytes,
                         int        dstarr[], int dstoff, int dstscanints,
                         int w, int h);
 
+    /**
+     * Copies a rectangular region of data from the source array to the
+     * destination buffer using the following relationship:
+     * <pre>
+     * for each xy : 0 <= x,y < w,h {
+     *     int srcpos = y * srcscanbytes + x * srcbytesperpixel + srcoff;
+     *     int dstpos = y * dstscanints  + x * dstintsperpixel  + dstoff;
+     *     for each j : 0 <= j < srcbytesperpixel {
+     *         load data from srcarr[srcpos + j];
+     *     }
+     *     convert data to destination pixel format
+     *     for each k : 0 <= k < dstintsperpixel {
+     *         store data into dstbuf.put(dstpos + k, pixel data)
+     *     }
+     * }
+     * </pre>
+     * 
+     * @param srcbuf the byte array containing the source data
+     * @param srcoff the index in the array of the first source pixel data
+     * @param srcscanbytes number of array indices between rows of data in the source
+     * @param dstbuf the nio buffer containing the destination data
+     * @param dstoff the absolute location in the buffer of the first destination pixel data
+     * @param dstscanints number of buffer elements between rows of data in the destination
+     * @param w the number of pixels to process across before moving to the next row
+     * @param h the number of rows of pixels to process
+     */
     public void convert(byte      srcarr[], int srcoff, int srcscanbytes,
                         IntBuffer dstbuf,   int dstoff, int dstscanints,
                         int w, int h);
--- a/javafx-ui-common/src/com/sun/javafx/image/IntToBytePixelConverter.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/image/IntToBytePixelConverter.java	Tue Jun 18 12:21:58 2013 -0700
@@ -31,14 +31,92 @@
 public interface IntToBytePixelConverter
     extends PixelConverter<IntBuffer, ByteBuffer>
 {
+    /**
+     * Copies a rectangular region of data from the source array to the
+     * destination array using the following relationship:
+     * <pre>
+     * for each xy : 0 <= x,y < w,h {
+     *     int srcpos = y * srcscanints  + x * srcintsperpixel  + srcoff;
+     *     int dstpos = y * dstscanbytes + x * dstbytesperpixel + dstoff;
+     *     for each j : 0 <= j < srcintsperpixel {
+     *         load data from srcarr[srcpos + j];
+     *     }
+     *     convert data to destination pixel format
+     *     for each k : 0 <= k < dstbytesperpixel {
+     *         store data into dstarr[dstpos + k] = pixel data;
+     *     }
+     * }
+     * </pre>
+     * 
+     * @param srcbuf the int array containing the source data
+     * @param srcoff the index in the array of the first source pixel data
+     * @param srcscanints number of array indices between rows of data in the source
+     * @param dstbuf the byte array containing the destination data
+     * @param dstoff the index in the array of the first destination pixel data
+     * @param dstscanbytes number of array indices between rows of data in the destination
+     * @param w the number of pixels to process across before moving to the next row
+     * @param h the number of rows of pixels to process
+     */
     public void convert(int  srcarr[], int srcoff, int srcscanints,
                         byte dstarr[], int dstoff, int dstscanbytes,
                         int w, int h);
 
+    /**
+     * Copies a rectangular region of data from the source buffer to the
+     * destination array using the following relationship:
+     * <pre>
+     * for each xy : 0 <= x,y < w,h {
+     *     int srcpos = y * srcscanints  + x * srcintsperpixel  + srcoff;
+     *     int dstpos = y * dstscanbytes + x * dstbytesperpixel + dstoff;
+     *     for each j : 0 <= j < srcintsperpixel {
+     *         load data from srcbuf.get(srcpos + j);
+     *     }
+     *     convert data to destination pixel format
+     *     for each k : 0 <= k < dstbytesperpixel {
+     *         store data into dstarr[dstpos + k] = pixel data;
+     *     }
+     * }
+     * </pre>
+     * 
+     * @param srcbuf the nio buffer containing the source data
+     * @param srcoff the absolute location in the buffer of the first source pixel data
+     * @param srcscanints number of buffer elements between rows of data in the source
+     * @param dstbuf the byte array containing the destination data
+     * @param dstoff the index in the array of the first destination pixel data
+     * @param dstscanbytes number of array indices between rows of data in the destination
+     * @param w the number of pixels to process across before moving to the next row
+     * @param h the number of rows of pixels to process
+     */
     public void convert(IntBuffer srcbuf,   int srcoff, int srcscanints,
                         byte      dstarr[], int dstoff, int dstscanbytes,
                         int w, int h);
 
+    /**
+     * Copies a rectangular region of data from the source array to the
+     * destination buffer using the following relationship:
+     * <pre>
+     * for each xy : 0 <= x,y < w,h {
+     *     int srcpos = y * srcscanints  + x * srcintsperpixel  + srcoff;
+     *     int dstpos = y * dstscanbytes + x * dstbytesperpixel + dstoff;
+     *     for each j : 0 <= j < srcintsperpixel {
+     *         load data from srcarr[srcpos + j];
+     *     }
+     *     convert data to destination pixel format
+     *     for each k : 0 <= k < dstbytesperpixel {
+     *         store data into dstbuf.put(dstpos + k, pixel data);
+     *     }
+     * }
+     * </pre>
+     * 
+     * @param srcbuf the int array containing the source data
+     * @param srcoff the index in the array of the first source pixel data
+     * @param srcscanints number of array indices between rows of data in the source
+     * @param dstbuf the nio buffer containing the destination data
+     * @param dstoff the absolute location in the buffer of the first destination pixel data
+     * @param dstscanbytes number of buffer elements between rows of data in the destination
+     * @param w the number of pixels to process across before moving to the next row
+     * @param h the number of rows of pixels to process
+     */
     public void convert(int        srcarr[], int srcoff, int srcscanints,
                         ByteBuffer dstbuf,   int dstoff, int dstscanbytes,
                         int w, int h);
--- a/javafx-ui-common/src/com/sun/javafx/image/IntToIntPixelConverter.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/image/IntToIntPixelConverter.java	Tue Jun 18 12:21:58 2013 -0700
@@ -30,14 +30,92 @@
 public interface IntToIntPixelConverter
     extends PixelConverter<IntBuffer, IntBuffer>
 {
+    /**
+     * Copies a rectangular region of data from the source array to the
+     * destination array using the following relationship:
+     * <pre>
+     * for each xy : 0 <= x,y < w,h {
+     *     int srcpos = y * srcscanints + x * srcintsperpixel + srcoff;
+     *     int dstpos = y * dstscanints + x * dstintsperpixel + dstoff;
+     *     for each j : 0 <= j < srcintsperpixel {
+     *         load data from srcarr[srcpos + j];
+     *     }
+     *     convert data to destination pixel format
+     *     for each k : 0 <= k < dstintsperpixel {
+     *         store data into dstarr[dstpos + k] = pixel data;
+     *     }
+     * }
+     * </pre>
+     * 
+     * @param srcbuf the int array containing the source data
+     * @param srcoff the index in the array of the first source pixel data
+     * @param srcscanints number of array indices between rows of data in the source
+     * @param dstbuf the int array containing the destination data
+     * @param dstoff the index in the array of the first destination pixel data
+     * @param dstscanints number of array indices between rows of data in the destination
+     * @param w the number of pixels to process across before moving to the next row
+     * @param h the number of rows of pixels to process
+     */
     public void convert(int srcarr[], int srcoff, int srcscanints,
                         int dstarr[], int dstoff, int dstscanints,
                         int w, int h);
 
+    /**
+     * Copies a rectangular region of data from the source buffer to the
+     * destination array using the following relationship:
+     * <pre>
+     * for each xy : 0 <= x,y < w,h {
+     *     int srcpos = y * srcscanints + x * srcintsperpixel + srcoff;
+     *     int dstpos = y * dstscanints + x * dstintsperpixel + dstoff;
+     *     for each j : 0 <= j < srcintsperpixel {
+     *         load data from srcbuf.get(srcpos + j);
+     *     }
+     *     convert data to destination pixel format
+     *     for each k : 0 <= k < dstintsperpixel {
+     *         store data into dstarr[dstpos + k] = pixel data;
+     *     }
+     * }
+     * </pre>
+     * 
+     * @param srcbuf the nio buffer containing the source data
+     * @param srcoff the absolute location in the buffer of the first source pixel data
+     * @param srcscanints number of buffer elements between rows of data in the source
+     * @param dstbuf the int array containing the destination data
+     * @param dstoff the index in the array of the first destination pixel data
+     * @param dstscanints number of array indices between rows of data in the destination
+     * @param w the number of pixels to process across before moving to the next row
+     * @param h the number of rows of pixels to process
+     */
     public void convert(IntBuffer srcbuf,   int srcoff, int srcscanints,
                         int       dstarr[], int dstoff, int dstscanints,
                         int w, int h);
 
+    /**
+     * Copies a rectangular region of data from the source array to the
+     * destination buffer using the following relationship:
+     * <pre>
+     * for each xy : 0 <= x,y < w,h {
+     *     int srcpos = y * srcscanints + x * srcintsperpixel + srcoff;
+     *     int dstpos = y * dstscanints + x * dstintsperpixel + dstoff;
+     *     for each j : 0 <= j < srcintsperpixel {
+     *         load data from srcarr[srcpos + j];
+     *     }
+     *     convert data to destination pixel format
+     *     for each k : 0 <= k < dstintsperpixel {
+     *         store data into dstbuf.put(dstpos + k, pixel data);
+     *     }
+     * }
+     * </pre>
+     * 
+     * @param srcbuf the int array containing the source data
+     * @param srcoff the index in the array of the first source pixel data
+     * @param srcscanints number of array indices between rows of data in the source
+     * @param dstbuf the nio buffer containing the destination data
+     * @param dstoff the absolute location in the buffer of the first destination pixel data
+     * @param dstscanints number of buffer elements between rows of data in the destination
+     * @param w the number of pixels to process across before moving to the next row
+     * @param h the number of rows of pixels to process
+     */
     public void convert(int       srcarr[], int srcoff, int srcscanints,
                         IntBuffer dstbuf,   int dstoff, int dstscanints,
                         int w, int h);
--- a/javafx-ui-common/src/com/sun/javafx/image/PixelConverter.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/image/PixelConverter.java	Tue Jun 18 12:21:58 2013 -0700
@@ -28,8 +28,34 @@
 import java.nio.Buffer;
 
 public interface PixelConverter<T extends Buffer, U extends Buffer> {
-    public void convert(T srcbuf, int srcoff, int srcscanbytes,
-                        U dstbuf, int dstoff, int dstscanbytes,
+    /**
+     * Copies a rectangular region of data from the source buffer to the
+     * destination buffer using the following relationship:
+     * <pre>
+     * for each xy : 0 <= x,y < w,h {
+     *     int srcpos = y * srcscanelems + x * srcelemsperpixel + srcoff;
+     *     int dstpos = y * dstscanelems + x * dstelemsperpixel + dstoff;
+     *     for each j : 0 <= j < srcelemsperpixel {
+     *         load data from srcbuf.get(srcpos + j);
+     *     }
+     *     convert data to destination pixel format
+     *     for each k : 0 <= k < dstelemsperpixel {
+     *         store data into dstbuf.put(dstpos + k, pixel data);
+     *     }
+     * }
+     * </pre>
+     * 
+     * @param srcbuf the nio buffer containing the source data
+     * @param srcoff the absolute location in the buffer of the first source pixel data
+     * @param srcscanelems number of buffer elements between rows of data in the source
+     * @param dstbuf the nio buffer containing the destination data
+     * @param dstoff the absolute location in the buffer of the first destination pixel data
+     * @param dstscanelems number of buffer elements between rows of data in the destination
+     * @param w the number of pixels to process across before moving to the next row
+     * @param h the number of rows of pixels to process
+     */
+    public void convert(T srcbuf, int srcoff, int srcscanelems,
+                        U dstbuf, int dstoff, int dstscanelems,
                         int w, int h);
 
     public PixelGetter<T> getGetter();
--- a/javafx-ui-common/src/com/sun/javafx/image/impl/BaseByteToByteConverter.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/BaseByteToByteConverter.java	Tue Jun 18 12:21:58 2013 -0700
@@ -94,6 +94,8 @@
             h = 1;
         }
         if (srcbuf.hasArray() && dstbuf.hasArray()) {
+            srcoff += srcbuf.arrayOffset();
+            dstoff += dstbuf.arrayOffset();
             doConvert(srcbuf.array(), srcoff, srcscanbytes,
                       dstbuf.array(), dstoff, dstscanbytes,
                       w, h);
@@ -117,7 +119,9 @@
             h = 1;
         }
         if (srcbuf.hasArray()) {
-            doConvert(srcbuf.array(), srcoff, srcscanbytes,
+            byte srcarr[] = srcbuf.array();
+            srcoff += srcbuf.arrayOffset();
+            doConvert(srcarr, srcoff, srcscanbytes,
                       dstarr, dstoff, dstscanbytes,
                       w, h);
         } else {
@@ -141,8 +145,10 @@
             h = 1;
         }
         if (dstbuf.hasArray()) {
+            byte dstarr[] = dstbuf.array();
+            dstoff += dstbuf.arrayOffset();
             doConvert(srcarr, srcoff, srcscanbytes,
-                      dstbuf.array(), dstbuf.arrayOffset(), dstscanbytes,
+                      dstarr, dstoff, dstscanbytes,
                       w, h);
         } else {
             ByteBuffer srcbuf = ByteBuffer.wrap(srcarr);
--- a/javafx-ui-common/src/com/sun/javafx/image/impl/BaseByteToIntConverter.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/BaseByteToIntConverter.java	Tue Jun 18 12:21:58 2013 -0700
@@ -92,6 +92,8 @@
             h = 1;
         }
         if (srcbuf.hasArray() && dstbuf.hasArray()) {
+            srcoff += srcbuf.arrayOffset();
+            dstoff += dstbuf.arrayOffset();
             doConvert(srcbuf.array(), srcoff, srcscanbytes,
                       dstbuf.array(), dstoff, dstscanints,
                       w, h);
@@ -115,7 +117,9 @@
             h = 1;
         }
         if (srcbuf.hasArray()) {
-            doConvert(srcbuf.array(), srcoff, srcscanbytes,
+            byte srcarr[] = srcbuf.array();
+            srcoff += srcbuf.arrayOffset();
+            doConvert(srcarr, srcoff, srcscanbytes,
                       dstarr, dstoff, dstscanints,
                       w, h);
         } else {
@@ -139,8 +143,10 @@
             h = 1;
         }
         if (dstbuf.hasArray()) {
+            int dstarr[] = dstbuf.array();
+            dstoff += dstbuf.arrayOffset();
             doConvert(srcarr, srcoff, srcscanbytes,
-                      dstbuf.array(), dstoff, dstscanints,
+                      dstarr, dstoff, dstscanints,
                       w, h);
         } else {
             ByteBuffer srcbuf = ByteBuffer.wrap(srcarr);
--- a/javafx-ui-common/src/com/sun/javafx/image/impl/BaseIntToByteConverter.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/BaseIntToByteConverter.java	Tue Jun 18 12:21:58 2013 -0700
@@ -92,6 +92,8 @@
             h = 1;
         }
         if (srcbuf.hasArray() && dstbuf.hasArray()) {
+            srcoff += srcbuf.arrayOffset();
+            dstoff += dstbuf.arrayOffset();
             doConvert(srcbuf.array(), srcoff, srcscanints,
                       dstbuf.array(), dstoff, dstscanbytes,
                       w, h);
@@ -115,7 +117,9 @@
             h = 1;
         }
         if (srcbuf.hasArray()) {
-            doConvert(srcbuf.array(), srcoff, srcscanints,
+            int srcarr[] = srcbuf.array();
+            srcoff += srcbuf.arrayOffset();
+            doConvert(srcarr, srcoff, srcscanints,
                       dstarr, dstoff, dstscanbytes,
                       w, h);
         } else {
@@ -139,8 +143,10 @@
             h = 1;
         }
         if (dstbuf.hasArray()) {
+            byte dstarr[] = dstbuf.array();
+            dstoff += dstbuf.arrayOffset();
             doConvert(srcarr, srcoff, srcscanints,
-                      dstbuf.array(), dstoff, dstscanbytes,
+                      dstarr, dstoff, dstscanbytes,
                       w, h);
         } else {
             IntBuffer srcbuf = IntBuffer.wrap(srcarr);
--- a/javafx-ui-common/src/com/sun/javafx/image/impl/BaseIntToIntConverter.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/BaseIntToIntConverter.java	Tue Jun 18 12:21:58 2013 -0700
@@ -90,6 +90,8 @@
             h = 1;
         }
         if (srcbuf.hasArray() && dstbuf.hasArray()) {
+            srcoff += srcbuf.arrayOffset();
+            dstoff += dstbuf.arrayOffset();
             doConvert(srcbuf.array(), srcoff, srcscanints,
                       dstbuf.array(), dstoff, dstscanints,
                       w, h);
@@ -113,7 +115,9 @@
             h = 1;
         }
         if (srcbuf.hasArray()) {
-            doConvert(srcbuf.array(), srcoff, srcscanints,
+            int srcarr[] = srcbuf.array();
+            srcoff += srcbuf.arrayOffset();
+            doConvert(srcarr, srcoff, srcscanints,
                       dstarr, dstoff, dstscanints,
                       w, h);
         } else {
@@ -137,8 +141,10 @@
             h = 1;
         }
         if (dstbuf.hasArray()) {
+            int dstarr[] = dstbuf.array();
+            dstoff += dstbuf.arrayOffset();
             doConvert(srcarr, srcoff, srcscanints,
-                      dstbuf.array(), dstoff, dstscanints,
+                      dstarr, dstoff, dstscanints,
                       w, h);
         } else {
             IntBuffer srcbuf = IntBuffer.wrap(srcarr);
--- a/javafx-ui-common/src/com/sun/javafx/image/impl/IntArgb.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/IntArgb.java	Tue Jun 18 12:21:58 2013 -0700
@@ -41,7 +41,7 @@
     public static final IntPixelAccessor accessor = Accessor.instance;
 
     public static final IntToBytePixelConverter ToByteBgraConverter =
-        IntArgb.ToByteBgraSameConv.nonpremul;
+        new IntTo4ByteSameConverter(IntArgb.getter, ByteBgra.setter);
     public static final IntToBytePixelConverter ToByteBgraPreConverter =
         IntArgb.ToByteBgraPreConv.instance;
     public static final IntToIntPixelConverter ToIntArgbConverter =
@@ -167,56 +167,6 @@
         }
     }
 
-    static class ToByteBgraSameConv extends BaseIntToByteConverter {
-        static final IntToBytePixelConverter nonpremul = new ToByteBgraSameConv(false);
-        static final IntToBytePixelConverter premul = new ToByteBgraSameConv(true);
-
-        private ToByteBgraSameConv(boolean isPremult) {
-            super(isPremult ?  IntArgbPre.getter :  IntArgb.getter,
-                  isPremult ? ByteBgraPre.setter : ByteBgra.setter);
-        }
-
-        @Override
-        void doConvert(int  srcarr[], int srcoff, int srcscanints,
-                       byte dstarr[], int dstoff, int dstscanbytes,
-                       int w, int h)
-        {
-            srcscanints -= w;
-            dstscanbytes -= w * 4;
-            while (--h >= 0) {
-                for (int x = 0; x < w; x++) {
-                    int pixel = srcarr[srcoff++];
-                    dstarr[dstoff++] = (byte) (pixel      );
-                    dstarr[dstoff++] = (byte) (pixel >>  8);
-                    dstarr[dstoff++] = (byte) (pixel >> 16);
-                    dstarr[dstoff++] = (byte) (pixel >> 24);
-                }
-                srcoff += srcscanints;
-                dstoff += dstscanbytes;
-            }
-        }
-
-        @Override
-        void doConvert(IntBuffer  srcbuf, int srcoff, int srcscanints,
-                       ByteBuffer dstbuf, int dstoff, int dstscanbytes,
-                       int w, int h)
-        {
-            dstscanbytes -= w * 4;
-            while (--h >= 0) {
-                for (int x = 0; x < w; x++) {
-                    int pixel = srcbuf.get(srcoff + x);
-                    dstbuf.put(dstoff    , (byte) (pixel      ));
-                    dstbuf.put(dstoff + 1, (byte) (pixel >>  8));
-                    dstbuf.put(dstoff + 2, (byte) (pixel >> 16));
-                    dstbuf.put(dstoff + 3, (byte) (pixel >> 24));
-                    dstoff += 4;
-                }
-                srcoff += srcscanints;
-                dstoff += dstscanbytes;
-            }
-        }
-    }
-
     static class ToByteBgraPreConv extends BaseIntToByteConverter {
         public static final IntToBytePixelConverter instance =
             new ToByteBgraPreConv();
--- a/javafx-ui-common/src/com/sun/javafx/image/impl/IntArgbPre.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/IntArgbPre.java	Tue Jun 18 12:21:58 2013 -0700
@@ -36,14 +36,14 @@
 import java.nio.IntBuffer;
 
 public class IntArgbPre {
-    public static final IntPixelGetter     getter = IntArgb.Accessor.instance;
-    public static final IntPixelSetter     setter = IntArgb.Accessor.instance;
-    public static final IntPixelAccessor accessor = IntArgb.Accessor.instance;
+    public static final IntPixelGetter     getter = Accessor.instance;
+    public static final IntPixelSetter     setter = Accessor.instance;
+    public static final IntPixelAccessor accessor = Accessor.instance;
 
     public static final IntToBytePixelConverter ToByteBgraConverter =
         IntArgbPre.ToByteBgraConv.instance;
     public static final IntToBytePixelConverter ToByteBgraPreConverter =
-        IntArgb.ToByteBgraSameConv.premul;
+        new IntTo4ByteSameConverter(IntArgbPre.getter, ByteBgraPre.setter);
     public static final IntToIntPixelConverter ToIntArgbConverter =
         IntArgbPre.ToIntArgbConv.instance;
     public static final IntToIntPixelConverter ToIntArgbPreConverter =
@@ -213,9 +213,10 @@
                     int g = (pixel >>  8) & 0xff;
                     int b = (pixel      ) & 0xff;
                     if (a > 0 && a < 0xff) {
-                        r = (r * a + 0x7f) / 0xff;
-                        g = (g * a + 0x7f) / 0xff;
-                        b = (b * a + 0x7f) / 0xff;
+                        int halfa = a >> 1;
+                        r = (r * 0xff + halfa) / a;
+                        g = (g * 0xff + halfa) / a;
+                        b = (b * 0xff + halfa) / a;
                     }
                     dstbuf.put(dstoff    , (byte) b);
                     dstbuf.put(dstoff + 1, (byte) g);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/IntTo4ByteSameConverter.java	Tue Jun 18 12:21:58 2013 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012, 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 java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import com.sun.javafx.image.BytePixelSetter;
+import com.sun.javafx.image.IntPixelGetter;
+
+class IntTo4ByteSameConverter extends BaseIntToByteConverter {
+
+    IntTo4ByteSameConverter(IntPixelGetter getter, BytePixelSetter setter) {
+        super(getter, setter);
+    }
+
+    @Override
+    void doConvert(int  srcarr[], int srcoff, int srcscanints,
+                   byte dstarr[], int dstoff, int dstscanbytes,
+                   int w, int h)
+    {
+        srcscanints -= w;
+        dstscanbytes -= w * 4;
+        while (--h >= 0) {
+            for (int x = 0; x < w; x++) {
+                int pixel = srcarr[srcoff++];
+                dstarr[dstoff++] = (byte) (pixel      );
+                dstarr[dstoff++] = (byte) (pixel >>  8);
+                dstarr[dstoff++] = (byte) (pixel >> 16);
+                dstarr[dstoff++] = (byte) (pixel >> 24);
+            }
+            srcoff += srcscanints;
+            dstoff += dstscanbytes;
+        }
+    }
+
+    @Override
+    void doConvert(IntBuffer srcbuf, int srcoff, int srcscanints,
+                   ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                   int w, int h)
+    {
+        dstscanbytes -= w * 4;
+        while (--h >= 0) {
+            for (int x = 0; x < w; x++) {
+                int pixel = srcbuf.get(srcoff + x);
+                dstbuf.put(dstoff    , (byte) (pixel      ));
+                dstbuf.put(dstoff + 1, (byte) (pixel >>  8));
+                dstbuf.put(dstoff + 2, (byte) (pixel >> 16));
+                dstbuf.put(dstoff + 3, (byte) (pixel >> 24));
+                dstoff += 4;
+            }
+            srcoff += srcscanints;
+            dstoff += dstscanbytes;
+        }
+    }
+}
--- a/javafx-ui-common/src/com/sun/javafx/scene/layout/region/BackgroundImage.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/scene/layout/region/BackgroundImage.java	Tue Jun 18 12:21:58 2013 -0700
@@ -24,7 +24,6 @@
  */
 package com.sun.javafx.scene.layout.region;
 
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
@@ -37,6 +36,7 @@
 import com.sun.javafx.css.StyleableProperty;
 import com.sun.javafx.css.ParsedValue;
 import com.sun.javafx.css.converters.BooleanConverter;
+import com.sun.javafx.css.converters.EnumConverter;
 import com.sun.javafx.css.converters.URLConverter;
 import java.util.ArrayList;
 import javafx.beans.value.WritableValue;
@@ -495,9 +495,11 @@
         public static BackgroundRepeatConverter getInstance() {
             return Holder.BACKGROUND_REPEAT_CONVERTER;
         }
-
+        
+        private final EnumConverter<Repeat> converter;
         private BackgroundRepeatConverter() {
             super();
+            this.converter = new EnumConverter<Repeat>(Repeat.class);
         }
 
         @Override
@@ -506,8 +508,8 @@
             BackgroundRepeat[] backgroundRepeat = new BackgroundRepeat[layers.length];
             for (int l = 0; l < layers.length; l++) {
                 ParsedValue<String,Repeat>[] repeats = layers[l];
-                Repeat horizontal = repeats[0].convert(null);
-                Repeat vertical = repeats[1].convert(null);
+                Repeat horizontal = converter.convert(repeats[0], null);
+                Repeat vertical = converter.convert(repeats[1], null);
                 backgroundRepeat[l] = new BackgroundRepeat(horizontal,vertical);
             }
             return backgroundRepeat;
--- a/javafx-ui-common/src/com/sun/javafx/scene/layout/region/BorderImage.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/scene/layout/region/BorderImage.java	Tue Jun 18 12:21:58 2013 -0700
@@ -36,6 +36,7 @@
 import com.sun.javafx.css.StyleConverter;
 import com.sun.javafx.css.StyleableProperty;
 import com.sun.javafx.css.ParsedValue;
+import com.sun.javafx.css.converters.EnumConverter;
 import com.sun.javafx.css.converters.InsetsConverter;
 import com.sun.javafx.css.converters.URLConverter;
 import java.util.ArrayList;
@@ -431,8 +432,10 @@
             return Holder.BORDER_IMAGE_REPEAT_CONVERTER;
         }
 
+        private final EnumConverter<Repeat> repeatConverter;
         private RepeatConverter() {
             super();
+            repeatConverter = new EnumConverter<Repeat>(Repeat.class);
         }
 
         @Override
@@ -441,8 +444,8 @@
             BorderImageRepeat[] borderImageRepeats = new BorderImageRepeat[layers.length];
             for (int l = 0; l < layers.length; l++) {
                 ParsedValue<String,Repeat>[] repeats = layers[l];
-                Repeat horizontal = repeats[0].convert(null);
-                Repeat vertical = repeats[1].convert(null);
+                Repeat horizontal = repeatConverter.convert(repeats[0],null);
+                Repeat vertical = repeatConverter.convert(repeats[1],null);
                 borderImageRepeats[l] = new BorderImageRepeat(horizontal, vertical);
             }
             return borderImageRepeats;
--- a/javafx-ui-common/src/com/sun/javafx/scene/layout/region/BorderImageConverter.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/scene/layout/region/BorderImageConverter.java	Tue Jun 18 12:21:58 2013 -0700
@@ -46,9 +46,9 @@
         return Holder.BORDER_IMAGE_CONVERTER;
     }
 
-    private BorderImageConverter() {
+   private BorderImageConverter() {
         super();
-    }
+   }
 
     @Override
     public List<BorderImage> convert(Map<StyleableProperty, Object> convertedValues) {
--- a/javafx-ui-common/src/com/sun/javafx/tk/PlatformImage.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/tk/PlatformImage.java	Tue Jun 18 12:21:58 2013 -0700
@@ -38,6 +38,16 @@
  */
 public interface PlatformImage {
     /**
+     * Gets the scale representing how large an area a 72DPI virtual
+     * pixel covers in terms of the pixels of this image.
+     * A 72DPI platform image would return 1.0f.
+     * A 144DPI platform image would return 2.0f.
+     * 
+     * @return the number of actual image pixels per 72DPI virtual pixel
+     */
+    public float getPixelScale();
+
+    /**
      * @param x X coordinate of pixel
      * @param y Y coordinate of pixel
      * @return the non-premultiplied pixel in integer ARGB component ordering.
--- a/javafx-ui-common/src/javafx/scene/Node.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/javafx/scene/Node.java	Tue Jun 18 12:21:58 2013 -0700
@@ -3309,9 +3309,13 @@
     @Deprecated
     protected void impl_geomChanged() {
         if (geomBoundsInvalid) {
-            //We need to call this even if geomBounds are already invalid.
-            //Text is relying on this behaviour.
-            impl_notifyLayoutBoundsChanged(); 
+            // GeomBoundsInvalid is false when node geometry changed and
+            // the untransformed node bounds haven't been recalculated yet.
+            // Most of the time, the recalculation of layout and transformed
+            // node bounds don't require validation of untransformed bounds
+            // and so we can not skip the following notifications.
+            impl_notifyLayoutBoundsChanged();
+            transformedBoundsChanged();
             return;
         }
         geomBounds.makeEmpty();
--- a/javafx-ui-common/src/javafx/scene/Parent.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/javafx/scene/Parent.java	Tue Jun 18 12:21:58 2013 -0700
@@ -1283,7 +1283,7 @@
             } else {
                 bounds = bounds.deriveWithNewBounds(cachedBounds);
             }
-            if (dirtyChildren != null) dirtyChildren.clear();
+
             return bounds;
         } else {
             // there is a scale, shear, or rotation happening, so need to
@@ -1323,7 +1323,7 @@
             else
                 bounds = bounds.deriveWithNewBounds((float)minX, (float)minY, (float)minZ,
                         (float)maxX, (float)maxY, (float)maxZ);
-            if (dirtyChildren != null) dirtyChildren.clear();
+
             return bounds;
         }
     }
--- a/javafx-ui-common/src/javafx/scene/Scene.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/javafx/scene/Scene.java	Tue Jun 18 12:21:58 2013 -0700
@@ -1902,23 +1902,6 @@
         }
 
         getKeyHandler().process(e);
-
-        // our little secret...
-        if (!e.isConsumed() && e.getCode() == KeyCode.DIGIT8 &&
-             e.getEventType() == KeyEvent.KEY_PRESSED && e.isControlDown() && e.isShiftDown()) {
-            try {
-                Class scenicview = Class.forName("com.javafx.experiments.scenicview.ScenicView");
-                Class params[] = new Class[1];
-                params[0] = Scene.class;
-                java.lang.reflect.Method method = scenicview.getDeclaredMethod("show", params);
-                method.invoke(null, this);
-
-            } catch (Exception ex) {
-                // oh well
-                //System.out.println("exception instantiating ScenicView:"+ex);
-
-            }
-        }
     }
 
     void requestFocus(Node node) {
--- a/javafx-ui-common/src/javafx/scene/canvas/GraphicsContext.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/javafx/scene/canvas/GraphicsContext.java	Tue Jun 18 12:21:58 2013 -0700
@@ -303,7 +303,7 @@
     private void flushPolyBuf(GrowableDataBuffer buf,
                               float polybuf[], int n, byte command)
     {
-        curState.transform.deltaTransform(polybuf, 0, polybuf, 0, n/2);
+        curState.transform.transform(polybuf, 0, polybuf, 0, n/2);
         for (int i = 0; i < n; i += 2) {
             buf.putByte(command);
             buf.putFloat(polybuf[i]);
@@ -330,6 +330,7 @@
         if (close) {
             buf.putByte(PGCanvas.CLOSEPATH);
         }
+        buf.putByte(PGCanvas.PATHEND);
         buf.putByte(command);
         // Now that we have changed the PG layer path, we need to mark our path dirty.
         markPathDirty();
--- a/javafx-ui-common/src/javafx/scene/image/Image.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/javafx/scene/image/Image.java	Tue Jun 18 12:21:58 2013 -0700
@@ -734,9 +734,10 @@
             if (loader.getFrameCount() > 1) {
                 makeAnimationTimeline(loader);
             } else {
-                setPlatformImageWH(loader.getFrame(0),
-                                   loader.getWidth(),
-                                   loader.getHeight());
+                PlatformImage pi = loader.getFrame(0);
+                double w = loader.getWidth() / pi.getPixelScale();
+                double h = loader.getHeight() / pi.getPixelScale();
+                setPlatformImageWH(pi, w, h);
             }
         } else {
             setError(true);
@@ -769,7 +770,10 @@
         // the last frame is shown, the wrap around is "instantaneous"
         keyFrames.add(createPlatformImageSetKeyFrame(duration, frames[0]));
 
-        setPlatformImageWH(frames[0], loader.getWidth(), loader.getHeight());
+        PlatformImage zeroFrame = frames[0];
+        double w = loader.getWidth() / zeroFrame.getPixelScale();
+        double h = loader.getHeight() / zeroFrame.getPixelScale();
+        setPlatformImageWH(zeroFrame, w, h);
         timeline.play();
     }
 
--- a/javafx-ui-common/src/javafx/scene/input/DragEvent.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/javafx/scene/input/DragEvent.java	Tue Jun 18 12:21:58 2013 -0700
@@ -39,7 +39,7 @@
 /**
  * Drag events replace mouse events during drag-and-drop gesture.
  * The difference between press-drag-release and drag-and-drop gestures
- * is described at {@link javafx.scene.input#MouseEvent MouseEvent}.
+ * is described at {@link javafx.scene.input.MouseEvent MouseEvent}.
  * <p>
  * Drag and drop gesture can be started by calling {@code startDragAndDrop()}
  * (on a node or scene) inside of a {@link MouseEvent#DRAG_DETECTED DRAG_DETECTED} event handler.
--- a/javafx-ui-common/src/javafx/scene/input/MouseDragEvent.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/javafx/scene/input/MouseDragEvent.java	Tue Jun 18 12:21:58 2013 -0700
@@ -30,7 +30,7 @@
 /**
  * Mouse drag events are delivered to potential gesture targets during
  * full press-drag-release gestures. The difference among different
- * gesture types is described at {@link javafx.scene.input#MouseEvent MouseEvent}.
+ * gesture types is described at {@link javafx.scene.input.MouseEvent MouseEvent}.
  * <p>
  * Full press-drag-release gesture can be started by calling
  * {@code startFullDrag()} (on a node or scene) inside of a DRAG_DETECTED
--- a/javafx-ui-common/src/javafx/scene/input/MouseEvent.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/javafx/scene/input/MouseEvent.java	Tue Jun 18 12:21:58 2013 -0700
@@ -39,7 +39,7 @@
 /**
  * When mouse event occurs, the top-most node under cursor is picked and
  * the event is delivered to it through capturing and bubbling phases
- * described at {@link javafx.event#EventDispatcher EventDispatcher}.
+ * described at {@link javafx.event.EventDispatcher EventDispatcher}.
  * <p>
  * The mouse (pointer's) location is available relative to several
  * coordinate systems: x,y - relative to the origin of the
@@ -67,13 +67,13 @@
  * full press-drag-release gesture has to be activated. This gesture is 
  * best used for connecting nodes by "wires", dragging nodes to other nodes etc.
  * This gesture type is more closely described at 
- * {@link javafx.scene.input#MouseDragEvent MouseDragEvent} which contains
+ * {@link javafx.scene.input.MouseDragEvent MouseDragEvent} which contains
  * the events delivered to the gesture targets.
  * <p>
  * The third gesture type is platform-supported drag-and-drop gesture. It serves
  * best to transfer data and works also between (not necessarily FX)
  * applications. This gesture type is more closely described
- * at {@link javafx.scene.input#DragEvent DragEvent}.
+ * at {@link javafx.scene.input.DragEvent DragEvent}.
  * <p>
  * In a short summary, simple press-drag-release gesture is activated
  * automatically when a mouse button is pressed and delivers all
--- a/javafx-ui-common/src/javafx/scene/layout/GridPane.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/src/javafx/scene/layout/GridPane.java	Tue Jun 18 12:21:58 2013 -0700
@@ -53,6 +53,7 @@
 import com.sun.javafx.css.converters.BooleanConverter;
 import com.sun.javafx.css.converters.EnumConverter;
 import com.sun.javafx.css.converters.SizeConverter;
+import java.util.Iterator;
 import javafx.collections.ListChangeListener;
 import javafx.geometry.Orientation;
 
@@ -593,7 +594,7 @@
             setConstraints(nodes[i], columnIndex, rowIndex + i);
         }
     }
-    
+
     static int getNodeRowIndex(Node node) {
         Integer rowIndex = getRowIndex(node);
         return rowIndex != null? rowIndex : 0;
@@ -926,7 +927,7 @@
                 int end = getNodeColumnEnd(child);
                 columnIndex = Math.max(columnIndex, (end != REMAINING? end : index) + 1);
             }
-        }        
+        }
         createRow(rowIndex, columnIndex, children);
         getChildren().addAll(children);
     }
@@ -951,7 +952,7 @@
                 int end = getNodeRowEnd(child);
                 rowIndex = Math.max(rowIndex, (end != REMAINING? end : index) + 1);
             }
-        }        
+        }
         createColumn(columnIndex, rowIndex, children);
         getChildren().addAll(children);
     }
@@ -983,7 +984,7 @@
     // This is set to true while in layoutChildren and set false on the conclusion.
     // It is used to decide whether to update metricsDirty in requestLayout().
     private boolean performingLayout = false;
-    
+
     @Override protected double computeMinWidth(double height) {
         computeGridMetrics();
         if (getContentBias() == Orientation.VERTICAL) {
@@ -1194,7 +1195,7 @@
             if (computeMin || computeMax || computePref || computeGrow || rowVPos == VPos.BASELINE) {
                 // compute from content
                 for (int j = 0; j < endNodes.size(); j++) {
-                    Node child = endNodes.get(j);                    
+                    Node child = endNodes.get(j);
                     Insets margin = getMargin(child);
                     double top = margin != null? margin.getTop() : 0;
                     int rowIndex = getNodeRowIndex(child);
@@ -1316,7 +1317,7 @@
                     columnPercentWidth[i] = constraints.getPercentWidth();
                     computeGrow = false;
                 } else {
-                    double w = constraints.getPrefWidth();          
+                    double w = constraints.getPrefWidth();
                     if (w != USE_COMPUTED_SIZE) {
                         columnPrefWidth[i] = w;
                         computePref = false;
@@ -1339,7 +1340,7 @@
             }
 
             if (computeMin || computeMax || computePref || computeGrow) {
-                // compute from content                
+                // compute from content
                 for (int j = 0; j < endNodes.size(); j++) {
                     Node child = endNodes.get(j);
                     Insets margin = getMargin(child);
@@ -1392,18 +1393,18 @@
 
             if (columnMinWidth[i] == USE_PREF_SIZE) {
                 //RT-20573 Use the bounded size if the pref has not been set
-                columnMinWidth[i] = columnPrefWidth[i] == 0 ? 
-                    boundedSize(columnPrefWidth[i], columnMinWidth[i], columnMaxWidth[i]) == USE_PREF_SIZE ? 
-                        0 : boundedSize(columnPrefWidth[i], columnMinWidth[i], columnMaxWidth[i]) : 
+                columnMinWidth[i] = columnPrefWidth[i] == 0 ?
+                    boundedSize(columnPrefWidth[i], columnMinWidth[i], columnMaxWidth[i]) == USE_PREF_SIZE ?
+                        0 : boundedSize(columnPrefWidth[i], columnMinWidth[i], columnMaxWidth[i]) :
                     columnPrefWidth[i];
             }
             if (columnMaxWidth[i] == USE_PREF_SIZE) {
-                columnMaxWidth[i] = columnPrefWidth[i] == 0 ? 
-                    boundedSize(columnPrefWidth[i], columnMinWidth[i], columnMaxWidth[i]) == USE_PREF_SIZE ? 
-                        0 : boundedSize(columnPrefWidth[i], columnMinWidth[i], columnMaxWidth[i]) : 
+                columnMaxWidth[i] = columnPrefWidth[i] == 0 ?
+                    boundedSize(columnPrefWidth[i], columnMinWidth[i], columnMaxWidth[i]) == USE_PREF_SIZE ?
+                        0 : boundedSize(columnPrefWidth[i], columnMinWidth[i], columnMaxWidth[i]) :
                     columnPrefWidth[i];
-            }                        
-            columnPrefWidth[i] = boundedSize(columnPrefWidth[i], columnMinWidth[i], columnMaxWidth[i]);            
+            }
+            columnPrefWidth[i] = boundedSize(columnPrefWidth[i], columnMinWidth[i], columnMaxWidth[i]);
             //System.out.println("column "+i+": h="+columnWidths[i]+" percent="+columnPercentWidth[i]+" min="+columnMinWidth[i]+" pref="+columnPrefWidth[i]+" max="+columnMaxWidth[i]+" grow="+columnGrow[i]);
         }
         // if percentages sum is bigger than 100, treat them as weights
@@ -1426,10 +1427,12 @@
     }
 
     double[] getColumnWidths() {
+        doLayout(false);
         return columnWidths;
     }
 
     double[] getRowHeights() {
+        doLayout(false);
         return rowHeights;
     }
 
@@ -1457,87 +1460,10 @@
         }
         super.requestLayout();
     }
-
+    
     @Override protected void layoutChildren() {
         performingLayout = true;
-        final double snaphgap = snapSpace(getHgap());
-        final double snapvgap = snapSpace(getVgap());
-        final double top = snapSpace(getInsets().getTop());
-        final double bottom = snapSpace(getInsets().getBottom());
-        final double left = snapSpace(getInsets().getLeft());
-        final double right = snapSpace(getInsets().getRight());
-
-        final double width = getWidth();
-        final double height = getHeight();
-        final double contentHeight = height - top - bottom;
-        final double contentWidth = width - left - right;
-        double columnTotal = 0;
-        double rowTotal = 0;
-        computeGridMetrics();
-
-        Orientation contentBias = getContentBias();        
-        if (contentBias == null) {
-            rowTotal = adjustRowHeights(rowPrefHeight, height);
-            columnTotal = adjustColumnWidths(columnPrefWidth, width);
-        } else if (contentBias == Orientation.HORIZONTAL) {
-            columnTotal = adjustColumnWidths(columnPrefWidth, width);
-            computeRowMetrics(rowHeights.length, columnWidths);
-            rowTotal = adjustRowHeights(rowPrefHeight, height);
-        } else if (contentBias == Orientation.VERTICAL) {
-            rowTotal = adjustRowHeights(rowPrefHeight, height);
-            computeColumnMetrics(columnWidths.length, rowHeights);
-            columnTotal = adjustColumnWidths(columnPrefWidth, width);
-        }
-
-        final double x = left + computeXOffset(contentWidth, columnTotal, getAlignment().getHpos());
-        final double y = top + computeYOffset(contentHeight, rowTotal, getAlignment().getVpos());
-        for (int i = 0; i < getChildren().size(); i++) {
-            Node child = getChildren().get(i);
-            if (child.isManaged()) {
-                int rowIndex = getNodeRowIndex(child);
-                int columnIndex = getNodeColumnIndex(child);
-                int colspan = getNodeColumnSpan(child);
-                if (colspan == REMAINING) {
-                    colspan = columnWidths.length - columnIndex;
-                }
-                int rowspan = getNodeRowSpan(child);
-                if (rowspan == REMAINING) {
-                    rowspan = rowHeights.length - rowIndex;
-                }
-                double areaX = x;
-                for (int j = 0; j < columnIndex; j++) {
-                    areaX += columnWidths[j] + snaphgap;
-                }
-                double areaY = y;
-                for (int j = 0; j < rowIndex; j++) {
-                    areaY += rowHeights[j] + snapvgap;
-                }
-                double areaW = columnWidths[columnIndex];
-                for (int j = 2; j <= colspan; j++) {
-                    areaW += columnWidths[columnIndex+j-1] + snaphgap;
-                }
-                double areaH = rowHeights[rowIndex];
-                for (int j = 2; j <= rowspan; j++) {
-                    areaH += rowHeights[rowIndex+j-1] + snapvgap;
-                }
-
-                HPos halign = getHalignment(child);
-                VPos valign = getValignment(child);
-                Insets margin = getMargin(child);
-                if (margin != null && valign == VPos.BASELINE) {
-                    // The top margin has already added to rowBaseline[] in computeRowMetric()
-                    // we do not need to add it again in layoutInArea.
-                    margin = new Insets(0, margin.getRight(), margin.getBottom(), margin.getLeft());
-                }
-                //System.out.println("layoutNode("+child.toString()+" row/span="+rowIndex+"/"+rowspan+" col/span="+columnIndex+"/"+colspan+" area="+areaX+","+areaY+" "+areaW+"x"+areaH+""+" rowBaseline="+rowBaseline[rowIndex]);
-                layoutInArea(child, areaX, areaY, areaW, areaH, rowBaseline[rowIndex],
-                        margin,
-                        shouldColumnFillWidth(columnIndex), shouldRowFillHeight(rowIndex),
-                        halign != null? halign : getColumnHalignment(columnIndex),
-                        valign != null? valign : getRowValignment(rowIndex));
-            }
-        }
-        layoutGridLines(x, y, rowTotal, columnTotal);
+        doLayout(true);
         performingLayout = false;
     }
 
@@ -1580,7 +1506,6 @@
     private double growOrShrinkRowHeights(Priority priority, double extraHeight) {
         final boolean shrinking = extraHeight < 0;
         List<Integer> adjusting = new ArrayList<Integer>();
-        List<Integer> adjusted = new ArrayList<Integer>();
 
         for (int i = 0; i < rowGrow.length; i++) {
             if (rowPercentHeight[i] < 0 && (shrinking || rowGrow[i] == priority)) {
@@ -1590,32 +1515,37 @@
 
         double available = extraHeight; // will be negative in shrinking case
         boolean handleRemainder = false;
-        int portion = 0;
-        while (available != 0 && adjusting.size() > 0) {
+        double portion = 0;
+
+        // RT-25684: We have to be careful that when subtracting change
+        // that we don't jump right past 0 - this leads to an infinite
+        // loop
+        final boolean wasPositive = available >= 0.0;
+        boolean isPositive = wasPositive;
+
+        double[] limitSize = shrinking? rowMinHeight : rowMaxHeight;
+        while (available != 0 && wasPositive == isPositive && adjusting.size() > 0) {
             if (!handleRemainder) {
-                portion = (int)available / adjusting.size(); // negative in shrinking case
+                portion = available > 0 ? Math.floor(available / adjusting.size()) :
+                        Math.ceil(available / adjusting.size()); // negative in shrinking case
             }
             if (portion != 0) {
-                for (int i = 0; i < adjusting.size(); i++) {
-                    final int index = adjusting.get(i);
-                    final double limit = (shrinking? rowMinHeight[index] : rowMaxHeight[index])
+                for (Iterator<Integer> i = adjusting.iterator(); i.hasNext() && available != 0;) {
+                    final int index = i.next();
+                    final double limit = snapSpace(limitSize[index])
                             - rowHeights[index]; // negative in shrinking case
                     final double change = Math.abs(limit) <= Math.abs(portion)? limit : portion;
-                    //System.out.println("row "+index+": height="+rowHeights[index]+" extra="+extraHeight+"portion="+portion+" row mpm="+rowMinHeight[index]+"/"+rowPrefHeight[index]+"/"+rowMaxHeight[index]+" limit="+limit+" change="+change);
-                    rowHeights[index] += change;                
+                    rowHeights[index] += change;
                     available -= change;
+                    isPositive = available >= 0.0;
                     if (Math.abs(change) < Math.abs(portion)) {
-                        adjusted.add(index);
+                        i.remove();
                     }
                     if (available == 0) {
                         break;
                     }
                 }
-                for (int i = 0; i < adjusted.size(); i++) {
-                    adjusting.remove(adjusted.get(i));
-                }
-                adjusted.clear();
-            } else {
+             } else {
                 // Handle the remainder
                 portion = (int)(available) % adjusting.size();
                 if (portion == 0) {
@@ -1627,10 +1557,7 @@
                 }
             }
         }
-                        
-        for (int i = 0; i < rowHeights.length; i++) {
-            rowHeights[i] = snapSpace(rowHeights[i]);            
-        }
+
         return available; // might be negative in shrinking case
     }
 
@@ -1672,44 +1599,51 @@
     }
 
     private double growOrShrinkColumnWidths(Priority priority, double extraWidth) {
+        if (extraWidth == 0) {
+            return 0;
+        }
         final boolean shrinking = extraWidth < 0;
-
         List<Integer> adjusting = new ArrayList<Integer>();
-        List<Integer> adjusted = new ArrayList<Integer>();
 
         for (int i = 0; i < columnGrow.length; i++) {
             if (columnPercentWidth[i] < 0 && (shrinking || columnGrow[i] == priority)) {
                 adjusting.add(i);
             }
         }
-        
+
         double available = extraWidth; // will be negative in shrinking case
         boolean handleRemainder = false;
-        int portion = 0;
-        while (available != 0 && adjusting.size() > 0) {            
+        double portion = 0;
+
+        // RT-25684: We have to be careful that when subtracting change
+        // that we don't jump right past 0 - this leads to an infinite
+        // loop
+        final boolean wasPositive = available >= 0.0;
+        boolean isPositive = wasPositive;
+
+        double[] limitSize = shrinking? columnMinWidth :
+                            columnMaxWidth;
+        while (available != 0 && wasPositive == isPositive && adjusting.size() > 0) {
             if (!handleRemainder) {
-                portion = (int)available / adjusting.size(); // negative in shrinking case
+                portion = available > 0 ? Math.floor(available / adjusting.size()) :
+                        Math.ceil(available / adjusting.size()); // negative in shrinking case
             }
             if (portion != 0) {
-                for (int i = 0; i < adjusting.size(); i++) {
-                    final int index = adjusting.get(i);
-                    final double limit = (shrinking? columnMinWidth[index] : columnMaxWidth[index])
+                for (Iterator<Integer> i = adjusting.iterator(); i.hasNext() && available != 0;) {
+                    final int index = i.next();
+                    final double limit = snapSpace(limitSize[index])
                             - columnWidths[index]; // negative in shrinking case
                     final double change = Math.abs(limit) <= Math.abs(portion)? limit : portion;
-                    columnWidths[index] += change;                
-                    //if (node.id.startsWith("debug.")) println("{if (shrinking) "vshrink" else "vgrow"}: {node.id} portion({portion})=available({available})/({sizeof adjusting}) change={change}");
+                    columnWidths[index] += change;
                     available -= change;
+                    isPositive = available >= 0.0;
                     if (Math.abs(change) < Math.abs(portion)) {
-                        adjusted.add(index);
+                        i.remove();
                     }
-                    if (available == 0) {                        
+                    if (available == 0) {
                         break;
-                    }                    
+                    }
                 }
-                for (int i = 0; i < adjusted.size(); i++) {
-                    adjusting.remove(adjusted.get(i));
-                }
-                adjusted.clear();
             } else {
                 // Handle the remainder
                 portion = (int)(available) % adjusting.size();
@@ -1722,10 +1656,7 @@
                 }
             }
         }
-               
-        for (int i = 0; i < columnWidths.length; i++) {
-            columnWidths[i] = snapSpace(columnWidths[i]);
-        }
+
         return available; // might be negative in shrinking case
     }
 
@@ -1786,6 +1717,89 @@
         return "Grid hgap="+getHgap()+", vgap="+getVgap()+", alignment="+getAlignment();
     }
 
+    private void doLayout(boolean withPositioning) {
+        final double snaphgap = snapSpace(getHgap());
+        final double snapvgap = snapSpace(getVgap());
+        final double top = snapSpace(getInsets().getTop());
+        final double bottom = snapSpace(getInsets().getBottom());
+        final double left = snapSpace(getInsets().getLeft());
+        final double right = snapSpace(getInsets().getRight());
+
+        final double width = getWidth();
+        final double height = getHeight();
+        final double contentHeight = height - top - bottom;
+        final double contentWidth = width - left - right;
+        double columnTotal = 0;
+        double rowTotal = 0;
+        computeGridMetrics();
+        
+        Orientation contentBias = getContentBias();
+        if (contentBias == null) {
+            rowTotal = adjustRowHeights(rowPrefHeight, height);
+            columnTotal = adjustColumnWidths(columnPrefWidth, width);
+        } else if (contentBias == Orientation.HORIZONTAL) {
+            columnTotal = adjustColumnWidths(columnPrefWidth, width);
+            computeRowMetrics(rowHeights.length, columnWidths);
+            rowTotal = adjustRowHeights(rowPrefHeight, height);
+        } else if (contentBias == Orientation.VERTICAL) {
+            rowTotal = adjustRowHeights(rowPrefHeight, height);
+            computeColumnMetrics(columnWidths.length, rowHeights);
+            columnTotal = adjustColumnWidths(columnPrefWidth, width);
+        }
+
+        if (withPositioning) {
+            final double x = left + computeXOffset(contentWidth, columnTotal, getAlignment().getHpos());
+            final double y = top + computeYOffset(contentHeight, rowTotal, getAlignment().getVpos());
+            for (int i = 0; i < getChildren().size(); i++) {
+                Node child = getChildren().get(i);
+                if (child.isManaged()) {
+                    int rowIndex = getNodeRowIndex(child);
+                    int columnIndex = getNodeColumnIndex(child);
+                    int colspan = getNodeColumnSpan(child);
+                    if (colspan == REMAINING) {
+                        colspan = columnWidths.length - columnIndex;
+                    }
+                    int rowspan = getNodeRowSpan(child);
+                    if (rowspan == REMAINING) {
+                        rowspan = rowHeights.length - rowIndex;
+                    }
+                    double areaX = x;
+                    for (int j = 0; j < columnIndex; j++) {
+                        areaX += columnWidths[j] + snaphgap;
+                    }
+                    double areaY = y;
+                    for (int j = 0; j < rowIndex; j++) {
+                        areaY += rowHeights[j] + snapvgap;
+                    }
+                    double areaW = columnWidths[columnIndex];
+                    for (int j = 2; j <= colspan; j++) {
+                        areaW += columnWidths[columnIndex+j-1] + snaphgap;
+                    }
+                    double areaH = rowHeights[rowIndex];
+                    for (int j = 2; j <= rowspan; j++) {
+                        areaH += rowHeights[rowIndex+j-1] + snapvgap;
+                    }
+
+                    HPos halign = getHalignment(child);
+                    VPos valign = getValignment(child);
+                    Insets margin = getMargin(child);
+                    if (margin != null && valign == VPos.BASELINE) {
+                        // The top margin has already added to rowBaseline[] in computeRowMetric()
+                        // we do not need to add it again in layoutInArea.
+                        margin = new Insets(0, margin.getRight(), margin.getBottom(), margin.getLeft());
+                    }
+                    //System.out.println("layoutNode("+child.toString()+" row/span="+rowIndex+"/"+rowspan+" col/span="+columnIndex+"/"+colspan+" area="+areaX+","+areaY+" "+areaW+"x"+areaH+""+" rowBaseline="+rowBaseline[rowIndex]);
+                    layoutInArea(child, areaX, areaY, areaW, areaH, rowBaseline[rowIndex],
+                            margin,
+                            shouldColumnFillWidth(columnIndex), shouldRowFillHeight(rowIndex),
+                            halign != null? halign : getColumnHalignment(columnIndex),
+                            valign != null? valign : getRowValignment(rowIndex));
+                }
+            }
+            layoutGridLines(x, y, rowTotal, columnTotal);
+        }
+    }
+
     /***************************************************************************
      *                                                                         *
      *                         Stylesheet Handling                             *
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/test/unit/com/sun/javafx/css/DeclarationTest.java	Tue Jun 18 12:21:58 2013 -0700
@@ -0,0 +1,108 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.sun.javafx.css;
+
+import com.sun.javafx.css.parser.CSSParser;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import javafx.scene.paint.Color;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class DeclarationTest {
+    
+    private static class Data {
+        private final Declaration d1, d2;
+        private final boolean expected;
+        Data(Declaration d1, Declaration d2, boolean expected){
+            this.d1 = d1;
+            this.d2 = d2;
+            this.expected = expected;
+        }
+        
+        @Override public String toString() {
+            return "\"" + d1 + "\" " + (expected ? "==" : "!=") + " \"" + d2 + "\"";
+        }
+    }
+    
+    public DeclarationTest(Data data) {
+        this.data = data;
+    }
+    private final Data data;
+    
+
+    @Parameters
+    public static Collection data() {
+
+        int n = 0;
+        final int GI = n++; // green inline
+        final int YI = n++; // yellow inline
+        final int GA1 = n++; // green author 1 
+        final int YA1 = n++; // yellow author 1 
+        final int GA2 = n++; // green author 2 
+        final int YA2 = n++; // yellow author 2 
+        
+        final Declaration[] DECLS = new Declaration[n];
+        
+        Stylesheet inlineSS = new Stylesheet();
+	inlineSS.setOrigin(Stylesheet.Origin.INLINE);
+                
+	DECLS[GI] = new Declaration("-fx-base", new ParsedValue<Color,Color>(Color.GREEN, null), false);
+	DECLS[YI] = new Declaration("-fx-color", new ParsedValue<Color,Color>(Color.YELLOW, null), false);
+	
+	Collections.addAll(inlineSS.getRules(),
+                    new Rule(Arrays.asList(SimpleSelector.getUniversalSelector()), Arrays.asList(DECLS[GI])),
+                    new Rule(Arrays.asList(SimpleSelector.getUniversalSelector()), Arrays.asList(DECLS[YI]))
+                );
+        
+        Stylesheet authorSS_1 = new Stylesheet();
+        authorSS_1.setOrigin(Stylesheet.Origin.AUTHOR);
+                
+	DECLS[GA1] = new Declaration("-fx-base", new ParsedValue<Color,Color>(Color.GREEN, null), false);
+	DECLS[YA1] = new Declaration("-fx-color", new ParsedValue<Color,Color>(Color.YELLOW, null), false);
+    
+	Collections.addAll(authorSS_1.getRules(),
+                    new Rule(Arrays.asList(SimpleSelector.getUniversalSelector()), Arrays.asList(DECLS[GA1])),
+                    new Rule(Arrays.asList(SimpleSelector.getUniversalSelector()), Arrays.asList(DECLS[YA1]))
+                );
+        
+	Stylesheet authorSS_2 = new Stylesheet();
+	authorSS_2.setOrigin(Stylesheet.Origin.AUTHOR);
+                
+	DECLS[GA2] = new Declaration("-fx-base", new ParsedValue<Color,Color>(Color.GREEN, null), false);
+	DECLS[YA2] = new Declaration("-fx-color", new ParsedValue<Color,Color>(Color.YELLOW, null), false);
+    
+	Collections.addAll(authorSS_2.getRules(),
+                    new Rule(Arrays.asList(SimpleSelector.getUniversalSelector()), Arrays.asList(DECLS[GA2])),
+                    new Rule(Arrays.asList(SimpleSelector.getUniversalSelector()), Arrays.asList(DECLS[YA2]))
+                );
+        
+        return Arrays.asList(new Object[] {
+            new Object[] { new Data(DECLS[GA1], DECLS[GA2], true) },
+            new Object[] { new Data(DECLS[GA1], DECLS[YA1], false) },
+            new Object[] { new Data(DECLS[GA1], DECLS[GI],  false) }
+        });
+    }
+    
+    @Test
+    public void testEquals() {
+
+        Declaration instance = data.d1;
+        Declaration obj = data.d2;
+        boolean expected = data.expected;
+        boolean actual = instance.equals(obj);
+        assertTrue(data.toString(), expected == actual);
+        
+    }
+
+}
Binary file javafx-ui-common/test/unit/com/sun/javafx/css/RT-30953-2.2.21.bss has changed
Binary file javafx-ui-common/test/unit/com/sun/javafx/css/RT-30953-2.2.4.bss has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/test/unit/com/sun/javafx/css/RT-30953.css	Tue Jun 18 12:21:58 2013 -0700
@@ -0,0 +1,226 @@
+.root {
+    -fx-background-color: red;
+    -fx-background-color: red, yellow;
+    -fx-background-image: url("duke.png");
+    -fx-background-image: url("duke.png"), url("duke.png");
+    -fx-background-insets: 1px;
+    -fx-background-insets: 1px, 2px;
+    -fx-background-position: left;
+    -fx-background-position: right;
+    -fx-background-position: 10px;
+    -fx-background-position: 10px 20px;
+    -fx-background-position: left 20px;
+    -fx-background-position: 10px 20px, 20px 10px;
+    -fx-background-position: left 20px, right 20px;
+    -fx-background-radius: 1;
+    -fx-background-radius: 1 2;
+    -fx-background-radius: 1 2 3;
+    -fx-background-radius: 1 2 3 4;
+    -fx-background-radius: 1, 1;
+    -fx-background-radius: 1 2 3 4, 1 2 3 4;
+    -fx-background-insets: 1;
+    -fx-background-insets: 1 2;
+    -fx-background-insets: 1 2 3;
+    -fx-background-insets: 1 2 3 4;
+    -fx-background-insets: 1, 1;
+    -fx-background-insets: 1 2 3 4, 1 2 3 4;    
+    -fx-background-repeat: repeat-x;
+    -fx-background-repeat: repeat-y;
+    -fx-background-repeat: repeat;
+    -fx-background-repeat: space;
+    -fx-background-repeat: round;
+    -fx-background-repeat: stretch;
+    -fx-background-repeat: no-repeat;
+    -fx-background-repeat: repeat no-repeat;
+    -fx-background-repeat: repeat-x, repeat-y;
+    -fx-background-repeat: repeat no-repeat, round space;    
+    -fx-background-size: 100px;
+    -fx-background-size: 100px 100px;
+    -fx-background-size: auto;
+    -fx-background-size: cover;
+    -fx-background-size: contain;
+    -fx-background-size: stretch;
+    -fx-background-size: stretch, contain;        
+    -fx-border-color: red;
+    -fx-border-color: red yellow;
+    -fx-border-color: red yellow green;
+    -fx-border-color: red yellow green blue;
+    -fx-border-color: red, red;
+    -fx-border-color: red yellow green blue, red yellow green blue; 
+    -fx-border-radius: 1;
+    -fx-border-radius: 1 2;
+    -fx-border-radius: 1 2 3;
+    -fx-border-radius: 1 2 3 4;
+    -fx-border-radius: 1, 1;
+    -fx-border-radius: 1 2 3 4, 1 2 3 4;
+    -fx-border-insets: 1;
+    -fx-border-insets: 1 2;
+    -fx-border-insets: 1 2 3;
+    -fx-border-insets: 1 2 3 4;
+    -fx-border-insets: 1, 1;
+    -fx-border-insets: 1 2 3 4, 1 2 3 4;        
+   -fx-border-style: solid;
+    -fx-border-style: solid phase 10;
+    -fx-border-style: dotted;
+    -fx-border-style: dashed;
+    -fx-border-style: segments(1, 2, 3);
+    -fx-border-style: solid centered;
+    -fx-border-style: solid phase 10 centered;
+    -fx-border-style: solid inside;
+    -fx-border-style: solid outside;
+    -fx-border-style: solid line-join miter 10;
+    -fx-border-style: solid line-join bevel;
+    -fx-border-style: solid line-join round;
+    -fx-border-style: solid centered line-join miter 10;
+    -fx-border-style: solid centered line-join bevel;
+    -fx-border-style: solid phase 10 centered line-join miter 10;
+    -fx-border-style: solid phase 10 centered line-join bevel;
+    -fx-border-style: solid line-cap square;
+    -fx-border-style: solid line-cap butt;
+    -fx-border-style: solid line-cap round;
+    -fx-border-style: solid centered line-cap square;
+    -fx-border-style: solid centered line-cap butt;
+    -fx-border-style: solid phase 10 centered line-cap square;
+    -fx-border-style: solid phase 10 centered line-cap butt;
+    -fx-border-style: solid line-join miter 10 line-cap square;
+    -fx-border-style: solid line-join bevel line-cap square;
+    -fx-border-style: solid phase 10 line-join bevel line-cap square;
+    -fx-border-style: solid phase 10 line-join bevel line-cap square, dashed phase 10 line-join bevel line-cap square;
+    -fx-border-width: 1;
+    -fx-border-width: 1 2;
+    -fx-border-width: 1 2 3;
+    -fx-border-width: 1 2 3 4;
+    -fx-border-width: 1, 1;
+    -fx-border-width: 1 2 3 4, 1 2 3 4;        
+    -fx-border-image-insets: 1;
+    -fx-border-image-insets: 1 2;
+    -fx-border-image-insets: 1 2 3;
+    -fx-border-image-insets: 1 2 3 4;
+    -fx-border-image-insets: 1, 1;
+    -fx-border-image-insets: 1 2 3 4, 1 2 3 4;        
+    -fx-border-image-repeat: repeat-x;
+    -fx-border-image-repeat: repeat-y;
+    -fx-border-image-repeat: repeat;
+    -fx-border-image-repeat: space;
+    -fx-border-image-repeat: round;
+    -fx-border-image-repeat: stretch;
+    -fx-border-image-repeat: no-repeat;
+    -fx-border-image-repeat: repeat no-repeat;
+    -fx-border-image-repeat: repeat-x, repeat-y;
+    -fx-border-image-repeat: repeat no-repeat, round space;     
+    -fx-border-image-slice: 10%;
+    -fx-border-image-slice: 10% fill;
+    -fx-border-image-slice: 10% 10%;
+    -fx-border-image-slice: 10% 10% 10%;
+    -fx-border-image-slice: 10% 10% 10% fill;
+    -fx-border-image-slice: 10% 10% 10% 10%;
+    -fx-border-image-slice: 10% 10% 10% 10% fill;
+    -fx-border-image-slice: 10%, 10%;
+    -fx-border-image-slice: 10% fill, 10% fill;
+    -fx-border-image-slice: 10% 10% 10% 10% fill, 10% 10% 10% 10% fill;        
+    -fx-border-image-source: url("duke.png");
+    -fx-border-image-source: url("duke.png"), url("duke.png");
+    -fx-border-image-width: 1;
+    -fx-border-image-width: 1 2;
+    -fx-border-image-width: 1 2 3;
+    -fx-border-image-width: 1 2 3 4;
+    -fx-border-image-width: 1, 1;
+    -fx-border-image-width: 1 2 3 4, 1 2 3 4;        
+    -fx-padding: 1;
+    -fx-padding: 1 2;
+    -fx-padding: 1 2 3;
+    -fx-padding: 1 2 3 4;
+    -fx-padding: 1, 1;
+    -fx-padding: 1 2 3 4, 1 2 3 4;        
+    -fx-label-padding: 1;
+    -fx-label-padding: 1 2;
+    -fx-label-padding: 1 2 3;
+    -fx-label-padding: 1 2 3 4;
+    -fx-label-padding: 1, 1;
+    -fx-label-padding: 1 2 3 4, 1 2 3 4;        
+    -fx-shape: "M150 0 L75 200 L225 200 Z";
+    -fx-font-size: 18pt;
+    -fx-font-size: 1.5em;
+    -fx-font-size: 150%;
+    -fx-font-size: xx-small;
+    -fx-font-size: x-small;
+    -fx-font-size: small;
+    -fx-font-size: medium;
+    -fx-font-size: large;
+    -fx-font-size: x-large;
+    -fx-font-size: xx-large;
+    -fx-font-size: smaller;
+    -fx-font-size: larger;
+    -fx-font-style: italic;
+    -fx-font-weight: normal;
+    -fx-font-weight: bold;
+    -fx-font-weight: bolder;
+    -fx-font-weight: lighter;
+    -fx-font-weight: inherit;
+/*    -fx-font-weight: 100;
+    -fx-font-weight: 200;
+    -fx-font-weight: 300;
+    -fx-font-weight: 400;
+    -fx-font-weight: 500;
+    -fx-font-weight: 600;
+    -fx-font-weight: 700;
+    -fx-font-weight: 800;
+    -fx-font-weight: 900;*/
+    -fx-font: 16 "Comic Sans MS";
+    -fx-font: 16 Arial;
+    -fx-font: bold 16 Arial;
+    -fx-font: italic 16 Arial;
+    -fx-font: bold italic 16 Arial;
+    -fx-font: italic bold 16 Arial;
+    -fx-stroke-dash-array: 10 20 30 40;
+    -fx-stroke-line-join: miter 45;
+    -fx-stroke-line-join: bevel;
+    -fx-stroke-line-join: round;
+    -fx-stroke-line-cap: round;
+    -fx-stroke-line-cap: square;
+    -fx-stroke-line-cap: butt;
+    -fx-stroke-type: centered;
+    -fx-stroke-type: inside;
+    -fx-stroke-type: outside;
+    -fx-font-smoothing-type: gray;
+    -fx-font-smoothing-type: lcd;
+    -fx-text-alignment: left;
+    -fx-text-alignment: center;
+    -fx-text-alignment: right;
+    -fx-text-alignment: justify;
+    -fx-text-origin: top;
+    -fx-text-origin: baseline;
+    -fx-text-origin: bottom;
+    -fx-orientation: horizontal;
+    -fx-orientation: vertical;
+    -fx-alignment: top-left;
+    -fx-alignment: top-center;
+    -fx-alignment: top-right;
+    -fx-alignment: center-left;
+    -fx-alignment: center;
+    -fx-alignment: center-right;
+    -fx-alignment: bottom-left;
+    -fx-alignment: bottom-center;
+    -fx-alignment: bottom-right;
+    -fx-alignment: baseline-left;
+    -fx-alignment: baseline-center;
+    -fx-alignment: baseline-right;
+    -fx-text-overrun: center-ellipsis;
+    -fx-text-overrun: center-word-ellipsis;
+    -fx-text-overrun: clip;
+    -fx-text-overrun: ellipsis;
+    -fx-text-overrun: leading-ellipsis;
+    -fx-text-overrun: leading-word-ellipsis;
+    -fx-text-overrun: word-ellipsis;
+    -fx-content-display: top;
+    -fx-content-display: right;
+    -fx-content-display: bottom;
+    -fx-content-display: left;
+    -fx-content-display: center;
+    -fx-content-display: graphic-only;
+    -fx-content-display: text-only;
+    -fx-hbar-policy: never;
+    -fx-hbar-policy: always;
+    -fx-hbar-policy: as-needed;
+}
+    
--- a/javafx-ui-common/test/unit/com/sun/javafx/css/RuleTest.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/test/unit/com/sun/javafx/css/RuleTest.java	Tue Jun 18 12:21:58 2013 -0700
@@ -195,7 +195,7 @@
         DataInputStream is = null;
         String[] strings = null;
         Rule expResult = null;
-        Rule result = Rule.readBinary(is, strings);
+        Rule result = Rule.readBinary(Stylesheet.BINARY_CSS_VERSION,is, strings);
         assertEquals(expResult, result);
         fail("The test case is a prototype.");
     }
--- a/javafx-ui-common/test/unit/com/sun/javafx/css/StyleConverterTest.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/test/unit/com/sun/javafx/css/StyleConverterTest.java	Tue Jun 18 12:21:58 2013 -0700
@@ -102,7 +102,7 @@
             byte[] b = new byte[]{0,0};                 
             ByteArrayInputStream bais = new ByteArrayInputStream(b); 
             DataInputStream dis = new DataInputStream(bais); 
-            StyleConverter ecv = StyleConverter.readBinary(dis,new String[]{"sun.invoke.util.Wrapper"}); 
+            StyleConverter ecv = StyleConverter.readBinary(Stylesheet.BINARY_CSS_VERSION,dis,new String[]{"sun.invoke.util.Wrapper"}); 
             assertNull(ecv);
         } catch(Exception e) {
             fail(e.getMessage());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/test/unit/com/sun/javafx/css/StyleTest.java	Tue Jun 18 12:21:58 2013 -0700
@@ -0,0 +1,91 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.sun.javafx.css;
+
+import com.sun.javafx.css.parser.CSSParser;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class StyleTest {
+    
+    private static class Data {
+        private final String s1, s2;
+        private final boolean expected;
+        Data(String s1, String s2, boolean expected){
+            this.s1 = s1;
+            this.s2 = s2;
+            this.expected = expected;
+        }
+        
+        @Override public String toString() {
+            return "\"" + s1 + "\" " + (expected ? "==" : "!=") + " \"" + s2 + "\"";
+        }
+    }
+    
+    public StyleTest(Data data) {
+        this.data = data;
+    }
+    private final Data data;
+    
+    private static Style createStyle(String stylesheetText) {
+        
+        List<Style> styles = new ArrayList<Style>();
+        Stylesheet stylesheet = CSSParser.getInstance().parse(stylesheetText);
+        Rule rule = stylesheet.getRules().get(0);
+        Selector sel = rule.getSelectors().get(0);
+        Declaration decl = rule.getDeclarations().get(0);
+        return new Style(sel, decl);
+    }
+
+    @Parameters
+    public static Collection data() {
+        
+        return Arrays.asList(new Object[] {
+            new Object[] { new Data("*.style { -fx-fill: red; }", 
+                                    "*.style { -fx-fill: red; }", true) },
+            new Object[] { new Data("*.style { -fx-fill: red; }", 
+                                    "*.bad   { -fx-fill: red; }", false) },
+            new Object[] { new Data("*.style:p { -fx-fill: red; }", 
+                                    "*.style:p { -fx-fill: red; }", true) },
+            new Object[] { new Data("*.style:p { -fx-fill: red; }", 
+                                    "*.style:q { -fx-fill: red; }", false) },
+            new Object[] { new Data("*.style:p { -fx-fill: red; }", 
+                                    "*.bad:p   { -fx-fill: red; }", false) },
+            new Object[] { new Data("*.style#c { -fx-fill: red; }", 
+                                    "*.style#c { -fx-fill: red; }", true) },
+            new Object[] { new Data("*.style#c { -fx-fill: red; }", 
+                                    "*.style#d { -fx-fill: red; }", false) },
+            new Object[] { new Data("*.style#c:p { -fx-fill: red; }", 
+                                    "*.style#c:p { -fx-fill: red; }", true) },
+            new Object[] { new Data("*.style#c:p { -fx-fill: red; }", 
+                                    "*.style#c:q { -fx-fill: red; }", false) },
+            new Object[] { new Data("*.style { -fx-fill: red; }", 
+                                    "*.style { -fx-fill: green; }", false) },
+            new Object[] { new Data("*.style { -fx-border-color: red; }", 
+                                    "*.style { -fx-fill: red; }", false) },
+        });
+    }
+    
+    @Test
+    public void testEquals() {
+
+        Style instance = createStyle(data.s1);
+        Style obj = createStyle(data.s2);
+        boolean expected = data.expected;
+        boolean actual = instance.equals(obj);
+        assertTrue(data.toString(), expected == actual);
+        
+    }
+
+}
--- a/javafx-ui-common/test/unit/com/sun/javafx/css/StylesheetTest.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/test/unit/com/sun/javafx/css/StylesheetTest.java	Tue Jun 18 12:21:58 2013 -0700
@@ -25,12 +25,21 @@
 package com.sun.javafx.css;
 
 import com.sun.javafx.css.Stylesheet.Origin;
+import com.sun.javafx.css.converters.EnumConverter;
+import com.sun.javafx.css.converters.StringConverter;
+import com.sun.javafx.css.parser.CSSParser;
 import java.net.URL;
 import java.util.Collections;
 import java.util.List;
+import javafx.geometry.Orientation;
+import javafx.geometry.Pos;
+import javafx.geometry.VPos;
 import javafx.scene.Group;
 import javafx.scene.Scene;
 import javafx.scene.shape.Rectangle;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontSmoothingType;
+import javafx.scene.text.TextAlignment;
 import javafx.stage.Stage;
 import org.junit.*;
 import static org.junit.Assert.*;
@@ -218,5 +227,128 @@
         }
         
     }
+
+    @Test
+    public void testRT_30953_parse() {
+        
+        try {
+            // RT-30953-2.2.4_33.bss was generated with javafx version 2.2.4_33
+            URL url = StylesheetTest.class.getResource("RT-30953.css");
+            if (url == null) {
+                fail("Can't find RT-30953.css");
+            }
+            
+            Stylesheet ss = CSSParser.getInstance().parse(url);
+            checkConvert(ss);
+            
+       } catch (Exception e) {
+            fail(e.toString());
+        }
+        
+    }
+    
+    @Test
+    public void testRT_30953_deserialize_from_2_2_4() {
+        
+        // RT-30953-2.2.4bss was generated with javafx version 2.2.4 from 7u10
+        Stylesheet ss = deserialize("RT-30953-2.2.4.bss");
+        checkConvert(ss);
+    }
+
+    @Test
+    public void testRT_30953_deserialize_from_2_2_21() {
+        
+        // RT-30953-2.2.21.bss was generated with javafx version 2.2.21 from 7u21
+        Stylesheet ss = deserialize("RT-30953-2.2.21.bss");
+        checkConvert(ss);
+        
+    }
+    
+    private Stylesheet deserialize(String bssFile) {
+        Stylesheet ss = null;
+        try {
+            URL url = StylesheetTest.class.getResource(bssFile);
+            if (url == null) {
+                fail(bssFile);
+            }
+            ss = Stylesheet.loadBinary(url);
+        } catch (Exception e) {
+            fail(e.toString());
+        } finally {
+            return ss;
+        }
+    }
+    
+    private void checkConvert(Stylesheet ss) {
+        Declaration decl = null;
+        StyleConverter converter = null;
+        try {
+            for (Rule r : ss.getRules()) {
+                for (Declaration d : r.getDeclarations()) {
+                    decl = d;
+                    ParsedValue pv = decl.getParsedValue();
+                    converter = pv.getConverter();
+                    if (converter == null) {
+                        
+                        if ("inherit".equals(pv.getValue())) continue;
+                        
+                        String prop = d.getProperty().toLowerCase();
+                        if ("-fx-shape".equals(prop)) {
+                            StringConverter.getInstance().convert(pv, null);
+                        } else if ("-fx-font-smoothing-type".equals(prop)) {
+                            (new EnumConverter<FontSmoothingType>(FontSmoothingType.class)).convert(pv, null);
+                        } else if ("-fx-text-alignment".equals(prop)) {
+                            (new EnumConverter<TextAlignment>(TextAlignment.class)).convert(pv, null);
+                        } else if ("-fx-alignment".equals(prop)) {
+                            (new EnumConverter<Pos>(Pos.class)).convert(pv, null);
+                        } else if ("-fx-text-origin".equals(prop)) {
+                            (new EnumConverter<VPos>(VPos.class)).convert(pv, null);
+                        } else if ("-fx-text-overrun".equals(prop)) {
+                            Class cl = null;
+                            try {
+                                cl = Class.forName("javafx.scene.control.OverrunStyle");
+                            } catch (Exception ignored) {
+                                // just means we're running ant test from javafx-ui-common    
+                            }
+                            if (cl != null) {
+                                (new EnumConverter(cl)).convert(pv, null);
+                            }
+                        } else if ("-fx-orientation".equals(prop)) {
+                            (new EnumConverter<Orientation>(Orientation.class)).convert(pv, null);
+                        } else if ("-fx-content-display".equals(prop)) {
+                            Class cl = null;
+                            try {
+                                cl = Class.forName("javafx.scene.control.CpntentDisplay");
+                            } catch (Exception ignored) {
+                                // just means we're running ant test from javafx-ui-common    
+                            }
+                            if (cl != null) {
+                                (new EnumConverter(cl)).convert(pv, null);
+                            }
+                        } else if ("-fx-hbar-policy".equals(prop)) {
+                            Class cl = null;
+                            try {
+                                cl = Class.forName("javafx.scene.control.ScrollPane.ScrollBarPolicy");
+                            } catch (Exception ignored) {
+                                // just means we're running ant test from javafx-ui-common    
+                            }
+                            if (cl != null) {
+                                (new EnumConverter(cl)).convert(pv, null);
+                            }
+                        } else {
+                            System.out.println("No converter for " + d.toString() + ". Skipped conversion.");
+                        }
+                        continue;
+                    }
+                    Object value = converter.convert(pv, Font.getDefault());
+                }
+            }
+       } catch (Exception e) {
+            if (decl == null) fail(e.toString());
+            else if (converter != null) fail(decl.getProperty() + ", " + converter + ", " + e.toString());                
+            else fail(decl.getProperty() + ", " + e.toString());
+        }
+        
+    }
     
 }
--- a/javafx-ui-common/test/unit/com/sun/javafx/css/converters/EnumConverterTest.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/test/unit/com/sun/javafx/css/converters/EnumConverterTest.java	Tue Jun 18 12:21:58 2013 -0700
@@ -8,6 +8,7 @@
 import com.sun.javafx.css.StringStore;
 import com.sun.javafx.css.StyleConverter;
 import com.sun.javafx.css.StyleableProperty;
+import com.sun.javafx.css.Stylesheet;
 import java.io.*;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -148,7 +149,7 @@
             byte[] b = new byte[]{0,0};                 
             ByteArrayInputStream bais = new ByteArrayInputStream(b); 
             DataInputStream dis = new DataInputStream(bais); 
-            StyleConverter ecv = EnumConverter.readBinary(dis,new String[]{"sun.invoke.util.Wrapper"}); 
+            StyleConverter ecv = EnumConverter.readBinary(Stylesheet.BINARY_CSS_VERSION,dis,new String[]{"sun.invoke.util.Wrapper"}); 
             // if assertions are off, then ecv will be null.
             assertNull(ecv);
         } catch (java.io.IOException ioe) {
@@ -192,7 +193,7 @@
         String[] strings = sstore.strings.toArray(new String[sstore.strings.size()]);
 //System.out.println(Arrays.toString(strings));
 //System.out.println(Arrays.toString(baos.toByteArray()));
-        StyleConverter actual = StyleConverter.readBinary(dis, strings);
+        StyleConverter actual = StyleConverter.readBinary(Stylesheet.BINARY_CSS_VERSION,dis, strings);
         
         assertEquals(expected, actual);
     }
Binary file javafx-ui-common/test/unit/com/sun/javafx/css/duke.png has changed
--- a/javafx-ui-common/test/unit/com/sun/javafx/css/parser/CSSParserTest.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/test/unit/com/sun/javafx/css/parser/CSSParserTest.java	Tue Jun 18 12:21:58 2013 -0700
@@ -173,7 +173,7 @@
             DataInputStream dis = new DataInputStream(bais);
             
             Stylesheet restored = new Stylesheet();
-            restored.readBinary(dis, stringStore.strings.toArray(new String[stringStore.strings.size()]));
+            restored.readBinary(Stylesheet.BINARY_CSS_VERSION,dis, stringStore.strings.toArray(new String[stringStore.strings.size()]));
             
             List<Rule> cssRules = stylesheet.getRules();
             List<Rule> bssRules = restored.getRules();
--- a/javafx-ui-common/test/unit/com/sun/javafx/image/ConverterTest.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/test/unit/com/sun/javafx/image/ConverterTest.java	Tue Jun 18 12:21:58 2013 -0700
@@ -45,6 +45,42 @@
 /**
  */
 public class ConverterTest {
+    static ByteBuffer heapByteBuffer(int off, int len) {
+        ByteBuffer bbuf = ByteBuffer.allocate(off + len);
+        if (off > 0) {
+            bbuf.position(off);
+            bbuf = bbuf.slice();
+        }
+        return bbuf;
+    }
+
+    static ByteBuffer directByteBuffer(int off, int len) {
+        ByteBuffer bbuf = ByteBuffer.allocateDirect(off + len);
+        if (off > 0) {
+            bbuf.position(off);
+            bbuf = bbuf.slice();
+        }
+        return bbuf;
+    }
+
+    static IntBuffer heapIntBuffer(int off, int len) {
+        IntBuffer ibuf = IntBuffer.allocate(off + len);
+        if (off > 0) {
+            ibuf.position(off);
+            ibuf = ibuf.slice();
+        }
+        return ibuf;
+    }
+
+    static IntBuffer directIntBuffer(int off, int len) {
+        IntBuffer ibuf = ByteBuffer.allocateDirect((off + len) * 4).asIntBuffer();
+        if (off > 0) {
+            ibuf.position(off);
+            ibuf = ibuf.slice();
+        }
+        return ibuf;
+    }
+
     static Color derive(Color c, double opacity) {
         return new Color(c.getRed(), c.getGreen(), c.getBlue(), c.getOpacity() * opacity);
     }
@@ -305,7 +341,7 @@
             int red   = (pixel >> rshift) & 0xff;
             int green = (pixel >> gshift) & 0xff;
             int blue  = (pixel >> bshift) & 0xff;
-            if (alpha < 255 && getter.getAlphaType() == AlphaType.PREMULTIPLIED) {
+            if (alpha > 0 && alpha < 255 && getter.getAlphaType() == AlphaType.PREMULTIPLIED) {
                 int halfa = alpha >> 1;
                 red   = (red   >= alpha) ? 255 : (red   * 255 + halfa) / alpha;
                 green = (green >= alpha) ? 255 : (green * 255 + halfa) / alpha;
@@ -501,7 +537,13 @@
 
     @Test
     public void testByteAccessors() {
-        ByteBuffer bbuf = ByteBuffer.allocate(8);
+        testByteAccessors(heapByteBuffer(0, 8));
+        testByteAccessors(heapByteBuffer(1, 8));
+        testByteAccessors(directByteBuffer(0, 8));
+        testByteAccessors(directByteBuffer(1, 8));
+    }
+
+    private void testByteAccessors(ByteBuffer bbuf) {
         byte barr[] = new byte[8];
         for (ByteFormat bfmt : ByteFormats) {
             BytePixelGetter getter = bfmt.getGetter();
@@ -524,7 +566,13 @@
 
     @Test
     public void testIntAccessors() {
-        IntBuffer ibuf = IntBuffer.allocate(2);
+        testIntAccessors(heapIntBuffer(0, 2));
+        testIntAccessors(heapIntBuffer(1, 2));
+        testIntAccessors(directIntBuffer(0, 2));
+        testIntAccessors(directIntBuffer(1, 2));
+    }
+    
+    private void testIntAccessors(IntBuffer ibuf) {
         int iarr[] = new int[2];
         for (IntFormat ifmt : IntFormats) {
             IntPixelGetter getter = ifmt.getGetter();
@@ -575,11 +623,16 @@
 
     @Test
     public void testB2BConverterTypes() {
-        ByteBuffer srchbuf = ByteBuffer.allocate(4 * TestColors.length);
-        ByteBuffer srcdbuf = ByteBuffer.allocateDirect(4 * TestColors.length);
+        testB2BConverterTypes(0);
+        testB2BConverterTypes(1);
+    }
+    
+    private void testB2BConverterTypes(int off) {
+        ByteBuffer srchbuf = heapByteBuffer(off, 4 * TestColors.length);
+        ByteBuffer srcdbuf = directByteBuffer(off, 4 * TestColors.length);
         byte srcarr[] = new byte[4 * TestColors.length];
-        ByteBuffer dsthbuf = ByteBuffer.allocate(4 * TestColors.length);
-        ByteBuffer dstdbuf = ByteBuffer.allocateDirect(4 * TestColors.length);
+        ByteBuffer dsthbuf = heapByteBuffer(off, 4 * TestColors.length);
+        ByteBuffer dstdbuf = directByteBuffer(off, 4 * TestColors.length);
         byte dstarr[] = new byte[4 * TestColors.length];
         for (ByteFormat bfmtgetter : ByteFormats) {
             BytePixelGetter bpg = bfmtgetter.getGetter();
@@ -649,11 +702,16 @@
 
     @Test
     public void testB2IConverterTypes() {
-        ByteBuffer srchbuf = ByteBuffer.allocate(4 * TestColors.length);
-        ByteBuffer srcdbuf = ByteBuffer.allocateDirect(4 * TestColors.length);
+        testB2IConverterTypes(0);
+        testB2IConverterTypes(1);
+    }
+
+    private void testB2IConverterTypes(int off) {
+        ByteBuffer srchbuf = heapByteBuffer(off, 4 * TestColors.length);
+        ByteBuffer srcdbuf = directByteBuffer(off, 4 * TestColors.length);
         byte srcarr[] = new byte[4 * TestColors.length];
-        IntBuffer dsthbuf = IntBuffer.allocate(TestColors.length);
-        IntBuffer dstdbuf = IntBuffer.allocate(TestColors.length);
+        IntBuffer dsthbuf = heapIntBuffer(off, TestColors.length);
+        IntBuffer dstdbuf = directIntBuffer(off,TestColors.length);
         int dstarr[] = new int[TestColors.length];
         for (ByteFormat bfmtgetter : ByteFormats) {
             BytePixelGetter bpg = bfmtgetter.getGetter();
@@ -722,11 +780,16 @@
 
     @Test
     public void testI2BConverterTypes() {
-        IntBuffer srchbuf = IntBuffer.allocate(TestColors.length);
-        IntBuffer srcdbuf = IntBuffer.allocate(TestColors.length);
+        testI2BConverterTypes(0);
+        testI2BConverterTypes(1);
+    }
+
+    private void testI2BConverterTypes(int off) {
+        IntBuffer srchbuf = heapIntBuffer(off, TestColors.length);
+        IntBuffer srcdbuf = directIntBuffer(off, TestColors.length);
         int srcarr[] = new int[TestColors.length];
-        ByteBuffer dsthbuf = ByteBuffer.allocate(4 * TestColors.length);
-        ByteBuffer dstdbuf = ByteBuffer.allocateDirect(4 * TestColors.length);
+        ByteBuffer dsthbuf = heapByteBuffer(off, 4 * TestColors.length);
+        ByteBuffer dstdbuf = directByteBuffer(off, 4 * TestColors.length);
         byte dstarr[] = new byte[4 * TestColors.length];
         for (IntFormat ifmtgetter : IntFormats) {
             IntPixelGetter ipg = ifmtgetter.getGetter();
@@ -795,11 +858,16 @@
 
     @Test
     public void testI2IConverterTypes() {
-        IntBuffer srchbuf = IntBuffer.allocate(TestColors.length);
-        IntBuffer srcdbuf = IntBuffer.allocate(TestColors.length);
+        testI2IConverterTypes(0);
+        testI2IConverterTypes(1);
+    }
+
+    private void testI2IConverterTypes(int off) {
+        IntBuffer srchbuf = heapIntBuffer(off, TestColors.length);
+        IntBuffer srcdbuf = directIntBuffer(off, TestColors.length);
         int srcarr[] = new int[TestColors.length];
-        IntBuffer dsthbuf = IntBuffer.allocate(TestColors.length);
-        IntBuffer dstdbuf = IntBuffer.allocate(TestColors.length);
+        IntBuffer dsthbuf = heapIntBuffer(off, TestColors.length);
+        IntBuffer dstdbuf = directIntBuffer(off, TestColors.length);
         int dstarr[] = new int[TestColors.length];
         for (IntFormat ifmtgetter : IntFormats) {
             IntPixelGetter ipg = ifmtgetter.getGetter();
--- a/javafx-ui-common/test/unit/javafx/scene/Parent_recomputeBounds_Test.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-common/test/unit/javafx/scene/Parent_recomputeBounds_Test.java	Tue Jun 18 12:21:58 2013 -0700
@@ -25,6 +25,7 @@
 
 package javafx.scene;
 
+import javafx.scene.transform.Rotate;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import javafx.geometry.Bounds;
@@ -331,4 +332,47 @@
         assertEquals(300, b.getWidth(), 0.0001);
         assertEquals(300, b.getHeight(), 0.0001);
     }
+
+    @Test
+    public void transformedBoundsCalculationShouldNotInfluenceUntransformed() {
+        final Group g = new Group();
+        final Rectangle lt = new Rectangle(100, 100, 100, 100);
+        final Rectangle rt = new Rectangle(200, 100, 100, 100);
+        final Rectangle lb = new Rectangle(100, 200, 100, 100);
+        final Rectangle rb = new Rectangle(200, 200, 100, 100);
+        final Rectangle rm1 = new Rectangle(150, 150, 50, 50);
+        final Rectangle rm2 = new Rectangle(150, 150, 50, 50);
+        Bounds b;
+
+        g.getChildren().addAll(lt, rt, lb, rb, rm1, rm2);
+        for (int i = 0; i < 20; i++) {
+            g.getChildren().add(new Rectangle(150 + i, 150 + i, 50 + i, 50 + i));
+        }
+
+        b = g.getBoundsInLocal();
+        assertEquals(100, b.getMinX(), 0.0001);
+        assertEquals(100, b.getMinY(), 0.0001);
+        assertEquals(200, b.getWidth(), 0.0001);
+        assertEquals(200, b.getHeight(), 0.0001);
+
+        g.getTransforms().add(new Rotate(45));
+
+        lt.setX(50);
+        rt.setX(250);
+        lb.setY(250);
+        rb.setX(220);
+        rm1.setY(50);
+        rm2.setX(151);
+        rm2.setY(151);
+
+        // this call gets transformed Parent bounds and shouldn't clear the
+        // Parent's dirty children list
+        g.getBoundsInParent();
+
+        b = g.getBoundsInLocal();
+        assertEquals(50, b.getMinX(), 0.0001);
+        assertEquals(50, b.getMinY(), 0.0001);
+        assertEquals(300, b.getWidth(), 0.0001);
+        assertEquals(300, b.getHeight(), 0.0001);
+    }
 }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ContextMenuContent.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ContextMenuContent.java	Tue Jun 18 12:21:58 2013 -0700
@@ -1184,6 +1184,7 @@
             if (item instanceof CheckMenuItem) {
                 CheckMenuItem checkItem = (CheckMenuItem)item;
                 checkItem.setSelected(!checkItem.isSelected());
+                getParent().impl_processCSS(false);
             } else if (item instanceof RadioMenuItem) {
                 // this is a radio button. If there is a toggleGroup specified, we
                 // simply set selected to true. If no toggleGroup is specified, we
@@ -1191,6 +1192,7 @@
                 // exclusivity when no toggleGroup is set.
                 final RadioMenuItem radioItem = (RadioMenuItem) item;
                 radioItem.setSelected(radioItem.getToggleGroup() != null ? true : !radioItem.isSelected());
+                getParent().impl_processCSS(false);
             }
 
             // fire the action before hiding the menu
--- a/javafx-ui-controls/src/javafx/scene/chart/CategoryAxis.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/chart/CategoryAxis.java	Tue Jun 18 12:21:58 2013 -0700
@@ -202,9 +202,11 @@
     // -------------- CONSTRUCTORS -------------------------------------------------------------------------------------
 
     /**
-     * Create a auto-ranging category axis
+     * Create a auto-ranging category axis with an empty list of categories.
      */
-    public CategoryAxis() { }
+    public CategoryAxis() { 
+        this(FXCollections.<String>observableArrayList());
+    }
 
     /**
      * Create a category axis with the given categories. This will not auto-range but be fixed with the given categories.
--- a/javafx-ui-controls/test/javafx/scene/chart/CategoryAxisTest.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/chart/CategoryAxisTest.java	Tue Jun 18 12:21:58 2013 -0700
@@ -55,15 +55,13 @@
         assertTrue(axis.isGapStartAndEnd());
     }
 
-    @Test public void defaultCategoriesIsNull() {
-        assertNull(axis.getCategories());
-    }
-
     @Test public void defaultCategorySpacing() {
         assertEquals(axis.getCategorySpacing(), 1.0 , 0.0);
     }
 
-
+    @Test public void noArgConstructorSetsNonNullCategories() {
+        assertNotNull(axis.getCategories());
+    }
 
 
     /*********************************************************************
--- a/test-stub-toolkit/src/com/sun/javafx/pgstub/StubFilterable.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/test-stub-toolkit/src/com/sun/javafx/pgstub/StubFilterable.java	Tue Jun 18 12:21:58 2013 -0700
@@ -52,6 +52,11 @@
     }
 
     @Override
+    public float getPixelScale() {
+        return image.getPixelScale();
+    }
+
+    @Override
     public void flush() {
     }
 
--- a/test-stub-toolkit/src/com/sun/javafx/pgstub/StubPlatformImage.java	Thu Jun 06 08:14:21 2013 -0700
+++ b/test-stub-toolkit/src/com/sun/javafx/pgstub/StubPlatformImage.java	Tue Jun 18 12:21:58 2013 -0700
@@ -47,6 +47,11 @@
         return frame;
     }
 
+    @Override
+    public float getPixelScale() {
+        return 1.0f;
+    }
+
     public StubImageLoader getImageLoader() {
         return imageLoader;
     }