changeset 1466:949780327b1e

merge
author Martin Sladecek <martin.sladecek@oracle.com>
date Thu, 28 Jun 2012 12:36:02 +0200
parents ce19b9bed224 6f2d238b4c8b
children eb1d9eb2e3bc
files javafx-ui-common/src/javafx/scene/input/ContextMenuEvent.java javafx-ui-common/src/javafx/scene/input/DragEvent.java javafx-ui-common/src/javafx/scene/input/GestureEvent.java javafx-ui-common/src/javafx/scene/input/MouseEvent.java javafx-ui-common/src/javafx/scene/input/TouchPoint.java javafx-ui-common/test/unit/javafx/scene/input/TouchPoint_builder_Test.java
diffstat 95 files changed, 5932 insertions(+), 768 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Jun 28 12:35:17 2012 +0200
+++ b/.hgtags	Thu Jun 28 12:36:02 2012 +0200
@@ -31,3 +31,4 @@
 72bd9ac175004058c2503ed21c975a583d399836 2.2-b10
 85b700eea97b1307cd043a4eac6ebb6dfd64f8f5 2.2-b11
 348de34f8273c417ecd0131e958c8c4fea6af8a7 2.2-b12
+00a63ce77e97aa5c1e15a3c150a44dd5cce82bf5 2.2-b13
--- a/javafx-ui-common/src/com/sun/javafx/Utils.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/com/sun/javafx/Utils.java	Thu Jun 28 12:36:02 2012 +0200
@@ -27,7 +27,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Locale;
 
 import javafx.geometry.BoundingBox;
 import javafx.geometry.Bounds;
@@ -40,8 +39,10 @@
 import javafx.scene.paint.Color;
 import javafx.scene.paint.Stop;
 import javafx.stage.Screen;
+import javafx.stage.Stage;
 import javafx.stage.Window;
-import com.sun.javafx.PlatformUtil;
+
+import com.sun.javafx.stage.StageHelper;
 
 /**
  * Some basic utilities which need to be in java (for shifting operations or
@@ -597,7 +598,10 @@
 
         // ...and then we get the bounds of this screen
         final Screen currentScreen = getScreen(parent);
-        final Rectangle2D screenBounds = currentScreen.getVisualBounds();
+        final Rectangle2D screenBounds =
+                hasFullScreenStage(currentScreen)
+                        ? currentScreen.getBounds()
+                        : currentScreen.getVisualBounds();
 
         // test if this layout will force the node to appear outside
         // of the screens bounds. If so, we must reposition the item to a better position.
@@ -797,6 +801,18 @@
         }
     }
 
+    public static boolean hasFullScreenStage(final Screen screen) {
+        final List<Stage> allStages = StageHelper.getStages();
+
+        for (final Stage stage: allStages) {
+            if (stage.isFullScreen() && (getScreen(stage) == screen)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     /*
      * Returns true if the primary Screen has VGA dimensions, in landscape or portrait mode.
      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/AlphaType.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+public enum AlphaType {
+    OPAQUE,
+    PREMULTIPLIED,
+    NONPREMULTIPLIED
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/BytePixelAccessor.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+public interface BytePixelAccessor
+    extends BytePixelGetter, BytePixelSetter
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/BytePixelGetter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+import java.nio.ByteBuffer;
+
+public interface BytePixelGetter extends PixelGetter<ByteBuffer> {
+    public int getArgb(byte arr[], int offset);
+    public int getArgbPre(byte arr[], int offset);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/BytePixelSetter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+import java.nio.ByteBuffer;
+
+public interface BytePixelSetter extends PixelSetter<ByteBuffer> {
+    public void setArgb(byte arr[], int offset, int argb);
+    public void setArgbPre(byte arr[], int offset, int argbpre);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/ByteToBytePixelConverter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+import java.nio.ByteBuffer;
+
+public interface ByteToBytePixelConverter
+    extends PixelConverter<ByteBuffer, ByteBuffer>
+{
+    public void convert(byte       srcarr[], int srcoff, int srcscanbytes,
+                        byte       dstarr[], int dstoff, int dstscanbytes,
+                        int w, int h);
+
+    public void convert(ByteBuffer srcbuf,   int srcoff, int srcscanbytes,
+                        byte       dstarr[], int dstoff, int dstscanbytes,
+                        int w, int h);
+
+    public void convert(byte       srcarr[], int srcoff, int srcscanbytes,
+                        ByteBuffer dstbuf,   int dstoff, int dstscanbytes,
+                        int w, int h);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/ByteToIntPixelConverter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+public interface ByteToIntPixelConverter
+    extends PixelConverter<ByteBuffer, IntBuffer>
+{
+    public void convert(byte srcarr[], int srcoff, int srcscanbytes,
+                        int  dstarr[], int dstoff, int dstscanints,
+                        int w, int h);
+
+    public void convert(ByteBuffer srcbuf,   int srcoff, int srcscanbytes,
+                        int        dstarr[], int dstoff, int dstscanints,
+                        int w, int h);
+
+    public void convert(byte      srcarr[], int srcoff, int srcscanbytes,
+                        IntBuffer dstbuf,   int dstoff, int dstscanints,
+                        int w, int h);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/IntPixelAccessor.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+public interface IntPixelAccessor
+    extends IntPixelGetter, IntPixelSetter
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/IntPixelGetter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+import java.nio.IntBuffer;
+
+public interface IntPixelGetter extends PixelGetter<IntBuffer> {
+    public int getArgb(int arr[], int offset);
+    public int getArgbPre(int arr[], int offset);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/IntPixelSetter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+import java.nio.IntBuffer;
+
+public interface IntPixelSetter extends PixelSetter<IntBuffer> {
+    public void setArgb(int arr[], int offset, int argb);
+    public void setArgbPre(int arr[], int offset, int argbpre);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/IntToBytePixelConverter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+public interface IntToBytePixelConverter
+    extends PixelConverter<IntBuffer, ByteBuffer>
+{
+    public void convert(int  srcarr[], int srcoff, int srcscanints,
+                        byte dstarr[], int dstoff, int dstscanbytes,
+                        int w, int h);
+
+    public void convert(IntBuffer srcbuf,   int srcoff, int srcscanints,
+                        byte      dstarr[], int dstoff, int dstscanbytes,
+                        int w, int h);
+
+    public void convert(int        srcarr[], int srcoff, int srcscanints,
+                        ByteBuffer dstbuf,   int dstoff, int dstscanbytes,
+                        int w, int h);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/IntToIntPixelConverter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+import java.nio.IntBuffer;
+
+public interface IntToIntPixelConverter
+    extends PixelConverter<IntBuffer, IntBuffer>
+{
+    public void convert(int srcarr[], int srcoff, int srcscanints,
+                        int dstarr[], int dstoff, int dstscanints,
+                        int w, int h);
+
+    public void convert(IntBuffer srcbuf,   int srcoff, int srcscanints,
+                        int       dstarr[], int dstoff, int dstscanints,
+                        int w, int h);
+
+    public void convert(int       srcarr[], int srcoff, int srcscanints,
+                        IntBuffer dstbuf,   int dstoff, int dstscanints,
+                        int w, int h);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/PixelAccessor.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+import java.nio.Buffer;
+
+public interface PixelAccessor<T extends Buffer>
+    extends PixelGetter<T>, PixelSetter<T>
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/PixelConverter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+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,
+                        int w, int h);
+
+    public PixelGetter<T> getGetter();
+    public PixelSetter<U> getSetter();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/PixelGetter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+import java.nio.Buffer;
+
+public interface PixelGetter<T extends Buffer> {
+    public AlphaType getAlphaType();
+    public int getNumElements();
+
+    public int getArgb(T buf, int offset);
+    public int getArgbPre(T buf, int offset);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/PixelSetter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+import java.nio.Buffer;
+
+public interface PixelSetter<T extends Buffer> {
+    public AlphaType getAlphaType();
+    public int getNumElements();
+
+    public void setArgb(T buf, int offset, int argb);
+    public void setArgbPre(T buf, int offset, int argbpre);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/PixelUtils.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,288 @@
+/*
+ * 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;
+
+import com.sun.javafx.image.impl.ByteBgra;
+import com.sun.javafx.image.impl.ByteBgraPre;
+import com.sun.javafx.image.impl.ByteRgb;
+import com.sun.javafx.image.impl.General;
+import com.sun.javafx.image.impl.IntArgb;
+import com.sun.javafx.image.impl.IntArgbPre;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import javafx.scene.image.PixelFormat;
+import javafx.scene.image.WritablePixelFormat;
+
+public class PixelUtils {
+    private PixelUtils() {}
+
+    public static int RgbToGray(int r, int g, int b) {
+        return (int) (r * .3 + g * .59 + b * .11);
+    }
+
+    public static int RgbToGray(int xrgb) {
+        return RgbToGray((xrgb >> 16) & 0xff,
+                         (xrgb >>  8) & 0xff,
+                         (xrgb      ) & 0xff);
+    }
+
+    public static int NonPretoPre(int nonpre, int alpha) {
+        if (alpha == 0xff) return nonpre;
+        if (alpha == 0x00) return 0;
+        return (nonpre * alpha + 0x7f) / 0xff;
+    }
+
+    public static int PreToNonPre(int pre, int alpha) {
+        if (alpha == 0xff || alpha == 0x00) return pre;
+        return (pre >= alpha) ? 0xff : (pre * 0xff + (alpha >> 1)) / alpha;
+    }
+
+    public static int NonPretoPre(int nonpre) {
+        int a = nonpre >>> 24;
+        if (a == 0xff) return nonpre;
+        if (a == 0x00) return 0;
+        int r = (nonpre >> 16) & 0xff;
+        int g = (nonpre >>  8) & 0xff;
+        int b = (nonpre      ) & 0xff;
+        r = (r * a + 0x7f) / 0xff;
+        g = (g * a + 0x7f) / 0xff;
+        b = (b * a + 0x7f) / 0xff;
+        return (a << 24) | (r << 16) | (g << 8) | b;
+    }
+
+    public static int PretoNonPre(int pre) {
+        int a = pre >>> 24;
+        if (a == 0xff || a == 0x00) return pre;
+        int r = (pre >> 16) & 0xff;
+        int g = (pre >>  8) & 0xff;
+        int b = (pre      ) & 0xff;
+        int halfa = a >> 1;
+        r = (r >= a) ? 0xff : (r * 0xff + halfa) / a;
+        g = (g >= a) ? 0xff : (g * 0xff + halfa) / a;
+        b = (b >= a) ? 0xff : (b * 0xff + halfa) / a;
+        return (a << 24) | (r << 16) | (g << 8) | b;
+    }
+
+    public static BytePixelGetter getByteGetter(PixelFormat<ByteBuffer> pf) {
+        switch (pf.getType()) {
+            case BYTE_BGRA:
+                return ByteBgra.getter;
+            case BYTE_BGRA_PRE:
+                return ByteBgraPre.getter;
+            case BYTE_RGB:
+                return ByteRgb.getter;
+            case INT_ARGB:
+            case INT_ARGB_PRE:
+                // Impossible
+        }
+        return null;
+    }
+
+    public static IntPixelGetter getIntGetter(PixelFormat<IntBuffer> pf) {
+        switch (pf.getType()) {
+            case INT_ARGB:
+                return IntArgb.getter;
+            case INT_ARGB_PRE:
+                return IntArgbPre.getter;
+            case BYTE_BGRA:
+            case BYTE_BGRA_PRE:
+            case BYTE_RGB:
+                // Impossible
+        }
+        return null;
+    }
+
+    public static <T extends Buffer> PixelGetter<T> getGetter(PixelFormat<T> pf) {
+        switch (pf.getType()) {
+            case BYTE_BGRA:
+                return (PixelGetter<T>) ByteBgra.getter;
+            case BYTE_BGRA_PRE:
+                return (PixelGetter<T>) ByteBgraPre.getter;
+            case INT_ARGB:
+                return (PixelGetter<T>) IntArgb.getter;
+            case INT_ARGB_PRE:
+                return (PixelGetter<T>) IntArgbPre.getter;
+            case BYTE_RGB:
+                return (PixelGetter<T>) ByteRgb.getter;
+        }
+        return null;
+    }
+
+    public static BytePixelSetter getByteSetter(WritablePixelFormat<ByteBuffer> pf) {
+        switch (pf.getType()) {
+            case BYTE_BGRA:
+                return ByteBgra.setter;
+            case BYTE_BGRA_PRE:
+                return ByteBgraPre.setter;
+            case INT_ARGB:
+            case INT_ARGB_PRE:
+            case BYTE_RGB:
+                // Impossible
+        }
+        return null;
+    }
+
+    public static IntPixelSetter getIntSetter(WritablePixelFormat<IntBuffer> pf) {
+        switch (pf.getType()) {
+            case INT_ARGB:
+                return IntArgb.setter;
+            case INT_ARGB_PRE:
+                return IntArgbPre.setter;
+            case BYTE_BGRA:
+            case BYTE_BGRA_PRE:
+            case BYTE_RGB:
+                // Impossible
+        }
+        return null;
+    }
+
+    public static <T extends Buffer> PixelSetter<T> getSetter(WritablePixelFormat<T> pf) {
+        switch (pf.getType()) {
+            case BYTE_BGRA:
+                return (PixelSetter<T>) ByteBgra.setter;
+            case BYTE_BGRA_PRE:
+                return (PixelSetter<T>) ByteBgraPre.setter;
+            case INT_ARGB:
+                return (PixelSetter<T>) IntArgb.setter;
+            case INT_ARGB_PRE:
+                return (PixelSetter<T>) IntArgbPre.setter;
+            case BYTE_RGB:
+                // Impossible
+        }
+        return null;
+    }
+
+    public static <T extends Buffer, U extends Buffer>
+        PixelConverter<T, U> getConverter(PixelGetter<T> src, PixelSetter<U> dst)
+    {
+        if (src instanceof BytePixelGetter) {
+            if (dst instanceof BytePixelSetter) {
+                return (PixelConverter<T, U>)
+                    getB2BConverter((BytePixelGetter) src, (BytePixelSetter) dst);
+            } else {
+                return (PixelConverter<T, U>)
+                    getB2IConverter((BytePixelGetter) src, (IntPixelSetter) dst);
+            }
+        } else {
+            if (dst instanceof BytePixelSetter) {
+                return (PixelConverter<T, U>)
+                    getI2BConverter((IntPixelGetter) src, (BytePixelSetter) dst);
+            } else {
+                return (PixelConverter<T, U>)
+                    getI2IConverter((IntPixelGetter) src, (IntPixelSetter) dst);
+            }
+        }
+    }
+
+    public static ByteToBytePixelConverter
+        getB2BConverter(PixelGetter<ByteBuffer> src, PixelSetter<ByteBuffer> dst)
+    {
+        if (src ==        ByteBgra.getter) {
+            if (dst ==               ByteBgra.setter) {
+                return    ByteBgra.ToByteBgraConverter;
+            } else if (dst ==        ByteBgraPre.setter) {
+                return    ByteBgra.ToByteBgraPreConverter;
+            }
+        } else if (src == ByteBgraPre.getter) {
+            if (dst ==                  ByteBgra.setter) {
+                return    ByteBgraPre.ToByteBgraConverter;
+            } else if (dst ==           ByteBgraPre.setter) {
+                return    ByteBgraPre.ToByteBgraPreConverter;
+            }
+        } else if (src == ByteRgb.getter) {
+            if (dst ==              ByteBgra.setter) {
+                return    ByteRgb.ToByteBgraConverter;
+            } else if (dst ==       ByteBgraPre.setter) {
+                return    ByteRgb.ToByteBgraPreConverter;
+            }
+        }
+        return General.create((BytePixelGetter) src, (BytePixelSetter) dst);
+    }
+
+    public static ByteToIntPixelConverter
+        getB2IConverter(PixelGetter<ByteBuffer> src, PixelSetter<IntBuffer> dst)
+    {
+        if (src ==        ByteBgra.getter) {
+            if (dst ==               IntArgb.setter) {
+                return    ByteBgra.ToIntArgbConverter;
+            } else if (dst ==        IntArgbPre.setter) {
+                return    ByteBgra.ToIntArgbPreConverter;
+            }
+        } else if (src == ByteBgraPre.getter) {
+            if (dst ==                  IntArgb.setter) {
+                return    ByteBgraPre.ToIntArgbConverter;
+            } else if (dst ==           IntArgbPre.setter) {
+                return    ByteBgraPre.ToIntArgbPreConverter;
+            }
+        } else if (src == ByteRgb.getter) {
+            if (dst ==              IntArgb.setter) {
+                return    ByteRgb.ToIntArgbConverter;
+            } else if (dst ==       IntArgbPre.setter) {
+                return    ByteRgb.ToIntArgbPreConverter;
+            }
+        }
+        return General.create((BytePixelGetter) src, (IntPixelSetter) dst);
+    }
+
+    public static IntToBytePixelConverter
+        getI2BConverter(PixelGetter<IntBuffer> src, PixelSetter<ByteBuffer> dst)
+    {
+        if (src ==        IntArgb.getter) {
+            if (dst ==              ByteBgra.setter) {
+                return    IntArgb.ToByteBgraConverter;
+            } else if (dst ==       ByteBgraPre.setter) {
+                return    IntArgb.ToByteBgraPreConverter;
+            }
+        } else if (src == IntArgbPre.getter) {
+            if (dst ==                 ByteBgra.setter) {
+                return    IntArgbPre.ToByteBgraConverter;
+            } else if (dst ==          ByteBgraPre.setter) {
+                return    IntArgbPre.ToByteBgraPreConverter;
+            }
+        }
+        return General.create((IntPixelGetter) src, (BytePixelSetter) dst);
+    }
+
+    public static IntToIntPixelConverter
+        getI2IConverter(PixelGetter<IntBuffer> src, PixelSetter<IntBuffer> dst)
+    {
+        if (src ==        IntArgb.getter) {
+            if (dst ==              IntArgb.setter) {
+                return    IntArgb.ToIntArgbConverter;
+            } else if (dst ==       IntArgbPre.setter) {
+                return    IntArgb.ToIntArgbPreConverter;
+            }
+        } else if (src == IntArgbPre.getter) {
+            if (dst ==                 IntArgb.setter) {
+                return    IntArgbPre.ToIntArgbConverter;
+            } else if (dst ==          IntArgbPre.setter) {
+                return    IntArgbPre.ToIntArgbPreConverter;
+            }
+        }
+        return General.create((IntPixelGetter) src, (IntPixelSetter) dst);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/BaseByteToByteConverter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,278 @@
+/*
+ * 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 com.sun.javafx.image.BytePixelAccessor;
+import com.sun.javafx.image.BytePixelGetter;
+import com.sun.javafx.image.BytePixelSetter;
+import com.sun.javafx.image.ByteToBytePixelConverter;
+import java.nio.ByteBuffer;
+
+abstract class BaseByteToByteConverter
+    implements ByteToBytePixelConverter
+{
+    protected final BytePixelGetter getter;
+    protected final BytePixelSetter setter;
+    protected final int nSrcElems;
+    protected final int nDstElems;
+
+    BaseByteToByteConverter(BytePixelGetter getter, BytePixelSetter setter) {
+        this.getter = getter;
+        this.setter = setter;
+        this.nSrcElems = getter.getNumElements();
+        this.nDstElems = setter.getNumElements();
+    }
+
+    @Override
+    public final BytePixelGetter getGetter() {
+        return getter;
+    }
+
+    @Override
+    public final BytePixelSetter getSetter() {
+        return setter;
+    }
+
+    abstract void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                            byte dstarr[], int dstoff, int dstscanbytes,
+                            int w, int h);
+
+    abstract void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                            ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                            int w, int h);
+
+    @Override
+    public final void convert(byte srcarr[], int srcoff, int srcscanbytes,
+                              byte dstarr[], int dstoff, int dstscanbytes,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanbytes == w * nSrcElems &&
+            dstscanbytes == w * nDstElems)
+        {
+            w *= h;
+            h = 1;
+        }
+        doConvert(srcarr, srcoff, srcscanbytes,
+                  dstarr, dstoff, dstscanbytes,
+                  w, h);
+    }
+
+    @Override
+    public final void convert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                              ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanbytes == w * nSrcElems &&
+            dstscanbytes == w * nDstElems)
+        {
+            w *= h;
+            h = 1;
+        }
+        if (srcbuf.hasArray() && dstbuf.hasArray()) {
+            doConvert(srcbuf.array(), srcoff, srcscanbytes,
+                      dstbuf.array(), dstoff, dstscanbytes,
+                      w, h);
+        } else {
+            doConvert(srcbuf, srcoff, srcscanbytes,
+                      dstbuf, dstoff, dstscanbytes,
+                      w, h);
+        }
+    }
+
+    @Override
+    public final void convert(ByteBuffer srcbuf,   int srcoff, int srcscanbytes,
+                              byte       dstarr[], int dstoff, int dstscanbytes,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanbytes == w * nSrcElems &&
+            dstscanbytes == w * nDstElems)
+        {
+            w *= h;
+            h = 1;
+        }
+        if (srcbuf.hasArray()) {
+            doConvert(srcbuf.array(), srcoff, srcscanbytes,
+                      dstarr, dstoff, dstscanbytes,
+                      w, h);
+        } else {
+            ByteBuffer dstbuf = ByteBuffer.wrap(dstarr);
+            doConvert(srcbuf, srcoff, srcscanbytes,
+                      dstbuf, dstoff, dstscanbytes,
+                      w, h);
+        }
+    }
+
+    @Override
+    public final void convert(byte       srcarr[], int srcoff, int srcscanbytes,
+                              ByteBuffer dstbuf,   int dstoff, int dstscanbytes,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanbytes == w * nSrcElems &&
+            dstscanbytes == w * nDstElems)
+        {
+            w *= h;
+            h = 1;
+        }
+        if (dstbuf.hasArray()) {
+            doConvert(srcarr, srcoff, srcscanbytes,
+                      dstbuf.array(), dstbuf.arrayOffset(), dstscanbytes,
+                      w, h);
+        } else {
+            ByteBuffer srcbuf = ByteBuffer.wrap(srcarr);
+            doConvert(srcbuf, srcoff, srcscanbytes,
+                      dstbuf, dstoff, dstscanbytes,
+                      w, h);
+        }
+    }
+
+    static ByteToBytePixelConverter create(BytePixelAccessor fmt) {
+        return new ByteAnyToSameConverter(fmt);
+    }
+
+    static class ByteAnyToSameConverter extends BaseByteToByteConverter {
+        ByteAnyToSameConverter(BytePixelAccessor fmt) {
+            super(fmt, fmt);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       byte dstarr[], int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            while (--h >= 0) {
+                System.arraycopy(srcarr, srcoff, dstarr, dstoff, w * nSrcElems);
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            int srclimit = srcbuf.limit();
+            int origsrcpos = srcbuf.position();
+            int origdstpos = dstbuf.position();
+            try {
+                while (--h >= 0) {
+                    int newlimit = srcoff + w * nSrcElems;
+                    if (newlimit > srclimit) {
+                        throw new IndexOutOfBoundsException("" + srclimit);
+                    }
+                    srcbuf.limit(newlimit);
+                    srcbuf.position(srcoff);
+                    dstbuf.position(dstoff);
+                    dstbuf.put(srcbuf);
+                    srcoff += srcscanbytes;
+                    dstoff += dstscanbytes;
+                }
+            } finally {
+                srcbuf.limit(srclimit);
+                srcbuf.position(origsrcpos);
+                dstbuf.position(origdstpos);
+            }
+        }
+    }
+
+    public static ByteToBytePixelConverter
+        createReorderer(BytePixelGetter getter, BytePixelSetter setter,
+                        int c0, int c1, int c2, int c3)
+    {
+        return new FourByteReorderer(getter, setter, c0, c1, c2, c3);
+    }
+
+    static class FourByteReorderer extends BaseByteToByteConverter {
+        private final int c0, c1, c2, c3;
+
+        FourByteReorderer(BytePixelGetter getter, BytePixelSetter setter,
+                          int c0, int c1, int c2, int c3)
+        {
+            super(getter, setter);
+            this.c0 = c0;
+            this.c1 = c1;
+            this.c2 = c2;
+            this.c3 = c3;
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       byte dstarr[], int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    // load all then store in case the buffers point to
+                    // the same memory
+                    byte b0 = srcarr[srcoff + c0];
+                    byte b1 = srcarr[srcoff + c1];
+                    byte b2 = srcarr[srcoff + c2];
+                    byte b3 = srcarr[srcoff + c3];
+                    dstarr[dstoff++] = b0;
+                    dstarr[dstoff++] = b1;
+                    dstarr[dstoff++] = b2;
+                    dstarr[dstoff++] = b3;
+                    srcoff += 4;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    // load all then store in case the buffers point to
+                    // the same memory
+                    byte b0 = srcbuf.get(srcoff + c0);
+                    byte b1 = srcbuf.get(srcoff + c1);
+                    byte b2 = srcbuf.get(srcoff + c2);
+                    byte b3 = srcbuf.get(srcoff + c3);
+                    dstbuf.put(dstoff    , b0);
+                    dstbuf.put(dstoff + 1, b1);
+                    dstbuf.put(dstoff + 2, b2);
+                    dstbuf.put(dstoff + 3, b3);
+                    srcoff += 4;
+                    dstoff += 4;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/BaseByteToIntConverter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,152 @@
+/*
+ * 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 com.sun.javafx.image.BytePixelGetter;
+import com.sun.javafx.image.ByteToIntPixelConverter;
+import com.sun.javafx.image.IntPixelSetter;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+public abstract class BaseByteToIntConverter
+    implements ByteToIntPixelConverter
+{
+    protected final BytePixelGetter getter;
+    protected final IntPixelSetter  setter;
+    protected final int nSrcElems;
+
+    BaseByteToIntConverter(BytePixelGetter getter, IntPixelSetter setter) {
+        this.getter = getter;
+        this.setter = setter;
+        this.nSrcElems = getter.getNumElements();
+    }
+
+    @Override
+    public final BytePixelGetter getGetter() {
+        return getter;
+    }
+
+    @Override
+    public final IntPixelSetter getSetter() {
+        return setter;
+    }
+
+    abstract void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                            int  dstarr[], int dstoff, int dstscanints,
+                            int w, int h);
+
+    abstract void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                            IntBuffer  dstbuf, int dstoff, int dstscanints,
+                            int w, int h);
+
+    @Override
+    public final void convert(byte srcarr[], int srcoff, int srcscanbytes,
+                              int  dstarr[], int dstoff, int dstscanints,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanbytes == w * nSrcElems &&
+            dstscanints  == w)
+        {
+            w *= h;
+            h = 1;
+        }
+        doConvert(srcarr, srcoff, srcscanbytes,
+                  dstarr, dstoff, dstscanints,
+                  w, h);
+    }
+
+    @Override
+    public final void convert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                              IntBuffer  dstbuf, int dstoff, int dstscanints,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanbytes == w * nSrcElems &&
+            dstscanints  == w)
+        {
+            w *= h;
+            h = 1;
+        }
+        if (srcbuf.hasArray() && dstbuf.hasArray()) {
+            doConvert(srcbuf.array(), srcoff, srcscanbytes,
+                      dstbuf.array(), dstoff, dstscanints,
+                      w, h);
+        } else {
+            doConvert(srcbuf, srcoff, srcscanbytes,
+                      dstbuf, dstoff, dstscanints,
+                      w, h);
+        }
+    }
+
+    @Override
+    public final void convert(ByteBuffer srcbuf,   int srcoff, int srcscanbytes,
+                              int        dstarr[], int dstoff, int dstscanints,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanbytes == w * nSrcElems &&
+            dstscanints  == w)
+        {
+            w *= h;
+            h = 1;
+        }
+        if (srcbuf.hasArray()) {
+            doConvert(srcbuf.array(), srcoff, srcscanbytes,
+                      dstarr, dstoff, dstscanints,
+                      w, h);
+        } else {
+            IntBuffer dstbuf = IntBuffer.wrap(dstarr);
+            doConvert(srcbuf, srcoff, srcscanbytes,
+                      dstbuf, dstoff, dstscanints,
+                      w, h);
+        }
+    }
+
+    @Override
+    public final void convert(byte      srcarr[], int srcoff, int srcscanbytes,
+                              IntBuffer dstbuf,   int dstoff, int dstscanints,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanbytes == w * nSrcElems &&
+            dstscanints  == w)
+        {
+            w *= h;
+            h = 1;
+        }
+        if (dstbuf.hasArray()) {
+            doConvert(srcarr, srcoff, srcscanbytes,
+                      dstbuf.array(), dstoff, dstscanints,
+                      w, h);
+        } else {
+            ByteBuffer srcbuf = ByteBuffer.wrap(srcarr);
+            doConvert(srcbuf, srcoff, srcscanbytes,
+                      dstbuf, dstoff, dstscanints,
+                      w, h);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/BaseIntToByteConverter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,152 @@
+/*
+ * 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 com.sun.javafx.image.BytePixelSetter;
+import com.sun.javafx.image.IntPixelGetter;
+import com.sun.javafx.image.IntToBytePixelConverter;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+public abstract class BaseIntToByteConverter
+    implements IntToBytePixelConverter
+{
+    protected final IntPixelGetter  getter;
+    protected final BytePixelSetter setter;
+    protected final int nDstElems;
+
+    BaseIntToByteConverter(IntPixelGetter getter, BytePixelSetter setter) {
+        this.getter = getter;
+        this.setter = setter;
+        this.nDstElems = setter.getNumElements();
+    }
+
+    @Override
+    public final IntPixelGetter getGetter() {
+        return getter;
+    }
+
+    @Override
+    public final BytePixelSetter getSetter() {
+        return setter;
+    }
+
+    abstract void doConvert(int  srcarr[], int srcoff, int srcscanints,
+                            byte dstarr[], int dstoff, int dstscanbytes,
+                            int w, int h);
+
+    abstract void doConvert(IntBuffer  srcbuf, int srcoff, int srcscanints,
+                            ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                            int w, int h);
+
+    @Override
+    public final void convert(int  srcarr[], int srcoff, int srcscanints,
+                              byte dstarr[], int dstoff, int dstscanbytes,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanints  == w &&
+            dstscanbytes == w * nDstElems)
+        {
+            w *= h;
+            h = 1;
+        }
+        doConvert(srcarr, srcoff, srcscanints,
+                  dstarr, dstoff, dstscanbytes,
+                  w, h);
+    }
+
+    @Override
+    public final void convert(IntBuffer  srcbuf, int srcoff, int srcscanints,
+                              ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanints  == w &&
+            dstscanbytes == w * nDstElems)
+        {
+            w *= h;
+            h = 1;
+        }
+        if (srcbuf.hasArray() && dstbuf.hasArray()) {
+            doConvert(srcbuf.array(), srcoff, srcscanints,
+                      dstbuf.array(), dstoff, dstscanbytes,
+                      w, h);
+        } else {
+            doConvert(srcbuf, srcoff, srcscanints,
+                      dstbuf, dstoff, dstscanbytes,
+                      w, h);
+        }
+    }
+
+    @Override
+    public final void convert(IntBuffer srcbuf,   int srcoff, int srcscanints,
+                              byte      dstarr[], int dstoff, int dstscanbytes,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanints  == w &&
+            dstscanbytes == w * nDstElems)
+        {
+            w *= h;
+            h = 1;
+        }
+        if (srcbuf.hasArray()) {
+            doConvert(srcbuf.array(), srcoff, srcscanints,
+                      dstarr, dstoff, dstscanbytes,
+                      w, h);
+        } else {
+            ByteBuffer dstbuf = ByteBuffer.wrap(dstarr);
+            doConvert(srcbuf, srcoff, srcscanints,
+                      dstbuf, dstoff, dstscanbytes,
+                      w, h);
+        }
+    }
+
+    @Override
+    public final void convert(int        srcarr[], int srcoff, int srcscanints,
+                              ByteBuffer dstbuf,   int dstoff, int dstscanbytes,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanints  == w &&
+            dstscanbytes == w * nDstElems)
+        {
+            w *= h;
+            h = 1;
+        }
+        if (dstbuf.hasArray()) {
+            doConvert(srcarr, srcoff, srcscanints,
+                      dstbuf.array(), dstoff, dstscanbytes,
+                      w, h);
+        } else {
+            IntBuffer srcbuf = IntBuffer.wrap(srcarr);
+            doConvert(srcbuf, srcoff, srcscanints,
+                      dstbuf, dstoff, dstscanbytes,
+                      w, h);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/BaseIntToIntConverter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,200 @@
+/*
+ * 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 com.sun.javafx.image.IntPixelAccessor;
+import com.sun.javafx.image.IntPixelGetter;
+import com.sun.javafx.image.IntPixelSetter;
+import com.sun.javafx.image.IntToIntPixelConverter;
+import java.nio.IntBuffer;
+
+public abstract class BaseIntToIntConverter
+    implements IntToIntPixelConverter
+{
+    protected final IntPixelGetter getter;
+    protected final IntPixelSetter setter;
+
+    public BaseIntToIntConverter(IntPixelGetter getter, IntPixelSetter setter) {
+        this.getter = getter;
+        this.setter = setter;
+    }
+
+    @Override
+    public final IntPixelGetter getGetter() {
+        return getter;
+    }
+
+    @Override
+    public final IntPixelSetter getSetter() {
+        return setter;
+    }
+
+    abstract void doConvert(int srcarr[], int srcoff, int srcscanints,
+                            int dstarr[], int dstoff, int dstscanints,
+                            int w, int h);
+
+    abstract void doConvert(IntBuffer srcbuf, int srcoff, int srcscanints,
+                            IntBuffer dstbuf, int dstoff, int dstscanints,
+                            int w, int h);
+
+    @Override
+    public final void convert(int srcarr[], int srcoff, int srcscanints,
+                              int dstarr[], int dstoff, int dstscanints,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanints == w &&
+            dstscanints == w)
+        {
+            w *= h;
+            h = 1;
+        }
+        doConvert(srcarr, srcoff, srcscanints,
+                  dstarr, dstoff, dstscanints,
+                  w, h);
+    }
+
+    @Override
+    public final void convert(IntBuffer srcbuf, int srcoff, int srcscanints,
+                              IntBuffer dstbuf, int dstoff, int dstscanints,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanints == w &&
+            dstscanints == w)
+        {
+            w *= h;
+            h = 1;
+        }
+        if (srcbuf.hasArray() && dstbuf.hasArray()) {
+            doConvert(srcbuf.array(), srcoff, srcscanints,
+                      dstbuf.array(), dstoff, dstscanints,
+                      w, h);
+        } else {
+            doConvert(srcbuf, srcoff, srcscanints,
+                      dstbuf, dstoff, dstscanints,
+                      w, h);
+        }
+    }
+
+    @Override
+    public final void convert(IntBuffer srcbuf,   int srcoff, int srcscanints,
+                              int       dstarr[], int dstoff, int dstscanints,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanints == w &&
+            dstscanints == w)
+        {
+            w *= h;
+            h = 1;
+        }
+        if (srcbuf.hasArray()) {
+            doConvert(srcbuf.array(), srcoff, srcscanints,
+                      dstarr, dstoff, dstscanints,
+                      w, h);
+        } else {
+            IntBuffer dstbuf = IntBuffer.wrap(dstarr);
+            doConvert(srcbuf, srcoff, srcscanints,
+                      dstbuf, dstoff, dstscanints,
+                      w, h);
+        }
+    }
+
+    @Override
+    public final void convert(int       srcarr[], int srcoff, int srcscanints,
+                              IntBuffer dstbuf,   int dstoff, int dstscanints,
+                              int w, int h)
+    {
+        if (w <= 0 || h <= 0) return;
+        if (srcscanints == w &&
+            dstscanints == w)
+        {
+            w *= h;
+            h = 1;
+        }
+        if (dstbuf.hasArray()) {
+            doConvert(srcarr, srcoff, srcscanints,
+                      dstbuf.array(), dstoff, dstscanints,
+                      w, h);
+        } else {
+            IntBuffer srcbuf = IntBuffer.wrap(srcarr);
+            doConvert(srcbuf, srcoff, srcscanints,
+                      dstbuf, dstoff, dstscanints,
+                      w, h);
+        }
+    }
+
+    static IntToIntPixelConverter create(IntPixelAccessor fmt) {
+        return new IntAnyToSameConverter(fmt);
+    }
+
+    static class IntAnyToSameConverter extends BaseIntToIntConverter {
+        IntAnyToSameConverter(IntPixelAccessor fmt) {
+            super(fmt, fmt);
+        }
+
+        @Override
+        void doConvert(int srcarr[], int srcoff, int srcscanints,
+                       int dstarr[], int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            while (--h >= 0) {
+                System.arraycopy(srcarr, srcoff, dstarr, dstoff, w);
+                srcoff += srcscanints;
+                dstoff += dstscanints;
+            }
+        }
+
+        @Override
+        void doConvert(IntBuffer srcbuf, int srcoff, int srcscanints,
+                       IntBuffer dstbuf, int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            int srclimit = srcbuf.limit();
+            int origsrcpos = srcbuf.position();
+            int origdstpos = dstbuf.position();
+            try {
+                while (--h >= 0) {
+                    int newlimit = srcoff + w;
+                    if (newlimit > srclimit) {
+                        throw new IndexOutOfBoundsException("" + srclimit);
+                    }
+                    srcbuf.limit(newlimit);
+                    srcbuf.position(srcoff);
+                    dstbuf.position(dstoff);
+                    dstbuf.put(srcbuf);
+                    srcoff += srcscanints;
+                    dstoff += dstscanints;
+                }
+            } finally {
+                srcbuf.limit(srclimit);
+                srcbuf.position(origsrcpos);
+                dstbuf.position(origdstpos);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/ByteArgb.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,106 @@
+/*
+ * 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 com.sun.javafx.image.AlphaType;
+import com.sun.javafx.image.BytePixelAccessor;
+import com.sun.javafx.image.BytePixelGetter;
+import com.sun.javafx.image.BytePixelSetter;
+import com.sun.javafx.image.PixelUtils;
+import java.nio.ByteBuffer;
+
+public class ByteArgb {
+    public static final BytePixelGetter     getter = Accessor.instance;
+    public static final BytePixelSetter     setter = Accessor.instance;
+    public static final BytePixelAccessor accessor = Accessor.instance;
+
+    static class Accessor implements BytePixelAccessor {
+        static final BytePixelAccessor instance = new Accessor();
+        private Accessor() {}
+
+        @Override
+        public AlphaType getAlphaType() {
+            return AlphaType.NONPREMULTIPLIED;
+        }
+
+        @Override
+        public int getNumElements() {
+            return 4;
+        }
+
+        @Override
+        public int getArgb(byte arr[], int offset) {
+            return (((arr[offset    ]       ) << 24) |
+                    ((arr[offset + 1] & 0xff) << 16) |
+                    ((arr[offset + 2] & 0xff) <<  8) |
+                    ((arr[offset + 3] & 0xff)      ));
+        }
+
+        @Override
+        public int getArgbPre(byte arr[], int offset) {
+            return PixelUtils.NonPretoPre(getArgb(arr, offset));
+        }
+
+        @Override
+        public int getArgb(ByteBuffer buf, int offset) {
+            return (((buf.get(offset    )       ) << 24) |
+                    ((buf.get(offset + 1) & 0xff) << 16) |
+                    ((buf.get(offset + 2) & 0xff) <<  8) |
+                    ((buf.get(offset + 3) & 0xff)      ));
+        }
+
+        @Override
+        public int getArgbPre(ByteBuffer buf, int offset) {
+            return PixelUtils.NonPretoPre(getArgb(buf, offset));
+        }
+
+        @Override
+        public void setArgb(byte arr[], int offset, int argb) {
+            arr[offset    ] = (byte) (argb >> 24);
+            arr[offset + 1] = (byte) (argb >> 16);
+            arr[offset + 2] = (byte) (argb >>  8);
+            arr[offset + 3] = (byte) (argb      );
+        }
+
+        @Override
+        public void setArgbPre(byte arr[], int offset, int argbpre) {
+            setArgb(arr, offset, PixelUtils.PretoNonPre(argbpre));
+        }
+
+        @Override
+        public void setArgb(ByteBuffer buf, int offset, int argb) {
+            buf.put(offset    , (byte) (argb >> 24));
+            buf.put(offset + 1, (byte) (argb >> 16));
+            buf.put(offset + 2, (byte) (argb >>  8));
+            buf.put(offset + 3, (byte) (argb      ));
+        }
+
+        @Override
+        public void setArgbPre(ByteBuffer buf, int offset, int argbpre) {
+            setArgb(buf, offset, PixelUtils.PretoNonPre(argbpre));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/ByteBgra.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,311 @@
+/*
+ * 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 com.sun.javafx.image.AlphaType;
+import com.sun.javafx.image.BytePixelAccessor;
+import com.sun.javafx.image.BytePixelGetter;
+import com.sun.javafx.image.BytePixelSetter;
+import com.sun.javafx.image.ByteToBytePixelConverter;
+import com.sun.javafx.image.ByteToIntPixelConverter;
+import com.sun.javafx.image.PixelUtils;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+public class ByteBgra {
+    public static final BytePixelGetter     getter = Accessor.instance;
+    public static final BytePixelSetter     setter = Accessor.instance;
+    public static final BytePixelAccessor accessor = Accessor.instance;
+
+    public static final ByteToBytePixelConverter ToByteBgraConverter =
+        BaseByteToByteConverter.create(accessor);
+    public static final ByteToBytePixelConverter ToByteBgraPreConverter =
+        ByteBgra.ToByteBgraPreConv.instance;
+    public static final ByteToIntPixelConverter ToIntArgbConverter =
+        ByteBgra.ToIntArgbSameConv.nonpremul;
+    public static final ByteToIntPixelConverter ToIntArgbPreConverter =
+        ByteBgra.ToIntArgbPreConv.instance;
+
+    static class Accessor implements BytePixelAccessor {
+        static final BytePixelAccessor instance = new Accessor();
+        private Accessor() {}
+
+        @Override
+        public AlphaType getAlphaType() {
+            return AlphaType.NONPREMULTIPLIED;
+        }
+
+        @Override
+        public int getNumElements() {
+            return 4;
+        }
+
+        @Override
+        public int getArgb(byte arr[], int offset) {
+            return (((arr[offset    ] & 0xff)      ) |
+                    ((arr[offset + 1] & 0xff) <<  8) |
+                    ((arr[offset + 2] & 0xff) << 16) |
+                    ((arr[offset + 3]       ) << 24));
+        }
+
+        @Override
+        public int getArgbPre(byte arr[], int offset) {
+            return PixelUtils.NonPretoPre(getArgb(arr, offset));
+        }
+
+        @Override
+        public int getArgb(ByteBuffer buf, int offset) {
+            return (((buf.get(offset    ) & 0xff)      ) |
+                    ((buf.get(offset + 1) & 0xff) <<  8) |
+                    ((buf.get(offset + 2) & 0xff) << 16) |
+                    ((buf.get(offset + 3)       ) << 24));
+        }
+
+        @Override
+        public int getArgbPre(ByteBuffer buf, int offset) {
+            return PixelUtils.NonPretoPre(getArgb(buf, offset));
+        }
+
+        @Override
+        public void setArgb(byte arr[], int offset, int argb) {
+            arr[offset    ] = (byte) (argb      );
+            arr[offset + 1] = (byte) (argb >>  8);
+            arr[offset + 2] = (byte) (argb >> 16);
+            arr[offset + 3] = (byte) (argb >> 24);
+        }
+
+        @Override
+        public void setArgbPre(byte arr[], int offset, int argbpre) {
+            setArgb(arr, offset, PixelUtils.PretoNonPre(argbpre));
+        }
+
+        @Override
+        public void setArgb(ByteBuffer buf, int offset, int argb) {
+            buf.put(offset    , (byte) (argb      ));
+            buf.put(offset + 1, (byte) (argb >>  8));
+            buf.put(offset + 2, (byte) (argb >> 16));
+            buf.put(offset + 3, (byte) (argb >> 24));
+        }
+
+        @Override
+        public void setArgbPre(ByteBuffer buf, int offset, int argbpre) {
+            setArgb(buf, offset, PixelUtils.PretoNonPre(argbpre));
+        }
+    }
+
+    static class ToByteBgraPreConv extends BaseByteToByteConverter {
+        static final ByteToBytePixelConverter instance =
+            new ToByteBgraPreConv();
+
+        private ToByteBgraPreConv() {
+            super(ByteBgra.getter, ByteBgraPre.setter);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       byte dstarr[], int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    byte b = srcarr[srcoff++];
+                    byte g = srcarr[srcoff++];
+                    byte r = srcarr[srcoff++];
+                    int  a = srcarr[srcoff++] & 0xff;
+                    if (a < 0xff) {
+                        if (a == 0) {
+                            b = g = r = 0;
+                        } else {
+                            b = (byte) (((b & 0xff) * a + 0x7f) / 0xff);
+                            g = (byte) (((g & 0xff) * a + 0x7f) / 0xff);
+                            r = (byte) (((r & 0xff) * a + 0x7f) / 0xff);
+                        }
+                    }
+                    dstarr[dstoff++] = b;
+                    dstarr[dstoff++] = g;
+                    dstarr[dstoff++] = r;
+                    dstarr[dstoff++] = (byte) a;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    byte b = srcbuf.get(srcoff    );
+                    byte g = srcbuf.get(srcoff + 1);
+                    byte r = srcbuf.get(srcoff + 2);
+                    int  a = srcbuf.get(srcoff + 3) & 0xff;
+                    srcoff += 4;
+                    if (a < 0xff) {
+                        if (a == 0) {
+                            b = g = r = 0;
+                        } else {
+                            b = (byte) (((b & 0xff) * a + 0x7f) / 0xff);
+                            g = (byte) (((g & 0xff) * a + 0x7f) / 0xff);
+                            r = (byte) (((r & 0xff) * a + 0x7f) / 0xff);
+                        }
+                    }
+                    dstbuf.put(dstoff    , b);
+                    dstbuf.put(dstoff + 1, g);
+                    dstbuf.put(dstoff + 2, r);
+                    dstbuf.put(dstoff + 3, (byte) a);
+                    dstoff += 4;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+
+    static class ToIntArgbSameConv extends BaseByteToIntConverter {
+        static final ByteToIntPixelConverter nonpremul = new ToIntArgbSameConv(false);
+        static final ByteToIntPixelConverter    premul = new ToIntArgbSameConv(true);
+
+        private ToIntArgbSameConv(boolean isPremult) {
+            super(isPremult ? ByteBgra.getter : ByteBgraPre.getter,
+                  isPremult ?  IntArgb.setter :  IntArgbPre.setter);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       int  dstarr[], int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            dstscanints -= w;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    dstarr[dstoff++] =
+                        ((srcarr[srcoff++] & 0xff)      ) |
+                        ((srcarr[srcoff++] & 0xff) <<  8) |
+                        ((srcarr[srcoff++] & 0xff) << 16) |
+                        ((srcarr[srcoff++]       ) << 24);
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanints;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       IntBuffer  dstbuf, int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    dstbuf.put(dstoff + x,
+                               ((srcbuf.get(srcoff    ) & 0xff)      ) |
+                               ((srcbuf.get(srcoff + 1) & 0xff) <<  8) |
+                               ((srcbuf.get(srcoff + 2) & 0xff) << 16) |
+                               ((srcbuf.get(srcoff + 3)       ) << 24));
+                    srcoff += 4;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanints;
+            }
+        }
+    }
+
+    static class ToIntArgbPreConv extends BaseByteToIntConverter {
+        public static final ByteToIntPixelConverter instance =
+            new ToIntArgbPreConv();
+
+        private ToIntArgbPreConv() {
+            super(ByteBgra.getter, IntArgbPre.setter);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       int  dstarr[], int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            dstscanints  -= w;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int b = srcarr[srcoff++] & 0xff;
+                    int g = srcarr[srcoff++] & 0xff;
+                    int r = srcarr[srcoff++] & 0xff;
+                    int a = srcarr[srcoff++] & 0xff;
+                    if (a < 0xff) {
+                        if (a == 0) {
+                            b = g = r = 0;
+                        } else {
+                            b = (b * a + 0x7f) / 0xff;
+                            g = (g * a + 0x7f) / 0xff;
+                            r = (r * a + 0x7f) / 0xff;
+                        }
+                    }
+                    dstarr[dstoff++] =
+                        (a << 24) | (r << 16) | (g << 8) | b;
+                }
+                dstoff += dstscanints;
+                srcoff += srcscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       IntBuffer  dstbuf, int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int b = srcbuf.get(srcoff    ) & 0xff;
+                    int g = srcbuf.get(srcoff + 1) & 0xff;
+                    int r = srcbuf.get(srcoff + 2) & 0xff;
+                    int a = srcbuf.get(srcoff + 3) & 0xff;
+                    srcoff += 4;
+                    if (a < 0xff) {
+                        if (a == 0) {
+                            b = g = r = 0;
+                        } else {
+                            b = (b * a + 0x7f) / 0xff;
+                            g = (g * a + 0x7f) / 0xff;
+                            r = (r * a + 0x7f) / 0xff;
+                        }
+                    }
+                    dstbuf.put(dstoff + x, (a << 24) | (r << 16) | (g << 8) | b);
+                }
+                dstoff += dstscanints;
+                srcoff += srcscanbytes;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/ByteBgraPre.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,249 @@
+/*
+ * 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 com.sun.javafx.image.AlphaType;
+import com.sun.javafx.image.BytePixelAccessor;
+import com.sun.javafx.image.BytePixelGetter;
+import com.sun.javafx.image.BytePixelSetter;
+import com.sun.javafx.image.ByteToBytePixelConverter;
+import com.sun.javafx.image.ByteToIntPixelConverter;
+import com.sun.javafx.image.PixelUtils;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+public class ByteBgraPre {
+    public static final BytePixelGetter     getter = Accessor.instance;
+    public static final BytePixelSetter     setter = Accessor.instance;
+    public static final BytePixelAccessor accessor = Accessor.instance;
+
+    public static final ByteToBytePixelConverter ToByteBgraConverter =
+        ByteBgraPre.ToByteBgraConv.instance;
+    public static final ByteToBytePixelConverter ToByteBgraPreConverter =
+        BaseByteToByteConverter.create(accessor);
+    public static final ByteToIntPixelConverter ToIntArgbConverter =
+        ByteBgraPre.ToIntArgbConv.instance;
+    public static final ByteToIntPixelConverter ToIntArgbPreConverter =
+        ByteBgra.ToIntArgbSameConv.premul;
+
+    static class Accessor implements BytePixelAccessor {
+        static final BytePixelAccessor instance = new Accessor();
+        private Accessor() {}
+
+        @Override
+        public AlphaType getAlphaType() {
+            return AlphaType.PREMULTIPLIED;
+        }
+
+        @Override
+        public int getNumElements() {
+            return 4;
+        }
+
+        @Override
+        public int getArgb(byte arr[], int offset) {
+            return PixelUtils.PretoNonPre(getArgbPre(arr, offset));
+        }
+
+        @Override
+        public int getArgbPre(byte arr[], int offset) {
+            return (((arr[offset    ] & 0xff)      ) |
+                    ((arr[offset + 1] & 0xff) <<  8) |
+                    ((arr[offset + 2] & 0xff) << 16) |
+                    ((arr[offset + 3]       ) << 24));
+        }
+
+        @Override
+        public int getArgb(ByteBuffer buffer, int offset) {
+            return PixelUtils.PretoNonPre(getArgbPre(buffer, offset));
+        }
+
+        @Override
+        public int getArgbPre(ByteBuffer buffer, int offset) {
+            return (((buffer.get(offset    ) & 0xff)      ) |
+                    ((buffer.get(offset + 1) & 0xff) <<  8) |
+                    ((buffer.get(offset + 2) & 0xff) << 16) |
+                    ((buffer.get(offset + 3)       ) << 24));
+        }
+
+        @Override
+        public void setArgb(byte arr[], int offset, int argb) {
+            setArgbPre(arr, offset, PixelUtils.NonPretoPre(argb));
+        }
+
+        @Override
+        public void setArgbPre(byte arr[], int offset, int argbpre) {
+            arr[offset    ] = (byte) (argbpre      );
+            arr[offset + 1] = (byte) (argbpre >>  8);
+            arr[offset + 2] = (byte) (argbpre >> 16);
+            arr[offset + 3] = (byte) (argbpre >> 24);
+        }
+
+        @Override
+        public void setArgb(ByteBuffer buffer, int offset, int argb) {
+            setArgbPre(buffer, offset, PixelUtils.NonPretoPre(argb));
+        }
+
+        @Override
+        public void setArgbPre(ByteBuffer buffer, int offset, int argbpre) {
+            buffer.put(offset    , (byte) (argbpre      ));
+            buffer.put(offset + 1, (byte) (argbpre >>  8));
+            buffer.put(offset + 2, (byte) (argbpre >> 16));
+            buffer.put(offset + 3, (byte) (argbpre >> 24));
+        }
+    }
+
+    public static class ToByteBgraConv extends BaseByteToByteConverter {
+        public static final ByteToBytePixelConverter instance =
+            new ToByteBgraConv();
+
+        private ToByteBgraConv() {
+            super(ByteBgraPre.getter, ByteBgra.setter);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       byte dstarr[], int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    byte b = srcarr[srcoff++];
+                    byte g = srcarr[srcoff++];
+                    byte r = srcarr[srcoff++];
+                    int  a = srcarr[srcoff++] & 0xff;
+                    if (a > 0 && a < 0xff) {
+                        int halfa = a >> 1;
+                        b = (byte) (((b & 0xff) * 0xff + halfa) / a);
+                        g = (byte) (((g & 0xff) * 0xff + halfa) / a);
+                        r = (byte) (((r & 0xff) * 0xff + halfa) / a);
+                    }
+                    dstarr[dstoff++] = b;
+                    dstarr[dstoff++] = g;
+                    dstarr[dstoff++] = r;
+                    dstarr[dstoff++] = (byte) a;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    byte b = srcbuf.get(srcoff    );
+                    byte g = srcbuf.get(srcoff + 1);
+                    byte r = srcbuf.get(srcoff + 2);
+                    int  a = srcbuf.get(srcoff + 3) & 0xff;
+                    srcoff += 4;
+                    if (a > 0 && a < 0xff) {
+                        int halfa = a >> 1;
+                        b = (byte) (((b & 0xff) * 0xff + halfa) / a);
+                        g = (byte) (((g & 0xff) * 0xff + halfa) / a);
+                        r = (byte) (((r & 0xff) * 0xff + halfa) / a);
+                    }
+                    dstbuf.put(dstoff    , b);
+                    dstbuf.put(dstoff + 1, g);
+                    dstbuf.put(dstoff + 2, r);
+                    dstbuf.put(dstoff + 3, (byte) a);
+                    dstoff += 4;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+
+    public static class ToIntArgbConv extends BaseByteToIntConverter {
+        public static final ByteToIntPixelConverter instance =
+            new ToIntArgbConv();
+
+        private ToIntArgbConv() {
+            super(ByteBgraPre.getter, IntArgb.setter);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       int  dstarr[], int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            dstscanints  -= w;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int b = srcarr[srcoff++] & 0xff;
+                    int g = srcarr[srcoff++] & 0xff;
+                    int r = srcarr[srcoff++] & 0xff;
+                    int a = srcarr[srcoff++] & 0xff;
+                    if (a > 0 && a < 0xff) {
+                        int halfa = a >> 1;
+                        r = (r * 0xff + halfa) / a;
+                        g = (g * 0xff + halfa) / a;
+                        b = (b * 0xff + halfa) / a;
+                    }
+                    dstarr[dstoff++] =
+                        (a << 24) | (r << 16) | (g << 8) | b;
+                }
+                dstoff += dstscanints;
+                srcoff += srcscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       IntBuffer  dstbuf, int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int b = srcbuf.get(srcoff    ) & 0xff;
+                    int g = srcbuf.get(srcoff + 1) & 0xff;
+                    int r = srcbuf.get(srcoff + 2) & 0xff;
+                    int a = srcbuf.get(srcoff + 3) & 0xff;
+                    srcoff += 4;
+                    if (a > 0 && a < 0xff) {
+                        int halfa = a >> 1;
+                        r = (r * 0xff + halfa) / a;
+                        g = (g * 0xff + halfa) / a;
+                        b = (b * 0xff + halfa) / a;
+                    }
+                    dstbuf.put(dstoff + x, (a << 24) | (r << 16) | (g << 8) | b);
+                }
+                dstoff += dstscanints;
+                srcoff += srcscanbytes;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/ByteGray.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,178 @@
+/*
+ * 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 com.sun.javafx.image.AlphaType;
+import com.sun.javafx.image.BytePixelGetter;
+import com.sun.javafx.image.BytePixelSetter;
+import com.sun.javafx.image.ByteToBytePixelConverter;
+import com.sun.javafx.image.ByteToIntPixelConverter;
+import com.sun.javafx.image.IntPixelSetter;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+public class ByteGray {
+    public static final BytePixelGetter getter = Getter.instance;
+
+    public static final ByteToBytePixelConverter ToByteBgraConverter =
+        ByteRgb.ToByteBgrfConv.nonpremult;
+    public static final ByteToBytePixelConverter ToByteBgraPreConverter =
+        ByteRgb.ToByteBgrfConv.premult;
+    public static final ByteToIntPixelConverter ToIntArgbConverter =
+        ByteRgb.ToIntFrgbConv.nonpremult;
+    public static final ByteToIntPixelConverter ToIntArgbPreConverter =
+        ByteRgb.ToIntFrgbConv.premult;
+
+    static class Getter implements BytePixelGetter {
+        static final BytePixelGetter instance = new Getter();
+        private Getter() {}
+
+        @Override
+        public AlphaType getAlphaType() {
+            return AlphaType.OPAQUE;
+        }
+
+        @Override
+        public int getNumElements() {
+            return 1;
+        }
+
+        @Override
+        public int getArgb(byte arr[], int offset) {
+            int g = arr[offset] & 0xff;
+            return (0xff000000 | (g << 16) | (g << 8) | g);
+        }
+
+        @Override
+        public int getArgbPre(byte arr[], int offset) {
+            int g = arr[offset] & 0xff;
+            return (0xff000000 | (g << 16) | (g << 8) | g);
+        }
+
+        @Override
+        public int getArgb(ByteBuffer buf, int offset) {
+            int g = buf.get(offset) & 0xff;
+            return (0xff000000 | (g << 16) | (g << 8) | g);
+        }
+
+        @Override
+        public int getArgbPre(ByteBuffer buf, int offset) {
+            int g = buf.get(offset) & 0xff;
+            return (0xff000000 | (g << 16) | (g << 8) | g);
+        }
+    }
+
+    static class ToByteBgrfConv extends BaseByteToByteConverter {
+        public static final ByteToBytePixelConverter nonpremult =
+            new ToByteBgrfConv(ByteBgra.setter);
+        public static final ByteToBytePixelConverter    premult =
+            new ToByteBgrfConv(ByteBgraPre.setter);
+
+        ToByteBgrfConv(BytePixelSetter setter) {
+            super(ByteGray.getter, setter);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       byte dstarr[], int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    byte g = srcarr[srcoff + x];
+                    dstarr[dstoff++] = g;
+                    dstarr[dstoff++] = g;
+                    dstarr[dstoff++] = g;
+                    dstarr[dstoff++] = (byte) 0xff;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    byte g = srcbuf.get(srcoff + x);
+                    dstbuf.put(dstoff    , g);
+                    dstbuf.put(dstoff + 1, g);
+                    dstbuf.put(dstoff + 2, g);
+                    dstbuf.put(dstoff + 3, (byte) 0xff);
+                    dstoff += 4;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+
+    static class ToIntFrgbConv extends BaseByteToIntConverter {
+        public static final ByteToIntPixelConverter nonpremult =
+            new ToIntFrgbConv(IntArgb.setter);
+        public static final ByteToIntPixelConverter    premult =
+            new ToIntFrgbConv(IntArgbPre.setter);
+
+        private ToIntFrgbConv(IntPixelSetter setter) {
+            super(ByteRgb.getter, setter);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       int  dstarr[], int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int g = srcarr[srcoff + x] & 0xff;
+                    dstarr[dstoff + x] = 0xff000000 | (g << 16) | (g << 8) | g;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanints;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       IntBuffer  dstbuf, int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int g = srcbuf.get(srcoff + x) & 0xff;
+                    dstbuf.put(dstoff + x, 0xff000000 | (g << 16) | (g << 8) | g);
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanints;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/ByteGrayAlpha.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,248 @@
+/*
+ * 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 com.sun.javafx.image.AlphaType;
+import com.sun.javafx.image.BytePixelAccessor;
+import com.sun.javafx.image.BytePixelGetter;
+import com.sun.javafx.image.BytePixelSetter;
+import com.sun.javafx.image.ByteToBytePixelConverter;
+import com.sun.javafx.image.PixelUtils;
+import java.nio.ByteBuffer;
+
+public class ByteGrayAlpha {
+    public static final BytePixelGetter     getter = Accessor.nonpremul;
+    public static final BytePixelSetter     setter = Accessor.nonpremul;
+    public static final BytePixelAccessor accessor = Accessor.nonpremul;
+
+    public static final ByteToBytePixelConverter ToByteGrayAlphaPre =
+        ToByteGrayAlphaPreConv.instance;
+    public static final ByteToBytePixelConverter ToByteBgra =
+        ToByteBgraSameConv.nonpremul;
+
+    static class Accessor implements BytePixelAccessor {
+        static final BytePixelAccessor nonpremul = new Accessor(false);
+        static final BytePixelAccessor    premul = new Accessor(true);
+
+        private boolean isPremult;
+        private Accessor(boolean isPremult) {
+            this.isPremult = isPremult;
+        }
+
+        @Override
+        public AlphaType getAlphaType() {
+            return isPremult ? AlphaType.PREMULTIPLIED : AlphaType.NONPREMULTIPLIED;
+        }
+
+        @Override
+        public int getNumElements() {
+            return 2;
+        }
+
+        @Override
+        public int getArgb(byte arr[], int offset) {
+            int g = arr[offset    ] & 0xff;
+            int a = arr[offset + 1] & 0xff;
+            if (isPremult) g = PixelUtils.PreToNonPre(g, a);
+            return ((a << 24) | (g << 16) | (g << 8) | g);
+        }
+
+        @Override
+        public int getArgbPre(byte arr[], int offset) {
+            int g = arr[offset    ] & 0xff;
+            int a = arr[offset + 1] & 0xff;
+            if (!isPremult) g = PixelUtils.NonPretoPre(g, a);
+            return ((a << 24) | (g << 16) | (g << 8) | g);
+        }
+
+        @Override
+        public int getArgb(ByteBuffer buf, int offset) {
+            int g = buf.get(offset    ) & 0xff;
+            int a = buf.get(offset + 1) & 0xff;
+            if (isPremult) g = PixelUtils.PreToNonPre(g, a);
+            return ((a << 24) | (g << 16) | (g << 8) | g);
+        }
+
+        @Override
+        public int getArgbPre(ByteBuffer buf, int offset) {
+            int g = buf.get(offset    ) & 0xff;
+            int a = buf.get(offset + 1) & 0xff;
+            if (!isPremult) g = PixelUtils.NonPretoPre(g, a);
+            return ((a << 24) | (g << 16) | (g << 8) | g);
+        }
+
+        @Override
+        public void setArgb(byte arr[], int offset, int argb) {
+            int g = PixelUtils.RgbToGray(argb);
+            int a = (argb >>> 24);
+            if (isPremult) g = PixelUtils.NonPretoPre(g, a);
+            arr[offset    ] = (byte) g;
+            arr[offset + 1] = (byte) a;
+        }
+
+        @Override
+        public void setArgbPre(byte arr[], int offset, int argbpre) {
+            int g = PixelUtils.RgbToGray(argbpre);
+            int a = (argbpre >>> 24);
+            if (!isPremult) g = PixelUtils.PreToNonPre(g, a);
+            arr[offset    ] = (byte) g;
+            arr[offset + 1] = (byte) a;
+        }
+
+        @Override
+        public void setArgb(ByteBuffer buf, int offset, int argb) {
+            int g = PixelUtils.RgbToGray(argb);
+            int a = (argb >>> 24);
+            if (isPremult) g = PixelUtils.NonPretoPre(g, a);
+            buf.put(offset    , (byte) g);
+            buf.put(offset + 1, (byte) a);
+        }
+
+        @Override
+        public void setArgbPre(ByteBuffer buf, int offset, int argbpre) {
+            int g = PixelUtils.RgbToGray(argbpre);
+            int a = (argbpre >>> 24);
+            if (!isPremult) g = PixelUtils.PreToNonPre(g, a);
+            buf.put(offset    , (byte) g);
+            buf.put(offset + 1, (byte) a);
+        }
+    }
+
+    static class ToByteGrayAlphaPreConv extends BaseByteToByteConverter {
+        static final ByteToBytePixelConverter instance =
+            new ToByteGrayAlphaPreConv();
+
+        private ToByteGrayAlphaPreConv() {
+            super(ByteGrayAlpha.getter, ByteGrayAlphaPre.setter);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       byte dstarr[], int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 2;
+            dstscanbytes -= w * 2;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int g = srcarr[srcoff++] & 0xff;
+                    int a = srcarr[srcoff++];
+                    if (a != -1) {
+                        if (a == 0) {
+                            g = 0;
+                        } else {
+                            g = (g * (a & 0xff) + 0x7f) / 0xff;
+                        }
+                    }
+                    dstarr[dstoff++] = (byte) g;
+                    dstarr[dstoff++] = (byte) a;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 2;
+            dstscanbytes -= w * 2;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int g = srcbuf.get(srcoff++) & 0xff;
+                    int a = srcbuf.get(srcoff++);
+                    if (a != -1) {
+                        if (a == 0) {
+                            g = 0;
+                        } else {
+                            g = (g * (a & 0xff) + 0x7f) / 0xff;
+                        }
+                    }
+                    dstbuf.put(dstoff++, (byte) g);
+                    dstbuf.put(dstoff++, (byte) a);
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+
+    static class ToByteBgraSameConv extends BaseByteToByteConverter {
+        static final ByteToBytePixelConverter nonpremul =
+            new ToByteBgraSameConv(false);
+        static final ByteToBytePixelConverter    premul =
+            new ToByteBgraSameConv(true);
+
+        private ToByteBgraSameConv(boolean isPremult) {
+            super(isPremult ? ByteGrayAlphaPre.getter : ByteGrayAlpha.getter,
+                  isPremult ?      ByteBgraPre.setter :      ByteBgra.setter);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       byte dstarr[], int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 2;
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    byte g = srcarr[srcoff++];
+                    byte a = srcarr[srcoff++];
+                    dstarr[dstoff++] = g;
+                    dstarr[dstoff++] = g;
+                    dstarr[dstoff++] = g;
+                    dstarr[dstoff++] = a;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 2;
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    byte g = srcbuf.get(srcoff++);
+                    byte a = srcbuf.get(srcoff++);
+                    dstbuf.put(dstoff++, g);
+                    dstbuf.put(dstoff++, g);
+                    dstbuf.put(dstoff++, g);
+                    dstbuf.put(dstoff++, a);
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/ByteGrayAlphaPre.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,40 @@
+/*
+ * 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 com.sun.javafx.image.BytePixelAccessor;
+import com.sun.javafx.image.BytePixelGetter;
+import com.sun.javafx.image.BytePixelSetter;
+import com.sun.javafx.image.ByteToBytePixelConverter;
+
+public class ByteGrayAlphaPre {
+    public static final BytePixelGetter     getter = ByteGrayAlpha.Accessor.premul;
+    public static final BytePixelSetter     setter = ByteGrayAlpha.Accessor.premul;
+    public static final BytePixelAccessor accessor = ByteGrayAlpha.Accessor.premul;
+
+    public static final ByteToBytePixelConverter ToByteBgraPre =
+        ByteGrayAlpha.ToByteBgraSameConv.premul;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/ByteRgb.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,244 @@
+/*
+ * 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 com.sun.javafx.image.AlphaType;
+import com.sun.javafx.image.BytePixelGetter;
+import com.sun.javafx.image.BytePixelSetter;
+import com.sun.javafx.image.ByteToBytePixelConverter;
+import com.sun.javafx.image.ByteToIntPixelConverter;
+import com.sun.javafx.image.IntPixelSetter;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+public class ByteRgb {
+    public static final BytePixelGetter getter = Getter.instance;
+
+    public static final ByteToBytePixelConverter ToByteBgraConverter =
+        ByteRgb.ToByteBgrfConv.nonpremult;
+    public static final ByteToBytePixelConverter ToByteBgraPreConverter =
+        ByteRgb.ToByteBgrfConv.premult;
+    public static final ByteToIntPixelConverter ToIntArgbConverter =
+        ByteRgb.ToIntFrgbConv.nonpremult;
+    public static final ByteToIntPixelConverter ToIntArgbPreConverter =
+        ByteRgb.ToIntFrgbConv.premult;
+    public static final ByteToBytePixelConverter ToByteArgbConverter =
+        ByteRgb.ToByteFrgbConv.nonpremult;
+
+    static class Getter implements BytePixelGetter {
+        static final BytePixelGetter instance = new Getter();
+        private Getter() {}
+
+        @Override
+        public AlphaType getAlphaType() {
+            return AlphaType.OPAQUE;
+        }
+
+        @Override
+        public int getNumElements() {
+            return 3;
+        }
+
+        @Override
+        public int getArgb(byte arr[], int offset) {
+            return (((arr[offset + 2] & 0xff)      ) |
+                    ((arr[offset + 1] & 0xff) <<  8) |
+                    ((arr[offset    ] & 0xff) << 16) |
+                    ((                  0xff) << 24));
+        }
+
+        @Override
+        public int getArgbPre(byte arr[], int offset) {
+            return (((arr[offset + 2] & 0xff)      ) |
+                    ((arr[offset + 1] & 0xff) <<  8) |
+                    ((arr[offset    ] & 0xff) << 16) |
+                    ((                  0xff) << 24));
+        }
+
+        @Override
+        public int getArgb(ByteBuffer buffer, int offset) {
+            return (((buffer.get(offset + 2) & 0xff)      ) |
+                    ((buffer.get(offset + 1) & 0xff) <<  8) |
+                    ((buffer.get(offset    ) & 0xff) << 16) |
+                    ((                         0xff) << 24));
+        }
+
+        @Override
+        public int getArgbPre(ByteBuffer buffer, int offset) {
+            return (((buffer.get(offset + 2) & 0xff)      ) |
+                    ((buffer.get(offset + 1) & 0xff) <<  8) |
+                    ((buffer.get(offset    ) & 0xff) << 16) |
+                    ((                         0xff) << 24));
+        }
+    }
+
+    static class ToByteBgrfConv extends BaseByteToByteConverter {
+        public static final ByteToBytePixelConverter nonpremult =
+            new ToByteBgrfConv(ByteBgra.setter);
+        public static final ByteToBytePixelConverter    premult =
+            new ToByteBgrfConv(ByteBgraPre.setter);
+
+        private ToByteBgrfConv(BytePixelSetter setter) {
+            super(ByteRgb.getter, setter);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       byte dstarr[], int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 3;
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    dstarr[dstoff++] = srcarr[srcoff + 2];
+                    dstarr[dstoff++] = srcarr[srcoff + 1];
+                    dstarr[dstoff++] = srcarr[srcoff    ];
+                    dstarr[dstoff++] = (byte) 0xff;
+                    srcoff += 3;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 3;
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    dstbuf.put(dstoff    , srcbuf.get(srcoff + 2));
+                    dstbuf.put(dstoff + 1, srcbuf.get(srcoff + 1));
+                    dstbuf.put(dstoff + 2, srcbuf.get(srcoff    ));
+                    dstbuf.put(dstoff + 3, (byte) 0xff);
+                    srcoff += 3;
+                    dstoff += 4;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+
+    static class ToIntFrgbConv extends BaseByteToIntConverter {
+        public static final ByteToIntPixelConverter nonpremult =
+            new ToIntFrgbConv(IntArgb.setter);
+        public static final ByteToIntPixelConverter    premult =
+            new ToIntFrgbConv(IntArgbPre.setter);
+
+        private ToIntFrgbConv(IntPixelSetter setter) {
+            super(ByteRgb.getter, setter);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       int  dstarr[], int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 3;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int r = srcarr[srcoff++] & 0xff;
+                    int g = srcarr[srcoff++] & 0xff;
+                    int b = srcarr[srcoff++] & 0xff;
+                    dstarr[dstoff + x] = 0xff000000 | (r << 16) | (g << 8) | b;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanints;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       IntBuffer  dstbuf, int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 3;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int r = srcbuf.get(srcoff    ) & 0xff;
+                    int g = srcbuf.get(srcoff + 1) & 0xff;
+                    int b = srcbuf.get(srcoff + 2) & 0xff;
+                    srcoff += 3;
+                    dstbuf.put(dstoff + x, 0xff000000 | (r << 16) | (g << 8) | b);
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanints;
+            }
+        }
+    }
+
+    static class ToByteFrgbConv extends BaseByteToByteConverter {
+        static final ByteToBytePixelConverter nonpremult =
+            new ToByteFrgbConv(ByteArgb.setter);
+
+        private ToByteFrgbConv(BytePixelSetter setter) {
+            super(ByteRgb.getter, setter);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       byte dstarr[], int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 3;
+            srcscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    dstarr[dstoff++] = (byte) 0xff;
+                    dstarr[dstoff++] = srcarr[srcoff++];
+                    dstarr[dstoff++] = srcarr[srcoff++];
+                    dstarr[dstoff++] = srcarr[srcoff++];
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 3;
+            srcscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    dstbuf.put(dstoff++, (byte) 0xff);
+                    dstbuf.put(dstoff++, srcbuf.get(srcoff++));
+                    dstbuf.put(dstoff++, srcbuf.get(srcoff++));
+                    dstbuf.put(dstoff++, srcbuf.get(srcoff++));
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/ByteRgba.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,310 @@
+/*
+ * 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 com.sun.javafx.image.AlphaType;
+import com.sun.javafx.image.BytePixelAccessor;
+import com.sun.javafx.image.BytePixelGetter;
+import com.sun.javafx.image.BytePixelSetter;
+import com.sun.javafx.image.ByteToBytePixelConverter;
+import com.sun.javafx.image.ByteToIntPixelConverter;
+import com.sun.javafx.image.PixelUtils;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+public class ByteRgba {
+    public static final BytePixelGetter     getter = Accessor.instance;
+    public static final BytePixelSetter     setter = Accessor.instance;
+    public static final BytePixelAccessor accessor = Accessor.instance;
+
+    public static final ByteToBytePixelConverter ToByteRgbaConverter =
+        BaseByteToByteConverter.create(accessor);
+    public static final ByteToBytePixelConverter ToByteBgraConverter =
+        BaseByteToByteConverter.createReorderer(getter, ByteBgra.setter,
+                                                2, 1, 0, 3);
+//    public static final ByteToBytePixelConverter ToByteBgraPreConverter =
+//        ByteRgba.ToByteBgraPreConv.instance;
+
+    static class Accessor implements BytePixelAccessor {
+        static final BytePixelAccessor instance = new Accessor();
+        private Accessor() {}
+
+        @Override
+        public AlphaType getAlphaType() {
+            return AlphaType.NONPREMULTIPLIED;
+        }
+
+        @Override
+        public int getNumElements() {
+            return 4;
+        }
+
+        @Override
+        public int getArgb(byte arr[], int offset) {
+            return (((arr[offset + 2] & 0xff)      ) |
+                    ((arr[offset + 1] & 0xff) <<  8) |
+                    ((arr[offset    ] & 0xff) << 16) |
+                    ((arr[offset + 3]       ) << 24));
+        }
+
+        @Override
+        public int getArgbPre(byte arr[], int offset) {
+            return PixelUtils.NonPretoPre(getArgb(arr, offset));
+        }
+
+        @Override
+        public int getArgb(ByteBuffer buf, int offset) {
+            return (((buf.get(offset + 2) & 0xff)      ) |
+                    ((buf.get(offset + 1) & 0xff) <<  8) |
+                    ((buf.get(offset    ) & 0xff) << 16) |
+                    ((buf.get(offset + 3)       ) << 24));
+        }
+
+        @Override
+        public int getArgbPre(ByteBuffer buf, int offset) {
+            return PixelUtils.NonPretoPre(getArgb(buf, offset));
+        }
+
+        @Override
+        public void setArgb(byte arr[], int offset, int argb) {
+            arr[offset    ] = (byte) (argb >> 24);
+            arr[offset + 1] = (byte) (argb >>  8);
+            arr[offset + 2] = (byte) (argb      );
+            arr[offset + 3] = (byte) (argb >> 24);
+        }
+
+        @Override
+        public void setArgbPre(byte arr[], int offset, int argbpre) {
+            setArgb(arr, offset, PixelUtils.PretoNonPre(argbpre));
+        }
+
+        @Override
+        public void setArgb(ByteBuffer buf, int offset, int argb) {
+            buf.put(offset    , (byte) (argb >> 16));
+            buf.put(offset + 1, (byte) (argb >>  8));
+            buf.put(offset + 2, (byte) (argb      ));
+            buf.put(offset + 3, (byte) (argb >> 24));
+        }
+
+        @Override
+        public void setArgbPre(ByteBuffer buf, int offset, int argbpre) {
+            setArgb(buf, offset, PixelUtils.PretoNonPre(argbpre));
+        }
+    }
+
+    static class ToByteBgraPreConv extends BaseByteToByteConverter {
+        static final ByteToBytePixelConverter instance =
+            new ToByteBgraPreConv();
+
+        private ToByteBgraPreConv() {
+            super(ByteRgba.getter, ByteBgraPre.setter);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       byte dstarr[], int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    byte r = srcarr[srcoff++];
+                    byte g = srcarr[srcoff++];
+                    byte b = srcarr[srcoff++];
+                    int  a = srcarr[srcoff++] & 0xff;
+                    if (a < 0xff) {
+                        if (a == 0) {
+                            b = g = r = 0;
+                        } else {
+                            b = (byte) (((b & 0xff) * a + 0x7f) / 0xff);
+                            g = (byte) (((g & 0xff) * a + 0x7f) / 0xff);
+                            r = (byte) (((r & 0xff) * a + 0x7f) / 0xff);
+                        }
+                    }
+                    dstarr[dstoff++] = b;
+                    dstarr[dstoff++] = g;
+                    dstarr[dstoff++] = r;
+                    dstarr[dstoff++] = (byte) a;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            dstscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    byte r = srcbuf.get(srcoff    );
+                    byte g = srcbuf.get(srcoff + 1);
+                    byte b = srcbuf.get(srcoff + 2);
+                    int  a = srcbuf.get(srcoff + 3) & 0xff;
+                    srcoff += 4;
+                    if (a < 0xff) {
+                        if (a == 0) {
+                            b = g = r = 0;
+                        } else {
+                            b = (byte) (((b & 0xff) * a + 0x7f) / 0xff);
+                            g = (byte) (((g & 0xff) * a + 0x7f) / 0xff);
+                            r = (byte) (((r & 0xff) * a + 0x7f) / 0xff);
+                        }
+                    }
+                    dstbuf.put(dstoff    , b);
+                    dstbuf.put(dstoff + 1, g);
+                    dstbuf.put(dstoff + 2, r);
+                    dstbuf.put(dstoff + 3, (byte) a);
+                    dstoff += 4;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+
+    static class ToIntArgbSameConv extends BaseByteToIntConverter {
+        static final ByteToIntPixelConverter nonpremul = new ToIntArgbSameConv(false);
+        static final ByteToIntPixelConverter    premul = new ToIntArgbSameConv(true);
+
+        private ToIntArgbSameConv(boolean isPremult) {
+            super(isPremult ? ByteBgraPre.getter : ByteRgba.getter,
+                  isPremult ?  IntArgbPre.setter :  IntArgb.setter);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       int  dstarr[], int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            dstscanints -= w;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    dstarr[dstoff++] =
+                        ((srcarr[srcoff++] & 0xff)      ) |
+                        ((srcarr[srcoff++] & 0xff) <<  8) |
+                        ((srcarr[srcoff++] & 0xff) << 16) |
+                        ((srcarr[srcoff++]       ) << 24);
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanints;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       IntBuffer  dstbuf, int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    dstbuf.put(dstoff + x,
+                               ((srcbuf.get(srcoff    ) & 0xff)      ) |
+                               ((srcbuf.get(srcoff + 1) & 0xff) <<  8) |
+                               ((srcbuf.get(srcoff + 2) & 0xff) << 16) |
+                               ((srcbuf.get(srcoff + 3)       ) << 24));
+                    srcoff += 4;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanints;
+            }
+        }
+    }
+
+    static class ToIntArgbPreConv extends BaseByteToIntConverter {
+        public static final ByteToIntPixelConverter instance =
+            new ToIntArgbPreConv();
+
+        private ToIntArgbPreConv() {
+            super(ByteRgba.getter, IntArgbPre.setter);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       int  dstarr[], int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            dstscanints  -= w;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int b = srcarr[srcoff++] & 0xff;
+                    int g = srcarr[srcoff++] & 0xff;
+                    int r = srcarr[srcoff++] & 0xff;
+                    int a = srcarr[srcoff++] & 0xff;
+                    if (a < 0xff) {
+                        if (a == 0) {
+                            b = g = r = 0;
+                        } else {
+                            b = (b * a + 0x7f) / 0xff;
+                            g = (g * a + 0x7f) / 0xff;
+                            r = (r * a + 0x7f) / 0xff;
+                        }
+                    }
+                    dstarr[dstoff++] =
+                        (a << 24) | (r << 16) | (g << 8) | b;
+                }
+                dstoff += dstscanints;
+                srcoff += srcscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       IntBuffer  dstbuf, int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            srcscanbytes -= w * 4;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int b = srcbuf.get(srcoff    ) & 0xff;
+                    int g = srcbuf.get(srcoff + 1) & 0xff;
+                    int r = srcbuf.get(srcoff + 2) & 0xff;
+                    int a = srcbuf.get(srcoff + 3) & 0xff;
+                    srcoff += 4;
+                    if (a < 0xff) {
+                        if (a == 0) {
+                            b = g = r = 0;
+                        } else {
+                            b = (b * a + 0x7f) / 0xff;
+                            g = (g * a + 0x7f) / 0xff;
+                            r = (r * a + 0x7f) / 0xff;
+                        }
+                    }
+                    dstbuf.put(dstoff + x, (a << 24) | (r << 16) | (g << 8) | b);
+                }
+                dstoff += dstscanints;
+                srcoff += srcscanbytes;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/General.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,278 @@
+/*
+ * 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 com.sun.javafx.image.AlphaType;
+import com.sun.javafx.image.BytePixelGetter;
+import com.sun.javafx.image.BytePixelSetter;
+import com.sun.javafx.image.ByteToBytePixelConverter;
+import com.sun.javafx.image.ByteToIntPixelConverter;
+import com.sun.javafx.image.IntPixelGetter;
+import com.sun.javafx.image.IntPixelSetter;
+import com.sun.javafx.image.IntToBytePixelConverter;
+import com.sun.javafx.image.IntToIntPixelConverter;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+public class General {
+    public static ByteToBytePixelConverter create(BytePixelGetter src,
+                                                  BytePixelSetter dst)
+    {
+        return new ByteToByteGeneralConverter(src, dst);
+    }
+
+    public static ByteToIntPixelConverter create(BytePixelGetter src,
+                                                 IntPixelSetter  dst)
+    {
+        return new ByteToIntGeneralConverter(src, dst);
+    }
+
+    public static IntToBytePixelConverter create(IntPixelGetter  src,
+                                                 BytePixelSetter dst)
+    {
+        return new IntToByteGeneralConverter(src, dst);
+    }
+
+    public static IntToIntPixelConverter create(IntPixelGetter src,
+                                                IntPixelSetter dst)
+    {
+        return new IntToIntGeneralConverter(src, dst);
+    }
+
+    static class ByteToByteGeneralConverter extends BaseByteToByteConverter {
+        boolean usePremult;
+
+        ByteToByteGeneralConverter(BytePixelGetter getter, BytePixelSetter setter) {
+            super(getter, setter);
+            usePremult = (getter.getAlphaType() != AlphaType.NONPREMULTIPLIED &&
+                          setter.getAlphaType() != AlphaType.NONPREMULTIPLIED);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       byte dstarr[], int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= nSrcElems * w;
+            dstscanbytes -= nDstElems * w;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    if (usePremult) {
+                        setter.setArgbPre(dstarr, dstoff, getter.getArgbPre(srcarr, srcoff));
+                    } else {
+                        setter.setArgb(dstarr, dstoff, getter.getArgb(srcarr, srcoff));
+                    }
+                    srcoff += nSrcElems;
+                    dstoff += nDstElems;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= nSrcElems * w;
+            dstscanbytes -= nDstElems * w;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    if (usePremult) {
+                        setter.setArgbPre(dstbuf, dstoff, getter.getArgbPre(srcbuf, srcoff));
+                    } else {
+                        setter.setArgb(dstbuf, dstoff, getter.getArgb(srcbuf, srcoff));
+                    }
+                    srcoff += nSrcElems;
+                    dstoff += nDstElems;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+
+    static class ByteToIntGeneralConverter extends BaseByteToIntConverter {
+        boolean usePremult;
+
+        ByteToIntGeneralConverter(BytePixelGetter getter, IntPixelSetter setter) {
+            super(getter, setter);
+            usePremult = (getter.getAlphaType() != AlphaType.NONPREMULTIPLIED &&
+                          setter.getAlphaType() != AlphaType.NONPREMULTIPLIED);
+        }
+
+        @Override
+        void doConvert(byte srcarr[], int srcoff, int srcscanbytes,
+                       int  dstarr[], int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= nSrcElems * w;
+            dstscanbytes -= w;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    if (usePremult) {
+                        setter.setArgbPre(dstarr, dstoff, getter.getArgbPre(srcarr, srcoff));
+                    } else {
+                        setter.setArgb(dstarr, dstoff, getter.getArgb(srcarr, srcoff));
+                    }
+                    srcoff += nSrcElems;
+                    dstoff++;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(ByteBuffer srcbuf, int srcoff, int srcscanbytes,
+                       IntBuffer  dstbuf, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= nSrcElems * w;
+            dstscanbytes -= w;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    if (usePremult) {
+                        setter.setArgbPre(dstbuf, dstoff, getter.getArgbPre(srcbuf, srcoff));
+                    } else {
+                        setter.setArgb(dstbuf, dstoff, getter.getArgb(srcbuf, srcoff));
+                    }
+                    srcoff += nSrcElems;
+                    dstoff++;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+    static class IntToByteGeneralConverter extends BaseIntToByteConverter {
+        boolean usePremult;
+
+        public IntToByteGeneralConverter(IntPixelGetter getter, BytePixelSetter setter) {
+            super(getter, setter);
+            usePremult = (getter.getAlphaType() != AlphaType.NONPREMULTIPLIED &&
+                          setter.getAlphaType() != AlphaType.NONPREMULTIPLIED);
+        }
+
+        @Override
+        void doConvert(int  srcarr[], int srcoff, int srcscanbytes,
+                       byte dstarr[], int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w;
+            dstscanbytes -= nDstElems * w;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    if (usePremult) {
+                        setter.setArgbPre(dstarr, dstoff, getter.getArgbPre(srcarr, srcoff));
+                    } else {
+                        setter.setArgb(dstarr, dstoff, getter.getArgb(srcarr, srcoff));
+                    }
+                    srcoff++;
+                    dstoff += nDstElems;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(IntBuffer  srcbuf, int srcoff, int srcscanbytes,
+                       ByteBuffer dstbuf, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w;
+            dstscanbytes -= nDstElems * w;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    if (usePremult) {
+                        setter.setArgbPre(dstbuf, dstoff, getter.getArgbPre(srcbuf, srcoff));
+                    } else {
+                        setter.setArgb(dstbuf, dstoff, getter.getArgb(srcbuf, srcoff));
+                    }
+                    srcoff++;
+                    dstoff += nDstElems;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+    static class IntToIntGeneralConverter extends BaseIntToIntConverter {
+        boolean usePremult;
+
+        public IntToIntGeneralConverter(IntPixelGetter getter, IntPixelSetter setter) {
+            super(getter, setter);
+            usePremult = (getter.getAlphaType() != AlphaType.NONPREMULTIPLIED &&
+                          setter.getAlphaType() != AlphaType.NONPREMULTIPLIED);
+        }
+
+        @Override
+        void doConvert(int srcarr[], int srcoff, int srcscanbytes,
+                       int dstarr[], int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w;
+            dstscanbytes -= w;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    if (usePremult) {
+                        setter.setArgbPre(dstarr, dstoff, getter.getArgbPre(srcarr, srcoff));
+                    } else {
+                        setter.setArgb(dstarr, dstoff, getter.getArgb(srcarr, srcoff));
+                    }
+                    srcoff++;
+                    dstoff++;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+
+        @Override
+        void doConvert(IntBuffer srcbuf, int srcoff, int srcscanbytes,
+                       IntBuffer dstbuf, int dstoff, int dstscanbytes,
+                       int w, int h)
+        {
+            srcscanbytes -= w;
+            dstscanbytes -= w;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    if (usePremult) {
+                        setter.setArgbPre(dstbuf, dstoff, getter.getArgbPre(srcbuf, srcoff));
+                    } else {
+                        setter.setArgb(dstbuf, dstoff, getter.getArgb(srcbuf, srcoff));
+                    }
+                    srcoff++;
+                    dstoff++;
+                }
+                srcoff += srcscanbytes;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/IntArgb.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,294 @@
+/*
+ * 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 com.sun.javafx.image.AlphaType;
+import com.sun.javafx.image.IntPixelAccessor;
+import com.sun.javafx.image.IntPixelGetter;
+import com.sun.javafx.image.IntPixelSetter;
+import com.sun.javafx.image.IntToBytePixelConverter;
+import com.sun.javafx.image.IntToIntPixelConverter;
+import com.sun.javafx.image.PixelUtils;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+public class IntArgb {
+    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 =
+        IntArgb.ToByteBgraSameConv.nonpremul;
+    public static final IntToBytePixelConverter ToByteBgraPreConverter =
+        IntArgb.ToByteBgraPreConv.instance;
+    public static final IntToIntPixelConverter ToIntArgbConverter =
+        BaseIntToIntConverter.create(accessor);
+    public static final IntToIntPixelConverter ToIntArgbPreConverter =
+        IntArgb.ToIntArgbPreConv.instance;
+
+    static class Accessor implements IntPixelAccessor {
+        static final IntPixelAccessor instance = new Accessor();
+        private Accessor() {}
+
+        @Override
+        public AlphaType getAlphaType() {
+            return AlphaType.NONPREMULTIPLIED;
+        }
+
+        @Override
+        public int getNumElements() {
+            return 1;
+        }
+
+        @Override
+        public int getArgb(int arr[], int offset) {
+            return arr[offset];
+        }
+
+        @Override
+        public int getArgbPre(int arr[], int offset) {
+            return PixelUtils.NonPretoPre(arr[offset]);
+        }
+
+        @Override
+        public int getArgb(IntBuffer buffer, int offset) {
+            return buffer.get(offset);
+        }
+
+        @Override
+        public int getArgbPre(IntBuffer buffer, int offset) {
+            return PixelUtils.NonPretoPre(buffer.get(offset));
+        }
+
+        @Override
+        public void setArgb(int arr[], int offset, int argb) {
+            arr[offset] = argb;
+        }
+
+        @Override
+        public void setArgbPre(int arr[], int offset, int argbpre) {
+            arr[offset] = PixelUtils.PretoNonPre(argbpre);
+        }
+
+        @Override
+        public void setArgb(IntBuffer buffer, int offset, int argb) {
+            buffer.put(offset, argb);
+        }
+
+        @Override
+        public void setArgbPre(IntBuffer buffer, int offset, int argbpre) {
+            buffer.put(offset, PixelUtils.PretoNonPre(argbpre));
+        }
+    }
+
+    public static class ToIntArgbPreConv extends BaseIntToIntConverter {
+        public static final IntToIntPixelConverter instance =
+            new ToIntArgbPreConv();
+
+        private ToIntArgbPreConv() {
+            super(IntArgb.getter, IntArgbPre.setter);
+        }
+
+        @Override
+        void doConvert(int srcarr[], int srcoff, int srcscanints,
+                       int dstarr[], int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            srcscanints -= w;
+            dstscanints -= w;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int pixel = srcarr[srcoff++];
+                    int a = pixel >>> 24;
+                    if (a < 0xff) {
+                        if (a == 0) {
+                            pixel = 0;
+                        } else {
+                            int r = (((pixel >> 16) & 0xff) * a + 0x7f) / 0xff;
+                            int g = (((pixel >>  8) & 0xff) * a + 0x7f) / 0xff;
+                            int b = (((pixel      ) & 0xff) * a + 0x7f) / 0xff;
+                            pixel = (a << 24) | (r << 16) | (g << 8) | b;
+                        }
+                    }
+                    dstarr[dstoff++] = pixel;
+                }
+                srcoff += srcscanints;
+                dstoff += dstscanints;
+            }
+        }
+
+        @Override
+        void doConvert(IntBuffer srcbuf, int srcoff, int srcscanints,
+                       IntBuffer dstbuf, int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int pixel = srcbuf.get(srcoff + x);
+                    int a = pixel >>> 24;
+                    if (a < 0xff) {
+                        if (a == 0) {
+                            pixel = 0;
+                        } else {
+                            int r = (((pixel >> 16) & 0xff) * a + 0x7f) / 0xff;
+                            int g = (((pixel >>  8) & 0xff) * a + 0x7f) / 0xff;
+                            int b = (((pixel      ) & 0xff) * a + 0x7f) / 0xff;
+                            pixel = (a << 24) | (r << 16) | (g << 8) | b;
+                        }
+                    }
+                    dstbuf.put(dstoff + x, pixel);
+                }
+                srcoff += srcscanints;
+                dstoff += dstscanints;
+            }
+        }
+    }
+
+    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();
+
+        private ToByteBgraPreConv() {
+            super(IntArgb.getter, ByteBgraPre.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++];
+                    int a = pixel >>> 24;
+                    int r = pixel >>  16;
+                    int g = pixel >>   8;
+                    int b = pixel       ;
+                    if (a < 0xff) {
+                        if (a == 0) {
+                            b = g = r = 0;
+                        } else {
+                            b = ((b & 0xff) * a + 0x7f) / 0xff;
+                            g = ((g & 0xff) * a + 0x7f) / 0xff;
+                            r = ((r & 0xff) * a + 0x7f) / 0xff;
+                        }
+                    }
+                    dstarr[dstoff++] = (byte) b;
+                    dstarr[dstoff++] = (byte) g;
+                    dstarr[dstoff++] = (byte) r;
+                    dstarr[dstoff++] = (byte) a;
+                }
+                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);
+                    int a = pixel >>> 24;
+                    int r = pixel >>  16;
+                    int g = pixel >>   8;
+                    int b = pixel       ;
+                    if (a < 0xff) {
+                        if (a == 0) {
+                            b = g = r = 0;
+                        } else {
+                            b = ((b & 0xff) * a + 0x7f) / 0xff;
+                            g = ((g & 0xff) * a + 0x7f) / 0xff;
+                            r = ((r & 0xff) * a + 0x7f) / 0xff;
+                        }
+                    }
+                    dstbuf.put(dstoff    , (byte) b);
+                    dstbuf.put(dstoff + 1, (byte) g);
+                    dstbuf.put(dstoff + 2, (byte) r);
+                    dstbuf.put(dstoff + 3, (byte) a);
+                    dstoff += 4;
+                }
+                srcoff += srcscanints;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-common/src/com/sun/javafx/image/impl/IntArgbPre.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,231 @@
+/*
+ * 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 com.sun.javafx.image.AlphaType;
+import com.sun.javafx.image.IntPixelAccessor;
+import com.sun.javafx.image.IntPixelGetter;
+import com.sun.javafx.image.IntPixelSetter;
+import com.sun.javafx.image.IntToBytePixelConverter;
+import com.sun.javafx.image.IntToIntPixelConverter;
+import com.sun.javafx.image.PixelUtils;
+import java.nio.ByteBuffer;
+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 IntToBytePixelConverter ToByteBgraConverter =
+        IntArgbPre.ToByteBgraConv.instance;
+    public static final IntToBytePixelConverter ToByteBgraPreConverter =
+        IntArgb.ToByteBgraSameConv.premul;
+    public static final IntToIntPixelConverter ToIntArgbConverter =
+        IntArgbPre.ToIntArgbConv.instance;
+    public static final IntToIntPixelConverter ToIntArgbPreConverter =
+        BaseIntToIntConverter.create(accessor);
+
+    static class Accessor implements IntPixelAccessor {
+        static final IntPixelAccessor instance = new Accessor();
+        private Accessor() {}
+
+        @Override
+        public AlphaType getAlphaType() {
+            return AlphaType.PREMULTIPLIED;
+        }
+
+        @Override
+        public int getNumElements() {
+            return 1;
+        }
+
+        @Override
+        public int getArgb(int arr[], int offset) {
+            return PixelUtils.PretoNonPre(arr[offset]);
+        }
+
+        @Override
+        public int getArgbPre(int arr[], int offset) {
+            return arr[offset];
+        }
+
+        @Override
+        public int getArgb(IntBuffer buffer, int offset) {
+            return PixelUtils.PretoNonPre(buffer.get(offset));
+        }
+
+        @Override
+        public int getArgbPre(IntBuffer buffer, int offset) {
+            return buffer.get(offset);
+        }
+
+        @Override
+        public void setArgb(int arr[], int offset, int argb) {
+            arr[offset] = PixelUtils.NonPretoPre(argb);
+        }
+
+        @Override
+        public void setArgbPre(int arr[], int offset, int argbpre) {
+            arr[offset] = argbpre;
+        }
+
+        @Override
+        public void setArgb(IntBuffer buffer, int offset, int argb) {
+            buffer.put(offset, PixelUtils.NonPretoPre(argb));
+        }
+
+        @Override
+        public void setArgbPre(IntBuffer buffer, int offset, int argbpre) {
+            buffer.put(offset, argbpre);
+        }
+    }
+
+    public static class ToIntArgbConv extends BaseIntToIntConverter {
+        public static final IntToIntPixelConverter instance =
+            new ToIntArgbConv();
+
+        private ToIntArgbConv() {
+            super(IntArgbPre.getter, IntArgb.setter);
+        }
+
+        @Override
+        void doConvert(int srcarr[], int srcoff, int srcscanints,
+                       int dstarr[], int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            srcscanints -= w;
+            dstscanints -= w;
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int pixel = srcarr[srcoff++];
+                    int a = pixel >>> 24;
+                    if (a > 0 && a < 0xff) {
+                        int halfa = a >> 1;
+                        int r = (((pixel >> 16) & 0xff) * 0xff + halfa) / a;
+                        int g = (((pixel >>  8) & 0xff) * 0xff + halfa) / a;
+                        int b = (((pixel      ) & 0xff) * 0xff + halfa) / a;
+                        pixel = (a << 24) | (r << 16) | (g << 8) | b;
+                    }
+                    dstarr[dstoff++] = pixel;
+                }
+                srcoff += srcscanints;
+                dstoff += dstscanints;
+            }
+        }
+
+        @Override
+        void doConvert(IntBuffer srcbuf, int srcoff, int srcscanints,
+                       IntBuffer dstbuf, int dstoff, int dstscanints,
+                       int w, int h)
+        {
+            while (--h >= 0) {
+                for (int x = 0; x < w; x++) {
+                    int pixel = srcbuf.get(srcoff + x);
+                    int a = pixel >>> 24;
+                    if (a > 0 && a < 0xff) {
+                        int halfa = a >> 1;
+                        int r = (((pixel >> 16) & 0xff) * 0xff + halfa) / a;
+                        int g = (((pixel >>  8) & 0xff) * 0xff + halfa) / a;
+                        int b = (((pixel      ) & 0xff) * 0xff + halfa) / a;
+                        pixel = (a << 24) | (r << 16) | (g << 8) | b;
+                    }
+                    dstbuf.put(dstoff + x, pixel);
+                }
+                srcoff += srcscanints;
+                dstoff += dstscanints;
+            }
+        }
+    }
+
+    static class ToByteBgraConv extends BaseIntToByteConverter {
+        public static final IntToBytePixelConverter instance =
+            new ToByteBgraConv();
+
+        private ToByteBgraConv() {
+            super(IntArgbPre.getter, 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++];
+                    int a = pixel >>> 24;
+                    int r = (pixel >> 16) & 0xff;
+                    int g = (pixel >>  8) & 0xff;
+                    int b = (pixel      ) & 0xff;
+                    if (a > 0 && a < 0xff) {
+                        int halfa = a >> 1;
+                        r = (r * 0xff + halfa) / a;
+                        g = (g * 0xff + halfa) / a;
+                        b = (b * 0xff + halfa) / a;
+                    }
+                    dstarr[dstoff++] = (byte) b;
+                    dstarr[dstoff++] = (byte) g;
+                    dstarr[dstoff++] = (byte) r;
+                    dstarr[dstoff++] = (byte) a;
+                }
+                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);
+                    int a = pixel >>> 24;
+                    int r = (pixel >> 16) & 0xff;
+                    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;
+                    }
+                    dstbuf.put(dstoff    , (byte) b);
+                    dstbuf.put(dstoff + 1, (byte) g);
+                    dstbuf.put(dstoff + 2, (byte) r);
+                    dstbuf.put(dstoff + 3, (byte) a);
+                    dstoff += 4;
+                }
+                srcoff += srcscanints;
+                dstoff += dstscanbytes;
+            }
+        }
+    }
+}
--- a/javafx-ui-common/src/com/sun/javafx/scene/input/InputEventUtils.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/com/sun/javafx/scene/input/InputEventUtils.java	Thu Jun 28 12:36:02 2012 +0200
@@ -56,14 +56,24 @@
             if (oldSourceNode != null) {
                 Point2D pt = oldSourceNode.localToScene(newX, newY);
                 pt = newSourceNode.sceneToLocal(pt);
-                newX = pt.getX();
-                newY = pt.getY();
+                if (pt != null) {
+                    newX = pt.getX();
+                    newY = pt.getY();
+                } else {
+                    newX = Double.NaN;
+                    newY = Double.NaN;
+                }
             } else {
                 // assume that since no node was in the evt, then it was in
                 // terms of the scene
                 Point2D pt = newSourceNode.sceneToLocal(newX, newY);
-                newX = pt.getX();
-                newY = pt.getY();
+                if (pt != null) {
+                    newX = pt.getX();
+                    newY = pt.getY();
+                } else {
+                    newX = Double.NaN;
+                    newY = Double.NaN;
+                }
             }
         } else {
             if (oldSourceNode != null) {
--- a/javafx-ui-common/src/com/sun/javafx/tk/PlatformImage.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/com/sun/javafx/tk/PlatformImage.java	Thu Jun 28 12:36:02 2012 +0200
@@ -26,7 +26,10 @@
 package com.sun.javafx.tk;
 
 import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
 import javafx.scene.image.PixelFormat;
+import javafx.scene.image.PixelReader;
 import javafx.scene.image.WritablePixelFormat;
 
 /**
@@ -50,21 +53,6 @@
     public void setArgb(int x, int y, int argb);
 
     /**
-     * @param x X coordinate of pixel
-     * @param y Y coordinate of pixel
-     * @return the premultiplied pixel in integer ARGB component ordering.
-     */
-    public int getArgbPre(int x, int y);
-
-    /**
-     * @param x X coordinate of pixel
-     * @param y Y coordinate of pixel
-     * @param argbpre premultiplied pixel data to store in integer ARGB
-     *  component ordering
-     */
-    public void setArgbPre(int x, int y, int argbpre);
-
-    /**
      * @return the PixelFormat to use for the pixel data transfer methods
      * getPixels() and setPixels().
      */
@@ -73,13 +61,30 @@
     public boolean isWritable();
     public PlatformImage promoteToWritableImage();
 
-    public <T extends Buffer>
-        void getPixels(int x, int y, int w, int h,
-                       T pixels, WritablePixelFormat<T> pixelformat,
-                       int scanlineBytes);
-    
-    public <T extends Buffer>
-        void setPixels(int x, int y, int w, int h,
-                       T pixels, PixelFormat<T> pixelformat,
-                       int scanlineBytes);
+    public <T extends Buffer> void getPixels(int x, int y, int w, int h,
+                                             WritablePixelFormat<T> pixelformat,
+                                             T pixels, int scanlineElems);
+
+    public void getPixels(int x, int y, int w, int h,
+                          WritablePixelFormat<ByteBuffer> pixelformat,
+                          byte pixels[], int offset, int scanlineBytes);
+
+    public void getPixels(int x, int y, int w, int h,
+                          WritablePixelFormat<IntBuffer> pixelformat,
+                          int pixels[], int offset, int scanlineInts);
+
+    public <T extends Buffer> void setPixels(int x, int y, int w, int h,
+                                             PixelFormat<T> pixelformat,
+                                             T pixels, int scanlineBytes);
+
+    public void setPixels(int x, int y, int w, int h,
+                          PixelFormat<ByteBuffer> pixelformat,
+                          byte pixels[], int offset, int scanlineBytes);
+
+    public void setPixels(int x, int y, int w, int h,
+                          PixelFormat<IntBuffer> pixelformat,
+                          int pixels[], int offset, int scanlineInts);
+
+    public void setPixels(int dstx, int dsty, int w, int h,
+                          PixelReader reader, int srcx, int srcy);
 }
--- a/javafx-ui-common/src/javafx/scene/Node.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/javafx/scene/Node.java	Thu Jun 28 12:36:02 2012 +0200
@@ -6151,7 +6151,7 @@
      */
     final class FocusedProperty extends ReadOnlyBooleanPropertyBase {
         private boolean value;
-        private boolean valid;
+        private boolean valid = true;
         private boolean needsChangeEvent = false;
 
         public void store(final boolean value) {
--- a/javafx-ui-common/src/javafx/scene/Scene.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/javafx/scene/Scene.java	Thu Jun 28 12:36:02 2012 +0200
@@ -1051,7 +1051,10 @@
      */
     @Deprecated
     public Object renderToImage(Object platformImage, float scale) {
-        Toolkit.getToolkit().checkFxUserThread();
+        if (!paused) {
+            Toolkit.getToolkit().checkFxUserThread();
+        }
+
         // NOTE: that we no longer use the passed in platform image. Since this
         // API is deprecated and will be removed in 3.0 this is not a concern.
         // Also, we used to return a TK image loader and now we return
@@ -1234,7 +1237,10 @@
      * @return the rendered image
      */
     public WritableImage snapshot(WritableImage image) {
-        Toolkit.getToolkit().checkFxUserThread();
+        if (!paused) {
+            Toolkit.getToolkit().checkFxUserThread();
+        }
+
         return  doSnapshot(image, 1.0f);
     }
 
@@ -1635,6 +1641,10 @@
                         break;
                 }
 
+                for (TouchPoint t : touchPoints) {
+                    t.impl_reset();
+                }
+
                 TouchEvent te = TouchEvent.impl_touchEvent(type, tp, touchList,
                         touchEventSetId, e.isShiftDown(), e.isControlDown(),
                         e.isAltDown(), e.isMetaDown());
@@ -2451,7 +2461,8 @@
                 throw new RuntimeException("Too many touch points reported");
             }
 
-            touchPoints[order] = new TouchPoint(id, state, x, y, xAbs, yAbs);
+            touchPoints[order] = TouchPoint.impl_touchPoint(id, state,
+                    x, y, xAbs, yAbs);
         }
 
         @Override
--- a/javafx-ui-common/src/javafx/scene/canvas/Canvas.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/javafx/scene/canvas/Canvas.java	Thu Jun 28 12:36:02 2012 +0200
@@ -251,7 +251,9 @@
     @Deprecated
     @Override
     public BaseBounds impl_computeGeomBounds(BaseBounds bounds, BaseTransform tx) {
-        return new RectBounds(0f, 0f, (float) getWidth(), (float) getHeight());
+        bounds = new RectBounds(0f, 0f, (float) getWidth(), (float) getHeight());  
+        bounds = tx.transform(bounds, bounds);
+        return bounds;
     }
 
     /**
--- a/javafx-ui-common/src/javafx/scene/canvas/GraphicsContext.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/javafx/scene/canvas/GraphicsContext.java	Thu Jun 28 12:36:02 2012 +0200
@@ -29,6 +29,15 @@
 import com.sun.javafx.geom.PathIterator;
 import com.sun.javafx.geom.transform.Affine2D;
 import com.sun.javafx.geom.transform.NoninvertibleTransformException;
+import com.sun.javafx.image.BytePixelGetter;
+import com.sun.javafx.image.BytePixelSetter;
+import com.sun.javafx.image.ByteToBytePixelConverter;
+import com.sun.javafx.image.IntPixelGetter;
+import com.sun.javafx.image.IntToBytePixelConverter;
+import com.sun.javafx.image.PixelConverter;
+import com.sun.javafx.image.PixelGetter;
+import com.sun.javafx.image.PixelUtils;
+import com.sun.javafx.image.impl.ByteBgraPre;
 import com.sun.javafx.sg.GrowableDataBuffer;
 import com.sun.javafx.sg.PGCanvas;
 import java.nio.Buffer;
@@ -788,10 +797,25 @@
     }
 
     /**
-     * Sets the current TextAlignment attribute
+     * Defines horizontal text alignment, relative to the text {@code x} origin.
+     * <p>
+     * Let horizontal bounds represent the logical width of a single line of
+     * text. Where each line of text has a separate horizontal bounds.
+     * <p>
+     * Then TextAlignment is specified as:
+     * <ul>
+     * <li>Left: the left edge of the horizontal bounds will be at {@code x}.
+     * <li>Center: the center, halfway between left and right edge, of the 
+     * horizontal bounds will be at {@code x}.
+     * <li>Right: the right edge of the horizontal bounds will be at {@code x}.
+     * </ul>
+     * <p>
+     *
+     * Note: Canvas does not support line wrapping, therefore the text
+     * alignment Justify is identical to left aligned text.
+     * <p>
      * 
-     * @param align {@code TextAlignment} with values of Left, Center, Right, or
-     * Justify.
+     * @param align {@code TextAlignment} with values of Left, Center, Right.
      */
     public void setTextAlign(TextAlignment align) {
         if (curState.textalign != align) {
@@ -1655,6 +1679,10 @@
                     return PixelFormat.getByteBgraPreInstance();
                 }
 
+                private BytePixelSetter getSetter() {
+                    return ByteBgraPre.setter;
+                }
+
                 @Override
                 public void setArgb(int x, int y, int argb) {
                     GrowableDataBuffer buf = getBuffer();
@@ -1673,18 +1701,98 @@
                     setArgb(x, y, (a << 24) | (r << 16) | (g << 8) | b);
                 }
 
+                private void writePixelBuffer(int x, int y, int w, int h,
+                                              byte[] pixels)
+                {
+                    GrowableDataBuffer buf = getBuffer();
+                    buf.putByte(PGCanvas.PUT_ARGBPRE_BUF);
+                    buf.putInt(x);
+                    buf.putInt(y);
+                    buf.putInt(w);
+                    buf.putInt(h);
+                    buf.putObject(pixels);
+                }
+
+                private int[] checkBounds(int x, int y, int w, int h,
+                                          PixelFormat pf, int scan)
+                {
+                    // assert (w >= 0 && h >= 0) - checked by caller
+                    int cw = (int) theCanvas.getWidth();
+                    int ch = (int) theCanvas.getHeight();
+                    if (x >= 0 && y >= 0 && x+w <= cw && y+h <= ch) {
+                        return null;
+                    }
+                    int offset = 0;
+                    if (x < 0) {
+                        w += x;
+                        if (w < 0) return null;
+                        if (pf != null) {
+                            switch (pf.getType()) {
+                                case BYTE_BGRA:
+                                case BYTE_BGRA_PRE:
+                                    offset -= x * 4;
+                                    break;
+                                case BYTE_RGB:
+                                    offset -= x * 3;
+                                    break;
+                                case BYTE_INDEXED:
+                                case INT_ARGB:
+                                case INT_ARGB_PRE:
+                                    offset -= x;
+                                    break;
+                                default:
+                                    throw new InternalError("unknown Pixel Format");
+                            }
+                        }
+                        x = 0;
+                    }
+                    if (y < 0) {
+                        h += y;
+                        if (h < 0) return null;
+                        offset -= y * scan;
+                        y = 0;
+                    }
+                    if (x + w > cw) {
+                        w = cw - x;
+                        if (w < 0) return null;
+                    }
+                    if (y + h > ch) {
+                        h = ch - y;
+                        if (h < 0) return null;
+                    }
+                    return new int[] {
+                        x, y, w, h, offset
+                    };
+                }
+
                 @Override
                 public <T extends Buffer> void
                     setPixels(int x, int y, int w, int h,
                               PixelFormat<T> pixelformat,
                               T buffer, int scan)
                 {
-                    for (int j = 0; j < h; j++) {
-                        for (int i = 0; i < w; i++) {
-                            int argb = pixelformat.getArgb(buffer, i, j, scan);
-                            setArgb(x + i, y + j, argb);
-                        }
+                    if (w <= 0 || h <= 0) return;
+                    int offset = buffer.position();
+                    int adjustments[] = checkBounds(x, y, w, h,
+                                                    pixelformat, scan);
+                    if (adjustments != null) {
+                        x = adjustments[0];
+                        y = adjustments[1];
+                        w = adjustments[2];
+                        h = adjustments[3];
+                        offset += adjustments[4];
                     }
+
+                    byte pixels[] = new byte[w * h * 4];
+                    ByteBuffer dst = ByteBuffer.wrap(pixels);
+
+                    PixelGetter<T> getter = PixelUtils.getGetter(pixelformat);
+                    PixelConverter<T, ByteBuffer> converter =
+                        PixelUtils.getConverter(getter, getSetter());
+                    converter.convert(buffer, offset, scan,
+                                      dst, 0, w * 4,
+                                      w, h);
+                    writePixelBuffer(x, y, w, h, pixels);
                 }
 
                 @Override
@@ -1692,9 +1800,26 @@
                                       PixelFormat<ByteBuffer> pixelformat,
                                       byte[] buffer, int offset, int scanlineStride)
                 {
-                    ByteBuffer bytebuf = ByteBuffer.wrap(buffer);
-                    bytebuf.position(offset);
-                    setPixels(x, y, w, h, pixelformat, bytebuf, scanlineStride);
+                    if (w <= 0 || h <= 0) return;
+                    int adjustments[] = checkBounds(x, y, w, h,
+                                                    pixelformat, scanlineStride);
+                    if (adjustments != null) {
+                        x = adjustments[0];
+                        y = adjustments[1];
+                        w = adjustments[2];
+                        h = adjustments[3];
+                        offset += adjustments[4];
+                    }
+
+                    byte pixels[] = new byte[w * h * 4];
+
+                    BytePixelGetter getter = PixelUtils.getByteGetter(pixelformat);
+                    ByteToBytePixelConverter converter =
+                        PixelUtils.getB2BConverter(getter, getSetter());
+                    converter.convert(buffer, offset, scanlineStride,
+                                      pixels, 0, w * 4,
+                                      w, h);
+                    writePixelBuffer(x, y, w, h, pixels);
                 }
 
                 @Override
@@ -1702,21 +1827,50 @@
                                       PixelFormat<IntBuffer> pixelformat,
                                       int[] buffer, int offset, int scanlineStride)
                 {
-                    IntBuffer bytebuf = IntBuffer.wrap(buffer);
-                    bytebuf.position(offset);
-                    setPixels(x, y, w, h, pixelformat, bytebuf, scanlineStride);
+                    if (w <= 0 || h <= 0) return;
+                    int adjustments[] = checkBounds(x, y, w, h,
+                                                    pixelformat, scanlineStride);
+                    if (adjustments != null) {
+                        x = adjustments[0];
+                        y = adjustments[1];
+                        w = adjustments[2];
+                        h = adjustments[3];
+                        offset += adjustments[4];
+                    }
+
+                    byte pixels[] = new byte[w * h * 4];
+
+                    IntPixelGetter getter = PixelUtils.getIntGetter(pixelformat);
+                    IntToBytePixelConverter converter =
+                        PixelUtils.getI2BConverter(getter, getSetter());
+                    converter.convert(buffer, offset, scanlineStride,
+                                      pixels, 0, w * 4,
+                                      w, h);
+                    writePixelBuffer(x, y, w, h, pixels);
                 }
 
                 @Override
                 public void setPixels(int dstx, int dsty, int w, int h,
                                       PixelReader reader, int srcx, int srcy)
                 {
-                    for (int j = 0; j < h; j++) {
-                        for (int i = 0; i < w; i++) {
-                            int argb = reader.getArgb(srcx + i, srcy + j);
-                            setArgb(dstx + i, dsty + j, argb);
-                        }
+                    if (w <= 0 || h <= 0) return;
+                    int adjustments[] = checkBounds(dstx, dsty, w, h, null, 0);
+                    if (adjustments != null) {
+                        int newx = adjustments[0];
+                        int newy = adjustments[1];
+                        srcx += newx - dstx;
+                        srcy += newy - dsty;
+                        dstx = newx;
+                        dsty = newy;
+                        w = adjustments[2];
+                        h = adjustments[3];
                     }
+
+                    byte pixels[] = new byte[w * h * 4];
+                    reader.getPixels(srcx, srcy, w, h,
+                                     PixelFormat.getByteBgraPreInstance(),
+                                     pixels, 0, w * 4);
+                    writePixelBuffer(dstx, dsty, w, h, pixels);
                 }
             };
         }
--- a/javafx-ui-common/src/javafx/scene/image/Image.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/javafx/scene/image/Image.java	Thu Jun 28 12:36:02 2012 +0200
@@ -647,18 +647,18 @@
     }
 
     /**
-     * Construct a new empty {@code Image} with the specified dimensions
-     * filled with transparent pixels to be used with the
-     * {@link #setArgb(int, int, int) setArgb()}
-     * and
-     * {@link #setColor(int, int, javafx.scene.paint.Color) setColor()}
-     * methods to create a completely custom image.
+     * Package private internal constructor used only by {@link WritableImage}.
+     * The dimensions must both be positive numbers <code>(&gt;&nbsp;0)</code>.
      * 
      * @param width the width of the empty image
      * @param height the height of the empty image
+     * @throws IllegalArgumentException if either dimension is negative or zero.
      */
     Image(int width, int height) {
         this(null, null, width, height, false, false, false);
+        if (width <= 0 || height <= 0) {
+            throw new IllegalArgumentException("Image dimensions must be positive (w,h > 0)");
+        }
         initialize(Toolkit.getToolkit().createPlatformImage(width, height));
     }
 
@@ -1091,7 +1091,7 @@
      * 
      * @return the {@code PixelReader} for reading the pixel data of the image
      */
-    public PixelReader getPixelReader() {
+    public final PixelReader getPixelReader() {
         if (!pixelsReadable()) {
             return null;
         }
@@ -1100,9 +1100,6 @@
                 @Override
                 public PixelFormat getPixelFormat() {
                     PlatformImage pimg = platformImage.get();
-//                    if (pimg == null) {
-//                        return null;
-//                    }
                     return pimg.getPlatformPixelFormat();
                 }
 
@@ -1129,14 +1126,8 @@
                                    T buffer, int scanlineStride)
                 {
                     PlatformImage pimg = platformImage.get();
-                    for (int j = 0; j < h; j++) {
-                        for (int i = 0; i < w; i++) {
-                            pixelformat.setArgb(buffer, i, j, scanlineStride,
-                                                pimg.getArgb(x+i, y+j));
-                        }
-                    }
-//                    checkPixelAccess(true, false).getPixels(x, y, w, h,
-//                                                            buffer, pixelformat, scanlineStride);
+                    pimg.getPixels(x, y, w, h, pixelformat,
+                                   buffer, scanlineStride);
                 }
 
                 @Override
@@ -1144,11 +1135,9 @@
                                     WritablePixelFormat<ByteBuffer> pixelformat,
                                     byte buffer[], int offset, int scanlineStride)
                 {
-                    ByteBuffer bytebuf = ByteBuffer.wrap(buffer);
-                    bytebuf.position(offset);
-                    getPixels(x, y, w, h, pixelformat, bytebuf, scanlineStride);
-//                    checkPixelAccess(true, false).getPixels(x, y, w, h,
-//                                                            buffer, pixelformat, scanlineStride);
+                    PlatformImage pimg = platformImage.get();
+                    pimg.getPixels(x, y, w, h, pixelformat,
+                                   buffer, offset, scanlineStride);
                 }
 
                 @Override
@@ -1156,11 +1145,9 @@
                                     WritablePixelFormat<IntBuffer> pixelformat,
                                     int buffer[], int offset, int scanlineStride)
                 {
-                    IntBuffer intbuf = IntBuffer.wrap(buffer);
-                    intbuf.position(offset);
-                    getPixels(x, y, w, h, pixelformat, intbuf, scanlineStride);
-//                    checkPixelAccess(true, false).getPixels(x, y, w, h,
-//                                                            buffer, pixelformat, scanlineStride);
+                    PlatformImage pimg = platformImage.get();
+                    pimg.getPixels(x, y, w, h, pixelformat,
+                                   buffer, offset, scanlineStride);
                 }
             };
         }
@@ -1171,6 +1158,7 @@
         PlatformImage pimg = platformImage.get();
         if (!pimg.isWritable()) {
             pimg = pimg.promoteToWritableImage();
+            // assert pimg.isWritable();
             platformImage.set(pimg);
         }
         return pimg;
--- a/javafx-ui-common/src/javafx/scene/image/WritableImage.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/javafx/scene/image/WritableImage.java	Thu Jun 28 12:36:02 2012 +0200
@@ -62,9 +62,11 @@
      * Images constructed this way will always be readable and writable
      * so the corresponding getPixelReader() and getPixelWriter() will
      * always return valid objects.
+     * The dimensions must both be positive numbers <code>(&gt;&nbsp;0)</code>.
      * 
      * @param width the desired width of the writable image
      * @param height the desired height of the desired image
+     * @throws IllegalArgumentException if either dimension is negative or zero.
      */
     public WritableImage(int width, int height) {
         super(width, height);
@@ -81,6 +83,7 @@
      * Images constructed this way will always be readable and writable
      * so the corresponding getPixelReader() and getPixelWriter() will
      * always return valid objects.
+     * The dimensions must both be positive numbers <code>(&gt;&nbsp;0)</code>.
      * 
      * @param width the desired width of the writable image and the
      *        width of the region to be read from the {@code reader}
@@ -88,6 +91,7 @@
      *        width of the region to be read from the {@code reader}
      * @throws ArrayIndexOutOfBoundsException if the {@code reader} does
      *         not access a surface of at least the requested dimensions
+     * @throws IllegalArgumentException if either dimension is negative or zero.
      */
     public WritableImage(PixelReader reader, int width, int height) {
         super(width, height);
@@ -105,6 +109,7 @@
      * Images constructed this way will always be readable and writable
      * so the corresponding getPixelReader() and getPixelWriter() will
      * always return valid objects.
+     * The dimensions must both be positive numbers <code>(&gt;&nbsp;0)</code>.
      * 
      * @param x the X coordinate of the upper left corner of the region to
      *        read from the {@code reader}
@@ -116,6 +121,7 @@
      *        width of the region to be read from the {@code reader}
      * @throws ArrayIndexOutOfBoundsException if the {@code reader} does
      *         not access a surface containing at least the indicated region
+     * @throws IllegalArgumentException if either dimension is negative or zero.
      */
     public WritableImage(PixelReader reader,
                          int x, int y, int width, int height)
@@ -141,7 +147,7 @@
      * 
      * @return the {@code PixelWriter} for writing pixels to the image
      */
-    public PixelWriter getPixelWriter() {
+    public final PixelWriter getPixelWriter() {
         if (getProgress() < 1.0 || isError()) {
             return null;
         }
@@ -178,15 +184,8 @@
                                    T buffer, int scanlineStride)
                 {
                     PlatformImage pimg = getWritablePlatformImage();
-                    for (int j = 0; j < h; j++) {
-                        for (int i = 0; i < w; i++) {
-                            int argb = pixelformat.getArgb(buffer, i, j,
-                                                           scanlineStride);
-                            pimg.setArgb(x+i, y+j, argb);
-                        }
-                    }
-//                    checkPixelAccess(true, true).setPixels(x, y, w, h,
-//                                                           buffer, pixelformat, scanlineStride);
+                    pimg.setPixels(x, y, w, h, pixelformat,
+                                   buffer, scanlineStride);
                     pixelsDirty();
                 }
 
@@ -195,11 +194,10 @@
                                       PixelFormat<ByteBuffer> pixelformat,
                                       byte buffer[], int offset, int scanlineStride)
                 {
-                    ByteBuffer bytebuf = ByteBuffer.wrap(buffer);
-                    bytebuf.position(offset);
-                    setPixels(x, y, w, h, pixelformat, bytebuf, scanlineStride);
-//                    checkPixelAccess(true, false).getPixels(x, y, w, h,
-//                                                            buffer, pixelformat, scanlineStride);
+                    PlatformImage pimg = getWritablePlatformImage();
+                    pimg.setPixels(x, y, w, h, pixelformat,
+                                   buffer, offset, scanlineStride);
+                    pixelsDirty();
                 }
 
                 @Override
@@ -207,23 +205,19 @@
                                       PixelFormat<IntBuffer> pixelformat,
                                       int buffer[], int offset, int scanlineStride)
                 {
-                    IntBuffer intbuf = IntBuffer.wrap(buffer);
-                    intbuf.position(offset);
-                    setPixels(x, y, w, h, pixelformat, intbuf, scanlineStride);
-//                    checkPixelAccess(true, false).getPixels(x, y, w, h,
-//                                                            buffer, pixelformat, scanlineStride);
+                    PlatformImage pimg = getWritablePlatformImage();
+                    pimg.setPixels(x, y, w, h, pixelformat,
+                                   buffer, offset, scanlineStride);
+                    pixelsDirty();
                 }
 
                 @Override
                 public void setPixels(int writex, int writey, int w, int h,
                                       PixelReader reader, int readx, int ready)
                 {
-                    for (int y = 0; y < h; y++) {
-                        for (int x = 0; x < w; x++) {
-                            setArgb(writex + x, writey + y,
-                                    reader.getArgb(readx + x, ready + y));
-                        }
-                    }
+                    PlatformImage pimg = getWritablePlatformImage();
+                    pimg.setPixels(writex, writey, w, h, reader, readx, ready);
+                    pixelsDirty();
                 }
             };
         }
--- a/javafx-ui-common/src/javafx/scene/input/ContextMenuEvent.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/javafx/scene/input/ContextMenuEvent.java	Thu Jun 28 12:36:02 2012 +0200
@@ -83,12 +83,10 @@
     private void recomputeCoordinatesToSource(ContextMenuEvent newEvent, Object newSource) {
 
         final Point2D newCoordinates = InputEventUtils.recomputeCoordinates(
-                new Point2D(x, y), source, newSource);
+                new Point2D(sceneX, sceneY), null, newSource);
 
         newEvent.x = newCoordinates.getX();
         newEvent.y = newCoordinates.getY();
-        newEvent.sceneX = getSceneX();
-        newEvent.sceneY = getSceneY();
     }
 
     @Override
--- a/javafx-ui-common/src/javafx/scene/input/DragEvent.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/javafx/scene/input/DragEvent.java	Thu Jun 28 12:36:02 2012 +0200
@@ -410,7 +410,7 @@
         }
 
         final Point2D newCoordinates = InputEventUtils.recomputeCoordinates(
-                new Point2D(x, y), source, newSource);
+                new Point2D(sceneX, sceneY), null, newSource);
 
         newEvent.x = newCoordinates.getX();
         newEvent.y = newCoordinates.getY();
--- a/javafx-ui-common/src/javafx/scene/input/GestureEvent.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/javafx/scene/input/GestureEvent.java	Thu Jun 28 12:36:02 2012 +0200
@@ -93,12 +93,10 @@
     private void recomputeCoordinatesToSource(GestureEvent newEvent, Object newSource) {
 
         final Point2D newCoordinates = InputEventUtils.recomputeCoordinates(
-                new Point2D(x, y), source, newSource);
+                new Point2D(sceneX, sceneY), null, newSource);
 
         newEvent.x = newCoordinates.getX();
         newEvent.y = newCoordinates.getY();
-        newEvent.sceneX = getSceneX();
-        newEvent.sceneY = getSceneY();
     }
 
     /**
--- a/javafx-ui-common/src/javafx/scene/input/MouseEvent.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/javafx/scene/input/MouseEvent.java	Thu Jun 28 12:36:02 2012 +0200
@@ -274,12 +274,10 @@
     private void recomputeCoordinatesToSource(MouseEvent newEvent, Object newSource) {
 
         final Point2D newCoordinates = InputEventUtils.recomputeCoordinates(
-                new Point2D(x, y), source, newSource);
+                new Point2D(sceneX, sceneY), null, newSource);
 
         newEvent.x = newCoordinates.getX();
         newEvent.y = newCoordinates.getY();
-        newEvent.sceneX = getSceneX();
-        newEvent.sceneY = getSceneY();
     }
 
     /**
@@ -354,6 +352,9 @@
                         : (EventType<? extends MouseEvent>)
                                 evt.getEventType()));
 
+        copyEvent.sceneX = evt.sceneX;
+        copyEvent.sceneY = evt.sceneY;
+
         evt.recomputeCoordinatesToSource(copyEvent, source);
         return copyEvent;
     }
--- a/javafx-ui-common/src/javafx/scene/input/TouchPoint.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/javafx/scene/input/TouchPoint.java	Thu Jun 28 12:36:02 2012 +0200
@@ -55,7 +55,7 @@
     private transient EventTarget target;
     private transient Object source;
 
-    public TouchPoint(int id, State state, double x, double y, double screenX,
+    private TouchPoint(int id, State state, double x, double y, double screenX,
             double screenY) {
         this.target = null;
         this.id = id;
@@ -77,7 +77,7 @@
     void recomputeToSource(Object oldSource, Object newSource) {
 
         final Point2D newCoordinates = InputEventUtils.recomputeCoordinates(
-                new Point2D(x, y), oldSource, newSource);
+                new Point2D(sceneX, sceneY), null, newSource);
 
         x = newCoordinates.getX();
         y = newCoordinates.getY();
@@ -122,6 +122,16 @@
         this.target = target;
     }
 
+    /**
+     * @treatAsPrivate implementation detail
+     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
+     */
+    @Deprecated
+    public void impl_reset() {
+        x = sceneX;
+        y = sceneY;
+    }
+
     private EventTarget grabbed = null;
 
     /**
@@ -292,6 +302,16 @@
     }
 
     /**
+     * @treatAsPrivate implementation detail
+     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
+     */
+    @Deprecated
+    public static TouchPoint impl_touchPoint(
+            int id, State state, double x, double y, double screenX, double screenY) {
+        return new TouchPoint(id, state, x, y, screenX, screenY);
+    }
+
+    /**
      * Represents current state of the touch point
      */
     public enum State {
--- a/javafx-ui-common/src/javafx/scene/layout/GridPane.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/javafx/scene/layout/GridPane.java	Thu Jun 28 12:36:02 2012 +0200
@@ -1589,27 +1589,47 @@
         }
 
         double available = extraHeight; // will be negative in shrinking case
-        while (Math.abs(available) > 1.0 && adjusting.size() > 0) {
-            final double portion = available / adjusting.size(); // negative in shrinking case
-            for (int i = 0; i < adjusting.size(); i++) {
-                final int index = adjusting.get(i);
-                final double limit = (shrinking? rowMinHeight[index] : rowMaxHeight[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;
-                available -= change;
-                if (Math.abs(change) < Math.abs(portion)) {
-                    adjusted.add(index);
+        boolean handleRemainder = false;
+        int portion = 0;
+        while (available != 0 && adjusting.size() > 0) {
+            if (!handleRemainder) {
+                portion = (int)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])
+                            - 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;                
+                    available -= change;
+                    if (Math.abs(change) < Math.abs(portion)) {
+                        adjusted.add(index);
+                    }
+                    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();
+                if (portion == 0) {
+                    break;
+                } else {
+                    // We have a remainder evenly distribute it.
+                    portion = shrinking ? -1 : 1;
+                    handleRemainder = true;
                 }
             }
-            for (int i = 0; i < adjusted.size(); i++) {
-                adjusting.remove(adjusted.get(i));
-            }
-            adjusted.clear();
         }
+                        
         for (int i = 0; i < rowHeights.length; i++) {
-            rowHeights[i] = snapSpace(rowHeights[i]);
+            rowHeights[i] = snapSpace(rowHeights[i]);            
         }
         return available; // might be negative in shrinking case
     }
@@ -1662,26 +1682,47 @@
                 adjusting.add(i);
             }
         }
+        
         double available = extraWidth; // will be negative in shrinking case
-        while (Math.abs(available) > 1.0 && adjusting.size() > 0) {            
-            final double portion = available / adjusting.size(); // negative in shrinking case
-            for (int i = 0; i < adjusting.size(); i++) {
-                final int index = adjusting.get(i);
-                final double limit = (shrinking? columnMinWidth[index] : columnMaxWidth[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}");
-                available -= change;
-                if (Math.abs(change) < Math.abs(portion)) {
-                    adjusted.add(index);
+        boolean handleRemainder = false;
+        int portion = 0;
+        while (available != 0 && adjusting.size() > 0) {            
+            if (!handleRemainder) {
+                portion = (int)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])
+                            - 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}");
+                    available -= change;
+                    if (Math.abs(change) < Math.abs(portion)) {
+                        adjusted.add(index);
+                    }
+                    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();
+                if (portion == 0) {
+                    break;
+                } else {
+                    // We have a remainder evenly distribute it.
+                    portion = shrinking ? -1 : 1;
+                    handleRemainder = true;
                 }
             }
-            for (int i = 0; i < adjusted.size(); i++) {
-                adjusting.remove(adjusted.get(i));
-            }
-            adjusted.clear();
         }
+               
         for (int i = 0; i < columnWidths.length; i++) {
             columnWidths[i] = snapSpace(columnWidths[i]);
         }
--- a/javafx-ui-common/src/javafx/scene/text/Font.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/javafx/scene/text/Font.java	Thu Jun 28 12:36:02 2012 +0200
@@ -386,7 +386,7 @@
      * <code>Font</code> object will be returned.
      * <p>
      * Any failure such as abbreviated input, or an unsupported font format
-     * will result in a code>null</code> return. It is the application's
+     * will result in a <code>null</code> return. It is the application's
      * responsibility to check this before use.
      * <p>
      * On a successful (non-null) return the font will be registered
--- a/javafx-ui-common/src/javafx/stage/PopupWindow.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/src/javafx/stage/PopupWindow.java	Thu Jun 28 12:36:02 2012 +0200
@@ -339,6 +339,9 @@
 
     private void showImpl(final Window owner) {
         if (isShowing()) {
+            if (autofixHandler != null) {
+                autofixHandler.adjustPosition();
+            }
             return;
         }
 
@@ -349,8 +352,7 @@
         }
 
         // It is required that the root window exist and be visible to show the popup.
-        Window rootWindow = getRootWindow(getOwnerWindow());
-        if (rootWindow != null && rootWindow.isShowing()) {
+        if (getRootWindow(owner).isShowing()) {
             // We do show() first so that the width and height of the
             // popup window are initialized. This way the x,y location of the
             // popup calculated below uses the right width and height values for
@@ -397,7 +399,7 @@
         }
     }
 
-    private Window focusGrabWindow;
+    private Window rootWindow;
 
     /**
      * @treatAsPrivate implementation detail
@@ -413,6 +415,8 @@
 
         final Window ownerWindowValue = getOwnerWindow();
         if (visible) {
+            rootWindow = getRootWindow(ownerWindowValue);
+
             startMonitorOwnerEvents(ownerWindowValue);
             // currently we consider popup window to be focused when it is
             // visible and its owner window is focused (we need to track
@@ -421,17 +425,15 @@
             // track focus state across multiple windows
             bindOwnerFocusedProperty(ownerWindowValue);
             setFocused(ownerWindowValue.isFocused());
-            focusGrabWindow = increaseFocusGrabInRootWindow(ownerWindowValue);
             handleAutofixActivation(true, isAutoFix());
+            rootWindow.impl_increaseFocusGrabCounter();
         } else {
             stopMonitorOwnerEvents(ownerWindowValue);
             unbindOwnerFocusedProperty(ownerWindowValue);
             setFocused(false);
-            if (focusGrabWindow != null) {
-                focusGrabWindow.impl_decreaseFocusGrabCounter();
-                focusGrabWindow = null;
-            }
             handleAutofixActivation(false, isAutoFix());
+            rootWindow.impl_decreaseFocusGrabCounter();
+            rootWindow = null;
         }
 
         PerformanceTracker.logEvent("PopupWindow.storeVisible for [PopupWindow] finished");
@@ -506,15 +508,6 @@
         parentEventRedirector.removeEventDispatcher(getEventDispatcher());
     }
 
-    private Window increaseFocusGrabInRootWindow(final Window ownerWindow) {
-        final Window rootWindow = getRootWindow(ownerWindow);
-        if (rootWindow != null) {
-            rootWindow.impl_increaseFocusGrabCounter();
-        }
-
-        return rootWindow;
-    }
-
     private ChangeListener<Boolean> ownerFocusedListener;
 
     private void bindOwnerFocusedProperty(final Window ownerWindowValue) {
@@ -607,7 +600,10 @@
         public void adjustPosition() {
             final Screen currentScreen =
                     Utils.getScreenForPoint(getX(), getY());
-            final Rectangle2D screenBounds = currentScreen.getVisualBounds();
+            final Rectangle2D screenBounds =
+                    Utils.hasFullScreenStage(currentScreen)
+                            ? currentScreen.getBounds()
+                            : currentScreen.getVisualBounds();
             double _x = Math.min(getX(), screenBounds.getMaxX() - getWidth());
             double _y = Math.min(getY(), screenBounds.getMaxY() - getHeight());
             _x = Math.max(_x, screenBounds.getMinX());
--- a/javafx-ui-common/test/unit/javafx/scene/MouseTest.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/test/unit/javafx/scene/MouseTest.java	Thu Jun 28 12:36:02 2012 +0200
@@ -911,7 +911,7 @@
     }
 
     @Test
-    public void NodeMovementsWithStillMouseShouldFireEnteredExited() {
+    public void nodeMovementsWithStillMouseShouldFireEnteredExited() {
         SimpleTestScene scene = new SimpleTestScene();
         MouseEventGenerator generator = new MouseEventGenerator();
 
@@ -934,6 +934,34 @@
         assertTrue(scene.smallSquareTracker.enteredMe);
     }
 
+    @Test
+    public void nodeWithNoninvertibleTransformShouldGetNanCoords() {
+        SimpleTestScene scene = new SimpleTestScene();
+        MouseEventGenerator generator = new MouseEventGenerator();
+
+        scene.processEvent(generator.generateMouseEvent(
+                MouseEvent.MOUSE_PRESSED, 250, 250));
+        scene.smallSquareTracker.clear();
+
+        scene.smallSquareTracker.node.addEventHandler(MouseEvent.MOUSE_RELEASED,
+                new EventHandler<MouseEvent>() {
+
+            @Override public void handle(MouseEvent event) {
+                assertEquals(Double.NaN, event.getX(), 0.0001);
+                assertEquals(Double.NaN, event.getY(), 0.0001);
+                assertEquals(251.0, event.getSceneX(), 0.0001);
+                assertEquals(251.0, event.getSceneY(), 0.0001);
+            }
+        });
+
+        ((Rectangle) scene.smallSquareTracker.node).setScaleX(0);
+
+        scene.processEvent(generator.generateMouseEvent(
+                MouseEvent.MOUSE_RELEASED, 251, 251));
+
+        assertTrue(scene.smallSquareTracker.released);
+    }
+
     private static class SimpleTestScene {
 
         MouseEventTracker sceneTracker;
--- a/javafx-ui-common/test/unit/javafx/scene/canvas/CanvasTest.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/test/unit/javafx/scene/canvas/CanvasTest.java	Thu Jun 28 12:36:02 2012 +0200
@@ -25,7 +25,14 @@
 package javafx.scene.canvas;
 
 import javafx.scene.NodeTest;
+import javafx.scene.effect.BlendMode;
+import javafx.scene.paint.Color;
 import javafx.scene.shape.ArcType;
+import javafx.scene.shape.StrokeLineCap;
+import javafx.scene.shape.StrokeLineJoin;
+import javafx.scene.transform.Affine;
+import javafx.scene.transform.Rotate;
+import javafx.scene.transform.Transform;
 import org.junit.Test;
 import static org.junit.Assert.*;
 
@@ -200,13 +207,165 @@
     
     
     
-    @Test public void testGCState_basic() throws Exception {
-        //need getters
+    @Test public void testGCState_Translate() throws Exception {
         Canvas node = new Canvas();
         GraphicsContext gc = node.getGraphicsContext2D();
         
         gc.translate(50, 50);
+        Affine result = gc.getTransform();
+        Affine expected = new Affine();
+        
+        expected.setTx(50);
+        expected.setTy(50);
+        
+        assertMatrix(result, expected);
     }
     
-            
+    @Test public void testGCState_Scale() throws Exception {
+        Canvas node = new Canvas();
+        GraphicsContext gc = node.getGraphicsContext2D();
+        
+        gc.scale(3, 3);
+        Affine result = gc.getTransform();
+        Affine expected = new Affine();
+        
+        expected.setMxx(3);
+        expected.setMyy(3);
+        
+        assertMatrix(result, expected);
+    }
+
+    @Test public void testGCState_Rotate() throws Exception {
+        Canvas node = new Canvas();
+        GraphicsContext gc = node.getGraphicsContext2D();
+        
+        gc.rotate(45.0);
+        Affine result = gc.getTransform();
+        
+        Rotate expected = new Rotate(45, 0, 0);
+                
+        assertMatrix(result, expected);
+    }
+
+    @Test public void testGCState_getTransform() throws Exception {
+        Canvas node = new Canvas();
+        GraphicsContext gc = node.getGraphicsContext2D();
+        
+
+        Affine expected = new Affine();
+        gc.setTransform(expected);
+        Affine result = gc.getTransform();
+        
+        assertMatrix(result, expected);
+        
+        gc.setTransform(expected.getMxx(), expected.getMyx(), expected.getMxy(), 
+                expected.getMyy(), expected.getTx(), expected.getTy());
+        
+        Affine result2 = gc.getTransform();
+        
+        assertMatrix(result2, expected);        
+    }
+
+    @Test public void testGCState_FillStrokeSaveRestore() throws Exception {
+        Canvas node = new Canvas();
+        GraphicsContext gc = node.getGraphicsContext2D();
+        
+        Affine expected = new Affine();
+        gc.setTransform(expected);
+        Affine result = gc.getTransform();
+        
+        assertMatrix(result, expected);
+        
+        gc.setFill(Color.BLACK);
+        assertEquals(Color.BLACK, gc.getFill());
+        gc.save();
+        gc.setFill(Color.RED);
+        assertEquals(gc.getFill(), Color.RED);
+        gc.restore();
+        assertEquals(Color.BLACK, gc.getFill());
+        gc.setStroke(Color.BLACK);
+        assertEquals(Color.BLACK, gc.getStroke());
+        gc.save();
+        gc.setStroke(Color.RED);
+        assertEquals(gc.getStroke(), Color.RED);
+        gc.restore();
+        assertEquals(Color.BLACK, gc.getStroke());
+        assertMatrix(result, expected);
+    }
+
+    @Test public void testGCState_Line() throws Exception {
+        Canvas node = new Canvas();
+        GraphicsContext gc = node.getGraphicsContext2D();
+        
+        gc.setLineCap(StrokeLineCap.BUTT);
+        gc.setLineJoin(StrokeLineJoin.MITER);
+        gc.setLineWidth(5);
+        gc.setMiterLimit(3);
+        
+        gc.save();
+        gc.setLineCap(StrokeLineCap.ROUND);
+        gc.setLineJoin(StrokeLineJoin.BEVEL);
+        gc.setLineWidth(1);
+        gc.setMiterLimit(1);
+        assertEquals(gc.getLineCap(), StrokeLineCap.ROUND);
+        assertEquals(gc.getLineJoin(), StrokeLineJoin.BEVEL);
+        assertEquals(gc.getLineWidth(), 1, 0.00001);
+        assertEquals(gc.getMiterLimit(), 1, 0.00001);
+        gc.restore();
+        
+        assertEquals(gc.getLineCap(), StrokeLineCap.BUTT);
+        assertEquals(gc.getLineJoin(), StrokeLineJoin.MITER);
+        assertEquals(gc.getLineWidth(), 5, 0.00001);
+        assertEquals(gc.getMiterLimit(), 3, 0.00001);
+    }
+
+    @Test (expected=NullPointerException.class) 
+    public void testGCState_LineNull() throws Exception {
+        Canvas node = new Canvas();
+        GraphicsContext gc = node.getGraphicsContext2D();
+        
+        gc.setLineCap(null);     
+    }
+
+    @Test (expected=NullPointerException.class) 
+    public void testGCState_LineNull2() throws Exception {
+        Canvas node = new Canvas();
+        GraphicsContext gc = node.getGraphicsContext2D();
+        
+        gc.setLineJoin(null);      
+    }
+
+    @Test public void testGCState_BlendMode() throws Exception {
+        Canvas node = new Canvas();
+        GraphicsContext gc = node.getGraphicsContext2D();
+        
+        gc.setGlobalBlendMode(BlendMode.ADD);
+        gc.setGlobalAlpha(0);
+        
+        gc.save();
+        gc.setGlobalAlpha(0.5);
+        gc.setGlobalBlendMode(BlendMode.COLOR_BURN);
+        assertEquals(gc.getGlobalBlendMode(), BlendMode.COLOR_BURN);
+        assertEquals(gc.getGlobalAlpha(), 0.5, 0.000001);
+        gc.restore();
+        
+        assertEquals(BlendMode.ADD, gc.getGlobalBlendMode());
+        assertEquals(0, gc.getGlobalAlpha(), 0.000001);       
+    }
+
+    public static void assertMatrix(Transform expected,
+            Transform result) {
+        assertEquals(expected.getMxx(), result.getMxx(), 0.00001);
+        assertEquals(expected.getMxy(), result.getMxy(), 0.00001);
+        assertEquals(expected.getMxz(), result.getMxz(), 0.00001);
+        assertEquals(expected.getTx(), result.getTx(), 0.00001);
+        assertEquals(expected.getMyx(), result.getMyx(), 0.00001);
+        assertEquals(expected.getMyy(), result.getMyy(), 0.00001);
+        assertEquals(expected.getMyz(), result.getMyz(), 0.00001);
+        assertEquals(expected.getTy(), result.getTy(), 0.00001);
+        assertEquals(expected.getMzx(), result.getMzx(), 0.00001);
+        assertEquals(expected.getMzy(), result.getMzy(), 0.00001);
+        assertEquals(expected.getMzz(), result.getMzz(), 0.00001);
+        assertEquals(expected.getTz(), result.getTz(), 0.00001);
+    }  
 }
--- a/javafx-ui-common/test/unit/javafx/scene/input/TouchEventTest.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/test/unit/javafx/scene/input/TouchEventTest.java	Thu Jun 28 12:36:02 2012 +0200
@@ -1110,6 +1110,70 @@
     }
 
     @Test
+    public void pointsShouldBeTransformedCorrectly() {
+        Scene scene = createScene();
+        Rectangle rect =
+                (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
+        rect.setTranslateX(15);
+        rect.setTranslateY(5);
+
+        touched = 0;
+        rect.addEventHandler(TouchEvent.ANY, new EventHandler<TouchEvent>() {
+            @Override public void handle(TouchEvent event) {
+                touched++;
+                switch(touched) {
+                    case 1:
+                        assertEquals(115.0, event.getTouchPoint().getX(), 0.0001);
+                        assertEquals(125.0, event.getTouchPoint().getY(), 0.0001);
+                        assertEquals(130.0, event.getTouchPoint().getSceneX(), 0.0001);
+                        assertEquals(130.0, event.getTouchPoint().getSceneY(), 0.0001);
+                        break;
+                    case 2:
+                    case 3:
+                    case 4:
+                    case 5:
+                        assertEquals(115.0, event.getTouchPoints().get(0).getX(), 0.0001);
+                        assertEquals(125.0, event.getTouchPoints().get(0).getY(), 0.0001);
+                        assertEquals(130.0, event.getTouchPoints().get(0).getSceneX(), 0.0001);
+                        assertEquals(130.0, event.getTouchPoints().get(0).getSceneY(), 0.0001);
+                        assertEquals(125.0, event.getTouchPoints().get(1).getX(), 0.0001);
+                        assertEquals(135.0, event.getTouchPoints().get(1).getY(), 0.0001);
+                        assertEquals(140.0, event.getTouchPoints().get(1).getSceneX(), 0.0001);
+                        assertEquals(140.0, event.getTouchPoints().get(1).getSceneY(), 0.0001);
+                        break;
+                    default:
+                        fail("Wrong touch point id " + event.getTouchPoint().getId());
+                }
+            }
+        });
+
+        ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
+                System.currentTimeMillis(), 1, true, true, false, true, false);
+        ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
+                TouchPoint.State.PRESSED, 1, 130, 130, 130, 130);
+        ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
+
+        ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
+                System.currentTimeMillis(), 2, true, true, false, true, false);
+        ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
+                TouchPoint.State.STATIONARY, 1, 130, 130, 130, 130);
+        ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
+                TouchPoint.State.PRESSED, 2, 140, 140, 140, 140);
+        ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
+
+        ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
+                System.currentTimeMillis(), 2, true, true, false, true, false);
+        ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
+                TouchPoint.State.RELEASED, 1, 130, 130, 130, 130);
+        ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
+                TouchPoint.State.RELEASED, 2, 140, 140, 140, 140);
+        ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
+
+
+        assertEquals(5, touched);
+    }
+
+    @Test
     public void shouldIgnoreIndirectTouchEvents() {
         Scene scene = createScene();
         Rectangle rect =
--- a/javafx-ui-common/test/unit/javafx/scene/input/TouchPoint_builder_Test.java	Thu Jun 28 12:35:17 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2011, 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 javafx.scene.input;
-
-import com.sun.javafx.test.BuilderTestBase;
-import java.util.Arrays;
-import java.util.Collection;
-import javafx.scene.shape.Rectangle;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public final class TouchPoint_builder_Test extends BuilderTestBase {
-    @Parameters
-    public static Collection data() {
-        BuilderTestBase.Configuration cfg = new BuilderTestBase.Configuration(TouchPoint.class);
-
-        cfg.addProperty("x", 1.0);
-        cfg.addProperty("y", 1.0);
-        cfg.addProperty("screenX", 1.0);
-        cfg.addProperty("screenY", 1.0);
-        cfg.addProperty("state", TouchPoint.State.MOVED);
-        cfg.addProperty("id", 1);
-
-        return Arrays.asList(new Object[] {
-            config(cfg)
-        });
-    }
-
-    public TouchPoint_builder_Test(final Configuration configuration) {
-        super(configuration);
-    }
-}
--- a/javafx-ui-common/test/unit/javafx/scene/layout/GridPaneTest.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/test/unit/javafx/scene/layout/GridPaneTest.java	Thu Jun 28 12:36:02 2012 +0200
@@ -1782,7 +1782,7 @@
         assertEquals(100, child1_0.getLayoutBounds().getHeight(), 1e-100);
         assertEquals(366, child2_0.getLayoutX(), 1e-100);
         assertEquals(0, child2_0.getLayoutY(), 1e-100);
-        assertEquals(233, child2_0.getLayoutBounds().getWidth(), 1e-100);
+        assertEquals(234, child2_0.getLayoutBounds().getWidth(), 1e-100);
         assertEquals(129, child2_0.getLayoutBounds().getHeight(), 1e-100);
 
         assertEquals(0, child0_1.getLayoutX(), 1e-100);
@@ -1795,7 +1795,7 @@
         assertEquals(300, child1_1.getLayoutBounds().getHeight(), 1e-100);
         assertEquals(366, child2_1.getLayoutX(), 1e-100);
         assertEquals(129, child2_1.getLayoutY(), 1e-100);
-        assertEquals(233, child2_1.getLayoutBounds().getWidth(), 1e-100);
+        assertEquals(234, child2_1.getLayoutBounds().getWidth(), 1e-100);
         assertEquals(300, child2_1.getLayoutBounds().getHeight(), 1e-100);
     }
 
@@ -2239,4 +2239,69 @@
         assertEquals(100, cw[0], 1e-100);
         assertEquals(50, cw[1], 1e-100);
     }
+    
+    @Test public void test_RT20931_cellHeightTotalShouldEqualColumnHeight() {
+        ColumnConstraints c1 = new ColumnConstraints();
+        c1.setMinWidth(10);
+        c1.setHgrow(Priority.SOMETIMES);
+        
+        ColumnConstraints c2 = new ColumnConstraints();
+        c2.setMinWidth(10);
+        c2.setHgrow(Priority.SOMETIMES);
+                
+        RowConstraints r1 = new RowConstraints();
+        r1.setMinHeight(10);
+        r1.setVgrow(Priority.SOMETIMES);
+        
+        RowConstraints r2 = new RowConstraints();
+        r2.setMinHeight(10);
+        r2.setVgrow(Priority.SOMETIMES);
+        
+        RowConstraints r3 = new RowConstraints();
+        r3.setMinHeight(10);
+        r3.setVgrow(Priority.SOMETIMES);        
+        
+        gridpane.getColumnConstraints().addAll(c1, c2);
+        gridpane.getRowConstraints().addAll(r1, r2, r3);
+        
+        gridpane.resize(150, 73);
+        gridpane.layout();        
+        double[] rh = gridpane.getRowHeights();
+
+        assertEquals(25, rh[0], 1e-100);
+        assertEquals(24, rh[1], 1e-100);
+        assertEquals(24, rh[2], 1e-100);
+    }
+    
+    @Test public void test_RT20931_cellWidthTotalShouldEqualRowWidth() {
+        ColumnConstraints c1 = new ColumnConstraints();
+        c1.setMinWidth(10);
+        c1.setHgrow(Priority.SOMETIMES);
+        
+        ColumnConstraints c2 = new ColumnConstraints();
+        c2.setMinWidth(10);
+        c2.setHgrow(Priority.SOMETIMES);
+                
+        RowConstraints r1 = new RowConstraints();
+        r1.setMinHeight(10);
+        r1.setVgrow(Priority.SOMETIMES);
+        
+        RowConstraints r2 = new RowConstraints();
+        r2.setMinHeight(10);
+        r2.setVgrow(Priority.SOMETIMES);
+        
+        RowConstraints r3 = new RowConstraints();
+        r3.setMinHeight(10);
+        r3.setVgrow(Priority.SOMETIMES);        
+        
+        gridpane.getColumnConstraints().addAll(c1, c2);
+        gridpane.getRowConstraints().addAll(r1, r2, r3);
+        
+        gridpane.resize(151, 73);
+        gridpane.layout();        
+        double[] cw = gridpane.getColumnWidths();
+
+        assertEquals(76, cw[0], 1e-100);
+        assertEquals(75, cw[1], 1e-100);
+    }    
 }
--- a/javafx-ui-common/test/unit/javafx/stage/PopupTest.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-common/test/unit/javafx/stage/PopupTest.java	Thu Jun 28 12:36:02 2012 +0200
@@ -67,6 +67,7 @@
 
     @After
     public void tearDown() {
+        stage.hide();
         toolkit.resetScreens();
     }
 
@@ -312,6 +313,25 @@
     }
 
     @Test
+    public void testDoubleShowAutofix() {
+        toolkit.setScreens(
+                new ScreenConfiguration(0, 0, 1920, 1200,
+                                        0, 200, 1920, 1000,
+                                        96));
+
+        final Popup popup = new Popup();
+        popup.getContent().add(new Rectangle(0, 0, 50, 50));
+
+        popup.show(stage, 1900, 100);
+        assertEquals(1920, popup.getX() + popup.getWidth(), 1e-100);
+        assertEquals(200, popup.getY(), 1e-100);
+
+        popup.show(stage, 1900, 100);
+        assertEquals(1920, popup.getX() + popup.getWidth(), 1e-100);
+        assertEquals(200, popup.getY(), 1e-100);
+    }
+
+    @Test
     public void testAutofixActivationAfterShow() {
         toolkit.setScreens(
                 new ScreenConfiguration(0, 0, 1920, 1200,
@@ -372,6 +392,23 @@
     }
 
     @Test
+    public void testAutofixWithFullScreen() {
+        toolkit.setScreens(
+                new ScreenConfiguration(0, 0, 1920, 1200,
+                                        0, 0, 1920, 1172,
+                                        96));
+
+        final Popup popup = new Popup();
+        popup.getContent().add(new Rectangle(0, 0, 50, 50));
+
+        stage.setFullScreen(true);
+        popup.show(stage, 100, 1160);
+
+        assertEquals(100, popup.getX(), 1e-100);
+        assertEquals(1150, popup.getY(), 1e-100);
+    }
+
+    @Test
     public void testSetPopupContentByChangingRootNode() {
         final Popup popup = new Popup();
 
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/GlobalMenuAdapter.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/GlobalMenuAdapter.java	Thu Jun 28 12:36:02 2012 +0200
@@ -27,9 +27,9 @@
 
 import javafx.beans.InvalidationListener;
 import javafx.beans.Observable;
-import javafx.collections.ObservableList;
 import javafx.collections.ListChangeListener;
 import javafx.collections.ListChangeListener.Change;
+import javafx.collections.ObservableList;
 import javafx.event.ActionEvent;
 import javafx.event.Event;
 import javafx.event.EventHandler;
@@ -170,8 +170,6 @@
         if(target != null && target.getOnMenuValidation() != null) {
             Event.fireEvent(target, new Event(target.MENU_VALIDATION_EVENT));
         }
-        if (!menu.isDisable()) menu.fire();
-        
     }
 
 
@@ -195,9 +193,7 @@
             if(target.getOnMenuValidation() != null) {
                 Event.fireEvent(target, new Event(target.MENU_VALIDATION_EVENT));
             }
-            if (!menuItem.isDisable()) menuItem.fire();
         }
-
     }
 
     private class CheckMenuItemAdapter extends CheckMenuItem implements CheckMenuItemBase {
@@ -221,9 +217,7 @@
             if(target.getOnMenuValidation() != null) {
                 Event.fireEvent(target, new Event(target.MENU_VALIDATION_EVENT));
             }
-            if (!menuItem.isDisable()) menuItem.fire();
         }
-
     }
 
     private class RadioMenuItemAdapter extends RadioMenuItem implements RadioMenuItemBase {
@@ -248,9 +242,7 @@
             if(target.getOnMenuValidation() != null) {
                 Event.fireEvent(target, new Event(target.MENU_VALIDATION_EVENT));
             }
-            if (!menuItem.isDisable()) menuItem.fire();
         }
-
     }
 
     private class SeparatorMenuItemAdapter extends SeparatorMenuItem implements SeparatorMenuItemBase {
@@ -271,9 +263,7 @@
             if(target.getOnMenuValidation() != null) {
                 Event.fireEvent(target, new Event(target.MENU_VALIDATION_EVENT));
             }
-            if (!menuItem.isDisable()) menuItem.fire();
         }
-
     }
 
     private class CustomMenuItemAdapter extends CustomMenuItem implements CustomMenuItemBase {
@@ -294,8 +284,6 @@
             if(target.getOnMenuValidation() != null) {
                 Event.fireEvent(target, new Event(target.MENU_VALIDATION_EVENT));
             }
-            if (!menuItem.isDisable()) menuItem.fire();
         }
-
     }
 }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/AccordionBehavior.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/AccordionBehavior.java	Thu Jun 28 12:36:02 2012 +0200
@@ -77,10 +77,10 @@
         return ACCORDION_BINDINGS;
     }
 
-    @Override protected void callAction(String name) {       
+    @Override protected void callAction(String name) {   
         Accordion accordion = getControl();
         if ("TraverseLeft".equals(name) || "TraverseUp".equals(name) || PAGE_UP.equals(name)) {
-            if (accordion.getPanes().get(focusModel.getFocusedIndex()).isFocused()) {
+            if (focusModel.getFocusedIndex() != -1 && accordion.getPanes().get(focusModel.getFocusedIndex()).isFocused()) {
                 focusModel.focusPrevious();
                 int next = focusModel.getFocusedIndex();
                 accordion.getPanes().get(next).requestFocus();
@@ -89,7 +89,7 @@
                 }
             }
         } else if ("TraverseRight".equals(name) || "TraverseDown".equals(name) || PAGE_DOWN.equals(name)) {
-            if (accordion.getPanes().get(focusModel.getFocusedIndex()).isFocused()) {
+            if (focusModel.getFocusedIndex() != -1 && accordion.getPanes().get(focusModel.getFocusedIndex()).isFocused()) {
                 focusModel.focusNext();
                 int next = focusModel.getFocusedIndex();
                 accordion.getPanes().get(next).requestFocus();
@@ -99,22 +99,26 @@
             }            
         } else if (CTRL_TAB.equals(name) || CTRL_PAGE_DOWN.equals(name)) {
             focusModel.focusNext();
-            int next = focusModel.getFocusedIndex();
-            accordion.getPanes().get(next).requestFocus();
-            accordion.getPanes().get(next).setExpanded(true);
+            if (focusModel.getFocusedIndex() != -1) {
+                int next = focusModel.getFocusedIndex();
+                accordion.getPanes().get(next).requestFocus();
+                accordion.getPanes().get(next).setExpanded(true);
+            }
         } else if (CTRL_SHIFT_TAB.equals(name) || CTRL_PAGE_UP.equals(name)) {
             focusModel.focusPrevious();
-            int next = focusModel.getFocusedIndex();
-            accordion.getPanes().get(next).requestFocus();
-            accordion.getPanes().get(next).setExpanded(true);
+            if (focusModel.getFocusedIndex() != -1) {
+                int next = focusModel.getFocusedIndex();            
+                accordion.getPanes().get(next).requestFocus();
+                accordion.getPanes().get(next).setExpanded(true);
+            }
         } else if (HOME.equals(name)) {
-            if (accordion.getPanes().get(focusModel.getFocusedIndex()).isFocused()) {
+            if (focusModel.getFocusedIndex() != -1 && accordion.getPanes().get(focusModel.getFocusedIndex()).isFocused()) {
                 TitledPane tp = accordion.getPanes().get(0);
                 tp.requestFocus();
                 tp.setExpanded(!tp.isExpanded());
             }
         } else if (END.equals(name)) {
-            if (accordion.getPanes().get(focusModel.getFocusedIndex()).isFocused()) {
+            if (focusModel.getFocusedIndex() != -1 && accordion.getPanes().get(focusModel.getFocusedIndex()).isFocused()) {
                 TitledPane tp = accordion.getPanes().get(accordion.getPanes().size() - 1);
                 tp.requestFocus();
                 tp.setExpanded(!tp.isExpanded());
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TextInputControlBehavior.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TextInputControlBehavior.java	Thu Jun 28 12:36:02 2012 +0200
@@ -119,17 +119,31 @@
 
     @Override public void callAction(String name) {
         TextInputControl textInputControl = getControl();
+        boolean done = false;
+
+        setCaretAnimating(false);
+
         if (textInputControl.isEditable()) {
-            setCaretAnimating(false);
             setEditing(true);
-            final IndexRange selection = textInputControl.getSelection();
-            final int start = selection.getStart();
-            final int end = selection.getEnd();
-
+            done = true;
             if ("InputCharacter".equals(name)) defaultKeyTyped(lastEvent);
             else if ("Cut".equals(name)) cut();
-            else if ("Copy".equals(name)) textInputControl.copy();
             else if ("Paste".equals(name)) paste();
+            else if ("DeletePreviousChar".equals(name)) deletePreviousChar();
+            else if ("DeleteNextChar".equals(name)) deleteNextChar();
+            else if ("DeletePreviousWord".equals(name)) deletePreviousWord();
+            else if ("DeleteNextWord".equals(name)) deleteNextWord();
+            else if ("DeleteSelection".equals(name)) deleteSelection();
+            else if ("Undo".equals(name)) undoManager.undo();
+            else if ("Redo".equals(name)) undoManager.redo();
+            else {
+                done = false;
+            }
+            setEditing(false);
+        }
+        if (!done) {
+            done = true;
+            if ("Copy".equals(name)) textInputControl.copy();
             else if ("SelectBackward".equals(name)) textInputControl.selectBackward();
             else if ("SelectForward".equals(name)) textInputControl.selectForward();
             else if ("PreviousWord".equals(name)) previousWord();
@@ -140,11 +154,6 @@
             else if ("SelectAll".equals(name)) textInputControl.selectAll();
             else if ("Home".equals(name)) textInputControl.home();
             else if ("End".equals(name)) textInputControl.end();
-            else if ("DeletePreviousChar".equals(name)) deletePreviousChar();
-            else if ("DeleteNextChar".equals(name)) deleteNextChar();
-            else if ("DeletePreviousWord".equals(name)) deletePreviousWord();
-            else if ("DeleteNextWord".equals(name)) deleteNextWord();
-            else if ("DeleteSelection".equals(name)) deleteSelection();
             else if ("Forward".equals(name)) textInputControl.forward();
             else if ("Backward".equals(name)) textInputControl.backward();
             else if ("Fire".equals(name)) fire(lastEvent);
@@ -153,25 +162,16 @@
             else if ("SelectEnd".equals(name)) selectEnd();
             else if ("SelectHomeExtend".equals(name)) selectHomeExtend();
             else if ("SelectEndExtend".equals(name)) selectEndExtend();
-            else if ("Undo".equals(name)) undoManager.undo();
-            else if ("Redo".equals(name)) undoManager.redo();
             else if ("ToParent".equals(name)) forwardToParent(lastEvent);
             /*DEBUG*/else if ("UseVK".equals(name) && isEmbedded()) {
                 ((com.sun.javafx.scene.control.skin.TextInputControlSkin)textInputControl.getSkin()).toggleUseVK();
             } else {
-                setEditing(false);
-                super.callAction(name);
+                done = false;
             }
-            setEditing(false);
-            setCaretAnimating(true);
-        } else if ("Copy".equals(name)) {
-            // If the key event is for the "copy" action then we go ahead
-            // and execute it, but for all other key events which occur
-            // when not editable, we don't allow.
-            textInputControl.copy();
-        } else if (name.startsWith("Traverse")) {
-            // Call super.callAction() for any focus traversal actions even if
-            // it's not editable
+        }
+        setCaretAnimating(true);
+
+        if (!done) {
             super.callAction(name);
         }
         // Note, I don't have to worry about "Consume" here.
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ButtonSkin.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ButtonSkin.java	Thu Jun 28 12:36:02 2012 +0200
@@ -25,7 +25,6 @@
 
 package com.sun.javafx.scene.control.skin;
 
-import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
 import javafx.geometry.Side;
 import javafx.scene.control.Button;
@@ -66,26 +65,10 @@
             setCancelButton(true);
         }       
 
-        button.addEventHandler(ActionEvent.ACTION, new EventHandler<ActionEvent>() {
-            @Override public void handle(ActionEvent e) {
-
-                ContextMenu cm = getSkinnable().getContextMenu();
-                if (cm != null) {
-                    if (!cm.isShowing()) {
-                        cm.show(getSkinnable(), Side.RIGHT, 0, 0);
-                        Utils.addMnemonics(cm, getSkinnable().getScene());
-                    }
-                    else {
-                        cm.hide();
-                        Utils.removeMnemonics(cm, getSkinnable().getScene());
-                    }
-                }
-            }
-        });
     }
 
 
-    @Override protected void handleControlPropertyChanged(String p) {
+    @Override protected void handleControlPropertyChanged(String p) {        
         super.handleControlPropertyChanged(p);
         if (p == "DEFAULT_BUTTON") {
             setDefaultButton(getSkinnable().isDefaultButton());
@@ -103,6 +86,11 @@
                     }
                 }
            }
+        } else if (p == "PARENT") {
+            if (getSkinnable().getParent() == null) {
+                getScene().getAccelerators().remove(defaultAcceleratorKeyCodeCombination);
+                getScene().getAccelerators().remove(cancelAcceleratorKeyCodeCombination);
+            }
         }
     }
 
@@ -115,67 +103,68 @@
         };
 
     Runnable cancelButtonRunnable = new Runnable() {
-            public void run() {                
+            public void run() {   
                 if (!getSkinnable().isDisabled()) {
                     getSkinnable().fire();
                 }
             }
         };
 
+    private KeyCodeCombination defaultAcceleratorKeyCodeCombination;
+    
     private void setDefaultButton(boolean value) {
 
         KeyCode acceleratorCode = KeyCode.ENTER;
-        KeyCodeCombination acceleratorKeyCombo = 
+        defaultAcceleratorKeyCodeCombination = 
                 new KeyCodeCombination(acceleratorCode);
 
         if (value == false) {
             /*
             ** first check of there's a default button already
             */
-            Runnable oldDefault = getSkinnable().getParent().getScene().getAccelerators().get(acceleratorKeyCombo);
+            Runnable oldDefault = getSkinnable().getParent().getScene().getAccelerators().get(defaultAcceleratorKeyCodeCombination);
             if (!defaultButtonRunnable.equals(oldDefault)) {
                 /*
                 ** is it us?
                 */
-                getSkinnable().getParent().getScene().getAccelerators().remove(acceleratorKeyCombo);
+                getSkinnable().getParent().getScene().getAccelerators().remove(defaultAcceleratorKeyCodeCombination);
             }
         }
         else {
             /*
             ** first check of there's a default button already
             */
-            Runnable oldDefault = getSkinnable().getParent().getScene().getAccelerators().get(acceleratorKeyCombo);
+            Runnable oldDefault = getSkinnable().getParent().getScene().getAccelerators().get(defaultAcceleratorKeyCodeCombination);
         }
-        getSkinnable().getParent().getScene().getAccelerators().put(acceleratorKeyCombo, defaultButtonRunnable);
+        getSkinnable().getParent().getScene().getAccelerators().put(defaultAcceleratorKeyCodeCombination, defaultButtonRunnable);
     }
 
-
+    private KeyCodeCombination cancelAcceleratorKeyCodeCombination;
 
     private void setCancelButton(boolean value) {
-
         KeyCode acceleratorCode = KeyCode.ESCAPE;
-        KeyCodeCombination acceleratorKeyCombo =
+        cancelAcceleratorKeyCodeCombination =
                 new KeyCodeCombination(acceleratorCode);
-
+        
         if (value == false) {
             /*
             ** first check of there's a default button already
             */
-            Runnable oldDefault = getSkinnable().getParent().getScene().getAccelerators().get(acceleratorKeyCombo);
+            Runnable oldDefault = getSkinnable().getParent().getScene().getAccelerators().get(cancelAcceleratorKeyCodeCombination);
             if (!defaultButtonRunnable.equals(oldDefault)) {
                 /*
                 ** is it us?
                 */
-                getSkinnable().getParent().getScene().getAccelerators().remove(acceleratorKeyCombo);
+                getSkinnable().getParent().getScene().getAccelerators().remove(cancelAcceleratorKeyCodeCombination);
             }
         }
         else {
             /*
             ** first check of there's a default button already
             */
-            Runnable oldDefault = getSkinnable().getParent().getScene().getAccelerators().get(acceleratorKeyCombo);
-        }
-        getSkinnable().getParent().getScene().getAccelerators().put(acceleratorKeyCombo, cancelButtonRunnable);
+            Runnable oldDefault = getSkinnable().getParent().getScene().getAccelerators().get(cancelAcceleratorKeyCodeCombination);
+        }        
+        getSkinnable().getParent().getScene().getAccelerators().put(cancelAcceleratorKeyCodeCombination, cancelButtonRunnable);
     }
 
 }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ChoiceBoxSkin.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ChoiceBoxSkin.java	Thu Jun 28 12:36:02 2012 +0200
@@ -106,6 +106,9 @@
                 }
             }
             updateSelection();
+            // RT-21891 weird initial appearance: need a better fix for this instead
+            // of having to rely on impl_processCSS. 
+            popup.getScene().getRoot().impl_processCSS(true); 
             requestLayout(); // RT-18052 resize of choicebox should happen immediately.
         }
     };
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ComboBoxListViewSkin.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ComboBoxListViewSkin.java	Thu Jun 28 12:36:02 2012 +0200
@@ -57,6 +57,14 @@
     // This may one day become a property on the ComboBox itself.
     private static final String COMBO_BOX_ROWS_TO_MEASURE_WIDTH_KEY = "comboBoxRowsToMeasureWidth";
     
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Private fields                                                          *
+     *                                                                         *
+     **************************************************************************/    
+    
     private final ComboBox<T> comboBox;
     
     private ListCell<T> buttonCell;
@@ -67,10 +75,41 @@
     
     private ObservableList<T> listViewItems;
     
+    private boolean listSelectionLock = false;
+    private boolean listViewSelectionDirty = false;
+    
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Listeners                                                               *
+     *                                                                         *
+     **************************************************************************/
+    
+    private boolean itemCountDirty;
+    private final ListChangeListener listViewItemsListener = new ListChangeListener() {
+        @Override public void onChanged(ListChangeListener.Change c) {
+            itemCountDirty = true;
+            requestLayout();
+        }
+    };
+    
+    private final WeakListChangeListener weakListViewItemsListener =
+            new WeakListChangeListener(listViewItemsListener);
+    
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Constructors                                                            *
+     *                                                                         *
+     **************************************************************************/   
+    
     public ComboBoxListViewSkin(final ComboBox<T> comboBox) {
         super(comboBox, new ComboBoxListViewBehavior<T>(comboBox));
         this.comboBox = comboBox;
         this.listView = createListView();
+        this.textField = getEditableInputNode();
         
         // Fix for RT-21207. Additional code related to this bug is further below.
         this.listView.setManaged(false);
@@ -117,24 +156,10 @@
         });
         
         // Fix for RT-19431 (also tested via ComboBoxListViewSkinTest)
+        updateValue(comboBox.getValue());
         comboBox.valueProperty().addListener(new ChangeListener<T>() {
             @Override public void changed(ObservableValue<? extends T> ov, T oldValue, T newValue) {
-                if (newValue == null) {
-                    listView.getSelectionModel().clearSelection();
-                } else {
-                    int index = comboBox.getSelectionModel().getSelectedIndex();
-                    if (index >= 0 && index < comboBox.getItems().size()) {
-                        T itemsObj = comboBox.getItems().get(index);
-                        if (itemsObj != null && itemsObj.equals(newValue)) {
-                            listView.getSelectionModel().select(index);
-                        } else {
-                            listView.getSelectionModel().select(newValue);
-                        }
-                    } else {
-                        // just select the first instance of newValue in the list
-                        listView.getSelectionModel().select(newValue);
-                    }
-                }
+                updateValue(newValue);
             }
         });
         
@@ -147,34 +172,15 @@
         registerChangeListener(comboBox.buttonCellProperty(), "BUTTON_CELL");
     }
     
-    public void updateListViewItems() {
-        if (listViewItems != null) {
-            listViewItems.removeListener(weakListViewItemsListener);
-        }
-
-        this.listViewItems = comboBox.getItems();
-        listView.setItems(null);
-        listView.setItems(listViewItems);
-
-        if (listViewItems != null) {
-            listViewItems.addListener(weakListViewItemsListener);
-        }
-        
-        itemCountDirty = true;
-        requestLayout();
-    }
     
-    private boolean itemCountDirty;
-    private final ListChangeListener listViewItemsListener = new ListChangeListener() {
-        @Override public void onChanged(ListChangeListener.Change c) {
-            itemCountDirty = true;
-            requestLayout();
-        }
-    };
     
-    private final WeakListChangeListener weakListViewItemsListener =
-            new WeakListChangeListener(listViewItemsListener);
+    /***************************************************************************
+     *                                                                         *
+     * Public API                                                              *
+     *                                                                         *
+     **************************************************************************/  
     
+    /** {@inheritDoc} */
     @Override protected void handleControlPropertyChanged(String p) {
         // Fix for RT-21207
         if (p == "SHOWING") {
@@ -206,12 +212,10 @@
         }
     }
     
+    /** {@inheritDoc} */
     @Override public Node getDisplayNode() {
         Node displayNode;
         if (comboBox.isEditable()) {
-            if (textField == null) {
-                textField = getEditableInputNode();
-            }
             displayNode = textField;
         } else {
             displayNode = buttonCell;
@@ -222,6 +226,88 @@
         return displayNode;
     }
     
+    /**
+     * 
+     */
+    public void updateListViewItems() {
+        if (listViewItems != null) {
+            listViewItems.removeListener(weakListViewItemsListener);
+        }
+
+        this.listViewItems = comboBox.getItems();
+        listView.setItems(null);
+        listView.setItems(listViewItems);
+
+        if (listViewItems != null) {
+            listViewItems.addListener(weakListViewItemsListener);
+        }
+        
+        itemCountDirty = true;
+        requestLayout();
+    }
+    
+    @Override public Node getPopupContent() {
+        return listView;
+    }
+    
+    @Override protected double computePrefWidth(double height) {
+        return listView.prefWidth(height);
+    }
+    
+    @Override protected double computeMinWidth(double height) {
+        return 50;
+    }
+    
+    @Override protected void layoutChildren() {
+        if (listViewSelectionDirty) {
+            try {
+                listSelectionLock = true;
+                T item = comboBox.getSelectionModel().getSelectedItem();
+                listView.getSelectionModel().clearSelection();
+                listView.getSelectionModel().select(item);
+            } finally {
+                listSelectionLock = false;
+                listViewSelectionDirty = false;
+            }
+        }
+        
+        super.layoutChildren();
+    }
+    
+    
+    
+    /***************************************************************************
+     *                                                                         *
+     * Private methods                                                         *
+     *                                                                         *
+     **************************************************************************/    
+    
+    private void updateValue(T newValue) {
+        if (newValue == null) {
+            listView.getSelectionModel().clearSelection();
+        } else {
+            int index = comboBox.getSelectionModel().getSelectedIndex();
+            if (index >= 0 && index < comboBox.getItems().size()) {
+                T itemsObj = comboBox.getItems().get(index);
+                if (itemsObj != null && itemsObj.equals(newValue)) {
+                    listView.getSelectionModel().select(index);
+                } else {
+                    listView.getSelectionModel().select(newValue);
+                }
+            } else {
+                // just select the first instance of newValue in the list
+                int listViewIndex = listView.getItems().indexOf(newValue);
+                if (listViewIndex == -1) {
+                    // RT-21336 Show the ComboBox value even though it doesn't
+                    // exist in the ComboBox items list (part one of fix)
+                    updateDisplayNode();
+                } else {
+                    listView.getSelectionModel().select(listViewIndex);
+                }
+            }
+        }
+    }
+    
     private TextField getEditableInputNode() {
         if (textField != null) return textField;
         
@@ -253,9 +339,9 @@
     private void updateDisplayNode() {
         StringConverter<T> c = comboBox.getConverter();
         if (c == null) return;
-                        
+              
+        T value = comboBox.getValue();
         if (comboBox.isEditable()) {
-            T value = comboBox.getValue();
             String stringValue = c.toString(value);
             if (value == null || stringValue == null) {
                 textField.setText("");
@@ -264,8 +350,14 @@
             }
         } else {
             int index = getSelectedIndex();
-            buttonCell.updateListView(listView);
-            buttonCell.updateIndex(index);
+            if (index > -1) {
+                buttonCell.updateListView(listView);
+                buttonCell.updateIndex(index);
+            } else {
+                // RT-21336 Show the ComboBox value even though it doesn't
+                // exist in the ComboBox items list (part two of fix)
+                updateDisplayText(buttonCell, value, false);
+            }
         }
     }
     
@@ -317,10 +409,6 @@
         buttonCell.setMouseTransparent(true);
     }
 
-    @Override public Node getPopupContent() {
-        return listView;
-    }
-    
     private void updateCellFactory() {
         Callback<ListView<T>, ListCell<T>> cf = comboBox.getCellFactory();
         cellFactory = cf != null ? cf : getDefaultCellFactory();
@@ -340,10 +428,9 @@
         };
     }
     
-    private boolean listSelectionLock = false;
-    
     private ListView<T> createListView() {
         final ListView<T> listView = new ListView<T>() {
+            private boolean isFirstSizeCalculation = true;
             
             @Override protected double computeMinHeight(double width) {
                 return 30;
@@ -380,12 +467,14 @@
             }
             
             private void doCSSCheck() {
-                if (getSkin() == null) {
+                Parent parent = getPopup().getScene().getRoot();
+                if ((isFirstSizeCalculation || getSkin() == null) && parent.getScene() != null) {
                     // if the skin is null, it means that the css related to the
                     // listview skin hasn't been loaded yet, so we force it here.
                     // This ensures the combobox button is the correct width
                     // when it is first displayed, before the listview is shown.
-                    getPopup().getScene().getRoot().impl_processCSS(true);
+                    parent.impl_processCSS(true);
+                    isFirstSizeCalculation = false;
                 }
             }
         };
@@ -456,30 +545,6 @@
         return ph;
     }
 
-    @Override protected double computePrefWidth(double height) {
-        return listView.prefWidth(height);
-    }
-    
-    @Override protected double computeMinWidth(double height) {
-        return 50;
-    }
-    
-    private boolean listViewSelectionDirty = false;
-    @Override protected void layoutChildren() {
-        if (listViewSelectionDirty) {
-            try {
-                listSelectionLock = true;
-                T item = comboBox.getSelectionModel().getSelectedItem();
-                listView.getSelectionModel().clearSelection();
-                listView.getSelectionModel().select(item);
-            } finally {
-                listSelectionLock = false;
-                listViewSelectionDirty = false;
-            }
-        }
-        
-        super.layoutChildren();
-    }
 
     
     /**************************************************************************
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ComboBoxPopupControl.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ComboBoxPopupControl.java	Thu Jun 28 12:36:02 2012 +0200
@@ -137,5 +137,6 @@
         };
         getSkinnable().layoutXProperty().addListener(layoutPosListener);
         getSkinnable().layoutYProperty().addListener(layoutPosListener);
+        getSkinnable().widthProperty().addListener(layoutPosListener);
     }
 }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/FXVKSkin.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/FXVKSkin.java	Thu Jun 28 12:36:02 2012 +0200
@@ -68,7 +68,7 @@
 import static javafx.scene.input.KeyCode.*;
 import static javafx.scene.input.MouseEvent.*;
 
-import static com.sun.javafx.scene.control.skin.resources.ControlResources.*;
+import static com.sun.javafx.scene.control.skin.resources.EmbeddedResources.*;
 
 public class FXVKSkin extends SkinBase<FXVK, BehaviorBase<FXVK>> {
 
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/MenuBarSkin.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/MenuBarSkin.java	Thu Jun 28 12:36:02 2012 +0200
@@ -54,15 +54,20 @@
 import javafx.scene.input.MouseEvent;
 import javafx.scene.layout.HBox;
 import javafx.stage.Stage;
+import javafx.beans.value.WeakChangeListener;
 
 import com.sun.javafx.menu.MenuBase;
 import com.sun.javafx.scene.control.GlobalMenuAdapter;
+import com.sun.javafx.scene.control.WeakEventHandler;
 import com.sun.javafx.scene.control.behavior.BehaviorBase;
 import com.sun.javafx.scene.traversal.Direction;
 import com.sun.javafx.scene.traversal.TraversalEngine;
 import com.sun.javafx.scene.traversal.TraverseListener;
 import com.sun.javafx.stage.StageHelper;
 import com.sun.javafx.tk.Toolkit;
+import java.lang.ref.WeakReference;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import javafx.event.ActionEvent;
 import javafx.event.EventType;
 import javafx.scene.input.*;
@@ -143,8 +148,11 @@
         });
     }
 
-
-
+    private WeakEventHandler weakSceneKeyEventHandler;
+    private WeakEventHandler weakSceneMouseEventHandler;
+    private EventHandler keyEventHandler;
+    private EventHandler mouseEventHandler;
+    
     /***************************************************************************
      *                                                                         *
      * Constructors                                                            *
@@ -156,8 +164,9 @@
         
         container = new HBox();
         getChildren().add(container);
-     
-        control.getScene().addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
+        
+        // Key navigation 
+        keyEventHandler = new EventHandler<KeyEvent>() {
             @Override public void handle(KeyEvent event) {
                 // process right left and may be tab key events
                 if (openMenu != null) {
@@ -212,19 +221,26 @@
                     }
                 }
             }
-        });
+        };
+        weakSceneKeyEventHandler = new WeakEventHandler(control.getScene(), KeyEvent.KEY_PRESSED, 
+                keyEventHandler);
+        control.getScene().addEventFilter(KeyEvent.KEY_PRESSED, weakSceneKeyEventHandler);
+        
         // When we click else where in the scene - menu selection should be cleared.
-        control.getScene().addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
-            @Override
-            public void handle(MouseEvent t) {
+        mouseEventHandler = new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent t) {
                 if (!container.localToScene(container.getLayoutBounds()).contains(t.getX(), t.getY())) {
                     unSelectMenus();
                     firstF10 = true;
                 }
             }
-        });
+        };
+        weakSceneMouseEventHandler = new WeakEventHandler(control.getScene(), MouseEvent.MOUSE_CLICKED, 
+                mouseEventHandler);
+        control.getScene().addEventFilter(MouseEvent.MOUSE_CLICKED, weakSceneMouseEventHandler);
+        
         // When the parent window looses focus - menu selection should be cleared
-        control.getScene().getWindow().focusedProperty().addListener(new ChangeListener<Boolean>() {
+        control.getScene().getWindow().focusedProperty().addListener(new WeakChangeListener(new ChangeListener<Boolean>() {
             @Override
             public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
               if (!t1) {
@@ -232,7 +248,7 @@
                   firstF10 = true;
               }
             }
-        });
+        }));
         
         rebuildUI();
         control.getMenus().addListener(new ListChangeListener<Menu>() {
@@ -288,9 +304,23 @@
         };
         engine.addTraverseListener(this);
         setImpl_traversalEngine(engine);
+        
+        control.sceneProperty().addListener(new ChangeListener<Scene>() {
+            @Override
+            public void changed(ObservableValue<? extends Scene> ov, Scene t, Scene t1) {
+                if (weakSceneKeyEventHandler != null) {
+                    // remove event filter from the old scene (t)
+                    t.removeEventFilter(KeyEvent.KEY_PRESSED, weakSceneKeyEventHandler);
+                }
+                if (weakSceneMouseEventHandler != null) {
+                    // remove event filter from the old scene (t)
+                    t.removeEventFilter(MouseEvent.MOUSE_CLICKED, weakSceneMouseEventHandler);
+                }
+            }
+        });
     }
     
-
+    
     Runnable firstMenuRunnable = new Runnable() {
             public void run() {
                 /*
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/NestedTableColumnHeader.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/NestedTableColumnHeader.java	Thu Jun 28 12:36:02 2012 +0200
@@ -73,7 +73,6 @@
         } else if (getTableColumn() != null) {
             setColumns(getTableColumn().getColumns());
         }
-//        getColumns().addListener(weakColumnsListener);
     }
     
     
@@ -458,7 +457,7 @@
 
         newCol.setTableHeaderRow(getTableHeaderRow());
         newCol.setParentHeader(this);
-
+        
         return newCol;
     }
 }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/PaginationSkin.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/PaginationSkin.java	Thu Jun 28 12:36:02 2012 +0200
@@ -325,6 +325,10 @@
             animate = false;
         }
 
+        // Remove the children in the pane before we create a new page.
+        currentStackPane.getChildren().clear();
+        nextStackPane.getChildren().clear();
+        
         pagination.setCurrentPageIndex(currentIndex);
         createPage(currentStackPane, currentIndex);
 
@@ -635,9 +639,6 @@
                 timeline.setOnFinished(new EventHandler<ActionEvent>() {
                     @Override
                     public void handle(ActionEvent arg0) {
-                        // Create a new page by removing the children.
-                        currentStackPane.getChildren().clear();
-                        nextStackPane.getChildren().clear();
                         resetIndexes(false);
                         navigation.initializePageIndicators();
                         navigation.updatePageIndicators();
@@ -645,13 +646,10 @@
                 });
                 return;
             }
-            // Create a new page by removing the children.
-            currentStackPane.getChildren().clear();
-            nextStackPane.getChildren().clear();
             resetIndexes(false);
             navigation.initializePageIndicators();
             navigation.updatePageIndicators();
-        } else if (p == "PAGE_COUNT") {
+        } else if (p == "PAGE_COUNT") {          
             resetIndexes(false);
             navigation.initializePageIndicators();
             navigation.updatePageIndicators();
@@ -807,11 +805,9 @@
 
         // Create the indicators using fromIndex and toIndex.
         private void initializePageIndicators() {
-            if (!indicatorButtons.getToggles().isEmpty()) {
-                previousIndicatorCount = 0;
-                controlBox.getChildren().clear();
-                indicatorButtons.getToggles().clear();
-            }
+            previousIndicatorCount = 0;
+            controlBox.getChildren().clear();
+            indicatorButtons.getToggles().clear();
 
             controlBox.getChildren().add(leftArrowButton);
             for (int i = fromIndex; i <= toIndex; i++) {
@@ -878,8 +874,12 @@
             int indicatorCount = 0;
             for (int i = 0; i < getSkinnable().getMaxPageIndicatorCount(); i++) {
                 int index = i < indicatorButtons.getToggles().size() ? i : indicatorButtons.getToggles().size() - 1;
-                IndicatorButton ib = (IndicatorButton)indicatorButtons.getToggles().get(index);
-                double iw = snapSize(Utils.boundedSize(ib.prefWidth(-1), ib.minWidth(-1), ib.maxWidth(-1)));
+                double iw = minButtonSize;
+                if (index != -1) {
+                    IndicatorButton ib = (IndicatorButton)indicatorButtons.getToggles().get(index);
+                    iw = snapSize(Utils.boundedSize(ib.prefWidth(-1), ib.minWidth(-1), ib.maxWidth(-1)));
+                }
+
                 x += (iw + controlBox.getSpacing());
                 if (x >= w) {
                     break;
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ProgressIndicatorSkin.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ProgressIndicatorSkin.java	Thu Jun 28 12:36:02 2012 +0200
@@ -294,7 +294,7 @@
 
         @Override protected void layoutChildren() {
             // Position and size the circular background
-            double textHeight = doneText.getLayoutBounds().getHeight();
+            double doneTextHeight = doneText.getLayoutBounds().getHeight();
             /*
             ** use the min of width, or height, keep it a circle
             */
@@ -302,15 +302,12 @@
             double radiusH = (control.getHeight() - (skin.getInsets().getTop() + skin.getInsets().getBottom())) / 2;
             double radius = Math.min(radiusW, radiusH);
 
-            radius = Math.min(radius, (control.getHeight() - skin.getInsets().getTop() - skin.getInsets().getBottom() - textGap - textHeight) / 2);
+            radius = Math.min(radius, (control.getHeight() - skin.getInsets().getTop() - skin.getInsets().getBottom() - textGap - doneTextHeight) / 2);
             indicator.impl_setShape(new Circle(radius));
             indicator.resize(2 * radius, 2 * radius);
 
-            final double h = indicator.getHeight() + textGap + textHeight;
-            final double y = (getHeight() - h) / 2;
-
-            indicator.setLayoutX((getWidth() - indicator.getWidth()) / 2);
-            indicator.setLayoutY(y);
+            indicator.setLayoutX(skin.getInsets().getLeft()+textGap);
+            indicator.setLayoutY(skin.getInsets().getTop());
 
             arcShape.setRadiusX(((indicator.getWidth() - indicator.getInsets().getLeft() - indicator.getInsets().getRight()) / 2));
             arcShape.setRadiusY(arcShape.getRadiusX());
@@ -329,13 +326,23 @@
             /*
             ** if the % text can't fit anywhere in the bounds then don't display it
             */
-            if (control.getWidth() >= com.sun.javafx.scene.control.skin.Utils.computeTextWidth(font, text.getText(), 0.0) &&
-                control.getHeight() >= com.sun.javafx.scene.control.skin.Utils.computeTextHeight(font, text.getText(), 0.0)) {
+            double textWidth = com.sun.javafx.scene.control.skin.Utils.computeTextWidth(font, text.getText(), 0.0);
+            double textHeight = com.sun.javafx.scene.control.skin.Utils.computeTextHeight(font, text.getText(), 0.0);
+            if (control.getWidth() >= textWidth && control.getHeight() >= textHeight) {
                 if (!text.isVisible()) {
                     text.setVisible(true);
                 }
-                text.setLayoutY(y + indicator.getHeight() + textGap);
-                text.setLayoutX(indicator.getLayoutX() + (indicator.getWidth() - text.getLayoutBounds().getWidth()) / 2);
+                text.setLayoutY(skin.getInsets().getTop() + indicator.getHeight() + textGap);
+                /*
+                ** try to centre the text at the indicators radius.
+                ** but if it can't then use the padding
+                */
+                if (textWidth > (radius*2)) {
+                    text.setLayoutX(skin.getInsets().getLeft());
+                }
+                else {
+                    text.setLayoutX(skin.getInsets().getLeft()+((radius*2 - textWidth)/2));
+                }
             }
             else {
                 if (text.isVisible()) {
@@ -434,10 +441,9 @@
 
             double diameter = radius*2;
             childrenG.resize(diameter, diameter);
-            final double y = (getHeight() - diameter) / 2;
 
-            childrenG.setLayoutX((getWidth() - diameter) / 2);
-            childrenG.setLayoutY(y);
+            childrenG.setLayoutX(skin.getInsets().getLeft());
+            childrenG.setLayoutY(skin.getInsets().getTop());
         }
 
         private Timeline indeterminateTimeline;
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ScrollPaneSkin.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ScrollPaneSkin.java	Thu Jun 28 12:36:02 2012 +0200
@@ -742,13 +742,17 @@
         vsbvis = determineVerticalSBVisible();
         hsbvis = determineHorizontalSBVisible();
 
-        if (vsbvis && !PlatformUtil.isEmbedded()) {
-            contentWidth -= vsbWidth;
+        if (vsbvis) {
             hsbWidth -= vsbWidth;
+            if (!PlatformUtil.isEmbedded()) {
+                contentWidth -= vsbWidth;
+            }
         }
-        if (hsbvis && !PlatformUtil.isEmbedded()) {
-            contentHeight -= hsbHeight;
+        if (hsbvis) {
             vsbHeight -= hsbHeight;
+            if (!PlatformUtil.isEmbedded()) {
+                contentHeight -= hsbHeight;
+            }
         }
         if (scrollNode != null && scrollNode.isResizable()) {
             // maybe adjust size now that scrollbars may take up space
@@ -798,9 +802,7 @@
         updateHorizontalSB();
 
         viewRect.resize(snapSize(contentWidth), snapSize(contentHeight));
-        clipRect.setWidth(snapSize(contentWidth));
-        clipRect.setHeight(snapSize(contentHeight));
-        clipRect.relocate(snapPosition(getInsets().getLeft() - viewRect.getLayoutX()), snapPosition(getInsets().getTop() - viewRect.getLayoutY()));
+        resetClip();
 
         if (vsbvis && hsbvis) {
             corner.setVisible(true);
@@ -932,15 +934,22 @@
     private double updatePosX() {
         viewRect.setLayoutX(snapPosition(getInsets().getLeft() - posX / (hsb.getMax() - hsb.getMin()) * (nodeWidth - contentWidth)));
         getSkinnable().setHvalue(Utils.clamp(getSkinnable().getHmin(), posX, getSkinnable().getHmax()));
+        resetClip();
         return posX;
     }
 
     private double updatePosY() {
         viewRect.setLayoutY(snapPosition(getInsets().getTop() - posY / (vsb.getMax() - vsb.getMin()) * (nodeHeight - contentHeight)));
         getSkinnable().setVvalue(Utils.clamp(getSkinnable().getVmin(), posY, getSkinnable().getVmax()));
+        resetClip();
         return posY;
     }
 
+    private void resetClip() {
+        clipRect.setWidth(snapSize(contentWidth));
+        clipRect.setHeight(snapSize(contentHeight));
+        clipRect.relocate(snapPosition(getInsets().getLeft() - viewRect.getLayoutX()), snapPosition(getInsets().getTop() - viewRect.getLayoutY()));
+    }
 
     Timeline sbTouchTimeline;
     KeyFrame sbTouchKF1;
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableCellSkin.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableCellSkin.java	Thu Jun 28 12:36:02 2012 +0200
@@ -30,6 +30,7 @@
 import javafx.scene.control.TableCell;
 
 import com.sun.javafx.scene.control.behavior.TableCellBehavior;
+import javafx.scene.shape.Rectangle;
 
 /**
  */
@@ -51,10 +52,17 @@
     
     private WeakInvalidationListener weakColumnWidthListener =
             new WeakInvalidationListener(columnWidthListener);
-
+    
     public TableCellSkin(TableCell control) {
         super(control, new TableCellBehavior(control));
         
+        // RT-22038
+        Rectangle clip = new Rectangle();
+        clip.widthProperty().bind(widthProperty());
+        clip.heightProperty().bind(heightProperty());
+        setClip(clip);
+        // --- end of RT-22038
+        
         if (getSkinnable().getTableColumn() != null) {
             getSkinnable().getTableColumn().widthProperty().addListener(
                 new WeakInvalidationListener(weakColumnWidthListener));
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableColumnHeader.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableColumnHeader.java	Thu Jun 28 12:36:02 2012 +0200
@@ -301,7 +301,7 @@
     private boolean isColumnReorderingEnabled() {
         // we only allow for column reordering if there are more than one column,
         // and if we are not on an embedded platform
-        return PlatformUtil.isEmbedded() && getTableView().getVisibleLeafColumns().size() > 1;
+        return ! PlatformUtil.isEmbedded() && getTableView().getVisibleLeafColumns().size() > 1;
     }
     
     private void initUI() {
@@ -763,7 +763,7 @@
 
         // Based on where the mouse actually is, we have to shuffle
         // where we want the column to end up. This code handles that.
-        int currentPos = getTableView().getVisibleLeafIndex(getTableColumn());
+        int currentPos = getIndex();
         newColumnPos += newColumnPos > currentPos && beforeMidPoint ?
             -1 : (newColumnPos < currentPos && !beforeMidPoint ? 1 : 0);
         
@@ -783,6 +783,13 @@
         getTableHeaderRow().setReordering(true);
     }
 
+    private int getIndex() {
+        ObservableList<TableColumn> columns = column.getParentColumn() == null ?
+            getTableView().getColumns() :
+            column.getParentColumn().getColumns();
+        return columns.indexOf(column);
+    }
+    
     protected void columnReorderingComplete(MouseEvent me) {
         // Move col from where it is now to the new position.
         moveColumn(getTableColumn(), newColumnPos);
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableHeaderRow.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableHeaderRow.java	Thu Jun 28 12:36:02 2012 +0200
@@ -207,7 +207,6 @@
 
         updateTableWidth();
         table.widthProperty().addListener(weakTableWidthListener);
-        table.getVisibleLeafColumns().addListener(weakVisibleLeafColumnsListener);
 
         // --- popup menu for hiding/showing columns
         columnPopupMenu = new ContextMenu();
@@ -287,21 +286,12 @@
      *                                                                         *
      **************************************************************************/    
     
-    private boolean headerDirty = false;
-    
     private InvalidationListener tableWidthListener = new InvalidationListener() {
         @Override public void invalidated(Observable valueModel) {
             updateTableWidth();
         }
     };
     
-    private ListChangeListener visibleLeafColumnsListener = new ListChangeListener<TableColumn<?,?>>() {
-        @Override public void onChanged(Change<? extends TableColumn<?,?>> c) {
-            headerDirty = true;
-            requestLayout();
-        }
-    };
-    
     private final ListChangeListener tableColumnsListener = new ListChangeListener<TableColumn<?,?>>() {
         @Override public void onChanged(Change<? extends TableColumn<?,?>> c) {
             while (c.next()) {
@@ -313,9 +303,6 @@
     private final WeakInvalidationListener weakTableWidthListener = 
             new WeakInvalidationListener(tableWidthListener);
     
-    private final WeakListChangeListener weakVisibleLeafColumnsListener =
-            new WeakListChangeListener(visibleLeafColumnsListener);
-    
     private final WeakListChangeListener weakTableColumnsListener =
             new WeakListChangeListener(tableColumnsListener);
     
@@ -385,11 +372,6 @@
     }
 
     @Override protected void layoutChildren() {
-        if (headerDirty) {
-            header.setColumns(table.getColumns());
-            headerDirty = false;
-        }
-        
         double x = scrollX;
         double headerWidth = snapSize(header.prefWidth(-1));
         double prefHeight = getHeight() - getInsets().getTop() - getInsets().getBottom();
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableViewSkin.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableViewSkin.java	Thu Jun 28 12:36:02 2012 +0200
@@ -451,7 +451,8 @@
         
         // painting the overlay over the column being reordered
         if (tableHeaderRow.getReorderingRegion() != null) {
-            TableColumn reorderingColumn = tableHeaderRow.getReorderingRegion().getTableColumn();
+            TableColumnHeader reorderingColumnHeader = tableHeaderRow.getReorderingRegion();
+            TableColumn reorderingColumn = reorderingColumnHeader.getTableColumn();
             if (reorderingColumn != null) {
                 Node n = tableHeaderRow.getReorderingRegion();
                 
@@ -460,7 +461,7 @@
                 // is off the left-side of the TableView (i.e. horizontal 
                 // scrolling has occured).
                 double minX = tableHeaderRow.sceneToLocal(n.localToScene(n.getBoundsInLocal())).getMinX();
-                double overlayWidth = reorderingColumn.getWidth();
+                double overlayWidth = reorderingColumnHeader.getWidth();
                 if (minX < 0) {
                     overlayWidth += minX;
                 }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextAreaSkin.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextAreaSkin.java	Thu Jun 28 12:36:02 2012 +0200
@@ -54,6 +54,7 @@
 import javafx.scene.control.ScrollPane;
 import javafx.scene.control.TextArea;
 import javafx.scene.input.MouseEvent;
+import javafx.scene.input.ScrollEvent;
 import javafx.scene.layout.Region;
 import javafx.scene.paint.Paint;
 import javafx.scene.shape.MoveTo;
@@ -272,11 +273,10 @@
                     Bounds b = caretPath.getBoundsInParent();
                     if (caretPos < anchorPos) {
                         selectionHandle2.setLayoutX(b.getMinX() - selectionHandle2.getWidth() / 2);
-                        selectionHandle2.setLayoutY(b.getMaxY());
+                        selectionHandle2.setLayoutY(b.getMaxY() - 1);
                     } else {
                         selectionHandle1.setLayoutX(b.getMinX() - selectionHandle1.getWidth() / 2);
-                        //selectionHandle1.setLayoutY(b.getMinY() - selectionHandle1.getHeight());
-                        selectionHandle1.setLayoutY(b.getMaxY());
+                        selectionHandle1.setLayoutY(b.getMinY() - selectionHandle1.getHeight() + 1);
                     }
                 }
             }
@@ -342,11 +342,10 @@
                 if (selection.getLength() > 0) {
                     if (caretPos < anchorPos) {
                         selectionHandle1.setLayoutX(b.getMinX() - selectionHandle1.getWidth() / 2);
-                        //selectionHandle1.setLayoutY(b.getMinY() - selectionHandle1.getHeight());
-                        selectionHandle1.setLayoutY(b.getMaxY());
+                        selectionHandle1.setLayoutY(b.getMinY() - selectionHandle1.getHeight() + 1);
                     } else {
                         selectionHandle2.setLayoutX(b.getMinX() - selectionHandle2.getWidth() / 2);
-                        selectionHandle2.setLayoutY(b.getMaxY());
+                        selectionHandle2.setLayoutY(b.getMaxY() - 1);
                     }
                 } else {
                     caretHandle.setLayoutX(b.getMinX() - caretHandle.getWidth() / 2 + 1);
@@ -431,6 +430,18 @@
         scrollPane.setContent(contentView);
         getChildren().add(scrollPane);
 
+        // RT-21658: We can currently only handle scroll events from touch if
+        // on the embedded platform.
+        if (!PlatformUtil.isEmbedded()) {
+            scrollPane.addEventFilter(ScrollEvent.ANY, new EventHandler<ScrollEvent>() {
+                @Override public void handle(ScrollEvent event) {
+                    if (event.isDirect()) {
+                        event.consume();
+                    }
+                }
+            });
+        }
+
         // Add selection
         selectionHighlightGroup.setManaged(false);
         selectionHighlightGroup.setVisible(false);
@@ -629,7 +640,7 @@
         if (textArea.isFocused()) setCaretAnimating(true);
 
         if (PlatformUtil.isEmbedded()) {
-            //selectionHandle1.setRotate(180);
+            selectionHandle1.setRotate(180);
 
             EventHandler<MouseEvent> handlePressHandler = new EventHandler<MouseEvent>() {
                 @Override public void handle(MouseEvent e) {
@@ -646,8 +657,9 @@
             caretHandle.setOnMouseDragged(new EventHandler<MouseEvent>() {
                 @Override public void handle(MouseEvent e) {
                     Text textNode = getTextNode();
-                    Point2D p = new Point2D(caretHandle.getLayoutX() + e.getX() + pressX - textNode.getLayoutX(),
-                                            caretHandle.getLayoutY() + e.getY() - pressY - 6 - getTextTranslateY());
+                    Point2D tp = textNode.localToScene(0, 0);
+                    Point2D p = new Point2D(e.getSceneX() - tp.getX() + 10/*??*/ - pressX + caretHandle.getWidth() / 2,
+                                            e.getSceneY() - tp.getY() - pressY - 6);
                     HitInfo hit = textNode.impl_hitTestChar(translateCaretPosition(p));
                     int pos = hit.getCharIndex();
                     if (pos > 0) {
@@ -670,8 +682,7 @@
                     Text textNode = getTextNode();
                     Point2D tp = textNode.localToScene(0, 0);
                     Point2D p = new Point2D(e.getSceneX() - tp.getX() + 10/*??*/ - pressX + selectionHandle1.getWidth() / 2,
-                                            //e.getSceneY() - tp.getY() - pressY + selectionHandle1.getHeight() + 5);
-                                            e.getSceneY() - tp.getY() - pressY - 6);
+                                            e.getSceneY() - tp.getY() - pressY + selectionHandle1.getHeight() + 5);
                     HitInfo hit = textNode.impl_hitTestChar(translateCaretPosition(p));
                     int pos = hit.getCharIndex();
                     if (textArea.getAnchor() < textArea.getCaretPosition()) {
@@ -958,12 +969,25 @@
     }
 
     private void scrollCaretToVisible() {
-            Bounds bounds = caretPath.getLayoutBounds();
-            TextArea textArea = getSkinnable();
+        TextArea textArea = getSkinnable();
+        Bounds bounds = caretPath.getLayoutBounds();
+        double x = bounds.getMinX() - textArea.getScrollLeft();
+        double y = bounds.getMinY() - textArea.getScrollTop();
+        double w = bounds.getWidth();
+        double h = bounds.getHeight();
 
-            scrollBoundsToVisible(new Rectangle2D(bounds.getMinX() - textArea.getScrollLeft(),
-                                                  bounds.getMinY() - textArea.getScrollTop(),
-                                                  bounds.getWidth(), bounds.getHeight()));
+        if (PlatformUtil.isEmbedded()) {
+            if (caretHandle.isVisible()) {
+                h += caretHandle.getHeight();
+            } else if (selectionHandle1.isVisible() && selectionHandle2.isVisible()) {
+                x -= selectionHandle1.getWidth() / 2;
+                y -= selectionHandle1.getHeight();
+                w += selectionHandle1.getWidth() / 2 + selectionHandle2.getWidth() / 2;
+                h += selectionHandle1.getHeight() + selectionHandle2.getHeight();
+            }
+        }
+
+        scrollBoundsToVisible(new Rectangle2D(x, y, w, h));
     }
 
     private void scrollBoundsToVisible(Rectangle2D bounds) {
@@ -1049,11 +1073,11 @@
     // Callbacks from Behavior class
 
     private double getTextTranslateX() {
-        return 0;
+        return contentView.getInsets().getLeft();
     }
 
     private double getTextTranslateY() {
-        return 0;
+        return contentView.getInsets().getTop();
     }
 
     private double getTextLeft() {
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextFieldSkin.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextFieldSkin.java	Thu Jun 28 12:36:02 2012 +0200
@@ -236,7 +236,7 @@
         textGroup.getChildren().addAll(selectionHighlightPath, textNode, caretPath);
         getChildren().add(textGroup);
         if (PlatformUtil.isEmbedded()) {
-            /*textGroup.*/getChildren().addAll(caretHandle, selectionHandle1, selectionHandle2);
+            getChildren().addAll(caretHandle, selectionHandle1, selectionHandle2);
         }
 
         // Add text
@@ -253,7 +253,12 @@
             }
         });
         textNode.fillProperty().bind(textFill);
-        textNode.impl_selectionFillProperty().bind(highlightTextFill);
+        textNode.impl_selectionFillProperty().bind(new ObjectBinding<Paint>() {
+            { bind(highlightTextFill, textFill, textField.focusedProperty()); }
+            @Override protected Paint computeValue() {
+                return textField.isFocused() ? highlightTextFill.get() : textFill.get();
+            }
+        });
         // updated by listener on caretPosition to ensure order
         textNode.impl_caretPositionProperty().set(textField.getCaretPosition());
         textField.selectionProperty().addListener(new InvalidationListener() {
@@ -346,6 +351,8 @@
         });
 
         if (PlatformUtil.isEmbedded()) {
+            selectionHandle1.setRotate(180);
+
             EventHandler<MouseEvent> handlePressHandler = new EventHandler<MouseEvent>() {
                 @Override public void handle(MouseEvent e) {
                     pressX = e.getX();
@@ -749,9 +756,10 @@
                                caretHandle.prefHeight(-1));
 
             Bounds b = caretPath.getBoundsInParent();
-            selectionHandle1.setLayoutY(b.getMaxY() - 3);
-            selectionHandle2.setLayoutY(b.getMaxY() - 3);
-            caretHandle.setLayoutY(b.getMaxY() - 3);
+            caretHandle.setLayoutY(b.getMaxY() - 1);
+            //selectionHandle1.setLayoutY(b.getMaxY() - 1);
+            selectionHandle1.setLayoutY(b.getMinY() - selectionHandle1.getHeight() + 1);
+            selectionHandle2.setLayoutY(b.getMaxY() - 1);
         }
     }
 
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextInputControlSkin.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextInputControlSkin.java	Thu Jun 28 12:36:02 2012 +0200
@@ -85,6 +85,7 @@
 import com.sun.javafx.tk.FontMetrics;
 import com.sun.javafx.tk.Toolkit;
 
+import static com.sun.javafx.PlatformUtil.*;
 import static com.sun.javafx.scene.control.skin.resources.ControlResources.*;
 
 /**
@@ -92,7 +93,7 @@
  */
 public abstract class TextInputControlSkin<T extends TextInputControl, B extends TextInputControlBehavior<T>> extends SkinBase<T, B> {
 
-    private static final boolean macOS = PlatformUtil.isMac();
+    private static final boolean macOS = isMac();
     /**
      * The font to use with this control. In 1.3 and prior we had a font property
      * on the TextInputControl itself, however now we just do it via CSS
@@ -235,7 +236,7 @@
     protected StackPane selectionHandle2 = null;
 
     public Point2D getMenuPosition() {
-        if (PlatformUtil.isEmbedded()) {
+        if (isEmbedded()) {
             if (caretHandle.isVisible()) {
                 return new Point2D(caretHandle.getLayoutX() + caretHandle.getWidth() / 2,
                                    caretHandle.getLayoutY());
@@ -252,7 +253,7 @@
     }
 
 
-    private static boolean useFXVK = PlatformUtil.isEmbedded();
+    private static boolean useFXVK = isEmbedded();
 
     /* For testing only */
     static int vkType = -1;
@@ -300,15 +301,15 @@
             { bind(textInput.focusedProperty(), textInput.anchorProperty(), textInput.caretPositionProperty(),
                     textInput.disabledProperty(), textInput.editableProperty(), displayCaret, blink);}
             @Override protected boolean computeValue() {
-                // RT-10682: On mac, we hide the caret during selection, but on windows we show it
+                // RT-10682: On Windows, we show the caret during selection, but on others we hide it
                 return !blink.get() && displayCaret.get() && textInput.isFocused() &&
-                        (!macOS || (textInput.getCaretPosition() == textInput.getAnchor())) &&
+                        (isWindows() || (textInput.getCaretPosition() == textInput.getAnchor())) &&
                         !textInput.isDisabled() &&
                         textInput.isEditable();
             }
         };
 
-        if (PlatformUtil.isEmbedded()) {
+        if (isEmbedded()) {
             caretHandle      = new StackPane();
             selectionHandle1 = new StackPane();
             selectionHandle2 = new StackPane();
@@ -362,12 +363,13 @@
             textInput.focusedProperty().addListener(new InvalidationListener() {
                 @Override public void invalidated(Observable observable) {
                     if (useFXVK) {
-                        if (textInput.isFocused()) {
+                        if (textInput.isEditable() && textInput.isFocused()) {
                             FXVK.attach(textInput);
                         } else if (getScene() == null ||
                                    getScene().getWindow() == null ||
                                    !getScene().getWindow().isFocused() ||
-                                   !(getScene().getFocusOwner() instanceof TextInputControl)) {
+                                   !(getScene().getFocusOwner() instanceof TextInputControl &&
+                                     ((TextInputControl)getScene().getFocusOwner()).isEditable())) {
                             FXVK.detach();
                         }
                     }
@@ -604,20 +606,25 @@
     final MenuItem deleteMI = new ContextMenuItem("DeleteSelection");
     final MenuItem selectWordMI = new ContextMenuItem("SelectWord");
     final MenuItem selectAllMI = new ContextMenuItem("SelectAll");
+    final MenuItem separatorMI = new SeparatorMenuItem();
 
     public void populateContextMenu(ContextMenu contextMenu) {
-        boolean hasText = (getSkinnable().getLength() > 0);
-        boolean hasSelection = (getSkinnable().getSelection().getLength() > 0);
+        TextInputControl textInputControl = getSkinnable();
+        boolean editable = textInputControl.isEditable();
+        boolean hasText = (textInputControl.getLength() > 0);
+        boolean hasSelection = (textInputControl.getSelection().getLength() > 0);
         boolean maskText = (maskText("A") != "A");
         ObservableList<MenuItem> items = contextMenu.getItems();
 
-        if (PlatformUtil.isEmbedded()) {
+        if (isEmbedded()) {
             items.clear();
             if (!maskText && hasSelection) {
-                items.add(cutMI);
+                if (editable) {
+                    items.add(cutMI);
+                }
                 items.add(copyMI);
             }
-            if (Clipboard.getSystemClipboard().hasString()) {
+            if (editable && Clipboard.getSystemClipboard().hasString()) {
                 items.add(pasteMI);
             }
             if (hasText) {
@@ -629,9 +636,11 @@
             selectWordMI.getProperties().put("refreshMenu", Boolean.TRUE);
             selectAllMI.getProperties().put("refreshMenu", Boolean.TRUE);
         } else {
-            if (items.size() == 0) {
-                items.addAll(undoMI, redoMI, cutMI, copyMI, pasteMI, deleteMI,
-                             new SeparatorMenuItem(), selectAllMI);
+            if (editable) {
+                items.setAll(undoMI, redoMI, cutMI, copyMI, pasteMI, deleteMI,
+                             separatorMI, selectAllMI);
+            } else {
+                items.setAll(copyMI, separatorMI, selectAllMI);
             }
             undoMI.setDisable(!getBehavior().canUndo());
             redoMI.setDisable(!getBehavior().canRedo());
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/VirtualFlow.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/VirtualFlow.java	Thu Jun 28 12:36:02 2012 +0200
@@ -554,7 +554,17 @@
                             virtualDelta = event.getTextDeltaY() * lastHeight;
                             break;
                         case LINES:
-                            virtualDelta = event.getTextDeltaY() * lastCellLength;
+                            /*
+                            ** if we've selected a cell, then use
+                            ** it's length for the scroll, otherwise
+                            ** use the length of the first visible cell
+                            */
+                            if (lastCellLength != -1) {
+                                virtualDelta = event.getTextDeltaY() * lastCellLength;
+                            }
+                            else if (getFirstVisibleCell() != null) {
+                                virtualDelta = event.getTextDeltaY() * getCellLength(getFirstVisibleCell());
+                            }
                             break;
                         case NONE:
                             virtualDelta = event.getDeltaY();
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/caspian/embedded-qvga.css	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/caspian/embedded-qvga.css	Thu Jun 28 12:36:02 2012 +0200
@@ -31,3 +31,17 @@
  * targeted at VGA screens).                                                   *
  *                                                                             *
  ******************************************************************************/
+
+/*******************************************************************************
+ *                                                                             *
+ * TextField, PasswordField, TextArea                                                                   *
+ *                                                                             *
+ ******************************************************************************/
+
+.text-field {
+    -fx-padding: 3 5 3 5; /* Restore values from caspian, as QVGA has no selection handles */
+}
+
+.text-area .content {
+    -fx-padding: 3 5 3 5; /* Restore values from caspian, as QVGA has no selection handles */
+}
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/caspian/embedded.css	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/caspian/embedded.css	Thu Jun 28 12:36:02 2012 +0200
@@ -92,39 +92,53 @@
 }
 
 
+
+/*******************************************************************************
+ *                                                                             *
+ * TextField, PasswordField, TextArea                                                                   *
+ *                                                                             *
+ ******************************************************************************/
+
+.text-field {
+    -fx-padding: 6 5 6 5; /* Adding 3px to top and bottom for handles */
+}
+
+.text-area .content {
+    -fx-padding: 9 5 9 5; /* Adding 6px to top and bottom for handles */
+}
+
+
 .caret-handle {
-    -fx-background-color: black /*#ACACAC*/,
+    -fx-background-color: transparent,
+                          black /*#ACACAC*/,
                           linear-gradient(to bottom, #AFAFAF 0%, #DFDFDF 100%);
-    -fx-background-insets: 0, 1;
-    -fx-shape: "M11.974,2.579L20,12.358V28H4V12.356L11.974,2.579z";
+    -fx-background-insets: -4 -18 -8 -18, 0, 1;
+    -fx-shape: "M11.974,2.579L20,12.358V20H4V12.356L11.974,2.579z";
 /*
     -fx-shape: "M11.972,1L3,12v17h18V12L11.972,1L11.972,1z";
     -fx-padding: 0.375em 0.291em 0.375em 0.291em;
 */
-    -fx-padding: 0.45em 0.3em 0.45em 0.3em;
+    -fx-padding: 0.32em 0.3em 0.32em 0.3em;
     -fx-cursor: hand;
 }
 
+
+
 .selection-handle {
-    -fx-background-color: transparent, #0071bc /*-fx-accent*/,
+    -fx-background-color: transparent,
+                          #0071bc /*-fx-accent*/,
                           linear-gradient(to bottom, #0063AA 0%, #008AED 100%);
-    -fx-background-insets: 0, 0, 1;
-    -fx-shape: "M10.974,2.579L19,12.358V28H3V12.356L10.974,2.579z";
+    -fx-background-insets: -4 -18 -8 -18, 0, 1;
+    -fx-shape: "M10.974,2.579L19,12.358V20H3V12.356L10.974,2.579z";
 /*
     -fx-shape: "M10.972,1L2,12v17h18V12L10.972,1L10.972,1z";
     -fx-padding: 0.375em 0.291em 0.375em 0.291em;
 */
-    -fx-padding: 0.45em 0.3em 0.45em 0.3em;
+    -fx-padding: 0.32em 0.3em 0.32em 0.3em;
     -fx-cursor: hand;
 }
 
-#selection-handle-1 {
-    -fx-background-insets: -4 0 -4 -4, 0, 1;
-}
 
-#selection-handle-2 {
-    -fx-background-insets: -4 -4 -4 0, 0, 1;
-}
 
 /*******************************************************************************
  *                                                                             *
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/resources/EmbeddedResources.java	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.javafx.scene.control.skin.resources;
+
+import java.util.ResourceBundle;
+
+public final class EmbeddedResources {
+
+    private static ResourceBundle embeddedResourceBundle;
+
+    public static ResourceBundle getBundle() {
+        if (embeddedResourceBundle == null) {
+            embeddedResourceBundle = ResourceBundle.getBundle("com/sun/javafx/scene/control/skin/resources/embedded");
+        }
+        return embeddedResourceBundle;
+    }
+
+    public static String getString(String key) {
+        return getBundle().getString(key);
+    }
+}
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/resources/controls.properties	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/resources/controls.properties	Thu Jun 28 12:36:02 2012 +0200
@@ -18,176 +18,3 @@
 TextInputControl.menu.SelectAll=Select All
 TextInputControl.menu.SelectWord=Select
 
-# Virtual Keyboard for embedded FX. This will not be localized for FX 2.2.
-#
-# Note: There can at most be only one of each of the special keys: BACKSPACE ENTER SHIFT SYM
-#
-# TODO: use sect, deg, reg, tm only once
-#
-FXVK.text.row1.key01=q 1 [
-FXVK.text.row1.key02=w 2 ]
-FXVK.text.row1.key03=e 3 { egrave eacute ecirc euml
-FXVK.text.row1.key04=r 4 } reg
-FXVK.text.row1.key05=t 5 < tm
-FXVK.text.row1.key06=y 6 > ygrave yacute ycirc ymacron yuml yhook
-FXVK.text.row1.key07=u 7 laquo ugrave uacute ucirc uuml
-FXVK.text.row1.key08=i 8 raquo igrave iacute icirc iuml
-FXVK.text.row1.key09=o 9 ` ograve oacute ocirc otilde ouml oslash deg
-FXVK.text.row1.key10=p 0 ~ para pi
-
-FXVK.text.row2.key01=a # agrave aacute acirc atilde auml aring
-FXVK.text.row2.key02=s $ euro pound yen scedil scaron szlig sigma
-FXVK.text.row2.key03=d % eth
-FXVK.text.row2.key04=f &
-FXVK.text.row2.key05=g * sect
-FXVK.text.row2.key06=h ( middot
-FXVK.text.row2.key07=j ) deg
-FXVK.text.row2.key08=k _ neq
-FXVK.text.row2.key09=l @
-
-FXVK.text.row3.key01=SHIFT
-FXVK.text.row3.key02=z / iexcl
-FXVK.text.row3.key03=x \\ iquest
-FXVK.text.row3.key04=c ; permil ccedil copy cent
-FXVK.text.row3.key05=v : reg
-FXVK.text.row3.key06=b = tm
-FXVK.text.row3.key07=n + ntilde
-FXVK.text.row3.key08=m - micro
-FXVK.text.row3.key09=' "
-FXVK.text.row3.key10=BACKSPACE
-
-FXVK.text.row4.key01=SYM
-FXVK.text.row4.key01.width=1.5
-FXVK.text.row4.key02=space
-FXVK.text.row4.key02.width=5
-FXVK.text.row4.key03=, !
-FXVK.text.row4.key04=. ?
-FXVK.text.row4.key05=ENTER
-FXVK.text.row4.key05.width=1.5
-
-
-
-FXVK.numeric.row1.key01=1
-FXVK.numeric.row1.key01.width=1.5
-FXVK.numeric.row1.key02=2
-FXVK.numeric.row1.key02.width=1.5
-FXVK.numeric.row1.key03=3
-FXVK.numeric.row1.key03.width=1.5
-FXVK.numeric.row1.key04=/
-FXVK.numeric.row1.key04.width=1.5
-
-FXVK.numeric.row2.key01=4
-FXVK.numeric.row2.key01.width=1.5
-FXVK.numeric.row2.key02=5
-FXVK.numeric.row2.key02.width=1.5
-FXVK.numeric.row2.key03=6
-FXVK.numeric.row2.key03.width=1.5
-FXVK.numeric.row2.key04=-
-FXVK.numeric.row2.key04.width=1.5
-
-FXVK.numeric.row3.key01=7
-FXVK.numeric.row3.key01.width=1.5
-FXVK.numeric.row3.key02=8
-FXVK.numeric.row3.key02.width=1.5
-FXVK.numeric.row3.key03=9
-FXVK.numeric.row3.key03.width=1.5
-FXVK.numeric.row3.key04=BACKSPACE
-FXVK.numeric.row3.key04.width=1.5
-
-FXVK.numeric.row4.key01=+
-FXVK.numeric.row4.key01.width=1.5
-FXVK.numeric.row4.key02=0
-FXVK.numeric.row4.key02.width=1.5
-FXVK.numeric.row4.key03=. ,
-FXVK.numeric.row4.key03.width=1.5
-FXVK.numeric.row4.key04=ENTER
-FXVK.numeric.row4.key04.width=1.5
-
-
-FXVK.url.row1.key01=q 1 [
-FXVK.url.row1.key02=w 2 ]
-FXVK.url.row1.key03=e 3 { egrave eacute ecirc euml
-FXVK.url.row1.key04=r 4 } reg
-FXVK.url.row1.key05=t 5 < tm
-FXVK.url.row1.key06=y 6 > ygrave yacute ycirc ymacron yuml yhook
-FXVK.url.row1.key07=u 7 laquo ugrave uacute ucirc uuml
-FXVK.url.row1.key08=i 8 raquo igrave iacute icirc iuml
-FXVK.url.row1.key09=o 9 ` ograve oacute ocirc otilde ouml oslash deg
-FXVK.url.row1.key10=p 0 ~ para pi
-
-FXVK.url.row2.key01=a # agrave aacute acirc atilde auml aring
-FXVK.url.row2.key02=s $ euro pound yen scedil scaron szlig sigma
-FXVK.url.row2.key03=d % eth
-FXVK.url.row2.key04=f & 
-FXVK.url.row2.key05=g * sect
-FXVK.url.row2.key06=h ( middot
-FXVK.url.row2.key07=j ) deg
-FXVK.url.row2.key08=k " neq
-FXVK.url.row2.key09=l @
-
-FXVK.url.row3.key01=SHIFT
-FXVK.url.row3.key02=z iexcl
-FXVK.url.row3.key03=x iquest
-FXVK.url.row3.key04=c ; permil ccedil copy cent
-FXVK.url.row3.key05=v : reg
-FXVK.url.row3.key06=b = tm
-FXVK.url.row3.key07=n + ntilde
-FXVK.url.row3.key08=m ' micro
-FXVK.url.row3.key09=- _
-FXVK.url.row3.key10=BACKSPACE
-
-FXVK.url.row4.key01=SYM
-FXVK.url.row4.key01.width=1.5
-FXVK.url.row4.key02=www. http://
-FXVK.url.row4.key02.width=1.5
-FXVK.url.row4.key03=. ,
-FXVK.url.row4.key03.width=1.5
-FXVK.url.row4.key04=.com .org .net .gov .edu
-FXVK.url.row4.key04.width=1.5
-FXVK.url.row4.key05=/ \\
-FXVK.url.row4.key05.width=1.5
-FXVK.url.row4.key06=ENTER
-FXVK.url.row4.key06.width=2.5
-
-
-FXVK.email.row1.key01=q 1 [
-FXVK.email.row1.key02=w 2 ]
-FXVK.email.row1.key03=e 3 { egrave eacute ecirc euml
-FXVK.email.row1.key04=r 4 } reg
-FXVK.email.row1.key05=t 5 < tm
-FXVK.email.row1.key06=y 6 > ygrave yacute ycirc ymacron yuml yhook
-FXVK.email.row1.key07=u 7 laquo ugrave uacute ucirc uuml
-FXVK.email.row1.key08=i 8 raquo igrave iacute icirc iuml
-FXVK.email.row1.key09=o 9 ` ograve oacute ocirc otilde ouml oslash deg
-FXVK.email.row1.key10=p 0 ~ para pi
-
-FXVK.email.row2.key01=a # agrave aacute acirc atilde auml aring
-FXVK.email.row2.key02=s $ euro pound yen scedil scaron szlig sigma
-FXVK.email.row2.key03=d % eth
-FXVK.email.row2.key04=f & 
-FXVK.email.row2.key05=g * sect
-FXVK.email.row2.key06=h ( middot
-FXVK.email.row2.key07=j ) deg
-FXVK.email.row2.key08=k _ neq
-FXVK.email.row2.key09=l "
-
-FXVK.email.row3.key01=SHIFT
-FXVK.email.row3.key02=z / iexcl
-FXVK.email.row3.key03=x \\ iquest
-FXVK.email.row3.key04=c ; permil ccedil copy cent
-FXVK.email.row3.key05=v : reg
-FXVK.email.row3.key06=b = tm
-FXVK.email.row3.key07=n + ntilde
-FXVK.email.row3.key08=m - micro
-FXVK.email.row3.key09=@ '
-FXVK.email.row3.key10=BACKSPACE
-
-FXVK.email.row4.key01=SYM
-FXVK.email.row4.key01.width=1.5
-FXVK.email.row4.key02=space
-FXVK.email.row4.key02.width=4
-FXVK.email.row4.key03=, !
-FXVK.email.row4.key04=. ?
-FXVK.email.row4.key05=.com .org .net .gov .edu
-FXVK.email.row4.key06=ENTER
-FXVK.email.row4.key06.width=1.5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/resources/embedded.properties	Thu Jun 28 12:36:02 2012 +0200
@@ -0,0 +1,173 @@
+# Virtual Keyboard for embedded FX. This will not be localized for FX 2.2.
+#
+# Note: There can at most be only one of each of the special keys: BACKSPACE ENTER SHIFT SYM
+#
+# TODO: use sect, deg, reg, tm only once
+#
+FXVK.text.row1.key01=q 1 [
+FXVK.text.row1.key02=w 2 ]
+FXVK.text.row1.key03=e 3 { egrave eacute ecirc euml
+FXVK.text.row1.key04=r 4 } reg
+FXVK.text.row1.key05=t 5 < tm
+FXVK.text.row1.key06=y 6 > ygrave yacute ycirc ymacron yuml yhook
+FXVK.text.row1.key07=u 7 laquo ugrave uacute ucirc uuml
+FXVK.text.row1.key08=i 8 raquo igrave iacute icirc iuml
+FXVK.text.row1.key09=o 9 ` ograve oacute ocirc otilde ouml oslash deg
+FXVK.text.row1.key10=p 0 ~ para pi
+
+FXVK.text.row2.key01=a # agrave aacute acirc atilde auml aring
+FXVK.text.row2.key02=s $ euro pound yen scedil scaron szlig sigma
+FXVK.text.row2.key03=d % eth
+FXVK.text.row2.key04=f &
+FXVK.text.row2.key05=g * sect
+FXVK.text.row2.key06=h ( middot
+FXVK.text.row2.key07=j ) deg
+FXVK.text.row2.key08=k _ neq
+FXVK.text.row2.key09=l @
+
+FXVK.text.row3.key01=SHIFT
+FXVK.text.row3.key02=z / iexcl
+FXVK.text.row3.key03=x \\ iquest
+FXVK.text.row3.key04=c ; permil ccedil copy cent
+FXVK.text.row3.key05=v : reg
+FXVK.text.row3.key06=b = tm
+FXVK.text.row3.key07=n + ntilde
+FXVK.text.row3.key08=m - micro
+FXVK.text.row3.key09=' "
+FXVK.text.row3.key10=BACKSPACE
+
+FXVK.text.row4.key01=SYM
+FXVK.text.row4.key01.width=1.5
+FXVK.text.row4.key02=space
+FXVK.text.row4.key02.width=5
+FXVK.text.row4.key03=, !
+FXVK.text.row4.key04=. ?
+FXVK.text.row4.key05=ENTER
+FXVK.text.row4.key05.width=1.5
+
+
+
+FXVK.numeric.row1.key01=1
+FXVK.numeric.row1.key01.width=1.5
+FXVK.numeric.row1.key02=2
+FXVK.numeric.row1.key02.width=1.5
+FXVK.numeric.row1.key03=3
+FXVK.numeric.row1.key03.width=1.5
+FXVK.numeric.row1.key04=/
+FXVK.numeric.row1.key04.width=1.5
+
+FXVK.numeric.row2.key01=4
+FXVK.numeric.row2.key01.width=1.5
+FXVK.numeric.row2.key02=5
+FXVK.numeric.row2.key02.width=1.5
+FXVK.numeric.row2.key03=6
+FXVK.numeric.row2.key03.width=1.5
+FXVK.numeric.row2.key04=-
+FXVK.numeric.row2.key04.width=1.5
+
+FXVK.numeric.row3.key01=7
+FXVK.numeric.row3.key01.width=1.5
+FXVK.numeric.row3.key02=8
+FXVK.numeric.row3.key02.width=1.5
+FXVK.numeric.row3.key03=9
+FXVK.numeric.row3.key03.width=1.5
+FXVK.numeric.row3.key04=BACKSPACE
+FXVK.numeric.row3.key04.width=1.5
+
+FXVK.numeric.row4.key01=+
+FXVK.numeric.row4.key01.width=1.5
+FXVK.numeric.row4.key02=0
+FXVK.numeric.row4.key02.width=1.5
+FXVK.numeric.row4.key03=. ,
+FXVK.numeric.row4.key03.width=1.5
+FXVK.numeric.row4.key04=ENTER
+FXVK.numeric.row4.key04.width=1.5
+
+
+FXVK.url.row1.key01=q 1 [
+FXVK.url.row1.key02=w 2 ]
+FXVK.url.row1.key03=e 3 { egrave eacute ecirc euml
+FXVK.url.row1.key04=r 4 } reg
+FXVK.url.row1.key05=t 5 < tm
+FXVK.url.row1.key06=y 6 > ygrave yacute ycirc ymacron yuml yhook
+FXVK.url.row1.key07=u 7 laquo ugrave uacute ucirc uuml
+FXVK.url.row1.key08=i 8 raquo igrave iacute icirc iuml
+FXVK.url.row1.key09=o 9 ` ograve oacute ocirc otilde ouml oslash deg
+FXVK.url.row1.key10=p 0 ~ para pi
+
+FXVK.url.row2.key01=a # agrave aacute acirc atilde auml aring
+FXVK.url.row2.key02=s $ euro pound yen scedil scaron szlig sigma
+FXVK.url.row2.key03=d % eth
+FXVK.url.row2.key04=f & 
+FXVK.url.row2.key05=g * sect
+FXVK.url.row2.key06=h ( middot
+FXVK.url.row2.key07=j ) deg
+FXVK.url.row2.key08=k " neq
+FXVK.url.row2.key09=l @
+
+FXVK.url.row3.key01=SHIFT
+FXVK.url.row3.key02=z iexcl
+FXVK.url.row3.key03=x iquest
+FXVK.url.row3.key04=c ; permil ccedil copy cent
+FXVK.url.row3.key05=v : reg
+FXVK.url.row3.key06=b = tm
+FXVK.url.row3.key07=n + ntilde
+FXVK.url.row3.key08=m ' micro
+FXVK.url.row3.key09=- _
+FXVK.url.row3.key10=BACKSPACE
+
+FXVK.url.row4.key01=SYM
+FXVK.url.row4.key01.width=1.5
+FXVK.url.row4.key02=www. http://
+FXVK.url.row4.key02.width=1.5
+FXVK.url.row4.key03=. ,
+FXVK.url.row4.key03.width=1.5
+FXVK.url.row4.key04=.com .org .net .gov .edu
+FXVK.url.row4.key04.width=1.5
+FXVK.url.row4.key05=/ \\
+FXVK.url.row4.key05.width=1.5
+FXVK.url.row4.key06=ENTER
+FXVK.url.row4.key06.width=2.5
+
+
+FXVK.email.row1.key01=q 1 [
+FXVK.email.row1.key02=w 2 ]
+FXVK.email.row1.key03=e 3 { egrave eacute ecirc euml
+FXVK.email.row1.key04=r 4 } reg
+FXVK.email.row1.key05=t 5 < tm
+FXVK.email.row1.key06=y 6 > ygrave yacute ycirc ymacron yuml yhook
+FXVK.email.row1.key07=u 7 laquo ugrave uacute ucirc uuml
+FXVK.email.row1.key08=i 8 raquo igrave iacute icirc iuml
+FXVK.email.row1.key09=o 9 ` ograve oacute ocirc otilde ouml oslash deg
+FXVK.email.row1.key10=p 0 ~ para pi
+
+FXVK.email.row2.key01=a # agrave aacute acirc atilde auml aring
+FXVK.email.row2.key02=s $ euro pound yen scedil scaron szlig sigma
+FXVK.email.row2.key03=d % eth
+FXVK.email.row2.key04=f & 
+FXVK.email.row2.key05=g * sect
+FXVK.email.row2.key06=h ( middot
+FXVK.email.row2.key07=j ) deg
+FXVK.email.row2.key08=k _ neq
+FXVK.email.row2.key09=l "
+
+FXVK.email.row3.key01=SHIFT
+FXVK.email.row3.key02=z / iexcl
+FXVK.email.row3.key03=x \\ iquest
+FXVK.email.row3.key04=c ; permil ccedil copy cent
+FXVK.email.row3.key05=v : reg
+FXVK.email.row3.key06=b = tm
+FXVK.email.row3.key07=n + ntilde
+FXVK.email.row3.key08=m - micro
+FXVK.email.row3.key09=@ '
+FXVK.email.row3.key10=BACKSPACE
+
+FXVK.email.row4.key01=SYM
+FXVK.email.row4.key01.width=1.5
+FXVK.email.row4.key02=space
+FXVK.email.row4.key02.width=4
+FXVK.email.row4.key03=, !
+FXVK.email.row4.key04=. ?
+FXVK.email.row4.key05=.com .org .net .gov .edu
+FXVK.email.row4.key06=ENTER
+FXVK.email.row4.key06.width=1.5
--- a/javafx-ui-controls/src/javafx/scene/control/ComboBox.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/javafx/scene/control/ComboBox.java	Thu Jun 28 12:36:02 2012 +0200
@@ -74,7 +74,20 @@
  * <p>As the ComboBox internally renders content with a ListView, API exists in
  * the ComboBox class to allow for a custom cell factory to be set. For more
  * information on cell factories, refer to the {@link Cell} and {@link ListCell}
- * classes.
+ * classes. It is important to note that if a cell factory is set on a ComboBox,
+ * cells will only be used in the ListView that shows when the ComboBox is 
+ * clicked. If you also want to customize the rendering of the 'button' area
+ * of the ComboBox, you can set a custom {@link ListCell} instance in the 
+ * {@link #buttonCellProperty() button cell} property. One way of doing this
+ * is with the following code (note the use of {@code setButtonCell}:
+ * 
+ * <pre>
+ * {@code
+ * Callback<ListView<String>, ListCell<String>> cellFactory = ...;
+ * ComboBox comboBox = new ComboBox();
+ * comboBox.setItems(items);
+ * comboBox.setButtonCell(cellFactory.call(null));
+ * comboBox.setCellFactory(cellFactory);}</pre>
  * 
  * <p>Because a ComboBox can be {@link #editableProperty() editable}, and the
  * default means of allowing user input is via a {@link TextField}, a 
--- a/javafx-ui-controls/src/javafx/scene/control/ListView.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/javafx/scene/control/ListView.java	Thu Jun 28 12:36:02 2012 +0200
@@ -58,6 +58,7 @@
 import com.sun.javafx.scene.control.WeakListChangeListener;
 import com.sun.javafx.scene.control.skin.ListViewSkin;
 import com.sun.javafx.scene.control.skin.VirtualContainerBase;
+import java.lang.ref.WeakReference;
 import javafx.beans.DefaultProperty;
 
 /**
@@ -305,19 +306,25 @@
     public final ObjectProperty<ObservableList<T>> itemsProperty() {
         if (items == null) {
             items = new SimpleObjectProperty<ObservableList<T>>(this, "items") {
+                WeakReference<ObservableList<T>> oldItemsRef;
+                
                 @Override protected void invalidated() {
+                    ObservableList<T> oldItems = oldItemsRef == null ? null : oldItemsRef.get();
+                    
                     // FIXME temporary fix for RT-15793. This will need to be
                     // properly fixed when time permits
                     if (getSelectionModel() instanceof ListViewBitSetSelectionModel) {
-                        ((ListViewBitSetSelectionModel)getSelectionModel()).updateItemsObserver(null, getItems());
+                        ((ListViewBitSetSelectionModel)getSelectionModel()).updateItemsObserver(oldItems, getItems());
                     }
                     if (getFocusModel() instanceof ListViewFocusModel) {
-                        ((ListViewFocusModel)getFocusModel()).updateItemsObserver(null, getItems());
+                        ((ListViewFocusModel)getFocusModel()).updateItemsObserver(oldItems, getItems());
                     }
                     if (getSkin() instanceof ListViewSkin) {
                         ListViewSkin skin = (ListViewSkin) getSkin();
                         skin.updateListViewItems();
                     }
+                    
+                    oldItemsRef = new WeakReference<ObservableList<T>>(getItems());
                 }
             };
         }
@@ -908,6 +915,7 @@
             this.listView.itemsProperty().addListener(weakItemsObserver);
             if (listView.getItems() != null) {
                 this.listView.getItems().addListener(weakItemsContentObserver);
+//                updateItemsObserver(null, this.listView.getItems());
             }
         }
         
@@ -945,12 +953,14 @@
         private WeakChangeListener weakItemsObserver = 
                 new WeakChangeListener(itemsObserver);
         
+        private int newListHash = -1;
         private void updateItemsObserver(ObservableList<T> oldList, ObservableList<T> newList) {
             // update listeners
             if (oldList != null) {
                 oldList.removeListener(weakItemsContentObserver);
             }
-            if (newList != null) {
+            if (newList != null && newList.hashCode() != newListHash) {
+                newListHash = newList.hashCode();
                 newList.addListener(weakItemsContentObserver);
             }
 
@@ -993,11 +1003,22 @@
             c.reset();
             while (c.next()) {
                 if (c.wasReplaced()) {
-                    // Fix for RT-18969: the list had setAll called on it
-                    int index = getSelectedIndex();
-                    if (index < getItemCount() && index >= 0) {
-                        clearSelection(index);
-                        select(index);
+                    if (c.getList().isEmpty()) {
+                        // the entire items list was emptied - clear selection
+                        clearSelection();
+                    } else {
+                        // Fix for RT-18969: the list had setAll called on it
+                        int index = getSelectedIndex();
+                        if (index < getItemCount() && index >= 0) {
+                            // Use of makeAtomic is a fix for RT-20945
+                            makeAtomic = true;
+                            clearSelection(index);
+                            makeAtomic = false;
+                            select(index);
+                        } else {
+                            // Fix for RT-22079
+                            clearSelection();
+                        }
                     }
                 } else if (c.wasAdded() || c.wasRemoved()) {
                     int shift = c.wasAdded() ? c.getAddedSize() : -c.getRemovedSize();
--- a/javafx-ui-controls/src/javafx/scene/control/MultipleSelectionModelBase.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/javafx/scene/control/MultipleSelectionModelBase.java	Thu Jun 28 12:36:02 2012 +0200
@@ -176,10 +176,12 @@
 
     /***********************************************************************
      *                                                                     *
-     * Internal properties                                                 *
+     * Internal field                                                      *
      *                                                                     *
      **********************************************************************/
 
+    // Fix for RT-20945
+    boolean makeAtomic = false;
 
 
     /***********************************************************************
@@ -279,6 +281,12 @@
         if (row < 0 || row >= getItemCount()) {
             return;
         }
+        
+        boolean isSameRow = row == getSelectedIndex();
+        T currentItem = getSelectedItem();
+        T newItem = getModelItem(row);
+        boolean isSameItem = newItem != null && newItem.equals(currentItem);
+        boolean fireUpdatedItemEvent = isSameRow && ! isSameItem;
 
         if (! selectedIndices.get(row)) {
             if (getSelectionMode() == SINGLE) {
@@ -292,6 +300,10 @@
         
         // TODO this isn't correct
         selectedIndicesSeq.callObservers(new NonIterableChange.SimpleAddChange<Integer>(0, 1, selectedIndicesSeq));
+        
+        if (fireUpdatedItemEvent) {
+            setSelectedItem(newItem);
+        }
     }
 
     @Override public void select(T obj) {
@@ -441,12 +453,16 @@
 
 //            updateLeadSelection();
 //            support.fireChangedEvent(SELECTED_INDICES);
-        selectedIndicesSeq.callObservers(new NonIterableChange.GenericAddRemoveChange<Integer>(0, 0, Collections.singletonList(index), selectedIndicesSeq));
+        selectedIndicesSeq.callObservers(
+                new NonIterableChange.GenericAddRemoveChange<Integer>(0, 0, 
+                Collections.singletonList(index), selectedIndicesSeq));
     }
 
     @Override public void clearSelection() {
-        setSelectedIndex(-1);
-        focus(-1);
+        if (! makeAtomic) {
+            setSelectedIndex(-1);
+            focus(-1);
+        }
 
         if (! selectedIndices.isEmpty()) {
             List<Integer> removed = new AbstractList<Integer>() {
@@ -462,7 +478,10 @@
             };
 
             quietClearSelection();
-            selectedIndicesSeq.callObservers(new NonIterableChange.GenericAddRemoveChange<Integer>(0, 0, removed, selectedIndicesSeq));
+            
+            selectedIndicesSeq.callObservers(
+                    new NonIterableChange.GenericAddRemoveChange<Integer>(0, 0, 
+                    removed, selectedIndicesSeq));
         }
     }
 
@@ -509,4 +528,6 @@
             select(focusIndex + 1);
         }
     }
+    
+    
 }
--- a/javafx-ui-controls/src/javafx/scene/control/Pagination.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/javafx/scene/control/Pagination.java	Thu Jun 28 12:36:02 2012 +0200
@@ -69,7 +69,7 @@
  * The control can be customized to display numeric page indicators or bullet style indicators by
  * setting the style class {@link STYLE_CLASS_BULLET}.  The 
  * {@link #maxPageIndicatorCountProperty() maxPageIndicatorCountProperty} can be used to change 
- * the number of page indicators.  The property value can also be changed 
+ * the maximum number of page indicators.  The property value can also be changed 
  * via CSS using -fx-max-page-indicator-count.
  *</p> 
  * 
@@ -185,11 +185,10 @@
     }
     
     /**
-     * The maximum number of page indicators to use for this pagination control.  This
-     * value must be greater than or equal to 1.  The page indicators will 
-     * be unselected when the {@link #currentPageIndexProperty currentPageIndex} 
-     * is greater than the maxPageIndicatorCount.  The number of page indicators will be
-     * reduced if maxPageIndicatorCount cannot fit within this control. 
+     * The maximum number of page indicators to use for this pagination control.  
+     * The maximum number of pages indicators will remain unchanged if the value is less than 1 
+     * or greater than the {@link #pageCount}.  The number of page indicators will be
+     * reduced to fit the control if the {@code maxPageIndicatorCount} cannot fit.
      * 
      * The default is 10 page indicators.
      */    
@@ -198,7 +197,7 @@
             maxPageIndicatorCount = new StyleableIntegerProperty(DEFAULT_MAX_PAGE_INDICATOR_COUNT) {
 
                 @Override protected void invalidated() {
-                    if (getMaxPageIndicatorCount() < 1) {
+                    if (getMaxPageIndicatorCount() < 1 || getMaxPageIndicatorCount() > getPageCount()) {
                         setMaxPageIndicatorCount(oldMaxPageIndicatorCount);
                     }
                     oldMaxPageIndicatorCount = getMaxPageIndicatorCount();
@@ -253,14 +252,14 @@
      * The default is an {@link INDETERMINATE} number of pages.
      */    
     public final IntegerProperty pageCountProperty() { return pageCount; }
-
-    private int oldPageIndex;
+    
     private final IntegerProperty currentPageIndex = new SimpleIntegerProperty(this, "currentPageIndex", 0) {
         @Override protected void invalidated() {
             if (getCurrentPageIndex() < 0) {
-                setCurrentPageIndex(oldPageIndex);
+                setCurrentPageIndex(0);
+            } else if (getCurrentPageIndex() > getPageCount() - 1) {
+                setCurrentPageIndex(getPageCount() - 1);
             }
-            oldPageIndex = getCurrentPageIndex();
         }
     };
     
@@ -276,9 +275,9 @@
     public final int getCurrentPageIndex() { return currentPageIndex.get(); }
     
     /**
-     * The current page index to display for this pagination control.  This value
-     * must be greater than or equal to 0.  The page indicators will be unselected when
-     * the currentPageIndex is greater than the {@link #maxPageIndicatorCountProperty maxPageIndicatorCount}.
+     * The current page index to display for this pagination control.  The first page will be 
+     * the current page if the value is less than 0.  Similarly the last page 
+     * will be the current page if the value is greater than the {@link #pageCount}
      * 
      * The default is 0 for the first page.
      */    
@@ -305,6 +304,8 @@
      * control.  The callback function should load and return the contents the page index.
      * Null should be returned if the page index does not exist.  The currentPageIndex 
      * will not change when null is returned.
+     * 
+     * The default is null if there is no page factory set.
      */    
     public final ObjectProperty<Callback<Integer, Node>> pageFactoryProperty() { return pageFactory; }
 
--- a/javafx-ui-controls/src/javafx/scene/control/TableCell.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/javafx/scene/control/TableCell.java	Thu Jun 28 12:36:02 2012 +0200
@@ -24,22 +24,17 @@
  */
 package javafx.scene.control;
 
-import com.sun.javafx.logging.PlatformLogger;
 import java.util.Map;
 
 import javafx.beans.InvalidationListener;
 import javafx.beans.Observable;
 import javafx.beans.WeakInvalidationListener;
-import javafx.beans.property.ObjectProperty;
-import javafx.beans.property.ObjectPropertyBase;
-import javafx.beans.property.SimpleObjectProperty;
 import javafx.beans.value.ObservableValue;
 import javafx.collections.ListChangeListener;
 import javafx.event.Event;
 import javafx.scene.control.TableView.TableViewFocusModel;
 
 import com.sun.javafx.property.PropertyReference;
-import com.sun.javafx.scene.control.Logging;
 import com.sun.javafx.scene.control.WeakListChangeListener;
 import java.lang.ref.WeakReference;
 import javafx.beans.property.ReadOnlyObjectProperty;
@@ -81,7 +76,6 @@
         // we listen to changes in the index property as this indicates that
         // the cell has been reappropriated
         indexProperty().addListener(indexListener);
-        updateItem();
     }
 
 
@@ -103,7 +97,8 @@
     };
     
     @Override void indexChanged() {
-        updateItem();
+        itemDirty = true;
+        requestLayout();
     }
 
     /*
@@ -132,7 +127,7 @@
             requestLayout();
         }
     };
-
+    
     private final InvalidationListener editingListener = new InvalidationListener() {
         @Override public void invalidated(Observable value) {
             updateEditing();
@@ -478,6 +473,15 @@
                 getTableView().getSelectionModel() != null &&
                 getTableView().getSelectionModel().isCellSelectionEnabled();
     }
+    
+    /*
+     * This was brought in to fix the issue in RT-22077, namely that the 
+     * ObservableValue was being GC'd, meaning that changes to the value were
+     * no longer being delivered. By extracting this value out of the method, 
+     * it is now referred to from TableCell and will therefore no longer be
+     * GC'd.
+     */
+    private ObservableValue<T> currentObservableValue = null;
 
     /*
      * This is called when we think that the data within this TableCell may have
@@ -510,6 +514,10 @@
      * the responsibility of the TableModel developer).
      */
     private void updateItem() {
+        if (currentObservableValue != null) {
+            currentObservableValue.removeListener(weaktableRowUpdateObserver);
+        }
+        
         // there is a whole heap of reasons why we should just punt...
         if (getIndex() < 0 || 
                 columnIndex < 0 ||
@@ -519,32 +527,30 @@
                 getTableView().getItems() == null) {
             return;
         }
-
+        
         // get the total number of items in the data model
         int itemCount = getTableView().getItems().size();
         
-        ObservableValue<T> observableValue = null;
         if (getIndex() >= itemCount) {
             updateItem(null, true);
             return;
         } else {
             if (getIndex() < itemCount) {
-                observableValue = getTableColumn().getCellObservableValue(getIndex());
+                currentObservableValue = getTableColumn().getCellObservableValue(getIndex());
             }
 
-            T value = observableValue == null ? null : observableValue.getValue();
+            T value = currentObservableValue == null ? null : currentObservableValue.getValue();
             
             // update the 'item' property of this cell.
             updateItem(value, value == null);
         }
         
-        if (observableValue == null) {
+        if (currentObservableValue == null) {
             return;
         }
         
         // add property change listeners to this item
-        observableValue.removeListener(weaktableRowUpdateObserver);
-        observableValue.addListener(weaktableRowUpdateObserver);
+        currentObservableValue.addListener(weaktableRowUpdateObserver);
     }
 
     @Override protected void layoutChildren() {
--- a/javafx-ui-controls/src/javafx/scene/control/TableColumn.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/javafx/scene/control/TableColumn.java	Thu Jun 28 12:36:02 2012 +0200
@@ -1142,12 +1142,15 @@
      */
     public final ObservableValue<T> getCellObservableValue(int index) {
         if (index < 0) return null;
+        
         // Get the table
         final TableView<S> table = getTableView();
         if (table == null || table.getItems() == null) return null;
+        
         // Get the rowData
         final List<S> items = table.getItems();
         if (index >= items.size()) return null; // Out of range
+        
         final S rowData = items.get(index);
         return getCellObservableValue(rowData);
     }
@@ -1172,9 +1175,11 @@
         // Get the factory
         final Callback<CellDataFeatures<S,T>, ObservableValue<T>> factory = getCellValueFactory();
         if (factory == null) return null;
+        
         // Get the table
         final TableView<S> table = getTableView();
         if (table == null) return null;
+        
         // Call the factory
         final CellDataFeatures<S,T> cdf = new CellDataFeatures<S,T>(table, this, item);
         return factory.call(cdf);
--- a/javafx-ui-controls/src/javafx/scene/control/TableView.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/javafx/scene/control/TableView.java	Thu Jun 28 12:36:02 2012 +0200
@@ -1874,10 +1874,12 @@
                     }
                     
                     quietClearSelection();
-                    selectedCells.setAll(newIndices);
-                    selectedCellsSeq.callObservers(
-                            new NonIterableChange.SimpleAddChange<TablePosition>(0, 
-                            newIndices.size(), selectedCellsSeq));
+                    
+                    // Fix for RT-22079
+                    for (int i = 0; i < newIndices.size(); i++) {
+                        TablePosition tp = newIndices.get(i);
+                        select(tp.getRow(), tp.getTableColumn());
+                    }
                 } else if (c.wasPermutated()) {
                     // General approach:
                     //   -- detected a sort has happened
--- a/javafx-ui-controls/src/javafx/scene/control/UAStylesheetLoader.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/src/javafx/scene/control/UAStylesheetLoader.java	Thu Jun 28 12:36:02 2012 +0200
@@ -64,12 +64,13 @@
                         if (com.sun.javafx.PlatformUtil.isEmbedded()) {
                             url = SkinBase.class.getResource("caspian/embedded.css");
                             StyleManager.getInstance().addUserAgentStylesheet(url.toExternalForm());
+                            
+                            if (com.sun.javafx.Utils.isQVGAScreen()) {
+                                url = SkinBase.class.getResource("caspian/embedded-qvga.css");
+                                StyleManager.getInstance().addUserAgentStylesheet(url.toExternalForm());
+                            }
                         }
                         
-                        if (com.sun.javafx.Utils.isQVGAScreen()) {
-                            url = SkinBase.class.getResource("caspian/embedded-qvga.css");
-                            StyleManager.getInstance().addUserAgentStylesheet(url.toExternalForm());
-                        }
                         stylesheetLoaded = true;
                     return null;
                 }
--- a/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/VirtualFlowTest.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/VirtualFlowTest.java	Thu Jun 28 12:36:02 2012 +0200
@@ -14,8 +14,10 @@
 import java.util.Iterator;
 import java.util.LinkedList;
 
+import javafx.event.Event;
 import javafx.scene.control.IndexedCell;
 import javafx.scene.control.SkinStub;
+import javafx.scene.input.ScrollEvent;
 
 import org.junit.Before;
 import org.junit.Ignore;
@@ -866,6 +868,55 @@
             if (i != 29) assertEquals("Bad index: " + i, 25, flow.getCellLength(i), 0.0);
         }
     }
+
+    /*
+    ** if we scroll the flow by a number of LINES,
+    ** without having done anything to select a cell
+    ** the flow should scroll.
+    */ 
+    @Test public void testInitialScrollEventActuallyScrolls() {
+        /*
+        ** re-initialize this, as it must be the first
+        ** interaction with the flow
+        */
+        flow = new VirtualFlow();
+        flow.setVertical(true);
+        flow.setCreateCell(new Callback<VirtualFlow, IndexedCell>() {
+            @Override public IndexedCell call(VirtualFlow p) {
+                return new CellStub(flow) {
+                    @Override protected double computeMinWidth(double height) { return computePrefWidth(height); }
+                    @Override protected double computeMaxWidth(double height) { return computePrefWidth(height); }
+                    @Override protected double computePrefWidth(double height) {
+                        return flow.isVertical() ? (c.getIndex() == 29 ? 200 : 100) : (c.getIndex() == 29 ? 100 : 25);
+                    }
+
+                    @Override protected double computeMinHeight(double width) { return computePrefHeight(width); }
+                    @Override protected double computeMaxHeight(double width) { return computePrefHeight(width); }
+                    @Override protected double computePrefHeight(double width) {
+                        return flow.isVertical() ? (c.getIndex() == 29 ? 100 : 25) : (c.getIndex() == 29 ? 200 : 100);
+                    }
+                };
+            }
+        });
+        
+        flow.setCellCount(100);
+        flow.resize(300, 300);
+        pulse();
+       
+        double originalValue = flow.getPosition();
+
+        Event.fireEvent(flow, 
+              ScrollEvent.impl_scrollEvent(ScrollEvent.SCROLL,
+                          0.0, -10.0, 0.0, -10.0,
+                          ScrollEvent.HorizontalTextScrollUnits.NONE, 0.0,
+                          ScrollEvent.VerticalTextScrollUnits.LINES, -1.0,
+                          0,
+                          0, 0,
+                          0, 0,
+                          false, false, false, false, true, false));
+
+        assertTrue(originalValue != flow.getPosition());
+    }
 }
 
 class CellStub extends IndexedCell {
@@ -878,6 +929,7 @@
     private void init(VirtualFlow flow) {
         this.flow = flow;
         setSkin(new SkinStub<CellStub>(this));
+        updateItem(this, false);
     }
 
     @Override
--- a/javafx-ui-controls/test/javafx/scene/control/AccordionTest.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/test/javafx/scene/control/AccordionTest.java	Thu Jun 28 12:36:02 2012 +0200
@@ -3,11 +3,14 @@
  */
 package javafx.scene.control;
 
+import com.sun.javafx.pgstub.StubToolkit;
+import com.sun.javafx.tk.Toolkit;
 import javafx.scene.Scene;
 import javafx.scene.layout.StackPane;
 import javafx.stage.Stage;
 import javafx.beans.property.SimpleObjectProperty;
 import javafx.beans.value.ObservableValue;
+import javafx.scene.input.KeyCode;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -16,14 +19,15 @@
 
 /**
  */
-public class AccordionTest {
-
+public class AccordionTest {    
     private Accordion accordion;
+    private Toolkit tk;
     private Scene scene;
     private Stage stage;
     private StackPane root;    
     
     @Before public void setup() {
+        tk = (StubToolkit)Toolkit.getToolkit();//This step is not needed (Just to make sure StubToolkit is loaded into VM)
         accordion = new Accordion();
         root = new StackPane();
         scene = new Scene(root);
@@ -154,4 +158,34 @@
         assertEquals(54, accordion.prefWidth(-1), 1e-100);
         assertEquals(170, accordion.prefHeight(-1), 1e-100);
     }
+    
+    @Test public void aiobeWhenFocusIsOnAControlInsideTheAccordion_RT22027() {
+        Button b1 = new Button("A");
+        Button b2 = new Button("B");
+        
+        TitledPane a = new TitledPane("A", b1);
+        TitledPane b = new TitledPane("B", b2);
+        
+        accordion.getPanes().addAll(a, b);
+        accordion.setExpandedPane(a);
+        accordion.setLayoutX(200);
+        
+        root.setPrefSize(800, 800);
+        root.getChildren().add(accordion);
+        b1.requestFocus();
+        show();
+        
+        root.impl_reapplyCSS();
+        root.autosize();
+        root.layout();
+                
+        KeyEventFirer keyboard = new KeyEventFirer(b1);                
+
+        try {        
+            keyboard.doKeyPress(KeyCode.HOME);
+            tk.firePulse(); 
+        } catch (Exception e) {
+            fail();
+        }
+    }
 }
--- a/javafx-ui-controls/test/javafx/scene/control/ButtonTest.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/test/javafx/scene/control/ButtonTest.java	Thu Jun 28 12:36:02 2012 +0200
@@ -16,10 +16,13 @@
 import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
 import javafx.scene.Scene;
+import javafx.scene.control.ContextMenu;
 import javafx.scene.input.KeyCode;
+import javafx.scene.input.MouseEvent;
 import javafx.scene.layout.StackPane;
 import javafx.scene.shape.Rectangle;
 import javafx.stage.Stage;
+import javafx.stage.WindowEvent;
 
 import org.junit.Before;
 import org.junit.Ignore;
@@ -189,6 +192,25 @@
         tk.firePulse();                
     }
 
+    @Test public void defaultButtonCanBeInvokeAfterRemovingFromTheScene_RT22106() {
+        btn.setDefaultButton(true);        
+        btn.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent actionEvent) {
+                fail();
+            }
+        });
+        root.getChildren().add(btn);
+        show();
+        
+        root.getChildren().remove(btn);        
+        
+        KeyEventFirer keyboard = new KeyEventFirer(root);        
+        keyboard.doKeyPress(KeyCode.ENTER);
+
+        tk.firePulse();                      
+    }
+    
     /*********************************************************************
      * Tests for the cancelButton state                                 *
      ********************************************************************/
@@ -258,6 +280,69 @@
         assertEquals("cancelButton", btn.cancelButtonProperty().getName());
     }
 
+    @Test public void cancelButtonCanBeInvokeAfterRemovingFromTheScene_RT22106() {
+        btn.setCancelButton(true);        
+        btn.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent actionEvent) {
+                fail();
+            }
+        });
+        root.getChildren().add(btn);
+        show();
+        
+        root.getChildren().remove(btn);        
+        
+        KeyEventFirer keyboard = new KeyEventFirer(root);        
+        keyboard.doKeyPress(KeyCode.ESCAPE);
+
+        tk.firePulse();                      
+    }
+
+
+    @Test public void conextMenuShouldntShowOnAction() {
+        final MouseEventGenerator generator = new MouseEventGenerator();
+
+        ContextMenu popupMenu = new ContextMenu();
+        MenuItem item1 = new MenuItem("_About");
+        popupMenu.getItems().add(item1);
+        popupMenu.setOnShown(new EventHandler<WindowEvent>() {
+            @Override public void handle(WindowEvent w) {
+                fail();
+            }
+        });
+
+        btn.setContextMenu(popupMenu);
+        btn.setDefaultButton(true);
+
+        root.getChildren().add(btn);
+        show();
+
+        double xval = (btn.localToScene(btn.getLayoutBounds())).getMinX();
+        double yval = (btn.localToScene(btn.getLayoutBounds())).getMinY();
+
+
+        /*
+        ** none of these should cause the context menu to appear,
+        ** so fire them all, and see if anything happens.
+        */
+        KeyEventFirer keyboard = new KeyEventFirer(btn);        
+        keyboard.doKeyPress(KeyCode.ENTER);
+
+        btn.fireEvent(new ActionEvent());
+        btn.fire();
+        scene.impl_processMouseEvent(
+            generator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, xval+10, yval+10));
+        scene.impl_processMouseEvent(
+            generator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, xval+10, yval+10));
+        scene.impl_processMouseEvent(
+            generator.generateMouseEvent(MouseEvent.MOUSE_CLICKED, xval+10, yval+10));
+       
+        tk.firePulse();                      
+    }
+
+
+    
 //  private Button button1;
 //  private Button button2;
 //
--- a/javafx-ui-controls/test/javafx/scene/control/ListViewTest.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/test/javafx/scene/control/ListViewTest.java	Thu Jun 28 12:36:02 2012 +0200
@@ -6,6 +6,8 @@
 import static javafx.scene.control.ControlTestUtils.assertStyleClassContains;
 import static org.junit.Assert.*;
 import java.util.Arrays;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.SimpleObjectProperty;
@@ -351,13 +353,22 @@
         assertTrue(sm.isSelected(0));
         assertEquals(1, hitCount);
         
+        // sleep for 100ms so that the currentTimeMillis is guaranteed to be
+        // a different value than the first one
+        try {
+            Thread.sleep(100);
+        } catch (InterruptedException ex) {
+            ex.printStackTrace();
+        }
+        
         // the list is totally changing (it is being cleared), so we should 
         // be nulling out the selection model state
         mod = FXCollections.observableArrayList();
         mod.add(System.currentTimeMillis()+"");
         listView.getItems().setAll(mod);
         
-        // it should be three, as there is a null event in between
-        assertEquals(3, hitCount);
+        // it should be two, as there is no null event in between (although there
+        // used to be, so the test used to be for three hits)
+        assertEquals(2, hitCount);
     }
 }
--- a/javafx-ui-controls/test/javafx/scene/control/PaginationTest.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/javafx-ui-controls/test/javafx/scene/control/PaginationTest.java	Thu Jun 28 12:36:02 2012 +0200
@@ -208,7 +208,7 @@
         pagination.setCurrentPageIndex(4);
     }
 
-    @Test public void setMaxPageIndicatorCountToZero() {
+    @Test public void setCountToZero() {
         pagination.setPageCount(0);
 
         root.setPrefSize(400, 400);
@@ -226,9 +226,40 @@
 
         pagination.setCurrentPageIndex(5);
         pagination.setCurrentPageIndex(-1);
-        assertEquals(5, pagination.getCurrentPageIndex());
+        assertEquals(0, pagination.getCurrentPageIndex());
     }
 
+    @Test public void setCurrentPageIndexGreaterThanPageCount() {
+        pagination.setPageCount(100);
+        root.setPrefSize(400, 400);
+        root.getChildren().add(pagination);
+        show();
+
+        pagination.setCurrentPageIndex(5);
+        pagination.setCurrentPageIndex(100);
+        assertEquals(99, pagination.getCurrentPageIndex());
+    }
+    
+    @Test public void setMaxPageIndicatorCountLessThanZero() {
+        pagination.setPageCount(100);
+        root.setPrefSize(400, 400);
+        root.getChildren().add(pagination);
+        show();
+
+        pagination.setMaxPageIndicatorCount(-1);
+        assertEquals(10, pagination.getMaxPageIndicatorCount());
+    }
+
+    @Test public void setMaxPageIndicatorCountGreaterThanPageCount() {
+        pagination.setPageCount(100);
+        root.setPrefSize(400, 400);
+        root.getChildren().add(pagination);
+        show();
+        
+        pagination.setMaxPageIndicatorCount(101);
+        assertEquals(10, pagination.getMaxPageIndicatorCount());
+    }
+    
     @Test public void pageCountIsLessThanMaxPageIndicatorCount_RT21660() {
         pagination.setPageCount(5);
         root.setPrefSize(400, 400);
--- a/test-stub-toolkit/src/com/sun/javafx/pgstub/StubPlatformImage.java	Thu Jun 28 12:35:17 2012 +0200
+++ b/test-stub-toolkit/src/com/sun/javafx/pgstub/StubPlatformImage.java	Thu Jun 28 12:36:02 2012 +0200
@@ -27,7 +27,10 @@
 
 import com.sun.javafx.tk.PlatformImage;
 import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
 import javafx.scene.image.PixelFormat;
+import javafx.scene.image.PixelReader;
 import javafx.scene.image.WritablePixelFormat;
 
 public final class StubPlatformImage implements PlatformImage {
@@ -77,33 +80,62 @@
     }
 
     @Override
-    public int getArgbPre(int x, int y) {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    @Override
     public void setArgb(int x, int y, int argb) {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
     @Override
-    public void setArgbPre(int x, int y, int argbpre) {
+    public <T extends Buffer> void getPixels(int x, int y, int w, int h,
+                                             WritablePixelFormat<T> pixelformat,
+                                             T pixels, int scanlineBytes)
+    {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
     @Override
-    public <T extends Buffer> void getPixels(int x, int y, int w, int h,
-                                             T pixels,
-                                             WritablePixelFormat<T> pixelformat,
-                                             int scanlineBytes) {
+    public void getPixels(int x, int y, int w, int h,
+                          WritablePixelFormat<ByteBuffer> pixelformat,
+                          byte[] pixels, int offset, int scanlineBytes)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void getPixels(int x, int y, int w, int h,
+                          WritablePixelFormat<IntBuffer> pixelformat,
+                          int[] pixels, int offset, int scanlineInts)
+    {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
     @Override
     public <T extends Buffer> void setPixels(int x, int y, int w, int h,
-                                             T pixels,
                                              PixelFormat<T> pixelformat,
-                                             int scanlineBytes) {
+                                             T pixels, int scanlineBytes)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h,
+                          PixelFormat<ByteBuffer> pixelformat,
+                          byte[] pixels, int offset, int scanlineBytes)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h,
+                          PixelFormat<IntBuffer> pixelformat,
+                          int[] pixels, int offset, int scanlineInts)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void setPixels(int dstx, int dsty, int w, int h,
+                          PixelReader reader, int srcx, int srcy)
+    {
         throw new UnsupportedOperationException("Not supported yet.");
     }