changeset 2981:9cd4222cfa62 8.0-b82

Automated merge with ssh://jfxsrc.us.oracle.com//javafx/8.0/MASTER/jfx/rt
author Paru Somashekar <parvathi.somashekar@oracle.com>
date Tue, 19 Mar 2013 22:28:50 +0100
parents bca7b8cc76b8 c2ebe930f201
children 4a4088d5aaf4 a2cfe5a168ae f40c493c859b
files javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TableCellBehaviorBase.java javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TreeCellBehavior.java javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ContextMenuSkin.java javafx-ui-controls/test/javafx/scene/control/KeyEventFirer.java javafx-ui-controls/test/javafx/scene/control/KeyModifier.java javafx-ui-controls/test/javafx/scene/control/MouseEventGenerator.java
diffstat 78 files changed, 3562 insertions(+), 875 deletions(-) [+]
line wrap: on
line diff
--- a/apps/experiments/Modena/src/modena/Modena.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/apps/experiments/Modena/src/modena/Modena.java	Tue Mar 19 22:28:50 2013 +0100
@@ -259,25 +259,13 @@
         System.out.println("accentColor = " + accentColor);
         System.out.println("backgroundColor = " + backgroundColor);
         if (baseColor != null && baseColor != Color.TRANSPARENT) {
-            final String color = String.format((Locale) null, "#%02x%02x%02x", 
-                    Math.round(baseColor.getRed() * 255), 
-                    Math.round(baseColor.getGreen() * 255), 
-                    Math.round(baseColor.getBlue() * 255));
-            styleSheetContent += "    -fx-base:"+color+";\n";
+            styleSheetContent += "    -fx-base:" + colorToRGBA(baseColor) + ";\n";
         }
         if (backgroundColor != null && backgroundColor != Color.TRANSPARENT) {
-            final String color = String.format((Locale) null, "#%02x%02x%02x", 
-                    Math.round(backgroundColor.getRed() * 255), 
-                    Math.round(backgroundColor.getGreen() * 255), 
-                    Math.round(backgroundColor.getBlue() * 255));
-            styleSheetContent += "    -fx-background:"+color+";\n";
+            styleSheetContent += "    -fx-background:" + colorToRGBA(backgroundColor) + ";\n";
         }
         if (accentColor != null && accentColor != Color.TRANSPARENT) {
-            final String color = String.format((Locale) null, "#%02x%02x%02x", 
-                    Math.round(accentColor.getRed() * 255), 
-                    Math.round(accentColor.getGreen() * 255), 
-                    Math.round(accentColor.getBlue() * 255));
-            styleSheetContent += "    -fx-accent:"+color+";\n";
+            styleSheetContent += "    -fx-accent:" + colorToRGBA(accentColor) + ";\n";
         }
         if (fontName != null) {
             styleSheetContent += "    -fx-font:"+fontSize+"px \""+fontName+"\";\n";
@@ -633,6 +621,19 @@
         URL.setURLStreamHandlerFactory(new StringURLStreamHandlerFactory());
     }
 
+    private String colorToRGBA(Color color) {
+        // Older version didn't care about opacity
+//        return String.format((Locale) null, "#%02x%02x%02x", 
+//                Math.round(color.getRed() * 255), 
+//                Math.round(color.getGreen() * 255), 
+//                Math.round(color.getBlue() * 255));
+        return String.format((Locale) null, "rgba(%d, %d, %d, %f)", 
+            (int) Math.round(color.getRed() * 255), 
+            (int) Math.round(color.getGreen() * 255), 
+            (int) Math.round(color.getBlue() * 255),
+            color.getOpacity());
+    }
+
     /**
      * Simple URLConnection that always returns the content of the cssBuffer
      */
--- a/javafx-ui-charts/src/javafx/scene/chart/BarChart.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-charts/src/javafx/scene/chart/BarChart.java	Tue Mar 19 22:28:50 2013 +0100
@@ -206,6 +206,11 @@
         if (!categoryAxis.getCategories().contains(category)) {
             categoryAxis.getCategories().add(itemIndex, category);
         } else if (categoryMap.containsKey(category)){
+            // RT-21162 : replacing the previous data, first remove the node from scenegraph.
+            Data data = categoryMap.get(category);
+            getPlotChildren().remove(data.getNode());
+            removeDataItemFromDisplay(series, data);
+            requestChartLayout();
             categoryMap.remove(category);
         }
         categoryMap.put(category, item);
@@ -275,10 +280,7 @@
             if (barVal < 0) {
                 bar.getStyleClass().add(NEGATIVE_STYLE);
             }
-//            item.setYValue(getYAxis().toRealValue(getYAxis().getZeroPosition()));
-//            item.setCurrentY(getYAxis().toRealValue(getYAxis().getZeroPosition()));
-            item.setYValue(getYAxis().toRealValue(bottomPos));
-            item.setCurrentY(getYAxis().toRealValue(bottomPos));
+            item.setCurrentY(getYAxis().toRealValue((barVal < 0) ? -bottomPos : bottomPos));
             getPlotChildren().add(bar);
             item.setYValue(getYAxis().toRealValue(barVal));
             animate(
@@ -292,8 +294,7 @@
             if (barVal < 0) {
                 bar.getStyleClass().add(NEGATIVE_STYLE);
             }
-            item.setXValue(getXAxis().toRealValue(getXAxis().getZeroPosition()));
-            item.setCurrentX(getXAxis().toRealValue(getXAxis().getZeroPosition()));
+            item.setCurrentX(getXAxis().toRealValue((barVal < 0) ? -bottomPos : bottomPos));
             getPlotChildren().add(bar);
             item.setXValue(getXAxis().toRealValue(barVal));
             animate(
--- a/javafx-ui-common/src/com/sun/javafx/css/StyleClassSet.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/StyleClassSet.java	Tue Mar 19 22:28:50 2013 +0100
@@ -47,7 +47,10 @@
 
         int nMax = styleClassNames != null ? styleClassNames.size() : 0;
         for(int n=0; n<nMax; n++) {
-            final StyleClass sc = getStyleClass(styleClassNames.get(n));
+            final String styleClass = styleClassNames.get(n);
+            if (styleClass == null || styleClass.isEmpty()) continue;
+
+            final StyleClass sc = getStyleClass(styleClass);
             add(sc);
         }
 
--- a/javafx-ui-common/src/com/sun/javafx/css/StyleManager.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/StyleManager.java	Tue Mar 19 22:28:50 2013 +0100
@@ -535,6 +535,9 @@
 
         final Set<Entry<List<String>, Map<Key, Cache>>> entries = 
                 masterCacheMap.entrySet();
+        if (entries == null || entries.isEmpty()) {
+            return;
+        }
 
         // If this StylesheetContainer is used by other entries, then those
         // caches need to be invalidated, too. But we need to go through all
@@ -548,8 +551,12 @@
         while (iter.hasNext()) {
             
             Entry<List<String>, Map<Key, Cache>> entry = iter.next();
-            List<String> containerList = entry.getKey();
-            if (containerList == null) continue;
+
+            List<String> containerList = entry != null ? entry.getKey() : null;
+            if (containerList == null) {
+                iter.remove();
+                continue;
+            }
             
             if (containerList.contains(sc.fname)) {
                 containerList.remove(sc.fname);
@@ -1325,7 +1332,11 @@
         key.className = cname;
         key.id = id;
         for(int n=0, nMax=styleClasses.size(); n<nMax; n++) {
-            key.styleClasses.add(StyleClassSet.getStyleClass(styleClasses.get(n)));
+
+            final String styleClass = styleClasses.get(n);
+            if (styleClass == null || styleClass.isEmpty()) continue;
+
+            key.styleClasses.add(StyleClassSet.getStyleClass(styleClass));
         }
 
         Cache cache = cacheMap.get(key);
--- a/javafx-ui-common/src/javafx/css/SimpleStyleableBooleanProperty.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-common/src/javafx/css/SimpleStyleableBooleanProperty.java	Tue Mar 19 22:28:50 2013 +0100
@@ -26,13 +26,10 @@
 package javafx.css;
 
 import javafx.beans.property.SimpleBooleanProperty;
-import javafx.beans.value.ObservableValue;
-import javafx.scene.Node;
 
 /**
  * This class extends {@code SimpleBooleanProperty} and provides a full
- * implementation of a {@code StyleableProperty}. The method 
- * {@link StyleableProperty#getCssMetaData()} is not implemented. 
+ * implementation of a {@code StyleableProperty}.
  * 
  * This class is used to make a {@link javafx.beans.property.BooleanProperty}, 
  * that would otherwise be implemented as a {@link SimpleBooleanProperty}, 
@@ -41,10 +38,17 @@
  * @see javafx.beans.property.SimpleBooleanProperty
  * @see CssMetaData
  * @see StyleableProperty
+ * @see StyleableBooleanProperty
  */
 @com.sun.javafx.beans.annotations.NoBuilder
-public abstract class SimpleStyleableBooleanProperty
-    extends SimpleBooleanProperty implements StyleableProperty<Boolean> {
+public class SimpleStyleableBooleanProperty extends StyleableBooleanProperty {
+
+    private static final Object DEFAULT_BEAN = null;
+    private static final String DEFAULT_NAME = "";
+
+    private final Object bean;
+    private final String name;
+    private final CssMetaData<? extends Styleable, Boolean> cssMetaData;
 
     /**
      * The constructor of the {@code SimpleStyleableBooleanProperty}.
@@ -52,8 +56,7 @@
      *            the CssMetaData associated with this {@code StyleableProperty}
      */
     public SimpleStyleableBooleanProperty(CssMetaData<? extends Styleable, Boolean> cssMetaData) {
-        super();
-        this.cssMetaData = cssMetaData;
+        this(cssMetaData, DEFAULT_BEAN, DEFAULT_NAME);
     }
 
     /**
@@ -65,8 +68,7 @@
      *            the initial value of the wrapped {@code Object}
      */
     public SimpleStyleableBooleanProperty(CssMetaData<? extends Styleable, Boolean> cssMetaData, boolean initialValue) {
-        super(initialValue);
-        this.cssMetaData = cssMetaData;
+        this(cssMetaData, DEFAULT_BEAN, DEFAULT_NAME, initialValue);
     }
 
     /**
@@ -80,7 +82,8 @@
      *            the name of this {@code BooleanProperty}
      */
     public SimpleStyleableBooleanProperty(CssMetaData<? extends Styleable, Boolean> cssMetaData, Object bean, String name) {
-        super(bean, name);
+        this.bean = bean;
+        this.name = (name == null) ? DEFAULT_NAME : name;
         this.cssMetaData = cssMetaData;
     }
 
@@ -97,43 +100,32 @@
      *            the initial value of the wrapped {@code Object}
      */
     public SimpleStyleableBooleanProperty(CssMetaData<? extends Styleable, Boolean> cssMetaData, Object bean, String name, boolean initialValue) {
-        super(bean, name, initialValue);
+        super(initialValue);
+        this.bean = bean;
+        this.name = (name == null) ? DEFAULT_NAME : name;
         this.cssMetaData = cssMetaData;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void applyStyle(StyleOrigin origin, Boolean v) {
-        // call set here in case it has been overridden in the javafx.beans.property
-        set(v.booleanValue());
-        this.origin = origin;
+    public Object getBean() {
+        return bean;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void bind(ObservableValue<? extends Boolean> observable) {
-        super.bind(observable);
-        origin = StyleOrigin.USER;
+    public String getName() {
+        return name;
     }
 
     /** {@inheritDoc} */
     @Override
-    public void set(boolean v) {
-        super.set(v);
-        origin = StyleOrigin.USER;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final StyleOrigin getStyleOrigin() { return origin; }
-
-    /** {@inheritDoc} */
-    @Override
     public final CssMetaData<? extends Styleable, Boolean> getCssMetaData() {
         return cssMetaData;
     }
 
-    private StyleOrigin origin = null;
-    private final CssMetaData<? extends Styleable, Boolean> cssMetaData;
-
 }
--- a/javafx-ui-common/src/javafx/css/SimpleStyleableDoubleProperty.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-common/src/javafx/css/SimpleStyleableDoubleProperty.java	Tue Mar 19 22:28:50 2013 +0100
@@ -26,25 +26,29 @@
 package javafx.css;
 
 import javafx.beans.property.SimpleDoubleProperty;
-import javafx.beans.value.ObservableValue;
-import javafx.scene.Node;
 
 /**
  * This class extends {@code SimpleDoubleProperty} and provides a full
- * implementation of a {@code StyleableProperty}. The method 
- * {@link StyleableProperty#getCssMetaData()} is not implemented. 
- * 
- * This class is used to make a {@link javafx.beans.property.DoubleProperty}, 
- * that would otherwise be implemented as a {@link SimpleDoubleProperty}, 
+ * implementation of a {@code StyleableProperty}.  
+ *
+ * This class is used to make a {@link javafx.beans.property.DoubleProperty},
+ * that would otherwise be implemented as a {@link SimpleDoubleProperty},
  * style&#8209;able by CSS.
- * 
+ *
  * @see javafx.beans.property.SimpleDoubleProperty
  * @see CssMetaData
  * @see StyleableProperty
+ * @see StyleableDoubleProperty
  */
 @com.sun.javafx.beans.annotations.NoBuilder
-public abstract class SimpleStyleableDoubleProperty
-    extends SimpleDoubleProperty implements StyleableProperty<Number> {
+public class SimpleStyleableDoubleProperty extends StyleableDoubleProperty {
+
+    private static final Object DEFAULT_BEAN = null;
+    private static final String DEFAULT_NAME = "";
+
+    private final Object bean;
+    private final String name;
+    private final CssMetaData<? extends Styleable, Number> cssMetaData;
 
     /**
      * The constructor of the {@code SimpleStyleableDoubleProperty}.
@@ -52,8 +56,7 @@
      *            the CssMetaData associated with this {@code StyleableProperty}
      */
     public SimpleStyleableDoubleProperty(CssMetaData<? extends Styleable, Number> cssMetaData) {
-        super();
-        this.cssMetaData = cssMetaData;
+        this(cssMetaData, DEFAULT_BEAN, DEFAULT_NAME);
     }
 
     /**
@@ -64,9 +67,8 @@
      * @param initialValue
      *            the initial value of the wrapped {@code Object}
      */
-    public SimpleStyleableDoubleProperty(CssMetaData<? extends Styleable, Number> cssMetaData, double initialValue) {
-        super(initialValue);
-        this.cssMetaData = cssMetaData;
+    public SimpleStyleableDoubleProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Double initialValue) {
+        this(cssMetaData, DEFAULT_BEAN, DEFAULT_NAME, initialValue);
     }
 
     /**
@@ -80,7 +82,8 @@
      *            the name of this {@code DoubleProperty}
      */
     public SimpleStyleableDoubleProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Object bean, String name) {
-        super(bean, name);
+        this.bean = bean;
+        this.name = (name == null) ? DEFAULT_NAME : name;
         this.cssMetaData = cssMetaData;
     }
 
@@ -96,43 +99,33 @@
      * @param initialValue
      *            the initial value of the wrapped {@code Object}
      */
-    public SimpleStyleableDoubleProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Object bean, String name, double initialValue) {
-        super(bean, name, initialValue);
+    public SimpleStyleableDoubleProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Object bean, String name, Double initialValue) {
+        super(initialValue);
+        this.bean = bean;
+        this.name = (name == null) ? DEFAULT_NAME : name;
         this.cssMetaData = cssMetaData;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void applyStyle(StyleOrigin origin, Number v) {
-        setValue(v);
-        this.origin = origin;
+    public Object getBean() {
+        return bean;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void bind(ObservableValue<? extends Number> observable) {
-        super.bind(observable);
-        origin = StyleOrigin.USER;
+    public String getName() {
+        return name;
     }
 
     /** {@inheritDoc} */
     @Override
-    public void set(double v) {
-        super.set(v);
-        origin = StyleOrigin.USER;
-    }
-
-
-    /** {@inheritDoc} */
-    @Override
-    public final StyleOrigin getStyleOrigin() { return origin; }
-
-    /** {@inheritDoc} */
-    @Override
     public final CssMetaData<? extends Styleable, Number> getCssMetaData() {
         return cssMetaData;
     }
 
-    private StyleOrigin origin = null;
-    private final CssMetaData<? extends Styleable, Number> cssMetaData;
 }
--- a/javafx-ui-common/src/javafx/css/SimpleStyleableFloatProperty.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-common/src/javafx/css/SimpleStyleableFloatProperty.java	Tue Mar 19 22:28:50 2013 +0100
@@ -26,25 +26,29 @@
 package javafx.css;
 
 import javafx.beans.property.SimpleFloatProperty;
-import javafx.beans.value.ObservableValue;
-import javafx.scene.Node;
 
 /**
  * This class extends {@code SimpleFloatProperty} and provides a full
- * implementation of a {@code StyleableProperty}. The method 
- * {@link StyleableProperty#getCssMetaData()} is not implemented. 
- * 
- * This class is used to make a {@link javafx.beans.property.FloatProperty}, 
- * that would otherwise be implemented as a {@link SimpleFloatProperty}, 
+ * implementation of a {@code StyleableProperty}.  
+ *
+ * This class is used to make a {@link javafx.beans.property.FloatProperty},
+ * that would otherwise be implemented as a {@link SimpleFloatProperty},
  * style&#8209;able by CSS.
- * 
+ *
  * @see javafx.beans.property.SimpleFloatProperty
  * @see CssMetaData
  * @see StyleableProperty
+ * @see StyleableFloatProperty
  */
 @com.sun.javafx.beans.annotations.NoBuilder
-public abstract class SimpleStyleableFloatProperty
-    extends SimpleFloatProperty implements StyleableProperty<Number> {
+public class SimpleStyleableFloatProperty extends StyleableFloatProperty {
+
+    private static final Object DEFAULT_BEAN = null;
+    private static final String DEFAULT_NAME = "";
+
+    private final Object bean;
+    private final String name;
+    private final CssMetaData<? extends Styleable, Number> cssMetaData;
 
     /**
      * The constructor of the {@code SimpleStyleableFloatProperty}.
@@ -52,8 +56,7 @@
      *            the CssMetaData associated with this {@code StyleableProperty}
      */
     public SimpleStyleableFloatProperty(CssMetaData<? extends Styleable, Number> cssMetaData) {
-        super();
-        this.cssMetaData = cssMetaData;
+        this(cssMetaData, DEFAULT_BEAN, DEFAULT_NAME);
     }
 
     /**
@@ -64,9 +67,8 @@
      * @param initialValue
      *            the initial value of the wrapped {@code Object}
      */
-    public SimpleStyleableFloatProperty(CssMetaData<? extends Styleable, Number> cssMetaData, float initialValue) {
-        super(initialValue);
-        this.cssMetaData = cssMetaData;
+    public SimpleStyleableFloatProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Float initialValue) {
+        this(cssMetaData, DEFAULT_BEAN, DEFAULT_NAME, initialValue);
     }
 
     /**
@@ -80,7 +82,8 @@
      *            the name of this {@code FloatProperty}
      */
     public SimpleStyleableFloatProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Object bean, String name) {
-        super(bean, name);
+        this.bean = bean;
+        this.name = (name == null) ? DEFAULT_NAME : name;
         this.cssMetaData = cssMetaData;
     }
 
@@ -96,43 +99,33 @@
      * @param initialValue
      *            the initial value of the wrapped {@code Object}
      */
-    public SimpleStyleableFloatProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Object bean, String name, float initialValue) {
-        super(bean, name, initialValue);
+    public SimpleStyleableFloatProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Object bean, String name, Float initialValue) {
+        super(initialValue);
+        this.bean = bean;
+        this.name = (name == null) ? DEFAULT_NAME : name;
         this.cssMetaData = cssMetaData;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void applyStyle(StyleOrigin origin, Number v) {
-        setValue(v);
-        this.origin = origin;
+    public Object getBean() {
+        return bean;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void bind(ObservableValue<? extends Number> observable) {
-        super.bind(observable);
-        origin = StyleOrigin.USER;
+    public String getName() {
+        return name;
     }
 
     /** {@inheritDoc} */
     @Override
-    public void set(float v) {
-        super.set(v);
-        origin = StyleOrigin.USER;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final StyleOrigin getStyleOrigin() { return origin; }
-
-    /** {@inheritDoc} */
-    @Override
     public final CssMetaData<? extends Styleable, Number> getCssMetaData() {
         return cssMetaData;
     }
 
-    private StyleOrigin origin = null;
-    private final CssMetaData<? extends Styleable, Number> cssMetaData;
-
 }
--- a/javafx-ui-common/src/javafx/css/SimpleStyleableIntegerProperty.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-common/src/javafx/css/SimpleStyleableIntegerProperty.java	Tue Mar 19 22:28:50 2013 +0100
@@ -26,25 +26,29 @@
 package javafx.css;
 
 import javafx.beans.property.SimpleIntegerProperty;
-import javafx.beans.value.ObservableValue;
-import javafx.scene.Node;
 
 /**
  * This class extends {@code SimpleIntegerProperty} and provides a full
- * implementation of a {@code StyleableProperty}. The method 
- * {@link StyleableProperty#getCssMetaData()} is not implemented. 
- * 
- * This class is used to make a {@link javafx.beans.property.IntegerProperty}, 
- * that would otherwise be implemented as a {@link SimpleIntegerProperty}, 
+ * implementation of a {@code StyleableProperty}.  
+ *
+ * This class is used to make a {@link javafx.beans.property.IntegerProperty},
+ * that would otherwise be implemented as a {@link SimpleIntegerProperty},
  * style&#8209;able by CSS.
- * 
+ *
  * @see javafx.beans.property.SimpleIntegerProperty
  * @see CssMetaData
  * @see StyleableProperty
+ * @see StyleableIntegerProperty
  */
 @com.sun.javafx.beans.annotations.NoBuilder
-public abstract class SimpleStyleableIntegerProperty
-    extends SimpleIntegerProperty implements StyleableProperty<Number> {
+public class SimpleStyleableIntegerProperty extends StyleableIntegerProperty {
+
+    private static final Object DEFAULT_BEAN = null;
+    private static final String DEFAULT_NAME = "";
+
+    private final Object bean;
+    private final String name;
+    private final CssMetaData<? extends Styleable, Number> cssMetaData;
 
     /**
      * The constructor of the {@code SimpleStyleableIntegerProperty}.
@@ -52,8 +56,7 @@
      *            the CssMetaData associated with this {@code StyleableProperty}
      */
     public SimpleStyleableIntegerProperty(CssMetaData<? extends Styleable, Number> cssMetaData) {
-        super();
-        this.cssMetaData = cssMetaData;
+        this(cssMetaData, DEFAULT_BEAN, DEFAULT_NAME);
     }
 
     /**
@@ -64,9 +67,8 @@
      * @param initialValue
      *            the initial value of the wrapped {@code Object}
      */
-    public SimpleStyleableIntegerProperty(CssMetaData<? extends Styleable, Number> cssMetaData, int initialValue) {
-        super(initialValue);
-        this.cssMetaData = cssMetaData;
+    public SimpleStyleableIntegerProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Integer initialValue) {
+        this(cssMetaData, DEFAULT_BEAN, DEFAULT_NAME, initialValue);
     }
 
     /**
@@ -80,7 +82,8 @@
      *            the name of this {@code IntegerProperty}
      */
     public SimpleStyleableIntegerProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Object bean, String name) {
-        super(bean, name);
+        this.bean = bean;
+        this.name = (name == null) ? DEFAULT_NAME : name;
         this.cssMetaData = cssMetaData;
     }
 
@@ -96,43 +99,33 @@
      * @param initialValue
      *            the initial value of the wrapped {@code Object}
      */
-    public SimpleStyleableIntegerProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Object bean, String name, int initialValue) {
-        super(bean, name, initialValue);
+    public SimpleStyleableIntegerProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Object bean, String name, Integer initialValue) {
+        super(initialValue);
+        this.bean = bean;
+        this.name = (name == null) ? DEFAULT_NAME : name;
         this.cssMetaData = cssMetaData;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void applyStyle(StyleOrigin origin, Number v) {
-        setValue(v);
-        this.origin = origin;
+    public Object getBean() {
+        return bean;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void bind(ObservableValue<? extends Number> observable) {
-        super.bind(observable);
-        origin = StyleOrigin.USER;
+    public String getName() {
+        return name;
     }
 
     /** {@inheritDoc} */
     @Override
-    public void set(int v) {
-        super.set(v);
-        origin = StyleOrigin.USER;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final StyleOrigin getStyleOrigin() { return origin; }
-
-    /** {@inheritDoc} */
-    @Override
     public final CssMetaData<? extends Styleable, Number> getCssMetaData() {
         return cssMetaData;
     }
 
-    private StyleOrigin origin = null;
-    private final CssMetaData<? extends Styleable, Number> cssMetaData;
-
 }
--- a/javafx-ui-common/src/javafx/css/SimpleStyleableLongProperty.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-common/src/javafx/css/SimpleStyleableLongProperty.java	Tue Mar 19 22:28:50 2013 +0100
@@ -26,25 +26,29 @@
 package javafx.css;
 
 import javafx.beans.property.SimpleLongProperty;
-import javafx.beans.value.ObservableValue;
-import javafx.scene.Node;
 
 /**
  * This class extends {@code SimpleLongProperty} and provides a full
- * implementation of a {@code StyleableProperty}. The method 
- * {@link StyleableProperty#getCssMetaData()} is not implemented. 
- * 
- * This class is used to make a {@link javafx.beans.property.LongProperty}, 
- * that would otherwise be implemented as a {@link SimpleLongProperty}, 
+ * implementation of a {@code StyleableProperty}.  
+ *
+ * This class is used to make a {@link javafx.beans.property.LongProperty},
+ * that would otherwise be implemented as a {@link SimpleLongProperty},
  * style&#8209;able by CSS.
- * 
+ *
  * @see javafx.beans.property.SimpleLongProperty
  * @see CssMetaData
  * @see StyleableProperty
+ * @see StyleableLongProperty
  */
 @com.sun.javafx.beans.annotations.NoBuilder
-public abstract class SimpleStyleableLongProperty
-    extends SimpleLongProperty implements StyleableProperty<Number> {
+public class SimpleStyleableLongProperty extends StyleableLongProperty {
+
+    private static final Object DEFAULT_BEAN = null;
+    private static final String DEFAULT_NAME = "";
+
+    private final Object bean;
+    private final String name;
+    private final CssMetaData<? extends Styleable, Number> cssMetaData;
 
     /**
      * The constructor of the {@code SimpleStyleableLongProperty}.
@@ -52,8 +56,7 @@
      *            the CssMetaData associated with this {@code StyleableProperty}
      */
     public SimpleStyleableLongProperty(CssMetaData<? extends Styleable, Number> cssMetaData) {
-        super();
-        this.cssMetaData = cssMetaData;
+        this(cssMetaData, DEFAULT_BEAN, DEFAULT_NAME);
     }
 
     /**
@@ -64,9 +67,8 @@
      * @param initialValue
      *            the initial value of the wrapped {@code Object}
      */
-    public SimpleStyleableLongProperty(CssMetaData<? extends Styleable, Number> cssMetaData, long initialValue) {
-        super(initialValue);
-        this.cssMetaData = cssMetaData;
+    public SimpleStyleableLongProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Long initialValue) {
+        this(cssMetaData, DEFAULT_BEAN, DEFAULT_NAME, initialValue);
     }
 
     /**
@@ -80,7 +82,8 @@
      *            the name of this {@code LongProperty}
      */
     public SimpleStyleableLongProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Object bean, String name) {
-        super(bean, name);
+        this.bean = bean;
+        this.name = (name == null) ? DEFAULT_NAME : name;
         this.cssMetaData = cssMetaData;
     }
 
@@ -96,43 +99,33 @@
      * @param initialValue
      *            the initial value of the wrapped {@code Object}
      */
-    public SimpleStyleableLongProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Object bean, String name, long initialValue) {
-        super(bean, name, initialValue);
+    public SimpleStyleableLongProperty(CssMetaData<? extends Styleable, Number> cssMetaData, Object bean, String name, Long initialValue) {
+        super(initialValue);
+        this.bean = bean;
+        this.name = (name == null) ? DEFAULT_NAME : name;
         this.cssMetaData = cssMetaData;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void applyStyle(StyleOrigin origin, Number v) {
-        setValue(v);
-        this.origin = origin;
+    public Object getBean() {
+        return bean;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void bind(ObservableValue<? extends Number> observable) {
-        super.bind(observable);
-        origin = StyleOrigin.USER;
+    public String getName() {
+        return name;
     }
 
     /** {@inheritDoc} */
     @Override
-    public void set(long v) {
-        super.set(v);
-        origin = StyleOrigin.USER;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final StyleOrigin getStyleOrigin() { return origin; }
-
-    /** {@inheritDoc} */
-    @Override
     public final CssMetaData<? extends Styleable, Number> getCssMetaData() {
         return cssMetaData;
     }
 
-    private StyleOrigin origin = null;
-    private final CssMetaData<? extends Styleable, Number> cssMetaData;
-
 }
--- a/javafx-ui-common/src/javafx/css/SimpleStyleableObjectProperty.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-common/src/javafx/css/SimpleStyleableObjectProperty.java	Tue Mar 19 22:28:50 2013 +0100
@@ -26,25 +26,29 @@
 package javafx.css;
 
 import javafx.beans.property.SimpleObjectProperty;
-import javafx.beans.value.ObservableValue;
-import javafx.scene.Node;
 
 /**
  * This class extends {@code SimpleObjectProperty} and provides a full
- * implementation of a {@code StyleableProperty}. The method 
- * {@link StyleableProperty#getCssMetaData()} is not implemented. 
- * 
- * This class is used to make a {@link javafx.beans.property.ObjectProperty}, 
- * that would otherwise be implemented as a {@link SimpleObjectProperty}, 
+ * implementation of a {@code StyleableProperty}.  
+ *
+ * This class is used to make a {@link javafx.beans.property.ObjectProperty},
+ * that would otherwise be implemented as a {@link SimpleObjectProperty},
  * style&#8209;able by CSS.
- * 
+ *
  * @see javafx.beans.property.SimpleObjectProperty
  * @see CssMetaData
  * @see StyleableProperty
+ * @see StyleableObjectProperty
  */
 @com.sun.javafx.beans.annotations.NoBuilder
-public abstract class SimpleStyleableObjectProperty<T>
-    extends SimpleObjectProperty<T> implements StyleableProperty<T> {
+public class SimpleStyleableObjectProperty<T> extends StyleableObjectProperty<T> {
+
+    private static final Object DEFAULT_BEAN = null;
+    private static final String DEFAULT_NAME = "";
+
+    private final Object bean;
+    private final String name;
+    private final CssMetaData<? extends Styleable, T> cssMetaData;
 
     /**
      * The constructor of the {@code SimpleStyleableObjectProperty}.
@@ -52,8 +56,7 @@
      *            the CssMetaData associated with this {@code StyleableProperty}
      */
     public SimpleStyleableObjectProperty(CssMetaData<? extends Styleable, T> cssMetaData) {
-        super();
-        this.cssMetaData = cssMetaData;
+        this(cssMetaData, DEFAULT_BEAN, DEFAULT_NAME);
     }
 
     /**
@@ -65,8 +68,7 @@
      *            the initial value of the wrapped {@code Object}
      */
     public SimpleStyleableObjectProperty(CssMetaData<? extends Styleable, T> cssMetaData, T initialValue) {
-        super(initialValue);
-        this.cssMetaData = cssMetaData;
+        this(cssMetaData, DEFAULT_BEAN, DEFAULT_NAME, initialValue);
     }
 
     /**
@@ -80,41 +82,50 @@
      *            the name of this {@code ObjectProperty}
      */
     public SimpleStyleableObjectProperty(CssMetaData<? extends Styleable, T> cssMetaData, Object bean, String name) {
-        super(bean, name);
+        this.bean = bean;
+        this.name = (name == null) ? DEFAULT_NAME : name;
         this.cssMetaData = cssMetaData;
     }
 
-    /** {@inheritDoc} */
-    @Override
-    public void applyStyle(StyleOrigin origin, T v) {
-        set(v);
-        this.origin = origin;
+    /**
+     * The constructor of the {@code SimpleStyleableObjectProperty}.
+     *
+     * @param cssMetaData
+     *            the CssMetaData associated with this {@code StyleableProperty}
+     * @param bean
+     *            the bean of this {@code ObjectProperty}
+     * @param name
+     *            the name of this {@code ObjectProperty}
+     * @param initialValue
+     *            the initial value of the wrapped {@code Object}
+     */
+    public SimpleStyleableObjectProperty(CssMetaData<? extends Styleable, T> cssMetaData, Object bean, String name, T initialValue) {
+        super(initialValue);
+        this.bean = bean;
+        this.name = (name == null) ? DEFAULT_NAME : name;
+        this.cssMetaData = cssMetaData;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void bind(ObservableValue<? extends T> observable) {
-        super.bind(observable);
-        origin = StyleOrigin.USER;
+    public Object getBean() {
+        return bean;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void set(T v) {
-        super.set(v);
-        origin = StyleOrigin.USER;
+    public String getName() {
+        return name;
     }
 
     /** {@inheritDoc} */
     @Override
-    public final StyleOrigin getStyleOrigin() { return origin; }
-
-    /** {@inheritDoc} */
-    @Override
     public final CssMetaData<? extends Styleable, T> getCssMetaData() {
         return cssMetaData;
     }
 
-    private StyleOrigin origin = null;
-    private final CssMetaData<? extends Styleable, T> cssMetaData;
 }
--- a/javafx-ui-common/src/javafx/css/SimpleStyleableStringProperty.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-common/src/javafx/css/SimpleStyleableStringProperty.java	Tue Mar 19 22:28:50 2013 +0100
@@ -26,25 +26,29 @@
 package javafx.css;
 
 import javafx.beans.property.SimpleStringProperty;
-import javafx.beans.value.ObservableValue;
-import javafx.scene.Node;
 
 /**
  * This class extends {@code SimpleStringProperty} and provides a full
- * implementation of a {@code StyleableProperty}. The method 
- * {@link StyleableProperty#getCssMetaData()} is not implemented. 
- * 
- * This class is used to make a {@link javafx.beans.property.StringProperty}, 
- * that would otherwise be implemented as a {@link SimpleStringProperty}, 
+ * implementation of a {@code StyleableProperty}.  
+ *
+ * This class is used to make a {@link javafx.beans.property.StringProperty},
+ * that would otherwise be implemented as a {@link SimpleStringProperty},
  * style&#8209;able by CSS.
- * 
+ *
  * @see javafx.beans.property.SimpleStringProperty
  * @see CssMetaData
  * @see StyleableProperty
+ * @see StyleableStringProperty
  */
 @com.sun.javafx.beans.annotations.NoBuilder
-public abstract class SimpleStyleableStringProperty
-    extends SimpleStringProperty implements StyleableProperty<String> {
+public class SimpleStyleableStringProperty extends StyleableStringProperty {
+
+    private static final Object DEFAULT_BEAN = null;
+    private static final String DEFAULT_NAME = "";
+
+    private final Object bean;
+    private final String name;
+    private final CssMetaData<? extends Styleable, String> cssMetaData;
 
     /**
      * The constructor of the {@code SimpleStyleableStringProperty}.
@@ -52,8 +56,7 @@
      *            the CssMetaData associated with this {@code StyleableProperty}
      */
     public SimpleStyleableStringProperty(CssMetaData<? extends Styleable, String> cssMetaData) {
-        super();
-        this.cssMetaData = cssMetaData;
+        this(cssMetaData, DEFAULT_BEAN, DEFAULT_NAME);
     }
 
     /**
@@ -65,8 +68,7 @@
      *            the initial value of the wrapped {@code Object}
      */
     public SimpleStyleableStringProperty(CssMetaData<? extends Styleable, String> cssMetaData, String initialValue) {
-        super(initialValue);
-        this.cssMetaData = cssMetaData;
+        this(cssMetaData, DEFAULT_BEAN, DEFAULT_NAME, initialValue);
     }
 
     /**
@@ -80,43 +82,50 @@
      *            the name of this {@code StringProperty}
      */
     public SimpleStyleableStringProperty(CssMetaData<? extends Styleable, String> cssMetaData, Object bean, String name) {
-        super(bean, name);
+        this.bean = bean;
+        this.name = (name == null) ? DEFAULT_NAME : name;
         this.cssMetaData = cssMetaData;
     }
 
-    /** {@inheritDoc} */
-    @Override
-    public void applyStyle(StyleOrigin origin, String v) {
-        // call set here in case the set method is overriden
-        set(v);
-        this.origin = origin;
+    /**
+     * The constructor of the {@code SimpleStyleableStringProperty}.
+     *
+     * @param cssMetaData
+     *            the CssMetaData associated with this {@code StyleableProperty}
+     * @param bean
+     *            the bean of this {@code StringProperty}
+     * @param name
+     *            the name of this {@code StringProperty}
+     * @param initialValue
+     *            the initial value of the wrapped {@code Object}
+     */
+    public SimpleStyleableStringProperty(CssMetaData<? extends Styleable, String> cssMetaData, Object bean, String name, String initialValue) {
+        super(initialValue);
+        this.bean = bean;
+        this.name = (name == null) ? DEFAULT_NAME : name;
+        this.cssMetaData = cssMetaData;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void bind(ObservableValue<? extends String> observable) {
-        super.bind(observable);
-        origin = StyleOrigin.USER;
+    public Object getBean() {
+        return bean;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void set(String v) {
-        super.set(v);
-        origin = StyleOrigin.USER;
+    public String getName() {
+        return name;
     }
 
     /** {@inheritDoc} */
     @Override
-    public final StyleOrigin getStyleOrigin() { return origin; }
-
-    /** {@inheritDoc} */
-    @Override
     public final CssMetaData<? extends Styleable, String> getCssMetaData() {
         return cssMetaData;
     }
 
-    private StyleOrigin origin = null;
-    private final CssMetaData<? extends Styleable, String> cssMetaData;
-
 }
--- a/javafx-ui-common/src/javafx/scene/CssStyleHelper.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-common/src/javafx/scene/CssStyleHelper.java	Tue Mar 19 22:28:50 2013 +0100
@@ -640,8 +640,10 @@
             final CssMetaData<Styleable,Object> cssMetaData = 
                     (CssMetaData<Styleable,Object>)styleables.get(n);
             
+            final StyleableProperty styleableProperty = cssMetaData.getStyleableProperty(node);
+            if (styleableProperty == null) continue;
+
             if (observableStyleMap != null) {
-                StyleableProperty<?> styleableProperty = cssMetaData.getStyleableProperty(node);
                 if (styleableProperty != null && observableStyleMap.containsKey(styleableProperty)) {
                     observableStyleMap.remove(styleableProperty);
                 }
@@ -652,6 +654,11 @@
             // to be set (usually due to a "bind").
             if (!cssMetaData.isSettable(node)) continue;
 
+            // need to know who set the current value - CSS, the user, or init
+            final StyleOrigin originOfCurrentValue = styleableProperty.getStyleOrigin();
+
+            final boolean isUserSet = originOfCurrentValue == StyleOrigin.USER;
+            
             final String property = cssMetaData.getProperty();
             
             // Create a List to hold the Styles if the node has 
@@ -661,124 +668,110 @@
                     : null;
 
             CalculatedValue calculatedValue = null;
-            boolean isUserSet = false;
-            
+
             if (fastpath) {
 
                 calculatedValue = cacheEntry.get(property);
-                if (calculatedValue == null || calculatedValue == SKIP) continue;
                 
-                // This block of code is repeated in the slowpath, but we 
-                // want to avoid calling getStyleableProperty if possible.
-                // See the use of 'if (isUserSet)' below.
-                final StyleableProperty styleableProperty = cssMetaData.getStyleableProperty(node);
-                if (styleableProperty == null) continue;
-                
-                final StyleOrigin origin = styleableProperty.getStyleOrigin();
-                
-                isUserSet = origin == StyleOrigin.USER;
+                // caclculatedValue may be null,
+                // but we should never put SKIP in cache.
+                assert(calculatedValue != SKIP);
                 
             } else {
 
-                final StyleableProperty styleableProperty = cssMetaData.getStyleableProperty(node);
-                if (styleableProperty == null) continue;
-                
-                final StyleOrigin origin = styleableProperty.getStyleOrigin();
-                
-                isUserSet = origin == StyleOrigin.USER;
-
                 calculatedValue = lookup(node, cssMetaData, isUserSet, node.pseudoClassStates, 
                         inlineStyles, node, cacheEntry, styleList);
 
                 // lookup is not supposed to return null.
                 assert(calculatedValue != null);
                 
+            }
+            
+            // cssMetaData#set might throw an exception and it is called
+            // from two places in this try block.
+            try {                    
+            
+                //
                 // RT-19089
                 // If the current value of the property was set by CSS 
                 // and there is no style for the property, then reset this
-                // property to its initial value. 
-                //
-                if (calculatedValue == SKIP || calculatedValue == null) {
-                    
-                    // Was value set by CSS?
-                    if (origin != StyleOrigin.USER && origin != null) {
+                // property to its initial value. If it was not set by CSS
+                // then leave the property alone.
+                // 
+                if (calculatedValue == null || calculatedValue == SKIP) {
+
+                    // if the current value was set by CSS and there 
+                    // is no calculated value for the property, then 
+                    // there was no style for the property in the current
+                    // state, so reset the property to its initial value.
+                    if (originOfCurrentValue != StyleOrigin.USER && originOfCurrentValue != null) {
 
                         Object initial = cssMetaData.getInitialValue(node);
-                        
-                        calculatedValue = new CalculatedValue(initial, null, false);
-                        
-                    } else {   
-                        // was set by user or was never set
-                        continue;
-                    }
+
+                        cssMetaData.set(node, initial, null);                        
+
+                    } 
                     
+                    continue;
+
+                } 
+                
+                if (fastpath == false) {
+                    
+                    // If we're not on the fastpath, then add the calculated
+                    // value to cache.
+                    cacheEntry.put(property, calculatedValue);
                 }
                 
-                cacheEntry.put(property, calculatedValue);
 
-            }
+                // RT-10522:
+                // If the user set the property and there is a style and
+                // the style came from the user agent stylesheet, then
+                // skip the value. A style from a user agent stylesheet should
+                // not override the user set style.
+                //
+                final StyleOrigin originOfCalculatedValue = calculatedValue.getOrigin();
+                assert originOfCalculatedValue != null : styleableProperty.toString();
+                if (isUserSet) {
+                    if (originOfCalculatedValue == StyleOrigin.USER_AGENT || originOfCalculatedValue == null) { 
+                        continue;
+                    }                
+                }
             
-            assert (calculatedValue != SKIP);
-            if (calculatedValue == SKIP) continue;
-            
-                        
-            // RT-10522:
-            // If the user set the property and there is a style and
-            // the style came from the user agent stylesheet, then
-            // skip the value. A style from a user agent stylesheet should
-            // not override the user set style.
-            //
-            // RT-21894: the origin might be null if the calculatedValue 
-            // comes from reverting back to the initial value. In this case,
-            // make sure the initial value doesn't overwrite the user set value.
-            // Also moved this condition from the fastpath block to here since
-            // the check needs to be done on any calculated value, not just
-            // calculatedValues from cache
-            //
-            final StyleOrigin cvOrigin = calculatedValue.getOrigin();
-            if (isUserSet) {
-                if (cvOrigin == StyleOrigin.USER_AGENT || cvOrigin == null) { 
-                    continue;
-                }                
-            }
-            
-                try {
-                    
-                    final Object value = calculatedValue.getValue();
-                    if (LOGGER.isLoggable(PlatformLogger.FINER)) {
-                        LOGGER.finer(property + ", call cssMetaData.set(" + 
-                                node + ", " + String.valueOf(value) + ", " +
-                                cvOrigin + ")");
-                    }
-
-                    cssMetaData.set(node, value, cvOrigin);
-                    
-                    if (observableStyleMap != null) {
-                        StyleableProperty<?> styleableProperty = cssMetaData.getStyleableProperty(node);                            
-                        observableStyleMap.put(styleableProperty, styleList);
-                    }
-                    
-                } catch (Exception e) {
-
-                    // RT-27155: if setting value raises exception, reset value 
-                    // the value to initial and thereafter skip setting the property
-                    cssMetaData.set(node, cssMetaData.getInitialValue(node), null);
-                    cacheEntry.put(property, SKIP);
-                    
-                    List<CssError> errors = null;
-                    if ((errors = StyleManager.getErrors()) != null) {
-                        final String msg = String.format("Failed to set css [%s] due to %s\n", cssMetaData, e.getMessage());
-                        final CssError error = new CssError.PropertySetError(cssMetaData, node, msg);
-                        errors.add(error);
-                    }
-                    // TODO: use logger here
-                    PlatformLogger logger = Logging.getCSSLogger();
-                    if (logger.isLoggable(PlatformLogger.WARNING)) {
-                        logger.warning(String.format("Failed to set css [%s]\n", cssMetaData), e);
-                    }
+                final Object value = calculatedValue.getValue();
+                if (LOGGER.isLoggable(PlatformLogger.FINER)) {
+                    LOGGER.finer(property + ", call cssMetaData.set(" + 
+                            node + ", " + String.valueOf(value) + ", " +
+                            originOfCalculatedValue + ")");
                 }
 
+                cssMetaData.set(node, value, originOfCalculatedValue);
+
+                if (observableStyleMap != null) {
+                    observableStyleMap.put(styleableProperty, styleList);
+                }
+
+            } catch (Exception e) {
+
+                // RT-27155: if setting value raises exception, reset value 
+                // the value to initial and thereafter skip setting the property
+                cssMetaData.set(node, cssMetaData.getInitialValue(node), null);
+                cacheEntry.put(property, SKIP);
+
+                List<CssError> errors = null;
+                if ((errors = StyleManager.getErrors()) != null) {
+                    final String msg = String.format("Failed to set css [%s] due to %s\n", cssMetaData, e.getMessage());
+                    final CssError error = new CssError.PropertySetError(cssMetaData, node, msg);
+                    errors.add(error);
+                }
+                // TODO: use logger here
+                PlatformLogger logger = Logging.getCSSLogger();
+                if (logger.isLoggable(PlatformLogger.WARNING)) {
+                    logger.warning(String.format("Failed to set css [%s]\n", cssMetaData), e);
+                }
             }
+
+        }
         
         cacheMetaData.previousCacheEntry = cacheEntry;
         
@@ -2055,7 +2048,7 @@
             while (parent != null) {
                 
                 CssStyleHelper parentHelper = (parent instanceof Node) ?
-                        ((Parent)parent).styleHelper
+                        ((Node)parent).styleHelper
                         : null;
                 
                 if (parentHelper != null) {
--- a/javafx-ui-common/src/javafx/scene/Parent.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-common/src/javafx/scene/Parent.java	Tue Mar 19 22:28:50 2013 +0100
@@ -1160,8 +1160,11 @@
             final Node child = children.get(i);
             
             // If the parent styles are being updated, recalculated or 
-            // reapplied, then make sure the children get the same treatment. 
-            child.cssFlag = flag;
+            // reapplied, then make sure the children get the same treatment.
+            // Unless the child is already more dirty than this parent (RT-29074).
+            if(flag.compareTo(child.cssFlag) > 0) {
+                child.cssFlag = flag;
+            }
             child.impl_processCSS();
         }
     }
--- a/javafx-ui-common/test/unit/com/sun/javafx/test/MouseEventGenerator.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-common/test/unit/com/sun/javafx/test/MouseEventGenerator.java	Tue Mar 19 22:28:50 2013 +0100
@@ -30,9 +30,8 @@
 import javafx.scene.input.MouseEvent;
 
 public final class MouseEventGenerator {
-    private boolean primaryButtonDown = false;
 
-    public MouseEvent generateMouseEvent(EventType<MouseEvent> type,
+    public static MouseEvent generateMouseEvent(EventType<MouseEvent> type,
             double x, double y) {
 
         MouseButton button = MouseButton.NONE;
@@ -41,6 +40,8 @@
                 type == MouseEvent.MOUSE_DRAGGED) {
             button = MouseButton.PRIMARY;
         }
+        
+        boolean primaryButtonDown = false;
 
         if (type == MouseEvent.MOUSE_PRESSED ||
                 type == MouseEvent.MOUSE_DRAGGED) {
--- a/javafx-ui-common/test/unit/javafx/scene/Node_effectiveOrientation_Css_Test.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-common/test/unit/javafx/scene/Node_effectiveOrientation_Css_Test.java	Tue Mar 19 22:28:50 2013 +0100
@@ -34,6 +34,7 @@
 import javafx.scene.shape.Rectangle;
 import javafx.stage.Stage;
 import org.junit.After;
+import org.junit.Ignore;
 import org.junit.Test;
 import static org.junit.Assert.*;
 import org.junit.Before;
@@ -41,6 +42,7 @@
 /**
  * Test :dir functional pseudo-class 
  */
+@Ignore
 public class Node_effectiveOrientation_Css_Test {
     
     private Group root;
--- a/javafx-ui-controls/nbproject/project.xml	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/nbproject/project.xml	Tue Mar 19 22:28:50 2013 +0100
@@ -141,14 +141,14 @@
                 <package-root>${src.dir}</package-root>
                 <classpath mode="compile">${javac.classpath}</classpath>
                 <built-to>dist/javafx-ui-controls.jar</built-to>
-                <source-level>1.6</source-level>
+                <source-level>1.7</source-level>
             </compilation-unit>
             <compilation-unit>
                 <package-root>${test.dir}</package-root>
                 <unit-tests/>
                 <classpath mode="compile">${javac.test.classpath}</classpath>
                 <built-to>${build.test.classes.dir}</built-to>
-                <source-level>1.6</source-level>
+                <source-level>1.7</source-level>
             </compilation-unit>
         </java-data>
         <spellchecker-wordlist xmlns="http://www.netbeans.org/ns/spellchecker-wordlist/1">
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/TableColumnComparator.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/TableColumnComparator.java	Tue Mar 19 22:28:50 2013 +0100
@@ -52,7 +52,7 @@
 
     @Override public int compare(S o1, S o2) {
         for (TableColumnBase<S,T> tc : columns) {
-            if (tc.getSortType() == null) continue;
+            if (tc.getSortType() == null || ! tc.isSortable()) continue;
             
             Comparator<T> c = tc.getComparator();
 
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/ListViewBehavior.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/ListViewBehavior.java	Tue Mar 19 22:28:50 2013 +0100
@@ -267,11 +267,13 @@
     private final ListChangeListener<Integer> selectedIndicesListener = new ListChangeListener<Integer>() {
         @Override public void onChanged(ListChangeListener.Change c) {
             while (c.next()) {
+                MultipleSelectionModel<T> sm = getControl().getSelectionModel();
+                
                 // there are no selected items, so lets clear out the anchor
                 if (! selectionChanging) {
-                    if (c.getList().isEmpty()) {
+                    if (sm.isEmpty()) {
                         setAnchor(-1);
-                    } else if (! c.getList().contains(getAnchor())) {
+                    } else if (! sm.isSelected(getAnchor())) {
                         setAnchor(-1);
                     }
                 }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/SliderBehavior.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/SliderBehavior.java	Tue Mar 19 22:28:50 2013 +0100
@@ -147,11 +147,6 @@
         }
     }
 
-    /**
-     */
-    public void trackRelease(MouseEvent e, double position) {
-    }
-
      /**
      * @param position The mouse position on track with 0.0 being beginning of
       *       track and 1.0 being the end
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TableCellBehaviorBase.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TableCellBehaviorBase.java	Tue Mar 19 22:28:50 2013 +0100
@@ -277,7 +277,12 @@
         TableColumnBase column = getTableColumn();
         boolean isAlreadySelected = sm.isSelected(row, column);
 
-        sm.clearAndSelect(row, column);
+        if (isAlreadySelected && (e.isControlDown() || e.isMetaDown())) {
+            sm.clearSelection(row, column);
+            isAlreadySelected = false;
+        } else {
+            sm.clearAndSelect(row, column);
+        }
 
         // handle editing, which only occurs with the primary mouse button
         if (e.getButton() == MouseButton.PRIMARY) {
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TableViewBehaviorBase.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TableViewBehaviorBase.java	Tue Mar 19 22:28:50 2013 +0100
@@ -57,6 +57,7 @@
 import javafx.collections.ListChangeListener;
 import javafx.collections.WeakListChangeListener;
 import javafx.scene.control.Control;
+import javafx.scene.control.MultipleSelectionModel;
 import javafx.scene.control.TableColumnBase;
 import javafx.scene.control.TableFocusModel;
 import javafx.scene.control.TablePositionBase;
@@ -235,14 +236,14 @@
                 TablePositionBase anchor = getAnchor();
                 boolean cellSelectionEnabled = sm.isCellSelectionEnabled();
                 
+                // there are no selected items, so lets clear out the anchor
                 if (! selectionChanging) {
-                    // there are no selected items, so lets clear out the anchor
-                    if (c.getList().isEmpty()) {
+                    if (sm.isEmpty()) {
                         setAnchor(null);
-                    } else if (! c.getList().contains(getAnchor())) {
+                    } else if (! sm.isSelected(anchor.getRow(), anchor.getTableColumn())) {
                         setAnchor(null);
                     }
-                } 
+                }
                 
                 int addedSize = c.getAddedSize();
                 List<TablePositionBase> addedSubList = (List<TablePositionBase>) c.getAddedSubList();
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TreeCellBehavior.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TreeCellBehavior.java	Tue Mar 19 22:28:50 2013 +0100
@@ -255,7 +255,12 @@
         MultipleSelectionModel sm = tv.getSelectionModel();
         boolean isAlreadySelected = sm.isSelected(index);
 
-        tv.getSelectionModel().clearAndSelect(index);
+        if (isAlreadySelected && (e.isControlDown() || e.isMetaDown())) {
+            sm.clearSelection(index);
+            isAlreadySelected = false;
+        } else {
+            sm.clearAndSelect(index);
+        }
 
         // handle editing, which only occurs with the primary mouse button
         if (e.getButton() == MouseButton.PRIMARY) {
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TreeTableCellBehavior.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TreeTableCellBehavior.java	Tue Mar 19 22:28:50 2013 +0100
@@ -123,7 +123,12 @@
         
         boolean isAlreadySelected = sm.isSelected(index, column);
 
-        sm.clearAndSelect(index, column);
+        if (isAlreadySelected && (e.isControlDown() || e.isMetaDown())) {
+            sm.clearSelection(index, column);
+            isAlreadySelected = false;
+        } else {
+            sm.clearAndSelect(index, column);
+        }
 
         // handle editing, which only occurs with the primary mouse button
         if (e.getButton() == MouseButton.PRIMARY) {
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TreeTableRowBehavior.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TreeTableRowBehavior.java	Tue Mar 19 22:28:50 2013 +0100
@@ -25,10 +25,14 @@
 
 package com.sun.javafx.scene.control.behavior;
 
+import java.util.Iterator;
+import java.util.List;
+
 import javafx.scene.Node;
 import javafx.scene.control.MultipleSelectionModel;
 import javafx.scene.control.TableSelectionModel;
 import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeTableColumn;
 import javafx.scene.control.TreeTableRow;
 import javafx.scene.control.TreeTableView;
 import javafx.scene.input.MouseButton;
@@ -67,13 +71,28 @@
         final TableSelectionModel sm = table.getSelectionModel();
         if (sm == null || sm.isCellSelectionEnabled()) return;
         
-        // handle editing, which only occurs with the primary mouse button
+        final int index = getControl().getIndex();
+        final boolean isAlreadySelected = sm.isSelected(index);
         int clickCount = e.getClickCount();
         if (clickCount == 1) {
+            // get width of all visible columns (we only care about clicks to the
+            // right of the right-most column)
+            List<TreeTableColumn<T, ?>> columns = getControl().getTreeTableView().getVisibleLeafColumns();
+            double width = 0.0;
+            for (int i = 0; i < columns.size(); i++) {
+                width += columns.get(i).getWidth();
+            }
+            
+            if (e.getX() < width) return;
+            
             // In the case of clicking to the right of the rightmost
             // TreeTableCell, we should still support selection, so that
             // is what we are doing here.
-            sm.select(treeItem);
+            if (isAlreadySelected) {
+                sm.clearSelection(index);
+            } else {
+                sm.select(treeItem);
+            }
         }
     }
 }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TreeViewBehavior.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TreeViewBehavior.java	Tue Mar 19 22:28:50 2013 +0100
@@ -198,11 +198,13 @@
     private final ListChangeListener<Integer> selectedIndicesListener = new ListChangeListener<Integer>() {
         @Override public void onChanged(ListChangeListener.Change c) {
             while (c.next()) {
+                MultipleSelectionModel<TreeItem<T>> sm = getControl().getSelectionModel();
+                
                 // there are no selected items, so lets clear out the anchor
                 if (! selectionChanging) {
-                    if (c.getList().isEmpty()) {
+                    if (sm.isEmpty()) {
                         setAnchor(-1);
-                    } else if (! c.getList().contains(getAnchor())) {
+                    } else if (! sm.isSelected(getAnchor())) {
                         setAnchor(-1);
                     }
                 }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ContextMenuContent.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ContextMenuContent.java	Tue Mar 19 22:28:50 2013 +0100
@@ -39,6 +39,7 @@
 import javafx.animation.Timeline;
 import javafx.beans.InvalidationListener;
 import javafx.beans.Observable;
+import javafx.beans.WeakInvalidationListener;
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableBooleanValue;
 import javafx.beans.value.ObservableValue;
@@ -76,6 +77,7 @@
 import javafx.stage.Window;
 
 import com.sun.javafx.scene.control.behavior.TwoLevelFocusPopupBehavior;
+import javafx.beans.WeakInvalidationListener;
 import javafx.beans.property.ReadOnlyBooleanProperty;
 import javafx.css.Styleable;
 
@@ -111,7 +113,14 @@
     private int currentFocusedIndex = -1;
     
     private boolean itemsDirty = true;
-    
+    private InvalidationListener popupShowingListener = new InvalidationListener() {
+        @Override public void invalidated(Observable arg0) {
+            updateItems();
+        }
+    };
+    private WeakInvalidationListener weakPopupShowingListener = 
+            new WeakInvalidationListener(popupShowingListener);
+
     /***************************************************************************
      * Constructors
      **************************************************************************/
@@ -137,11 +146,7 @@
         initialize();
         setUpBinds();
         // RT-20197 add menuitems only on first show.
-        popupMenu.showingProperty().addListener(new InvalidationListener() {
-            @Override public void invalidated(Observable arg0) {
-                updateItems();
-            }
-        });
+        popupMenu.showingProperty().addListener(weakPopupShowingListener);
 
         /*
         ** only add this if we're on an embedded
@@ -233,13 +238,21 @@
     }
     
     private void updateVisualItems() {
-        itemsContainer.getChildren().clear();
+        // clean up itemsContainer
+        ObservableList<Node> itemsContainerChilder = itemsContainer.getChildren();
+        for (int i = 0, max = itemsContainerChilder.size(); i < max; i++) {
+            MenuItemContainer container = (MenuItemContainer) itemsContainerChilder.get(i);
+            container.visibleProperty().unbind();
+            container.dispose();
+        }
+        itemsContainerChilder.clear();
+        
         for (int row = 0; row < getItems().size(); row++) {
             final MenuItem item = getItems().get(row);
             if (item instanceof CustomMenuItem && ((CustomMenuItem) item).getContent() == null) continue;
             MenuItemContainer menuItemContainer = new MenuItemContainer(item);
             menuItemContainer.visibleProperty().bind(item.visibleProperty());
-            itemsContainer.getChildren().add(menuItemContainer);
+            itemsContainerChilder.add(menuItemContainer);
             if (item instanceof SeparatorMenuItem) {
                 // TODO
                 // we don't want the hover highlight for separators, so for
@@ -247,8 +260,8 @@
                 // background entirely. This may cause issues if people
                 // intend to style the background differently.
                  Node node = ((CustomMenuItem) item).getContent();
-                 itemsContainer.getChildren().remove(menuItemContainer);
-                 itemsContainer.getChildren().add(node);
+                 itemsContainerChilder.remove(menuItemContainer);
+                 itemsContainerChilder.add(node);
                  // Add the (separator) menu item to properties map of this node.
                 // Special casing this for separator :
                 // This allows associating this container with SeparatorMenuItem.
@@ -1048,6 +1061,9 @@
         private Node label;
         private Node right;
 
+        private final List<WeakInvalidationListener> listeners = 
+                new ArrayList<WeakInvalidationListener>();
+
         protected Label getLabel(){
             return (Label) label;
         }
@@ -1088,12 +1104,28 @@
             // This allows associating this container with corresponding MenuItem.
             getProperties().put(MenuItem.class, item);
             
-            item.graphicProperty().addListener(new InvalidationListener() {
-                @Override public void invalidated(Observable o) {
+            InvalidationListener listener = new InvalidationListener() {
+                @Override public void invalidated(Observable observable) {
                     createChildren();
                     computeVisualMetrics();
                 }
-            });
+            };
+            WeakInvalidationListener weakListener = new WeakInvalidationListener(listener);
+            listeners.add(weakListener);
+            item.graphicProperty().addListener(weakListener);
+        }
+        
+        public void dispose() {
+            listeners.clear();
+            
+            if (label != null) {
+                ((Label)label).textProperty().unbind();
+            }
+            
+            left = null;
+            graphic = null;
+            label = null;
+            right = null;
         }
         
         private void createChildren() {
@@ -1180,6 +1212,11 @@
                             requestFocus();  // request Focus on hover
                         }
                     });
+                    setOnMouseReleased(new EventHandler<MouseEvent>() {
+                        @Override public void handle(MouseEvent event) {
+                            item.fire();
+                        }
+                    });
                 } else { // normal MenuItem
                     // accelerator text
 //                    Label rightNode = new Label("Ctrl+x");
@@ -1195,12 +1232,14 @@
                     
                     // accelerator support
                     updateAccelerator();
-                    item.acceleratorProperty().addListener(new InvalidationListener() {
-                        @Override
-                        public void invalidated(Observable observable) {
+                    InvalidationListener listener = new InvalidationListener() {
+                        @Override public void invalidated(Observable observable) {
                             updateAccelerator();
                         }
-                    });
+                    };
+                    WeakInvalidationListener weakListener = new WeakInvalidationListener(listener);
+                    listeners.add(weakListener);
+                    item.acceleratorProperty().addListener(weakListener);
                     
                     setOnMouseEntered(new EventHandler<MouseEvent>() {
                         @Override public void handle(MouseEvent event) {
@@ -1244,9 +1283,17 @@
         }
 
         void doSelect() {
+            doSelect(null);
+        }
+        
+        void doSelect(MouseEvent event) {
             // don't do anything on disabled menu items
             if (item == null || item.isDisable()) return;
-            
+            if (event != null && !(getLayoutBounds()).contains(event.getX(), event.getY())) {
+                // RT-23457 Mouse release happened outside the menu item - hide and return
+                hideAllMenus(item);
+                return;
+            }
             // toggle state of check or radio items
             if (item instanceof CheckMenuItem) {
                 CheckMenuItem checkItem = (CheckMenuItem)item;
@@ -1351,12 +1398,16 @@
         }
 
         private void listen(ObservableBooleanValue property, final PseudoClass pseudoClass) {
-            property.addListener(new InvalidationListener() {
+            InvalidationListener listener = new InvalidationListener() {
                 @Override public void invalidated(Observable valueModel) {
                     boolean active = ((ObservableBooleanValue)valueModel).get();
                     pseudoClassStateChanged(pseudoClass, active);
                 }
-            });
+            };
+            WeakInvalidationListener weakListener = new WeakInvalidationListener(listener);
+            
+            listeners.add(weakListener);
+            property.addListener(weakListener);
         }
 
         // Responsible for returning a graphic (if necessary) to position in the
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ContextMenuSkin.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ContextMenuSkin.java	Tue Mar 19 22:28:50 2013 +0100
@@ -58,6 +58,7 @@
     /***/
     public ContextMenuSkin(final ContextMenu popupMenu) {
         this.popupMenu = popupMenu;
+        
         // When a contextMenu is shown, requestFocus on its content to enable
         // keyboard navigation.
         popupMenu.addEventHandler(Menu.ON_SHOWN, new EventHandler<Event>() {
@@ -87,33 +88,6 @@
         }
     }
 
-//            /*
-//             * We see if any of the items in this menu currently own the focus.
-//             * If not, we simply determine if this PopupMenu is a 'root menu'
-//             * (i.e. does not have a parent menu) or a submenu.
-//             * A root menu does not show a selected item, whereas submenus
-//             * will always have the first item selected.
-//             */
-//            PopupMenuContent popupMenuContent = (PopupMenuContent) popupContent;
-//            if (popupMenuContent.getFocusedItem() != null) {
-//                popupMenuContent.getFocusedItem().requestFocus();
-//            }
-//            else {
-//                Node anchor = popupMenu.getAnchor();
-//                if (anchor instanceof Menu && ((Menu) anchor).getParentMenu() == null) {
-//                    popupMenuContent.requestFocus();
-//                } else {
-//                    MenuBehavior.getFirstValidMenuItem(popupMenu.getItems()).requestFocus();
-//                }
-//
-//            }
-
-//    private boolean focused = false;
-//    private void setFocused(boolean value) {
-//        focused = value;
-//        ((ContextMenuContent)popupContent).requestFocus();
-//    }
-
     @Override public ContextMenu getSkinnable() {
         return popupMenu;
     }
@@ -123,7 +97,7 @@
     }
 
     @Override public void dispose() {
+        root.idProperty().unbind();
+        root.styleProperty().unbind();
     }
-
-
 }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/CustomColorDialog.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/CustomColorDialog.java	Tue Mar 19 22:28:50 2013 +0100
@@ -83,7 +83,7 @@
     public CustomColorDialog(Window owner) {
         getStyleClass().add("custom-color-dialog");
         if (owner != null) dialog.initOwner(owner);
-        dialog.setTitle("Custom Colors..");
+        dialog.setTitle("Custom Colors");
         dialog.initModality(Modality.APPLICATION_MODAL);
         dialog.initStyle(StageStyle.UTILITY);
         colorRectPane = new ColorRectPane();
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/LabeledSkinBase.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/LabeledSkinBase.java	Tue Mar 19 22:28:50 2013 +0100
@@ -27,6 +27,7 @@
 
 import com.sun.javafx.tk.Toolkit;
 import com.sun.javafx.tk.FontMetrics;
+import javafx.application.Platform;
 import javafx.beans.InvalidationListener;
 import javafx.beans.Observable;
 import javafx.geometry.HPos;
@@ -446,8 +447,13 @@
                 }
                 if (mnemonic_underscore != null) {
                     if (getChildren().contains(mnemonic_underscore)) {
-                        getChildren().remove(mnemonic_underscore);
-                        mnemonic_underscore = null;
+                        Platform.runLater(new Runnable() {
+                           @Override
+                               public void run() {
+                                 getChildren().remove(mnemonic_underscore);
+                                 mnemonic_underscore = null;
+                           }
+                        });
                     }
                 }
             }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/SliderSkin.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/SliderSkin.java	Tue Mar 19 22:28:50 2013 +0100
@@ -25,19 +25,20 @@
 
 package com.sun.javafx.scene.control.skin;
 
+import javafx.animation.Transition;
 import javafx.event.EventHandler;
+import javafx.geometry.Insets;
 import javafx.geometry.Orientation;
 import javafx.geometry.Point2D;
 import javafx.geometry.Side;
 import javafx.scene.chart.NumberAxis;
 import javafx.scene.control.Slider;
+import javafx.scene.input.MouseEvent;
 import javafx.scene.layout.StackPane;
+import javafx.util.Duration;
+import javafx.util.StringConverter;
 
 import com.sun.javafx.scene.control.behavior.SliderBehavior;
-import javafx.animation.Transition;
-import javafx.geometry.Insets;
-import javafx.util.Duration;
-import javafx.util.StringConverter;
 
 /**
  * Region/css based skin for Slider
@@ -91,8 +92,8 @@
         getChildren().clear();
         getChildren().addAll(track, thumb);
         setShowTickMarks(getSkinnable().isShowTickMarks(), getSkinnable().isShowTickLabels());
-         track.setOnMousePressed( new EventHandler<javafx.scene.input.MouseEvent>() {
-            @Override public void handle(javafx.scene.input.MouseEvent me) {
+        track.setOnMousePressed( new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent me) {
                 if (!thumb.isPressed()) {
                     trackClicked = true;
                     if (getSkinnable().getOrientation() == Orientation.HORIZONTAL) {
@@ -104,17 +105,21 @@
                 }
             }
         });
-
-        track.setOnMouseReleased( new EventHandler<javafx.scene.input.MouseEvent>() {
-            @Override public void handle(javafx.scene.input.MouseEvent me) {
-                 //Nothing being done with the second param in sliderBehavior
-                //So, passing a dummy value
-                getBehavior().trackRelease(me, 0.0f);
+        
+        track.setOnMouseDragged(new EventHandler<MouseEvent>() {
+            public void handle(MouseEvent me) {
+                if (!thumb.isPressed()) {
+                    if (getSkinnable().getOrientation() == Orientation.HORIZONTAL) {
+                        getBehavior().trackPress(me, (me.getX() / trackLength));
+                    } else {
+                        getBehavior().trackPress(me, (me.getY() / trackLength));
+                    }
+                }
             }
         });
 
-        thumb.setOnMousePressed(new EventHandler<javafx.scene.input.MouseEvent>() {
-            @Override public void handle(javafx.scene.input.MouseEvent me) {
+        thumb.setOnMousePressed(new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent me) {
                 getBehavior().thumbPressed(me, 0.0f);
                 dragStart = thumb.localToParent(me.getX(), me.getY());
                 preDragThumbPos = (getSkinnable().getValue() - getSkinnable().getMin()) /
@@ -122,14 +127,14 @@
             }
         });
 
-        thumb.setOnMouseReleased(new EventHandler<javafx.scene.input.MouseEvent>() {
-            @Override public void handle(javafx.scene.input.MouseEvent me) {
+        thumb.setOnMouseReleased(new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent me) {
                 getBehavior().thumbReleased(me);
             }
         });
 
-          thumb.setOnMouseDragged(new EventHandler<javafx.scene.input.MouseEvent>() {
-            @Override public void handle(javafx.scene.input.MouseEvent me) {
+        thumb.setOnMouseDragged(new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent me) {
                 Point2D cur = thumb.localToParent(me.getX(), me.getY());
                 double dragPos = (getSkinnable().getOrientation() == Orientation.HORIZONTAL)?
                     cur.getX() - dragStart.getX() : -(cur.getY() - dragStart.getY());
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableRowSkin.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableRowSkin.java	Tue Mar 19 22:28:50 2013 +0100
@@ -110,7 +110,7 @@
         return cell.getTableColumn();
     }
 
-    @Override protected Node getGraphic() {
+    @Override protected ObjectProperty<Node> graphicProperty() {
         return null;
     }
 
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableRowSkinBase.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableRowSkinBase.java	Tue Mar 19 22:28:50 2013 +0100
@@ -116,7 +116,8 @@
      * graphic associated with a TreeItem (i.e. treeItem.getGraphic()), rather
      * than a graphic associated with a cell.
      */
-    protected abstract Node getGraphic(); 
+//    protected abstract Node getGraphic(); 
+    protected abstract ObjectProperty<Node> graphicProperty();
     
     protected abstract Control getVirtualFlowOwner(); // return TableView / TreeTableView
     
@@ -506,7 +507,8 @@
                         
                         // determine starting point of the graphic or cell node, and the
                         // remaining width available to them
-                        Node graphic = getGraphic();
+                        ObjectProperty<Node> graphicProperty = graphicProperty();
+                        Node graphic = graphicProperty == null ? null : graphicProperty.get();
                         
                         if (graphic != null) {
                             graphicWidth = graphic.prefWidth(-1) + 3;
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TreeCellSkin.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TreeCellSkin.java	Tue Mar 19 22:28:50 2013 +0100
@@ -43,6 +43,7 @@
 import javafx.css.StyleableProperty;
 import javafx.css.CssMetaData;
 import com.sun.javafx.css.converters.SizeConverter;
+import com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler;
 import com.sun.javafx.scene.control.behavior.TreeCellBehavior;
 import javafx.animation.RotateTransition;
 import javafx.beans.value.ChangeListener;
@@ -50,6 +51,7 @@
 import javafx.beans.value.WeakChangeListener;
 import javafx.css.Styleable;
 import javafx.geometry.Insets;
+import javafx.util.Callback;
 import javafx.util.Duration;
 
 public class TreeCellSkin extends CellSkinBase<TreeCell<?>, TreeCellBehavior> {
@@ -100,14 +102,17 @@
     private boolean disclosureNodeDirty = true;
     private TreeItem<?> treeItem;
     
-    private final ChangeListener<Boolean> treeItemExpandedListener = new ChangeListener<Boolean>() {
-        @Override public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean isExpanded) {
-            updateDisclosureNodeRotation(true);
+    private MultiplePropertyChangeListenerHandler treeItemListener = new MultiplePropertyChangeListenerHandler(new Callback<String, Void>() {
+        @Override public Void call(String p) {
+            if ("EXPANDED".equals(p)) {
+                updateDisclosureNodeRotation(true);
+            } else if ("GRAPHIC".equals(p)) {
+                getSkinnable().requestLayout();
+            }
+            return null;
         }
-    };
-    private final WeakChangeListener<Boolean> weakTreeItemExpandedListener = 
-            new WeakChangeListener(treeItemExpandedListener);
-
+    });
+    
     public TreeCellSkin(TreeCell<?> control) {
         super(control, new TreeCellBehavior(control));
         
@@ -153,11 +158,13 @@
     
     private void updateTreeItem() {
         if (treeItem != null) {
-            treeItem.expandedProperty().removeListener(weakTreeItemExpandedListener);
+            treeItemListener.unregisterChangeListener(treeItem.expandedProperty(), "EXPANDED");
+            treeItemListener.unregisterChangeListener(treeItem.graphicProperty(), "GRAPHIC");
         }
         treeItem = getSkinnable().getTreeItem();
         if (treeItem != null) {
-            treeItem.expandedProperty().addListener(weakTreeItemExpandedListener);
+            treeItemListener.registerChangeListener(treeItem.expandedProperty(), "EXPANDED");
+            treeItemListener.registerChangeListener(treeItem.graphicProperty(), "GRAPHIC");
         }
         
         updateDisclosureNodeRotation(false);
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TreeTableRowSkin.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TreeTableRowSkin.java	Tue Mar 19 22:28:50 2013 +0100
@@ -38,6 +38,7 @@
 import javafx.css.StyleableDoubleProperty;
 import javafx.css.CssMetaData;
 import com.sun.javafx.css.converters.SizeConverter;
+import com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler;
 import com.sun.javafx.scene.control.behavior.TreeTableRowBehavior;
 import javafx.animation.RotateTransition;
 import javafx.beans.property.ObjectProperty;
@@ -52,6 +53,7 @@
 import javafx.scene.control.TableRow;
 import javafx.scene.control.TreeTableCell;
 import javafx.scene.control.TreeTableColumn;
+import javafx.util.Callback;
 import javafx.util.Duration;
 
 /**
@@ -65,11 +67,16 @@
     private TreeItem<?> treeItem;
     private boolean disclosureNodeDirty = true;
     
-    private final ChangeListener<Boolean> treeItemExpandedListener = new ChangeListener<Boolean>() {
-        @Override public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean isExpanded) {
-            updateDisclosureNodeRotation(true);
+    private MultiplePropertyChangeListenerHandler treeItemListener = new MultiplePropertyChangeListenerHandler(new Callback<String, Void>() {
+        @Override public Void call(String p) {
+            if ("EXPANDED".equals(p)) {
+                updateDisclosureNodeRotation(true);
+            } else if ("GRAPHIC".equals(p)) {
+                getSkinnable().requestLayout();
+            }
+            return null;
         }
-    };
+    });
     
     public TreeTableRowSkin(TreeTableRow<T> control) {
         super(control, new TreeTableRowBehavior<T>(control));
@@ -156,11 +163,13 @@
     
     private void updateTreeItem() {
         if (treeItem != null) {
-            treeItem.expandedProperty().removeListener(treeItemExpandedListener);
+            treeItemListener.unregisterChangeListener(treeItem.expandedProperty(), "EXPANDED");
+            treeItemListener.unregisterChangeListener(treeItem.graphicProperty(), "GRAPHIC");
         }
         treeItem = getSkinnable().getTreeItem();
         if (treeItem != null) {
-            treeItem.expandedProperty().addListener(treeItemExpandedListener);
+            treeItemListener.registerChangeListener(treeItem.expandedProperty(), "EXPANDED");
+            treeItemListener.registerChangeListener(treeItem.graphicProperty(), "GRAPHIC");
         }
         
         updateDisclosureNodeRotation(false);
@@ -307,12 +316,12 @@
         return cell.getTableColumn();
     }
 
-    @Override protected Node getGraphic() {
+    @Override protected ObjectProperty<Node> graphicProperty() {
         TreeTableRow<T> treeTableRow = getSkinnable();
         if (treeTableRow == null) return null;
         if (treeItem == null) return null;
         
-        return treeItem.getGraphic();
+        return treeItem.graphicProperty();
     }
     
     @Override protected Control getVirtualFlowOwner() {
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/modena/modena.css	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/modena/modena.css	Tue Mar 19 22:28:50 2013 +0100
@@ -362,6 +362,8 @@
        the text is always vertically centered within the bounds. Based on
        the cap height of the text. */
     -fx-bounds-type: logical_vertical_center;
+    /* Enable LCD text rendering */
+    -fx-font-smoothing-type: lcd;
 }
 
 /* ====   BUTTON LIKE THINGS   ============================================== */
@@ -2254,14 +2256,14 @@
 }
 .tree-cell > .tree-disclosure-node,
 .tree-table-row-cell > .tree-disclosure-node {
-    -fx-padding: 4 2 4 8;
+    -fx-padding: 4 6 4 8;
     -fx-background-color: transparent;
 }
 .tree-cell > .tree-disclosure-node > .arrow,
 .tree-table-row-cell > .tree-disclosure-node > .arrow {
     -fx-background-color: -fx-text-background-color;
-    -fx-padding: 0.333333em; /* 4 */
-    -fx-shape: "M 0 -4 L 8 0 L 0 4 z";
+    -fx-padding: 0.333333em 0.229em 0.333333em 0.229em; /* 4 */
+    -fx-shape: "M 0 -3.5 L 4 0 L 0 3.5 z";
 }
 .tree-cell:expanded > .tree-disclosure-node > .arrow,
 .tree-table-row-cell:expanded > .tree-disclosure-node > .arrow {
@@ -2453,7 +2455,9 @@
     -fx-indent: 1em;
 }
 .tree-table-cell {
-    -fx-padding: 0.166667em; /* 2px, plus border adds 1px */
+    /* tree-table-cell needs slightly different padding to make the text sit at
+    the right height for the arrow */
+    -fx-padding: 0.25em 0.166667em 0.083em 0.166667em; /* 3 2 1 2 , plus border adds 1px */
     -fx-background-color: null;
     -fx-border-color: transparent -fx-table-cell-border-color transparent transparent;
     -fx-cell-size: 2.0em; /* 24 */
Binary file javafx-ui-controls/src/com/sun/javafx/scene/control/skin/modena/pattern-transparent.png has changed
--- a/javafx-ui-controls/src/javafx/scene/control/CheckBoxTreeItem.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/CheckBoxTreeItem.java	Tue Mar 19 22:28:50 2013 +0100
@@ -31,6 +31,7 @@
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
 import javafx.event.Event;
+import javafx.event.EventHandler;
 import javafx.event.EventType;
 import javafx.scene.Node;
 
@@ -87,7 +88,17 @@
     
     /**
      * An EventType used when the CheckBoxTreeItem selection / indeterminate
-     * state changes.
+     * state changes. To use this, it is recommended that you use code along the
+     * lines of the following:
+     *
+     *<pre>
+     * {@code
+     * child1.addEventHandler(CheckBoxTreeItem.<String>checkBoxSelectionChangedEvent(), new EventHandler<TreeModificationEvent<String>>() {
+     *     public void handle(TreeModificationEvent<String> event) {
+     *          ...     
+     *     }
+     * });}
+     * </pre>
      * 
      * @param <T> The type of the value contained within the TreeItem.
      */
@@ -199,7 +210,7 @@
     /** Sets the selected state of this CheckBoxTreeItem. */
     public final void setSelected(boolean value) { selectedProperty().setValue(value); }
     /** Returns the selected state of this CheckBoxTreeItem. */
-    public final boolean isSelected() { return selected == null ? false : selected.getValue(); }
+    public final boolean isSelected() { return selected.getValue(); }
     /** A {@link BooleanProperty} used to represent the selected state of this CheckBoxTreeItem. */
     public final BooleanProperty selectedProperty() { return selected; }
     
@@ -214,7 +225,7 @@
     /** Sets the indeterminate state of this CheckBoxTreeItem. */
     public final void setIndeterminate(boolean value) { indeterminateProperty().setValue(value); }
     /** Returns the indeterminate state of this CheckBoxTreeItem. */
-    public final boolean isIndeterminate() { return indeterminate == null ? false : indeterminate.getValue(); }
+    public final boolean isIndeterminate() { return indeterminate.getValue(); }
     /** A {@link BooleanProperty} used to represent the indeterminate state of this CheckBoxTreeItem. */
     public final BooleanProperty indeterminateProperty() { return indeterminate; }
     
@@ -234,7 +245,7 @@
     public final BooleanProperty independentProperty() { return independent; }
     private final BooleanProperty independent = new SimpleBooleanProperty(this, "independent", false);
     public final void setIndependent(boolean value) { independentProperty().setValue(value); }
-    public final boolean isIndependent() { return independent == null ? false : independent.getValue(); }
+    public final boolean isIndependent() { return independent.getValue(); }
     
     
     
--- a/javafx-ui-controls/src/javafx/scene/control/MultipleSelectionModelBase.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/MultipleSelectionModelBase.java	Tue Mar 19 22:28:50 2013 +0100
@@ -302,8 +302,8 @@
         setSelectedIndex(row);
         focus(row);
         
-        // TODO this isn't correct
-        selectedIndicesSeq.callObservers(new NonIterableChange.SimpleAddChange<Integer>(0, 1, selectedIndicesSeq));
+        int changeIndex = selectedIndicesSeq.indexOf(row);
+        selectedIndicesSeq.callObservers(new NonIterableChange.SimpleAddChange<Integer>(changeIndex, changeIndex+1, selectedIndicesSeq));
         
         if (fireUpdatedItemEvent) {
             setSelectedItem(newItem);
@@ -417,9 +417,14 @@
         selectedIndices.set(0, (int) rowCount, true);
         selectedIndicesSeq.callObservers(new NonIterableChange.SimpleAddChange<Integer>(0, (int) rowCount, selectedIndicesSeq));
 
-        setSelectedIndex(rowCount - 1);
-
-        focus(getSelectedIndex());
+        int focusedIndex = getFocusedIndex();
+        if (focusedIndex == -1) {
+            setSelectedIndex(rowCount - 1);
+            focus(rowCount - 1);
+        } else {
+            setSelectedIndex(focusedIndex);
+            focus(focusedIndex);
+        }
     }
     
     @Override public void selectFirst() {
@@ -455,10 +460,8 @@
             clearSelection();
         }
 
-//            updateLeadSelection();
-//            support.fireChangedEvent(SELECTED_INDICES);
         selectedIndicesSeq.callObservers(
-                new NonIterableChange.GenericAddRemoveChange<Integer>(0, 0, 
+                new NonIterableChange.GenericAddRemoveChange<Integer>(index, index+1, 
                 Collections.singletonList(index), selectedIndicesSeq));
     }
 
--- a/javafx-ui-controls/src/javafx/scene/control/TableView.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/TableView.java	Tue Mar 19 22:28:50 2013 +0100
@@ -1893,8 +1893,15 @@
                     indices.add(new TablePosition(getTableView(), i, null));
                 }
                 selectedCells.setAll(indices);
-                select(getItemCount() - 1);
-                focus(indices.get(indices.size() - 1));
+                
+                int focusedIndex = getFocusedIndex();
+                if (focusedIndex == -1) {
+                    select(getItemCount() - 1);
+                    focus(indices.get(indices.size() - 1));
+                } else {
+                    select(focusedIndex);
+                    focus(focusedIndex);
+                }
             }
         }
 
--- a/javafx-ui-controls/src/javafx/scene/control/Tooltip.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/Tooltip.java	Tue Mar 19 22:28:50 2013 +0100
@@ -51,6 +51,7 @@
 import javafx.css.StyleableProperty;
 import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
+import javafx.geometry.NodeOrientation;
 import javafx.scene.Node;
 import javafx.scene.Parent;
 import javafx.scene.Scene;
@@ -764,7 +765,21 @@
                     // ACTIVATED_TIMER expire, and wait until the next mouse
                     // the movement to start it again.
                     if (owner != null && owner.isShowing() && treeVisible) {
-                        activatedTooltip.show(owner, lastMouseX, lastMouseY);
+                        double x = lastMouseX;
+                        double y = lastMouseY;
+
+                        // The tooltip always inherits the nodeOrientation of
+                        // the Node that it is attached to (see RT-26147). It
+                        // is possible to override this for the Tooltip content
+                        // (but not the popup placement) by setting the
+                        // nodeOrientation on tooltip.getScene().getRoot().
+                        NodeOrientation nodeOrientation = hoveredNode.getEffectiveNodeOrientation();
+                        activatedTooltip.getScene().setNodeOrientation(nodeOrientation);
+                        if (nodeOrientation == NodeOrientation.RIGHT_TO_LEFT) {
+                            x -= activatedTooltip.getWidth();
+                        }
+
+                        activatedTooltip.show(owner, x, y);
                         visibleTooltip = activatedTooltip;
                         hoveredNode = null;
                         hideTimer.playFromStart();
--- a/javafx-ui-controls/src/javafx/scene/control/TreeTableView.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/TreeTableView.java	Tue Mar 19 22:28:50 2013 +0100
@@ -2304,8 +2304,15 @@
                     indices.add(new TreeTablePosition(getTreeTableView(), i, null));
                 }
                 selectedCells.setAll(indices);
-                select(getRowCount() - 1);
-                focus(indices.get(indices.size() - 1));
+                
+                int focusedIndex = getFocusedIndex();
+                if (focusedIndex == -1) {
+                    select(getItemCount() - 1);
+                    focus(indices.get(indices.size() - 1));
+                } else {
+                    select(focusedIndex);
+                    focus(focusedIndex);
+                }
             }
         }
 
--- a/javafx-ui-controls/src/javafx/scene/control/cell/CheckBoxListCell.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/cell/CheckBoxListCell.java	Tue Mar 19 22:28:50 2013 +0100
@@ -34,6 +34,7 @@
 import javafx.scene.control.ContentDisplay;
 import javafx.scene.control.ListCell;
 import javafx.scene.control.ListView;
+import javafx.scene.control.TreeItem;
 import javafx.util.Callback;
 import javafx.util.StringConverter;
 
@@ -88,7 +89,7 @@
      */
     public static <T> Callback<ListView<T>, ListCell<T>> forListView(
             final Callback<T, ObservableValue<Boolean>> getSelectedProperty) {
-        return forListView(getSelectedProperty, null);
+        return forListView(getSelectedProperty, CellUtils.<T>defaultStringConverter());
     }
     
     /**
@@ -169,7 +170,7 @@
     public CheckBoxListCell(
             final Callback<T, ObservableValue<Boolean>> getSelectedProperty, 
             final StringConverter<T> converter) {
-        this.getStyleClass().add("choice-box-list-cell");
+        this.getStyleClass().add("check-box-list-cell");
         setSelectedStateCallback(getSelectedProperty);
         setConverter(converter);
         
@@ -256,6 +257,10 @@
         if (! empty) {
             StringConverter c = getConverter();
             Callback<T, ObservableValue<Boolean>> callback = getSelectedStateCallback();
+            if (callback == null) {
+                throw new NullPointerException(
+                        "The CheckBoxListCell selectedStateCallbackProperty can not be null");
+            }
             
             setGraphic(checkBox);
             setText(c != null ? c.toString(item) : (item == null ? "" : item.toString()));
--- a/javafx-ui-controls/src/javafx/scene/control/cell/CheckBoxTableCell.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/cell/CheckBoxTableCell.java	Tue Mar 19 22:28:50 2013 +0100
@@ -197,7 +197,7 @@
      **************************************************************************/
     private final CheckBox checkBox;
     
-    private final boolean showLabel;
+    private boolean showLabel;
     
     private ObservableValue<Boolean> booleanProperty;
     
@@ -242,13 +242,13 @@
         // we let getSelectedProperty be null here, as we can always defer to the
         // TableColumn
         this.getStyleClass().add("check-box-table-cell");
-        setSelectedStateCallback(getSelectedProperty);
-        setConverter(converter);
-        this.showLabel = converter != null;
         
         this.checkBox = new CheckBox();
         setGraphic(checkBox);
         
+        setSelectedStateCallback(getSelectedProperty);
+        setConverter(converter);
+        
 //        // alignment is styleable through css. Calling setAlignment
 //        // makes it look to css like the user set the value and css will not 
 //        // override. Initializing alignment by calling set on the 
@@ -256,9 +256,7 @@
 //        final CssMetaData prop = CssMetaData.getCssMetaData(alignmentProperty());
 //        prop.set(this, Pos.CENTER);
         
-        if (showLabel) {
-            this.checkBox.setAlignment(Pos.CENTER_LEFT);
-        }
+        
     }
     
     
@@ -270,7 +268,11 @@
     
     // --- converter
     private ObjectProperty<StringConverter<T>> converter = 
-            new SimpleObjectProperty<StringConverter<T>>(this, "converter");
+            new SimpleObjectProperty<StringConverter<T>>(this, "converter") {
+        protected void invalidated() {
+            updateShowLabel();
+        }
+    };
 
     /**
      * The {@link StringConverter} property.
@@ -371,6 +373,11 @@
      *                                                                         *
      **************************************************************************/
     
+    private void updateShowLabel() {
+        this.showLabel = converter != null;
+        this.checkBox.setAlignment(showLabel ? Pos.CENTER_LEFT : Pos.CENTER);
+    }
+    
     private ObservableValue getSelectedProperty() {
         return getSelectedStateCallback() != null ?
                 getSelectedStateCallback().call(getIndex()) :
--- a/javafx-ui-controls/src/javafx/scene/control/cell/CheckBoxTreeCell.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/cell/CheckBoxTreeCell.java	Tue Mar 19 22:28:50 2013 +0100
@@ -408,10 +408,7 @@
             final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedProperty, 
             final StringConverter<TreeItem<T>> converter, 
             final Callback<TreeItem<T>, ObservableValue<Boolean>> getIndeterminateProperty) {
-        if (getSelectedProperty == null) {
-            throw new NullPointerException("getSelectedProperty can not be null");
-        }
-        this.getStyleClass().add("choice-box-tree-cell");
+        this.getStyleClass().add("check-box-tree-cell");
         setSelectedStateCallback(getSelectedProperty);
         setConverter(converter);
         
@@ -500,12 +497,11 @@
             setGraphic(null);
         } else {
             StringConverter c = getConverter();
-            Callback<TreeItem<T>, ObservableValue<Boolean>> callback = getSelectedStateCallback();
             
             TreeItem<T> treeItem = getTreeItem();
             
             // update the node content
-            setText(c.toString(treeItem));
+            setText(c != null ? c.toString(treeItem) : (treeItem == null ? "" : treeItem.toString()));
             checkBox.setGraphic(treeItem == null ? null : treeItem.getGraphic());
             setGraphic(checkBox);
             
@@ -527,6 +523,12 @@
                 indeterminateProperty = cbti.indeterminateProperty();
                 checkBox.indeterminateProperty().bindBidirectional(indeterminateProperty);
             } else {
+                Callback<TreeItem<T>, ObservableValue<Boolean>> callback = getSelectedStateCallback();
+                if (callback == null) {
+                    throw new NullPointerException(
+                            "The CheckBoxTreeCell selectedStateCallbackProperty can not be null");
+                }
+                
                 booleanProperty = callback.call(treeItem);
                 if (booleanProperty != null) {
                     checkBox.selectedProperty().bindBidirectional((BooleanProperty)booleanProperty);
--- a/javafx-ui-controls/src/javafx/scene/control/cell/CheckBoxTreeTableCell.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/cell/CheckBoxTreeTableCell.java	Tue Mar 19 22:28:50 2013 +0100
@@ -197,7 +197,7 @@
      **************************************************************************/
     private final CheckBox checkBox;
     
-    private final boolean showLabel;
+    private boolean showLabel;
     
     private ObservableValue<Boolean> booleanProperty;
     
@@ -241,24 +241,20 @@
             final StringConverter<T> converter) {
         // we let getSelectedProperty be null here, as we can always defer to the
         // TreeTableColumn
-        this.getStyleClass().add("choice-box-tree-table-cell");
-        setSelectedStateCallback(getSelectedProperty);
-        setConverter(converter);
-        this.showLabel = converter != null;
+        this.getStyleClass().add("check-box-tree-table-cell");
         
         this.checkBox = new CheckBox();
         setGraphic(checkBox);
         
+        setSelectedStateCallback(getSelectedProperty);
+        setConverter(converter);
+        
 //        // alignment is styleable through css. Calling setAlignment
 //        // makes it look to css like the user set the value and css will not 
 //        // override. Initializing alignment by calling set on the 
 //        // CssMetaData ensures that css will be able to override the value.
 //        final CssMetaData prop = CssMetaData.getCssMetaData(alignmentProperty());
 //        prop.set(this, Pos.CENTER);
-        
-        if (showLabel) {
-            this.checkBox.setAlignment(Pos.CENTER_LEFT);
-        }
     }
     
     
@@ -270,7 +266,11 @@
     
     // --- converter
     private ObjectProperty<StringConverter<T>> converter = 
-            new SimpleObjectProperty<StringConverter<T>>(this, "converter");
+            new SimpleObjectProperty<StringConverter<T>>(this, "converter") {
+        protected void invalidated() {
+            updateShowLabel();
+        }
+    };
 
     /**
      * The {@link StringConverter} property.
@@ -371,6 +371,11 @@
      *                                                                         *
      **************************************************************************/
     
+    private void updateShowLabel() {
+        this.showLabel = converter != null;
+        this.checkBox.setAlignment(showLabel ? Pos.CENTER_LEFT : Pos.CENTER);
+    }
+    
     private ObservableValue getSelectedProperty() {
         return getSelectedStateCallback() != null ?
                 getSelectedStateCallback().call(getIndex()) :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/com/sun/javafx/scene/control/infrastructure/ContextMenuEventFirer.java	Tue Mar 19 22:28:50 2013 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.javafx.scene.control.infrastructure;
+
+import javafx.event.Event;
+import javafx.geometry.Bounds;
+import javafx.scene.Node;
+import javafx.scene.input.ContextMenuEvent;
+
+
+public final class ContextMenuEventFirer {
+    
+    private ContextMenuEventFirer() {
+        // no-op
+    }
+    
+    public static void fireContextMenuEvent(Node target) {
+        fireContextMenuEvent(target, 0, 0);
+    }
+    
+    public static void fireContextMenuEvent(Node target, double deltaX, double deltaY) {
+        Bounds screenBounds = target.localToScreen(target.getLayoutBounds());
+        double screenX = screenBounds.getMaxX() - screenBounds.getWidth() / 2.0 + deltaX;
+        double screenY = screenBounds.getMaxY() - screenBounds.getHeight() / 2.0 + deltaY;
+        
+        ContextMenuEvent evt = new ContextMenuEvent(
+                target, 
+                target, 
+                ContextMenuEvent.CONTEXT_MENU_REQUESTED, 
+                deltaX, deltaY, 
+                screenX, screenY, 
+                false,                                      // keyboardTrigger
+                null);                                      // pickResult
+        
+        Event.fireEvent(target, evt);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/com/sun/javafx/scene/control/infrastructure/KeyEventFirer.java	Tue Mar 19 22:28:50 2013 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.javafx.scene.control.infrastructure;
+
+import java.util.Arrays;
+import java.util.List;
+import javafx.event.EventType;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.event.Event;
+import javafx.event.EventTarget;
+
+
+public class KeyEventFirer {
+    
+    private final EventTarget target;
+    
+    public KeyEventFirer(EventTarget target) {
+        this.target = target;
+    }
+    
+    public void doUpArrowPress(KeyModifier... modifiers) {
+        doKeyPress(KeyCode.UP, modifiers);
+    }
+    
+    public void doDownArrowPress(KeyModifier... modifiers) {
+        doKeyPress(KeyCode.DOWN, modifiers);
+    }
+    
+    public void doLeftArrowPress(KeyModifier... modifiers) {
+        doKeyPress(KeyCode.LEFT, modifiers);
+    }
+    
+    public void doRightArrowPress(KeyModifier... modifiers) {
+        doKeyPress(KeyCode.RIGHT, modifiers);
+    }
+    
+    public void doKeyPress(KeyCode keyCode, KeyModifier... modifiers) {
+        fireEvents(createMirroredEvents(keyCode, modifiers));
+    }
+    
+    private void fireEvents(KeyEvent... events) {
+        for (KeyEvent evt : events) {
+            Event.fireEvent(target, evt);
+        }
+    }
+    
+    private KeyEvent[] createMirroredEvents(KeyCode keyCode, KeyModifier... modifiers) {
+        KeyEvent[] events = new KeyEvent[2];
+        events[0] = createEvent(keyCode, KeyEvent.KEY_PRESSED, modifiers);
+        events[1] = createEvent(keyCode, KeyEvent.KEY_RELEASED, modifiers);
+        return events;
+    }
+    
+    private KeyEvent createEvent(KeyCode keyCode, EventType<KeyEvent> evtType, KeyModifier... modifiers) {
+        List<KeyModifier> ml = Arrays.asList(modifiers);
+
+        return new KeyEvent( null,
+                target, // EventTarget
+                evtType,  // eventType
+                null,     // Character (unused unless KeyCode == KEY_TYPED
+                null,     // text
+                keyCode, // KeyCode
+                ml.contains(KeyModifier.SHIFT),    // shiftDown
+                ml.contains(KeyModifier.CTRL),     // ctrlDown
+                ml.contains(KeyModifier.ALT),      // altDown
+                ml.contains(KeyModifier.META)      // metaData
+                ); 
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/com/sun/javafx/scene/control/infrastructure/KeyModifier.java	Tue Mar 19 22:28:50 2013 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.javafx.scene.control.infrastructure;
+
+import com.sun.javafx.Utils;
+import com.sun.javafx.pgstub.StubToolkit;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
+import com.sun.javafx.tk.Toolkit;
+import javafx.scene.input.KeyCode;
+
+public enum KeyModifier {
+    SHIFT,
+    CTRL,
+    ALT,
+    META;
+    
+    public static KeyModifier getShortcutKey() {
+        // The StubToolkit doesn't know what the platform shortcut key is, so 
+        // we have to tell it here (and lets not be cute about optimising this
+        // code as we need the platform shortcut key to be known elsewhere in the
+        // code base for keyboard navigation tests to work accurately).
+        if (Toolkit.getToolkit() instanceof StubToolkit) {
+            ((StubToolkit)Toolkit.getToolkit()).setPlatformShortcutKey(Utils.isMac() ? KeyCode.META : KeyCode.CONTROL);
+        } 
+        
+        switch (Toolkit.getToolkit().getPlatformShortcutKey()) {
+            case SHIFT:
+                return SHIFT;
+
+            case CONTROL:
+                return CTRL;
+
+            case ALT:
+                return ALT;
+
+            case META:
+                return META;
+
+            default:
+                return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/com/sun/javafx/scene/control/infrastructure/MouseEventFirer.java	Tue Mar 19 22:28:50 2013 +0100
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.javafx.scene.control.infrastructure;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javafx.event.Event;
+import javafx.event.EventType;
+import javafx.geometry.Bounds;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.canvas.Canvas;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.image.WritableImage;
+import javafx.scene.input.ContextMenuEvent;
+import javafx.scene.input.MouseButton;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.Pane;
+import javafx.scene.paint.Color;
+import javafx.stage.Stage;
+
+
+public final class MouseEventFirer {
+    
+    private MouseEventFirer() {
+        // no-op
+    }
+    
+    public static void fireMouseClickAndRelease(Node target, KeyModifier... modifiers) {
+        fireMouseEvent(target, MouseEvent.MOUSE_PRESSED, modifiers);
+        fireMouseEvent(target, MouseEvent.MOUSE_RELEASED, modifiers);
+    }
+    
+    public static void fireMouseClicked(Node target) {
+        fireMouseEvent(target, MouseEvent.MOUSE_CLICKED);
+    }
+    
+    public static void fireMouseClicked(Node target, MouseButton button) {
+        fireMouseEvent(target, MouseEvent.MOUSE_CLICKED, button, 0, 0);
+    }
+    
+    public static void fireMouseClicked(Node target, double deltaX, double deltaY) {
+        fireMouseEvent(target, MouseEvent.MOUSE_CLICKED, deltaX, deltaY);
+    }
+    
+    public static void fireMousePressed(Node target) {
+        fireMouseEvent(target, MouseEvent.MOUSE_PRESSED);
+    }
+    
+    public static void fireMousePressed(Node target, MouseButton button) {
+        fireMouseEvent(target, MouseEvent.MOUSE_PRESSED, button, 0, 0);
+    }
+    
+    public static void fireMousePressed(Node target, double deltaX, double deltaY) {
+        fireMouseEvent(target, MouseEvent.MOUSE_PRESSED, deltaX, deltaY);
+    }
+    
+    public static void fireMouseReleased(Node target) {
+        fireMouseEvent(target, MouseEvent.MOUSE_RELEASED);
+    }
+    
+    public static void fireMouseReleased(Node target, MouseButton button) {
+        fireMouseEvent(target, MouseEvent.MOUSE_RELEASED, button, 0, 0);
+    }
+    
+    public static void fireMouseReleased(Node target, double deltaX, double deltaY) {
+        fireMouseEvent(target, MouseEvent.MOUSE_RELEASED, deltaX, deltaY);
+    }
+    
+    public static void fireMouseEvent(Node target, EventType<MouseEvent> evtType, KeyModifier... modifiers) {
+        fireMouseEvent(target, evtType, 0, 0 , modifiers);
+    }
+    
+    public static void fireMouseEvent(Node target, EventType<MouseEvent> evtType, double deltaX, double deltaY, KeyModifier... modifiers) {
+        fireMouseEvent(target, evtType, MouseButton.PRIMARY, deltaX, deltaY, modifiers);
+    }
+    
+    public static void fireMouseEvent(Node target, EventType<MouseEvent> evtType, MouseButton button, double deltaX, double deltaY, KeyModifier... modifiers) {
+        fireMouseEvent(target, evtType, button, 1, deltaX, deltaY, modifiers);
+    }
+    
+    public static void fireMouseEvent(Node target, EventType<MouseEvent> evtType, MouseButton button, int clickCount, double deltaX, double deltaY, KeyModifier... modifiers) {
+        List<KeyModifier> ml = Arrays.asList(modifiers);
+        
+        Bounds screenBounds = target.localToScreen(target.getLayoutBounds());
+        double screenX = screenBounds.getMaxX() - screenBounds.getWidth() / 2.0 + deltaX;
+        double screenY = screenBounds.getMaxY() - screenBounds.getHeight() / 2.0 + deltaY;
+        
+        MouseEvent evt = new MouseEvent(
+                target, 
+                target, 
+                evtType, 
+                deltaX, deltaY, 
+                screenX, screenY, 
+                button, 
+                clickCount,
+                ml.contains(KeyModifier.SHIFT),    // shiftDown
+                ml.contains(KeyModifier.CTRL),     // ctrlDown
+                ml.contains(KeyModifier.ALT),      // altDown
+                ml.contains(KeyModifier.META),     // metaData
+                button == MouseButton.PRIMARY,     // primary button
+                button == MouseButton.MIDDLE,      // middle button
+                button == MouseButton.SECONDARY,   // secondary button
+                true,                              // synthesized 
+                button == MouseButton.SECONDARY,   // is popup trigger
+                true,                              // still since pick
+                null);                             // pick result
+        
+//        // lets see the click position.
+//        // Unfortunately this doesn't work at present because StubToolkit 
+//        // cannot generate snapshots
+//        WritableImage image = target.snapshot(null, null);
+//        Canvas canvas = new Canvas(image.getWidth(), image.getHeight());
+//        GraphicsContext g = canvas.getGraphicsContext2D();
+//        g.drawImage(image, 0, 0);
+//        
+//        g.setFill(Color.RED);
+//        g.setStroke(Color.WHITE);
+//        g.fillOval(deltaX - 2, deltaY - 2, 4, 4);
+//        g.strokeOval(deltaX - 2, deltaY - 2, 4, 4);
+//        
+//        Stage stage = new Stage();
+//        stage.setScene(new Scene(new Pane(canvas), image.getWidth(), image.getHeight()));
+//        stage.show();
+        
+        Event.fireEvent(target, evt);
+    }
+    
+//    public static void fireMouseEvent(Scene target, EventType<MouseEvent> evtType, MouseButton button, int clickCount, double deltaX, double deltaY, KeyModifier... modifiers) {
+//        List<KeyModifier> ml = Arrays.asList(modifiers);
+//        
+//        double screenX = target.getWindow().getX() + target.getX() + deltaX;
+//        double screenY = target.getWindow().getY() + target.getY() + deltaY;
+//        
+//        MouseEvent evt = new MouseEvent(
+//                target, 
+//                target, 
+//                evtType, 
+//                deltaX, deltaY, 
+//                screenX, screenY, 
+//                button, 
+//                clickCount,
+//                ml.contains(KeyModifier.SHIFT),    // shiftDown
+//                ml.contains(KeyModifier.CTRL),     // ctrlDown
+//                ml.contains(KeyModifier.ALT),      // altDown
+//                ml.contains(KeyModifier.META),     // metaData
+//                button == MouseButton.PRIMARY,     // primary button
+//                button == MouseButton.MIDDLE,      // middle button
+//                button == MouseButton.SECONDARY,   // secondary button
+//                true,                              // synthesized 
+//                button == MouseButton.SECONDARY,   // is popup trigger
+//                false,                             // still since pick
+//                null);                             // pick result
+//        
+//        Event.fireEvent(target, evt);
+//    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/com/sun/javafx/scene/control/infrastructure/MouseEventGenerator.java	Tue Mar 19 22:28:50 2013 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.javafx.scene.control.infrastructure;
+
+import javafx.event.EventType;
+import javafx.scene.input.MouseButton;
+import javafx.scene.input.MouseEvent;
+
+public final class MouseEventGenerator {
+
+    public static MouseEvent generateMouseEvent(EventType<MouseEvent> type,
+            double x, double y) {
+
+        MouseButton button = MouseButton.NONE;
+        if (type == MouseEvent.MOUSE_PRESSED ||
+                type == MouseEvent.MOUSE_RELEASED ||
+                type == MouseEvent.MOUSE_DRAGGED) {
+            button = MouseButton.PRIMARY;
+        }
+        
+        boolean primaryButtonDown = false;
+
+        if (type == MouseEvent.MOUSE_PRESSED ||
+                type == MouseEvent.MOUSE_DRAGGED) {
+            primaryButtonDown = true;
+        }
+
+        if (type == MouseEvent.MOUSE_RELEASED) {
+            primaryButtonDown = false;
+        }
+
+        MouseEvent event = new MouseEvent(type, x, y, x, y, button,
+                1, false, false, false, false, primaryButtonDown,
+                false, false, false, false, false, null);
+
+        return event;
+    }
+}
--- a/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/ChoiceBoxSkinTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/ChoiceBoxSkinTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -36,7 +36,6 @@
 /**
  * This fails with IllegalStateException because of the toolkit's check for the FX application thread
  */
-@Ignore
 public class ChoiceBoxSkinTest {
     private ChoiceBox choicebox;
     private ChoiceBoxSkinMock skin;
--- a/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/LabeledImplTestOther.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/LabeledImplTestOther.java	Tue Mar 19 22:28:50 2013 +0100
@@ -63,22 +63,23 @@
 public class LabeledImplTestOther {
     
     
-    @Test 
-    public void test_RT_21357() {
+    @Test public void test_RT_21357() {
         
         final Labeled labeled = new Label("label");
         final LabeledImpl labeledImpl = new LabeledImpl(labeled);
         
-        URL url = SkinBase.class.getResource("caspian/center-btn.png");
+        URL url = LabeledSkinBase.class.getResource("caspian/center-btn.png");
         Image img = new Image(url.toExternalForm());
+        assertNotNull(img);
+        
         ImageView iView = new ImageView(img);
         labeled.setGraphic(iView);  
         
         assertEquals(labeled.getGraphic(), labeledImpl.getGraphic());
+        assertNotNull(labeled.getGraphic());
     }
 
-    @Test 
-    public void test_RT_21617() {
+    @Test public void test_RT_21617() {
         
         MenuButton mb = new MenuButton();
         mb.setText("SomeText"); 
--- a/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/MenuButtonSkinTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/MenuButtonSkinTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -37,7 +37,6 @@
 /**
  * This fails with IllegalStateException because of the toolkit's check for the FX application thread
  */
-@Ignore
 public class MenuButtonSkinTest {
     private MenuButton menubutton;
     private MenuButtonSkinMock skin;
--- a/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/ToolBarSkinTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/ToolBarSkinTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -38,7 +38,6 @@
 /**
  * This fails with IllegalStateException because of the toolkit's check for the FX application thread
  */
-@Ignore
 public class ToolBarSkinTest {
     private ToolBar toolbar;
     private ToolBarSkinMock skin;
--- a/javafx-ui-controls/test/com/sun/javafx/scene/control/test/ControlAsserts.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/com/sun/javafx/scene/control/test/ControlAsserts.java	Tue Mar 19 22:28:50 2013 +0100
@@ -170,6 +170,10 @@
         assertCallback(control, startRow, endRow, callback);
     }
     
+    public static IndexedCell getCell(final Control control, final int index) {
+        return getVirtualFlow(control).getCell(index);
+    }
+    
     public static void assertCallback(final Control control, final int startRow, final int endRow, final Callback<IndexedCell<?>, Void> callback) {
         VirtualFlow<?> flow = getVirtualFlow(control);
         
--- a/javafx-ui-controls/test/javafx/scene/control/AccordionTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/AccordionTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -26,6 +26,7 @@
 package javafx.scene.control;
 
 import com.sun.javafx.pgstub.StubToolkit;
+import com.sun.javafx.scene.control.infrastructure.KeyEventFirer;
 import com.sun.javafx.tk.Toolkit;
 import javafx.scene.Scene;
 import javafx.scene.layout.StackPane;
--- a/javafx-ui-controls/test/javafx/scene/control/ButtonTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/ButtonTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -25,13 +25,25 @@
 
 package javafx.scene.control;
 
+import static javafx.scene.control.ControlTestUtils.assertPseudoClassDoesNotExist;
+import static javafx.scene.control.ControlTestUtils.assertPseudoClassExists;
+import static javafx.scene.control.ControlTestUtils.assertStyleClassContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import java.util.List;
+
 import javafx.beans.property.BooleanProperty;
 import javafx.beans.property.SimpleBooleanProperty;
 import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
 import javafx.scene.Scene;
 import javafx.scene.input.KeyCode;
+import javafx.scene.input.MouseButton;
 import javafx.scene.input.MouseEvent;
 import javafx.scene.layout.BackgroundFill;
 import javafx.scene.layout.HBox;
@@ -42,14 +54,17 @@
 import javafx.scene.shape.Rectangle;
 import javafx.stage.Stage;
 import javafx.stage.WindowEvent;
-import com.sun.javafx.pgstub.StubToolkit;
-import com.sun.javafx.tk.Toolkit;
+
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 
-import static javafx.scene.control.ControlTestUtils.*;
-import static org.junit.Assert.*;
+import com.sun.javafx.pgstub.StubToolkit;
+import com.sun.javafx.scene.control.infrastructure.ContextMenuEventFirer;
+import com.sun.javafx.scene.control.infrastructure.KeyEventFirer;
+import com.sun.javafx.scene.control.infrastructure.MouseEventFirer;
+//import com.sun.javafx.test.MouseEventGenerator;
+import com.sun.javafx.tk.Toolkit;
 
 /**
  * action (which can be bound, and can be null),
@@ -324,8 +339,6 @@
 
 
     @Test public void conextMenuShouldntShowOnAction() {
-        final MouseEventGenerator generator = new MouseEventGenerator();
-
         ContextMenu popupMenu = new ContextMenu();
         MenuItem item1 = new MenuItem("_About");
         popupMenu.getItems().add(item1);
@@ -341,10 +354,6 @@
         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.
@@ -354,14 +363,51 @@
 
         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();                      
+        
+        MouseEventFirer.fireMousePressed(btn);
+        MouseEventFirer.fireMouseReleased(btn);
+        MouseEventFirer.fireMouseClicked(btn);
+    }
+    
+    private int count = 0;
+    @Test public void conextMenuShouldShowOnInSomeCircumstances() {
+        ContextMenu popupMenu = new ContextMenu();
+        MenuItem item1 = new MenuItem("_About");
+        popupMenu.getItems().add(item1);
+        popupMenu.setOnShown(new EventHandler<WindowEvent>() {
+            @Override public void handle(WindowEvent w) {
+                System.out.println("popup shown");
+                count++;
+            }
+        });
+
+        btn.setContextMenu(popupMenu);
+        btn.setDefaultButton(true);
+
+        root.getChildren().add(btn);
+        show();
+        
+        btn.setOnAction(new EventHandler<ActionEvent>() {
+            @Override public void handle(ActionEvent event) {
+                fail();
+            }
+        });
+
+        assertEquals(0, count);
+        
+        /* Note that right-mouse press events don't force the popup open */
+        MouseEventFirer.fireMousePressed(btn, MouseButton.SECONDARY);
+        assertEquals(0, count);
+        
+        MouseEventFirer.fireMouseClicked(btn, MouseButton.SECONDARY);
+        assertEquals(0, count);
+        
+        MouseEventFirer.fireMouseReleased(btn, MouseButton.SECONDARY);
+        assertEquals(0, count);
+        
+        /* Only context menu events force it to appear */
+        ContextMenuEventFirer.fireContextMenuEvent(btn);
+        assertEquals(1, count);
     }
 
     static class MyButton extends Button {
@@ -427,10 +473,7 @@
 
         List<Stop> redStops3 = getStops(red);
         List<Stop> greenStops3 = getStops(green);
-System.err.println("0 = " + redStops0.toString());        
-System.err.println("1 = " + redStops1.toString());        
-System.err.println("2 = " + redStops2.toString());        
-System.err.println("3 = " + redStops3.toString());        
+
         // did red change color after red hover=true?
         assertFalse(redStops0.equals(redStops1));
         // did red change back to original color after green hover=true?
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/CheckBoxTreeItemTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -0,0 +1,630 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package javafx.scene.control;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import javafx.beans.value.ChangeListener;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.scene.control.CheckBoxTreeItem.TreeModificationEvent;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CheckBoxTreeItemTest {
+    
+    private CheckBoxTreeItem<Object> treeItem;
+    
+    private CheckBoxTreeItem<String> root;
+        private CheckBoxTreeItem<String> child1;
+        private CheckBoxTreeItem<String> child2;
+            private CheckBoxTreeItem<String> subchild1;
+            private CheckBoxTreeItem<String> subchild2;
+        private CheckBoxTreeItem<String> child3;
+    
+    @Before public void setup() {
+        treeItem = new CheckBoxTreeItem<>();
+        
+        root = new CheckBoxTreeItem<>("root");
+            child1 = new CheckBoxTreeItem<>("child1");
+            child2 = new CheckBoxTreeItem<>("child2");
+                subchild1 = new CheckBoxTreeItem<>("subchild1");
+                subchild2 = new CheckBoxTreeItem<>("subchild2");
+            child3 = new CheckBoxTreeItem<>("child3");
+            
+        child2.getChildren().addAll(subchild1, subchild2);
+        root.getChildren().addAll(child1, child2, child3);
+    }
+    
+    @After public void cleanup() {
+        treeItem = null;
+        root = null;
+        child1 = null;
+        child2 = null;
+        child3 = null;
+        subchild1 = null;
+        subchild2 = null;
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Util methods     
+     * 
+     *************************************************************************/
+    
+    private void assertIsSelected(CheckBoxTreeItem... items) {
+        for (CheckBoxTreeItem item : items) {
+            assertTrue(item.isSelected());
+        }
+    }
+    
+    private void assertIsNotSelected(CheckBoxTreeItem... items) {
+        for (CheckBoxTreeItem item : items) {
+            assertFalse(item.isSelected());
+        }
+    }
+    
+    private void assertAllChildrenSelected(CheckBoxTreeItem<?> parent) {
+        assertIsSelected(parent);
+        for (TreeItem child : parent.getChildren()) {
+            if (child instanceof CheckBoxTreeItem) {
+                assertAllChildrenSelected((CheckBoxTreeItem)child);
+            }
+        }
+    }
+    
+    private void assertAllChildrenNotSelected(CheckBoxTreeItem<?> parent) {
+        assertIsNotSelected(parent);
+        for (TreeItem child : parent.getChildren()) {
+            if (child instanceof CheckBoxTreeItem) {
+                assertAllChildrenNotSelected((CheckBoxTreeItem)child);
+            }
+        }
+    }
+    
+    private void setAllIndependent(CheckBoxTreeItem<?> parent) {
+        parent.setIndependent(true);
+        for (TreeItem child : parent.getChildren()) {
+            if (child instanceof CheckBoxTreeItem) {
+                ((CheckBoxTreeItem)child).setIndependent(true);
+            }
+        }
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests     
+     * 
+     *************************************************************************/
+
+    @Test public void testDefaultConstructor_hasNullValue() {
+        assertNull(treeItem.getValue());
+    }
+    
+    @Test public void testDefaultConstructor_hasNullGraphic() {
+        assertNull(treeItem.getGraphic());
+    }
+    
+    @Test public void testDefaultConstructor_hasNullParent() {
+        assertNull(treeItem.getParent());
+    }
+    
+    @Test public void testDefaultConstructor_hasEmptyChildren() {
+        assertNotNull(treeItem.getChildren());
+        assertTrue(treeItem.getChildren().isEmpty());
+    }
+    
+    @Test public void testDefaultConstructor_isExpandedIsTrue() {
+        assertFalse(treeItem.isExpanded());
+    }
+    
+    @Test public void testDefaultConstructor_isIndependentIsFalse() {
+        assertFalse(treeItem.isIndependent());
+    }
+    
+    @Test public void testDefaultConstructor_isIndeterminateIsFalse() {
+        assertFalse(treeItem.isIndeterminate());
+    }
+    
+    @Test public void testDefaultConstructor_isLeafIsTrue() {
+        assertTrue(treeItem.isLeaf());
+    }
+    
+    @Test public void testDefaultConstructor_isSelectedIsFalse() {
+        assertFalse(treeItem.isSelected());
+    }
+    
+    @Test public void testValueConstructor_hasNonNullValue() {
+        CheckBoxTreeItem<String> cbti = new CheckBoxTreeItem<>("TEST");
+        assertEquals("TEST", cbti.getValue());
+    }
+    
+    @Test public void testValueGraphicConstructor_hasNonNullValue() {
+        Rectangle graphic = new Rectangle(10, 10, Color.RED);
+        CheckBoxTreeItem<String> cbti = new CheckBoxTreeItem<>("TEST", graphic);
+        assertEquals("TEST", cbti.getValue());
+    }
+    
+    @Test public void testValueGraphicConstructor_hasNonNullGraphic() {
+        Rectangle graphic = new Rectangle(10, 10, Color.RED);
+        CheckBoxTreeItem<String> cbti = new CheckBoxTreeItem<>("TEST", graphic);
+        assertEquals(graphic, cbti.getGraphic());
+    }
+    
+    @Test public void testValueGraphicSelectedConstructor_isSelected() {
+        Rectangle graphic = new Rectangle(10, 10, Color.RED);
+        CheckBoxTreeItem<String> cbti = new CheckBoxTreeItem<>("TEST", graphic, true);
+        assertTrue(cbti.isSelected());
+    }
+    
+    @Test public void testValueGraphicSelectedIndependentConstructor_isIndependent() {
+        Rectangle graphic = new Rectangle(10, 10, Color.RED);
+        CheckBoxTreeItem<String> cbti = new CheckBoxTreeItem<>("TEST", graphic, true, true);
+        assertTrue(cbti.isIndependent());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Property tests     
+     * 
+     *************************************************************************/
+    
+    @Test public void testSelectedSetter() {
+        assertFalse(treeItem.isSelected());
+        treeItem.setSelected(true);
+        assertTrue(treeItem.isSelected());
+        treeItem.setSelected(false);
+        assertFalse(treeItem.isSelected());
+    }
+    
+    @Test public void testSelectedPropertySetter() {
+        assertFalse(treeItem.selectedProperty().get());
+        treeItem.selectedProperty().set(true);
+        assertTrue(treeItem.selectedProperty().get());
+        treeItem.setSelected(false);
+        assertFalse(treeItem.selectedProperty().get());
+    }
+    
+    private int selectedEventCount = 0;
+    @Test public void testSelectedPropertyEvent() {
+        treeItem.selectedProperty().addListener(new ChangeListener<Object>() {
+            public void changed(javafx.beans.value.ObservableValue<? extends Object> observable, Object oldValue, Object newValue) {
+                selectedEventCount++;
+            }
+        });
+        
+        // no event when the value is unchanged
+        treeItem.setSelected(false);
+        assertEquals(0, selectedEventCount);
+        
+        treeItem.setSelected(true);
+        assertEquals(1, selectedEventCount);
+        
+        treeItem.setSelected(false);
+        assertEquals(2, selectedEventCount);
+        
+        treeItem.setSelected(true);
+        assertEquals(3, selectedEventCount);
+    }
+    
+    
+    @Test public void testIndeterminateSetter() {
+        assertFalse(treeItem.isIndeterminate());
+        treeItem.setIndeterminate(true);
+        assertTrue(treeItem.isIndeterminate());
+        treeItem.setIndeterminate(false);
+        assertFalse(treeItem.isIndeterminate());
+    }
+    
+    @Test public void testIndeterminatePropertySetter() {
+        assertFalse(treeItem.indeterminateProperty().get());
+        treeItem.indeterminateProperty().set(true);
+        assertTrue(treeItem.indeterminateProperty().get());
+        treeItem.setIndeterminate(false);
+        assertFalse(treeItem.indeterminateProperty().get());
+    }
+    
+    private int indeterminateEventCount = 0;
+    @Test public void testIndeterminatePropertyEvent() {
+        treeItem.indeterminateProperty().addListener(new ChangeListener<Object>() {
+            public void changed(javafx.beans.value.ObservableValue<? extends Object> observable, Object oldValue, Object newValue) {
+                indeterminateEventCount++;
+            }
+        });
+        
+        // no event when the value is unchanged
+        treeItem.setIndeterminate(false);
+        assertEquals(0, indeterminateEventCount);
+        
+        treeItem.setIndeterminate(true);
+        assertEquals(1, indeterminateEventCount);
+        
+        treeItem.setIndeterminate(false);
+        assertEquals(2, indeterminateEventCount);
+        
+        treeItem.setIndeterminate(true);
+        assertEquals(3, indeterminateEventCount);
+    }
+    
+    
+    @Test public void testIndependentSetter() {
+        assertFalse(treeItem.isIndependent());
+        treeItem.setIndependent(true);
+        assertTrue(treeItem.isIndependent());
+        treeItem.setIndependent(false);
+        assertFalse(treeItem.isIndependent());
+    }
+    
+    @Test public void testIndependentPropertySetter() {
+        assertFalse(treeItem.independentProperty().get());
+        treeItem.independentProperty().set(true);
+        assertTrue(treeItem.independentProperty().get());
+        treeItem.setIndependent(false);
+        assertFalse(treeItem.independentProperty().get());
+    }
+    
+    private int independentEventCount = 0;
+    @Test public void testIndependentPropertyEvent() {
+        treeItem.independentProperty().addListener(new ChangeListener<Object>() {
+            public void changed(javafx.beans.value.ObservableValue<? extends Object> observable, Object oldValue, Object newValue) {
+                independentEventCount++;
+            }
+        });
+        
+        // no event when the value is unchanged
+        treeItem.setIndependent(false);
+        assertEquals(0, independentEventCount);
+        
+        treeItem.setIndependent(true);
+        assertEquals(1, independentEventCount);
+        
+        treeItem.setIndependent(false);
+        assertEquals(2, independentEventCount);
+        
+        treeItem.setIndependent(true);
+        assertEquals(3, independentEventCount);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Non-independent CheckBoxTreeItem tests      
+     * 
+     *************************************************************************/
+    
+    @Test public void testNonIndependent_updateRootSelected() {
+        assertAllChildrenNotSelected(root);
+        
+        root.setSelected(true);
+        assertAllChildrenSelected(root);
+        assertFalse(root.isIndeterminate());
+        
+        root.setSelected(false);
+        assertAllChildrenNotSelected(root);
+        assertFalse(root.isIndeterminate());
+    }
+    
+    @Test public void testNonIndependent_updateChild1Selected() {
+        assertAllChildrenNotSelected(root);
+        
+        child1.setSelected(true);
+        assertIsSelected(child1);
+        
+        assertIsNotSelected(root);
+        assertAllChildrenNotSelected(child2);
+        assertAllChildrenNotSelected(child3);
+        
+        assertTrue(root.isIndeterminate());
+        assertFalse(child2.isIndeterminate());
+        assertFalse(child3.isIndeterminate());
+    }
+    
+    @Test public void testNonIndependent_updateChild2Selected() {
+        assertAllChildrenNotSelected(root);
+        
+        child2.setSelected(true);
+        
+        assertIsNotSelected(root);
+        assertAllChildrenSelected(child2);
+        assertAllChildrenNotSelected(child3);
+        
+        assertTrue(root.isIndeterminate());
+        assertFalse(child1.isIndeterminate());
+        assertFalse(child2.isIndeterminate());
+        assertFalse(child3.isIndeterminate());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Independent CheckBoxTreeItem tests      
+     * 
+     *************************************************************************/
+    
+    @Test public void testIndependent_updateRootSelected() {
+        setAllIndependent(root);
+        assertAllChildrenNotSelected(root);
+        
+        root.setSelected(true);
+        assertTrue(root.isSelected());
+        assertFalse(child1.isSelected());
+        assertFalse(child2.isSelected());
+        assertFalse(subchild1.isSelected());
+        assertFalse(subchild2.isSelected());
+        assertFalse(child3.isSelected());
+        assertFalse(root.isIndeterminate());
+        
+        root.setSelected(false);
+        assertAllChildrenNotSelected(root);
+        assertFalse(root.isIndeterminate());
+    }
+    
+    @Test public void testIndependent_updateChild1Selected() {
+        setAllIndependent(root);
+        assertAllChildrenNotSelected(root);
+        
+        child1.setSelected(true);
+        assertIsSelected(child1);
+        
+        assertIsNotSelected(root);
+        assertAllChildrenNotSelected(child2);
+        assertAllChildrenNotSelected(child3);
+        
+        assertFalse(root.isIndeterminate());
+        assertFalse(child2.isIndeterminate());
+        assertFalse(child3.isIndeterminate());
+    }
+    
+    @Test public void testIndependent_updateChild2Selected() {
+        setAllIndependent(root);
+        assertAllChildrenNotSelected(root);
+        
+        child2.setSelected(true);
+        
+        assertIsNotSelected(root);
+        assertTrue(child2.isSelected());
+        assertFalse(subchild1.isSelected());
+        assertFalse(subchild2.isSelected());
+        assertAllChildrenNotSelected(child3);
+        
+        assertFalse(root.isIndeterminate());
+        assertFalse(child1.isIndeterminate());
+        assertFalse(child2.isIndeterminate());
+        assertFalse(child3.isIndeterminate());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Indeterminate CheckBoxTreeItem tests      
+     * 
+     *************************************************************************/
+    
+    @Test public void testIndeterminate_onRootNode() {
+        assertFalse(child1.isIndeterminate());
+        assertFalse(root.isIndependent());
+        
+        root.setIndeterminate(true);
+        assertTrue(root.isIndeterminate());
+        assertFalse(child1.isIndeterminate());
+        assertFalse(child2.isIndeterminate());
+        assertFalse(subchild1.isIndeterminate());
+        assertFalse(subchild2.isIndeterminate());
+        assertFalse(child3.isIndeterminate());
+    }
+    
+    @Test public void testIndeterminate_onChild1Node() {
+        assertFalse(child1.isIndeterminate());
+        
+        child1.setIndeterminate(true);
+        assertTrue(root.isIndeterminate());
+        assertTrue(child1.isIndeterminate());
+        assertFalse(child2.isIndeterminate());
+        assertFalse(subchild1.isIndeterminate());
+        assertFalse(subchild2.isIndeterminate());
+        assertFalse(child3.isIndeterminate());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * TreeModificationEvent tests      
+     * 
+     *************************************************************************/
+    
+    private int eventCount = 0;
+    @Test public void testTreeModificationEvent_child1_onSelectionChanged() {
+        assertEquals(0, eventCount);
+        child1.addEventHandler(CheckBoxTreeItem.<String>checkBoxSelectionChangedEvent(), new EventHandler<TreeModificationEvent<String>>() {
+            public void handle(TreeModificationEvent<String> event) {
+                eventCount++;
+                
+                assertTrue(event.wasSelectionChanged());
+                assertFalse(event.wasIndeterminateChanged());
+                assertEquals(child1, event.getTreeItem());
+            }
+        });
+        
+        child1.setSelected(true);
+        assertEquals(1, eventCount);
+    }
+    
+    @Test public void testTreeModificationEvent_child1_onSelectionChangedAgain() {
+        assertEquals(0, eventCount);
+        child1.addEventHandler(CheckBoxTreeItem.<String>checkBoxSelectionChangedEvent(), new EventHandler<TreeModificationEvent<String>>() {
+            public void handle(TreeModificationEvent<String> event) {
+                eventCount++;
+                
+                assertTrue(event.wasSelectionChanged());
+                assertFalse(event.wasIndeterminateChanged());
+                assertEquals(child1, event.getTreeItem());
+            }
+        });
+        
+        child1.setSelected(true);
+        assertEquals(1, eventCount);
+        
+        // shouldn't increment when changed to same value
+        child1.setSelected(true);
+        assertEquals(1, eventCount);
+        
+        // shouldn't increment when the root is changed and we are watching the child1
+        root.setSelected(true);
+        assertEquals(1, eventCount);
+    }
+    
+    @Test public void testTreeModificationEvent_child1_onSelectionChangedOnRootWhenChild1IsSelected() {
+        assertEquals(0, eventCount);
+        child1.addEventHandler(CheckBoxTreeItem.<String>checkBoxSelectionChangedEvent(), new EventHandler<TreeModificationEvent<String>>() {
+            public void handle(TreeModificationEvent<String> event) {
+                eventCount++;
+                
+                assertTrue(event.wasSelectionChanged());
+                assertFalse(event.wasIndeterminateChanged());
+                assertEquals(child1, event.getTreeItem());
+            }
+        });
+        
+        child1.setSelected(true);
+        assertEquals(1, eventCount);
+        
+        // shouldn't increment when the root is changed and we are watching the child1
+        root.setSelected(true);
+        assertEquals(1, eventCount);
+    }
+    
+    @Test public void testTreeModificationEvent_child1_onSelectionChangedOnRootWhenChild1IsNotSelected() {
+        assertEquals(0, eventCount);
+        child1.addEventHandler(CheckBoxTreeItem.<String>checkBoxSelectionChangedEvent(), new EventHandler<TreeModificationEvent<String>>() {
+            public void handle(TreeModificationEvent<String> event) {
+                eventCount++;
+                
+                assertTrue(event.wasSelectionChanged());
+                assertFalse(event.wasIndeterminateChanged());
+                assertEquals(child1, event.getTreeItem());
+            }
+        });
+        
+        // should increment when the root is changed and the child1 is unselected
+        root.setSelected(true);
+        assertEquals(1, eventCount);
+        
+        child1.setSelected(false);
+        assertEquals(2, eventCount);
+    }
+    
+    
+    
+    
+    @Test public void testTreeModificationEvent_child1_onIndeterminateChanged() {
+        assertEquals(0, eventCount);
+        child1.addEventHandler(CheckBoxTreeItem.<String>checkBoxSelectionChangedEvent(), new EventHandler<TreeModificationEvent<String>>() {
+            public void handle(TreeModificationEvent<String> event) {
+                eventCount++;
+                
+                assertFalse(event.wasSelectionChanged());
+                assertTrue(event.wasIndeterminateChanged());
+                assertEquals(child1, event.getTreeItem());
+            }
+        });
+        
+        child1.setIndeterminate(true);
+        assertEquals(1, eventCount);
+    }
+    
+    @Test public void testTreeModificationEvent_child1_onIndeterminateChangedAgain() {
+        assertEquals(0, eventCount);
+        child1.addEventHandler(CheckBoxTreeItem.<String>checkBoxSelectionChangedEvent(), new EventHandler<TreeModificationEvent<String>>() {
+            public void handle(TreeModificationEvent<String> event) {
+                eventCount++;
+                
+                assertFalse(event.wasSelectionChanged());
+                assertTrue(event.wasIndeterminateChanged());
+                assertEquals(child1, event.getTreeItem());
+            }
+        });
+        
+        child1.setIndeterminate(true);
+        assertEquals(1, eventCount);
+        
+        // shouldn't increment when changed to same value
+        child1.setIndeterminate(true);
+        assertEquals(1, eventCount);
+        
+        // shouldn't increment when the root is changed and we are watching the child1
+        root.setIndeterminate(true);
+        assertEquals(1, eventCount);
+    }
+    
+    @Test public void testTreeModificationEvent_child1_onIndeterminateChangedOnRootWhenChild1IsIndeterminate() {
+        assertEquals(0, eventCount);
+        child1.addEventHandler(CheckBoxTreeItem.<String>checkBoxSelectionChangedEvent(), new EventHandler<TreeModificationEvent<String>>() {
+            public void handle(TreeModificationEvent<String> event) {
+                eventCount++;
+                
+                assertFalse(event.wasSelectionChanged());
+                assertTrue(event.wasIndeterminateChanged());
+                assertEquals(child1, event.getTreeItem());
+            }
+        });
+        
+        child1.setIndeterminate(true);
+        assertEquals(1, eventCount);
+        
+        // shouldn't increment when the root is changed and we are watching the child1
+        root.setIndeterminate(true);
+        assertEquals(1, eventCount);
+    }
+    
+    @Test public void testTreeModificationEvent_child1_onIndeterminateChangedOnRootWhenChild1IsNotIndeterminate() {
+        assertEquals(0, eventCount);
+        child1.addEventHandler(CheckBoxTreeItem.<String>checkBoxSelectionChangedEvent(), new EventHandler<TreeModificationEvent<String>>() {
+            public void handle(TreeModificationEvent<String> event) {
+                eventCount++;
+                
+                assertFalse(event.wasSelectionChanged());
+                assertTrue(event.wasIndeterminateChanged());
+                assertEquals(child1, event.getTreeItem());
+            }
+        });
+        
+        root.setIndeterminate(true);
+        assertEquals(0, eventCount);
+        
+        child1.setIndeterminate(true);
+        assertEquals(1, eventCount);
+    }
+}
--- a/javafx-ui-controls/test/javafx/scene/control/ColorPickerTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/ColorPickerTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -29,25 +29,32 @@
  * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
  */
 
+import static javafx.scene.control.ControlTestUtils.assertStyleClassContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
 import javafx.scene.Scene;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.GridPane;
 import javafx.scene.layout.VBox;
 import javafx.scene.paint.Color;
 import javafx.stage.Stage;
-import static org.junit.Assert.*;
-import static javafx.scene.control.ControlTestUtils.assertStyleClassContains;
+
+import org.junit.Before;
+import org.junit.Test;
+
 import com.sun.javafx.pgstub.StubToolkit;
+import com.sun.javafx.scene.control.infrastructure.KeyEventFirer;
+import com.sun.javafx.scene.control.infrastructure.MouseEventGenerator;
 import com.sun.javafx.scene.control.skin.ColorPalette;
 import com.sun.javafx.scene.control.skin.ColorPickerPaletteRetriever;
 import com.sun.javafx.scene.control.skin.ColorPickerSkin;
 import com.sun.javafx.tk.Toolkit;
-import javafx.event.ActionEvent;
-import javafx.event.EventHandler;
-import javafx.scene.input.KeyCode;
-import javafx.scene.input.MouseEvent;
-import javafx.scene.layout.GridPane;
-
-import org.junit.Before;
-import org.junit.Test;
 
 public class ColorPickerTest {
     private ColorPicker colorPicker;
--- a/javafx-ui-controls/test/javafx/scene/control/KeyEventFirer.java	Tue Mar 19 10:22:16 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javafx.scene.control;
-
-import java.util.Arrays;
-import java.util.List;
-import javafx.event.EventType;
-import javafx.scene.input.KeyCode;
-import javafx.scene.input.KeyEvent;
-import javafx.event.Event;
-import javafx.event.EventTarget;
-
-
-public class KeyEventFirer {
-    
-    private final EventTarget target;
-    
-    public KeyEventFirer(EventTarget target) {
-        this.target = target;
-    }
-    
-    public void doUpArrowPress(KeyModifier... modifiers) {
-        doKeyPress(KeyCode.UP, modifiers);
-    }
-    
-    public void doDownArrowPress(KeyModifier... modifiers) {
-        doKeyPress(KeyCode.DOWN, modifiers);
-    }
-    
-    public void doLeftArrowPress(KeyModifier... modifiers) {
-        doKeyPress(KeyCode.LEFT, modifiers);
-    }
-    
-    public void doRightArrowPress(KeyModifier... modifiers) {
-        doKeyPress(KeyCode.RIGHT, modifiers);
-    }
-    
-    public void doKeyPress(KeyCode keyCode, KeyModifier... modifiers) {
-        fireEvents(createMirroredEvents(keyCode, modifiers));
-    }
-    
-    private void fireEvents(KeyEvent... events) {
-        for (KeyEvent evt : events) {
-            Event.fireEvent(target, evt);
-        }
-    }
-    
-    private KeyEvent[] createMirroredEvents(KeyCode keyCode, KeyModifier... modifiers) {
-        KeyEvent[] events = new KeyEvent[2];
-        events[0] = createEvent(keyCode, KeyEvent.KEY_PRESSED, modifiers);
-        events[1] = createEvent(keyCode, KeyEvent.KEY_RELEASED, modifiers);
-        return events;
-    }
-    
-    private KeyEvent createEvent(KeyCode keyCode, EventType<KeyEvent> evtType, KeyModifier... modifiers) {
-        List<KeyModifier> ml = Arrays.asList(modifiers);
-
-        return new KeyEvent( null,
-                target, // EventTarget
-                evtType,  // eventType
-                null,     // Character (unused unless KeyCode == KEY_TYPED
-                null,     // text
-                keyCode, // KeyCode
-                ml.contains(KeyModifier.SHIFT),    // shiftDown
-                ml.contains(KeyModifier.CTRL),     // ctrlDown
-                ml.contains(KeyModifier.ALT),      // altDown
-                ml.contains(KeyModifier.META)      // metaData
-                ); 
-    }
-}
--- a/javafx-ui-controls/test/javafx/scene/control/KeyModifier.java	Tue Mar 19 10:22:16 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javafx.scene.control;
-
-import com.sun.javafx.Utils;
-import com.sun.javafx.pgstub.StubToolkit;
-import com.sun.javafx.scene.control.behavior.KeyBinding;
-import com.sun.javafx.tk.Toolkit;
-import javafx.scene.input.KeyCode;
-
-public enum KeyModifier {
-    SHIFT,
-    CTRL,
-    ALT,
-    META;
-    
-    public static KeyModifier getShortcutKey() {
-        // The StubToolkit doesn't know what the platform shortcut key is, so 
-        // we have to tell it here (and lets not be cute about optimising this
-        // code as we need the platform shortcut key to be known elsewhere in the
-        // code base for keyboard navigation tests to work accurately).
-        if (Toolkit.getToolkit() instanceof StubToolkit) {
-            ((StubToolkit)Toolkit.getToolkit()).setPlatformShortcutKey(Utils.isMac() ? KeyCode.META : KeyCode.CONTROL);
-        } 
-        
-        switch (Toolkit.getToolkit().getPlatformShortcutKey()) {
-            case SHIFT:
-                return SHIFT;
-
-            case CONTROL:
-                return CTRL;
-
-            case ALT:
-                return ALT;
-
-            case META:
-                return META;
-
-            default:
-                return null;
-        }
-    }
-}
--- a/javafx-ui-controls/test/javafx/scene/control/ListViewKeyInputTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/ListViewKeyInputTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -27,6 +27,9 @@
 
 import com.sun.javafx.Utils;
 import com.sun.javafx.scene.control.behavior.ListViewAnchorRetriever;
+import com.sun.javafx.scene.control.infrastructure.KeyEventFirer;
+import com.sun.javafx.scene.control.infrastructure.KeyModifier;
+
 import static org.junit.Assert.*;
 
 import java.util.List;
@@ -1057,7 +1060,6 @@
         assertTrue(isSelected(0,1,2,3,4,5));
     }
     
-    @Ignore("Bug not yet fixed")
     @Test public void test_rt28065() {
         sm.setSelectionMode(SelectionMode.MULTIPLE);
         listView.getItems().setAll("Apple", "Orange", "Banana");
--- a/javafx-ui-controls/test/javafx/scene/control/MenuBarTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/MenuBarTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -25,27 +25,30 @@
 
 package javafx.scene.control;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.scene.Node;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+
+import org.junit.Before;
+import org.junit.Test;
+
 import com.sun.javafx.pgstub.StubToolkit;
+import com.sun.javafx.scene.control.infrastructure.KeyEventFirer;
+import com.sun.javafx.scene.control.infrastructure.MouseEventGenerator;
 import com.sun.javafx.scene.control.skin.ContextMenuContent;
 import com.sun.javafx.scene.control.skin.MenuBarMenuButtonRetriever;
 import com.sun.javafx.scene.control.skin.MenuBarSkin;
 import com.sun.javafx.tk.Toolkit;
-import javafx.event.Event;
-import javafx.event.EventHandler;
-import javafx.scene.Parent;
-import javafx.scene.Scene;
-import javafx.scene.input.MouseEvent;
-import javafx.scene.layout.AnchorPane;
-import javafx.stage.Stage;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
-import javafx.scene.Node;
-import javafx.scene.input.KeyCode;
-import javafx.scene.layout.VBox;
-
-import org.junit.Before;
-import org.junit.Test;
 
 
 /**
@@ -300,7 +303,6 @@
     }
     
     @Test public void testKeyNavigationWithDisabledMenuItem() {
-        final MouseEventGenerator generator = new MouseEventGenerator();
         VBox root = new VBox();
         Menu menu1 = new Menu("Menu1");
         Menu menu2 = new Menu("Menu2");
@@ -330,9 +332,9 @@
         MenuButton mb = MenuBarMenuButtonRetriever.getNodeForMenu(skin, 0);
         mb.getScene().getWindow().requestFocus();
         scene.impl_processMouseEvent(
-            generator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, xval+20, yval+20));
+            MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, xval+20, yval+20));
         scene.impl_processMouseEvent(
-            generator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, xval+20, yval+20));
+            MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, xval+20, yval+20));
         assertTrue(menu1.isShowing());
         
         KeyEventFirer keyboard = new KeyEventFirer(mb.getScene());
@@ -343,7 +345,6 @@
     
     
      @Test public void testMenuOnShowingEventFiringWithMenuHideOperation() {
-        final MouseEventGenerator generator = new MouseEventGenerator();
         VBox root = new VBox();
         Menu menu = new Menu("Menu");
 
@@ -379,34 +380,18 @@
         assertTrue(mb.isFocused());
         // click on menu to show 
         scene.impl_processMouseEvent(
-            generator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, xval+20, yval+20));
+            MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, xval+20, yval+20));
         scene.impl_processMouseEvent(
-            generator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, xval+20, yval+20));
+            MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, xval+20, yval+20));
         tk.firePulse(); 
         assertEquals(menu.showingProperty().get(), true);
         click = false;
         // click on menu to hide
         scene.impl_processMouseEvent(
-            generator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, xval+20, yval+20));
+            MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, xval+20, yval+20));
         scene.impl_processMouseEvent(
-            generator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, xval+20, yval+20));
+            MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, xval+20, yval+20));
         tk.firePulse(); 
         assertEquals(menu.showingProperty().get(), false);
     }
-    
-//    static final class MouseEventTracker {
-//        private Node node;
-//        
-//        public MouseEventTracker(final Node node) {
-//            this.node = node;
-//            
-//            node.setOnMouseClicked(new EventHandler<MouseEvent>() {
-//                @Override
-//                public void handle(MouseEvent t) {
-//                    // println here to check if node received mouse event
-//                }
-//            });
-//        }
-//    }
-
 }
--- a/javafx-ui-controls/test/javafx/scene/control/MenuItemTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/MenuItemTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -62,7 +62,7 @@
     private MenuItem menuItem;
 
     @BeforeClass public static void classSetup() {
-        eventType = new EventType<Event>(Event.ANY, "ON_EVENT");
+        eventType = new EventType<Event>(Event.ANY, "TEST_EVENT");
     }
 
     @Before public void setup() {
--- a/javafx-ui-controls/test/javafx/scene/control/MouseEventGenerator.java	Tue Mar 19 10:22:16 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javafx.scene.control;
-
-import javafx.event.EventType;
-import javafx.scene.input.MouseButton;
-import javafx.scene.input.MouseEvent;
-
-public final class MouseEventGenerator {
-    private static boolean primaryButtonDown = false;
-
-    public static MouseEvent generateMouseEvent(EventType<MouseEvent> type,
-            double x, double y) {
-
-        MouseButton button = MouseButton.NONE;
-        if (type == MouseEvent.MOUSE_PRESSED ||
-                type == MouseEvent.MOUSE_RELEASED ||
-                type == MouseEvent.MOUSE_DRAGGED) {
-            button = MouseButton.PRIMARY;
-        }
-
-        if (type == MouseEvent.MOUSE_PRESSED ||
-                type == MouseEvent.MOUSE_DRAGGED) {
-            primaryButtonDown = true;
-        }
-
-        if (type == MouseEvent.MOUSE_RELEASED) {
-            primaryButtonDown = false;
-        }
-
-        MouseEvent event = MouseEvent.impl_mouseEvent(x, y, x, y, button,
-                1, false, false, false, false, false, primaryButtonDown,
-                false, false, false, type);
-
-        return event;
-    }    
-}    
--- a/javafx-ui-controls/test/javafx/scene/control/MultipleSelectionModelImplTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/MultipleSelectionModelImplTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -738,7 +738,7 @@
     
     private int rt_28615_row_1_hit_count = 0;
     private int rt_28615_row_2_hit_count = 0;
-    @Ignore @Test public void test_rt_28615() {
+    @Test public void test_rt_28615() {
         msModel().setSelectionMode(SelectionMode.MULTIPLE);
 
         msModel().getSelectedItems().addListener(new ListChangeListener<Object>() {
--- a/javafx-ui-controls/test/javafx/scene/control/PaginationTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/PaginationTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -25,15 +25,18 @@
 
 package javafx.scene.control;
 
-import javafx.css.CssMetaData;
-import com.sun.javafx.pgstub.StubToolkit;
-import static javafx.scene.control.ControlTestUtils.*;
-import javafx.scene.control.Pagination;
-import com.sun.javafx.tk.Toolkit;
+import static javafx.scene.control.ControlTestUtils.assertStyleClassContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import javafx.beans.property.IntegerProperty;
 import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.SimpleIntegerProperty;
 import javafx.beans.property.SimpleObjectProperty;
+import javafx.css.CssMetaData;
 import javafx.css.StyleableProperty;
 import javafx.scene.Node;
 import javafx.scene.Scene;
@@ -42,13 +45,16 @@
 import javafx.scene.layout.VBox;
 import javafx.stage.Stage;
 import javafx.util.Callback;
-import static org.junit.Assert.*;
-
 
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 
+import com.sun.javafx.pgstub.StubToolkit;
+import com.sun.javafx.scene.control.infrastructure.KeyEventFirer;
+import com.sun.javafx.scene.control.infrastructure.MouseEventGenerator;
+import com.sun.javafx.tk.Toolkit;
+
 public class PaginationTest {
     private Pagination pagination;
     private Toolkit tk;
--- a/javafx-ui-controls/test/javafx/scene/control/TabPaneTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/TabPaneTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -25,12 +25,15 @@
 
 package javafx.scene.control;
 
-import javafx.css.CssMetaData;
-import static javafx.scene.control.ControlTestUtils.*;
-import com.sun.javafx.pgstub.StubToolkit;
-import com.sun.javafx.scene.control.skin.TabPaneSkin;
-import com.sun.javafx.scene.input.KeyCodeMap;
-import com.sun.javafx.tk.Toolkit;
+import static javafx.scene.control.ControlTestUtils.assertPseudoClassDoesNotExist;
+import static javafx.scene.control.ControlTestUtils.assertPseudoClassExists;
+import static javafx.scene.control.ControlTestUtils.assertStyleClassContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
 import javafx.application.Platform;
 import javafx.beans.property.BooleanProperty;
 import javafx.beans.property.DoubleProperty;
@@ -40,6 +43,7 @@
 import javafx.beans.property.SimpleObjectProperty;
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
+import javafx.css.CssMetaData;
 import javafx.css.StyleableProperty;
 import javafx.event.Event;
 import javafx.event.EventHandler;
@@ -52,13 +56,18 @@
 import javafx.scene.layout.StackPane;
 import javafx.scene.layout.VBox;
 import javafx.stage.Stage;
-import static org.junit.Assert.*;
-
 
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 
+import com.sun.javafx.pgstub.StubToolkit;
+import com.sun.javafx.scene.control.infrastructure.KeyEventFirer;
+import com.sun.javafx.scene.control.infrastructure.MouseEventGenerator;
+import com.sun.javafx.scene.control.skin.TabPaneSkin;
+import com.sun.javafx.scene.input.KeyCodeMap;
+import com.sun.javafx.tk.Toolkit;
+
 /**
  *
  * @author srikalyc
--- a/javafx-ui-controls/test/javafx/scene/control/TableViewKeyInputTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/TableViewKeyInputTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -28,6 +28,9 @@
 import com.sun.javafx.Utils;
 import com.sun.javafx.scene.control.behavior.ListViewAnchorRetriever;
 import com.sun.javafx.scene.control.behavior.TableViewAnchorRetriever;
+import com.sun.javafx.scene.control.infrastructure.KeyEventFirer;
+import com.sun.javafx.scene.control.infrastructure.KeyModifier;
+
 import static org.junit.Assert.*;
 
 import java.util.List;
@@ -1670,7 +1673,6 @@
         assertTrue(isSelected(0,1,2,3,4,5));
     }
     
-    @Ignore("Bug not yet fixed")
     @Test public void test_rt28065() {
         sm.setSelectionMode(SelectionMode.MULTIPLE);
         tableView.getItems().setAll("Apple", "Orange", "Banana");
--- a/javafx-ui-controls/test/javafx/scene/control/TitledPaneTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/TitledPaneTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -25,32 +25,38 @@
 
 package javafx.scene.control;
 
-import javafx.css.CssMetaData;
-import static javafx.scene.control.ControlTestUtils.*;
-import com.sun.javafx.pgstub.StubToolkit;
-import com.sun.javafx.scene.control.skin.TitledPaneSkin;
-import com.sun.javafx.tk.Toolkit;
+import static javafx.scene.control.ControlTestUtils.assertPseudoClassDoesNotExist;
+import static javafx.scene.control.ControlTestUtils.assertPseudoClassExists;
+import static javafx.scene.control.ControlTestUtils.assertStyleClassContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
 import javafx.beans.property.BooleanProperty;
 import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.SimpleBooleanProperty;
 import javafx.beans.property.SimpleObjectProperty;
+import javafx.css.CssMetaData;
 import javafx.css.StyleableProperty;
-import javafx.event.EventType;
 import javafx.geometry.Pos;
 import javafx.scene.Node;
 import javafx.scene.Scene;
 import javafx.scene.input.KeyCode;
-import javafx.scene.input.MouseButton;
 import javafx.scene.input.MouseEvent;
 import javafx.scene.layout.StackPane;
 import javafx.scene.shape.Rectangle;
 import javafx.stage.Stage;
-import static org.junit.Assert.*;
-
 
 import org.junit.Before;
 import org.junit.Test;
 
+import com.sun.javafx.pgstub.StubToolkit;
+import com.sun.javafx.scene.control.infrastructure.KeyEventFirer;
+import com.sun.javafx.scene.control.infrastructure.MouseEventGenerator;
+import com.sun.javafx.scene.control.skin.TitledPaneSkin;
+import com.sun.javafx.tk.Toolkit;
+
 /**
  *
  * @author srikalyc
--- a/javafx-ui-controls/test/javafx/scene/control/TreeTableViewKeyInputTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/TreeTableViewKeyInputTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -27,6 +27,9 @@
 
 import com.sun.javafx.Utils;
 import com.sun.javafx.scene.control.behavior.TreeTableViewAnchorRetriever;
+import com.sun.javafx.scene.control.infrastructure.KeyEventFirer;
+import com.sun.javafx.scene.control.infrastructure.KeyModifier;
+
 import static org.junit.Assert.*;
 
 import java.util.List;
@@ -2222,7 +2225,6 @@
         assertTrue(isSelected(0,1,2,3,4,5));
     } 
     
-    @Ignore("Bug not yet fixed")
     @Test public void test_rt28065() {
         sm.setSelectionMode(SelectionMode.MULTIPLE);
         
--- a/javafx-ui-controls/test/javafx/scene/control/TreeViewKeyInputTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/TreeViewKeyInputTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -27,6 +27,9 @@
 
 import com.sun.javafx.Utils;
 import com.sun.javafx.scene.control.behavior.TreeViewAnchorRetriever;
+import com.sun.javafx.scene.control.infrastructure.KeyEventFirer;
+import com.sun.javafx.scene.control.infrastructure.KeyModifier;
+
 import static org.junit.Assert.*;
 
 import java.util.List;
@@ -1225,7 +1228,6 @@
         assertTrue(isSelected(0,1,2,3,4,5));
     }
     
-    @Ignore("Bug not yet fixed")
     @Test public void test_rt28065() {
         sm.setSelectionMode(SelectionMode.MULTIPLE);
         
--- a/javafx-ui-controls/test/javafx/scene/control/TreeViewTest.java	Tue Mar 19 10:22:16 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/TreeViewTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -47,10 +47,12 @@
 import javafx.collections.FXCollections;
 import javafx.collections.ObservableList;
 import javafx.scene.Group;
+import javafx.scene.Node;
 import javafx.scene.Scene;
 import javafx.scene.control.cell.PropertyValueFactory;
 import javafx.scene.layout.VBox;
 import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
 import javafx.stage.Stage;
 import javafx.util.Callback;
 
@@ -790,4 +792,34 @@
         assertEquals((Object)s2, treeView.getSelectionModel().getSelectedItems().get(0));
         assertEquals(0, treeView.getSelectionModel().getSelectedIndex());
     }
+    
+    @Ignore("Test passes from within IDE but not when run from command line. Needs more investigation.")
+    @Test public void test_rt28678() {
+        TreeItem<String> s1, s2, s3, s4;
+        ObservableList<TreeItem<String>> items = FXCollections.observableArrayList(
+                s1 = new TreeItem<String>("String1"), 
+                s2 = new TreeItem<String>("String2"), 
+                s3 = new TreeItem<String>("String3"), 
+                s4 = new TreeItem<String>("String4"));
+        
+        final TreeView<String> treeView = new TreeView<String>();
+        
+        TreeItem<String> root = new TreeItem<String>("Root");
+        root.setExpanded(true);
+        treeView.setRoot(root);
+        treeView.setShowRoot(false);
+        root.getChildren().addAll(items);
+        
+        Node graphic = new Circle(6, Color.RED);
+        
+        assertNull(s2.getGraphic());
+        TreeCell s2Cell = (TreeCell) ControlAsserts.getCell(treeView, 1);
+        assertNull(s2Cell.getGraphic());
+        
+        s2.setGraphic(graphic);
+        Toolkit.getToolkit().firePulse();
+                
+        assertEquals(graphic, s2.getGraphic());
+        assertEquals(graphic, s2Cell.getGraphic());
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/CheckBoxListCellTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javafx.scene.control.cell;
+
+import static org.junit.Assert.*;
+import javafx.beans.property.ReadOnlyBooleanWrapper;
+import javafx.beans.property.ReadOnlyObjectWrapper;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.util.Callback;
+import javafx.util.StringConverter;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class CheckBoxListCellTest {
+    
+    private SimpleBooleanProperty booleanProperty;
+    private Callback<Object, ObservableValue<Boolean>> callback;
+    private StringConverter<Object> converter;
+    
+    @Before public void setup() {
+        booleanProperty = new SimpleBooleanProperty(false);
+        callback = new Callback<Object, ObservableValue<Boolean>>() {
+            public ObservableValue<Boolean> call(Object param) {
+                return booleanProperty;
+            }
+        };
+        converter = new StringConverter<Object>() {
+            @Override public String toString(Object object) {
+                return null;
+            }
+            
+            @Override public Object fromString(String string) {
+                return null;
+            }
+        };
+    }
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<ListView<T>, ListCell<T>> forListView(
+     *       final Callback<T, ObservableValue<Boolean>> getSelectedProperty)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forListView_callback_ensureCellFactoryIsNotNull() {
+        assertFalse(booleanProperty.get());
+        Callback<ListView<Object>, ListCell<Object>> cellFactory = CheckBoxListCell.forListView(callback);
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forListView_callback_ensureCellFactoryCreatesCells() {
+        assertFalse(booleanProperty.get());
+        Callback<ListView<Object>, ListCell<Object>> cellFactory = CheckBoxListCell.forListView(callback);
+        
+        ListView<Object> listView = new ListView<>();
+        CheckBoxListCell<Object> cell = (CheckBoxListCell<Object>)cellFactory.call(listView);
+        assertNotNull(cell);
+    }
+    
+    @Test public void testStatic_forListView_callback_ensureCellHasNonNullSelectedStateCallback() {
+        assertFalse(booleanProperty.get());
+        Callback<ListView<Object>, ListCell<Object>> cellFactory = CheckBoxListCell.forListView(callback);
+        
+        ListView<Object> listView = new ListView<>();
+        CheckBoxListCell<Object> cell = (CheckBoxListCell<Object>)cellFactory.call(listView);
+        assertNotNull(cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testStatic_forListView_callback_ensureCellHasNonNullStringConverter() {
+        assertFalse(booleanProperty.get());
+        Callback<ListView<Object>, ListCell<Object>> cellFactory = CheckBoxListCell.forListView(callback);
+        
+        ListView<Object> listView = new ListView<>();
+        CheckBoxListCell<Object> cell = (CheckBoxListCell<Object>)cellFactory.call(listView);
+        assertNotNull(cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<ListView<T>, ListCell<T>> forListView(
+     *       final Callback<T, ObservableValue<Boolean>> getSelectedProperty, 
+     *       final StringConverter<T> converter)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forListView_callback_2_ensureCellFactoryIsNotNull() {
+        assertFalse(booleanProperty.get());
+        Callback<ListView<Object>, ListCell<Object>> cellFactory = CheckBoxListCell.forListView(callback, converter);
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forListView_callback_2_ensureCellFactoryCreatesCells() {
+        assertFalse(booleanProperty.get());
+        Callback<ListView<Object>, ListCell<Object>> cellFactory = CheckBoxListCell.forListView(callback, converter);
+        
+        ListView<Object> listView = new ListView<>();
+        CheckBoxListCell<Object> cell = (CheckBoxListCell<Object>)cellFactory.call(listView);
+        assertNotNull(cell);
+    }
+    
+    @Test public void testStatic_forListView_callback_2_ensureCellHasNonNullSelectedStateCallback() {
+        assertFalse(booleanProperty.get());
+        Callback<ListView<Object>, ListCell<Object>> cellFactory = CheckBoxListCell.forListView(callback, converter);
+        
+        ListView<Object> listView = new ListView<>();
+        CheckBoxListCell<Object> cell = (CheckBoxListCell<Object>)cellFactory.call(listView);
+        assertNotNull(cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testStatic_forListView_callback_2_ensureCellHasSetStringConverter() {
+        assertFalse(booleanProperty.get());
+        Callback<ListView<Object>, ListCell<Object>> cellFactory = CheckBoxListCell.forListView(callback, converter);
+        
+        ListView<Object> listView = new ListView<>();
+        CheckBoxListCell<Object> cell = (CheckBoxListCell<Object>)cellFactory.call(listView);
+        assertNotNull(cell.getConverter());
+        assertEquals(converter, cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testConstructor_noArgs_defaultCallbackIsNull() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>();
+        assertNull(cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNotNull() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>();
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>();
+        assertTrue(cell.getStyleClass().contains("check-box-list-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsACheckBox() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>();
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for one-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_getSelectedProperty_selectedPropertyIsNotNull() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>(callback);
+        assertEquals(callback, cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_defaultStringConverterIsNotNull() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>(callback);
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_defaultStyleClass() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>(callback);
+        assertTrue(cell.getStyleClass().contains("check-box-list-cell"));
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_defaultGraphicIsACheckBox() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>(callback);
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for two-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_getSelectedProperty_converter_selectedPropertyIsNotNull() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>(callback, converter);
+        assertEquals(callback, cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_converter_defaultStringConverterIsNotNull() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>(callback, converter);
+        assertNotNull(cell.getConverter());
+        assertEquals(converter, cell.getConverter());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_converter_defaultStyleClass() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>(callback, converter);
+        assertTrue(cell.getStyleClass().contains("check-box-list-cell"));
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_converter_defaultGraphicIsACheckBox() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>(callback, converter);
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test(expected=NullPointerException.class)
+    public void test_getSelectedPropertyIsNull() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>();
+        cell.updateItem("TEST", false);
+    }
+    
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_graphicIsNotNull() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>(callback);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getGraphic());
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>(callback);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nullConverter() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>(callback);
+        cell.setConverter(null);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>(callback);
+        cell.setConverter(new StringConverter<Object>() {
+            @Override public Object fromString(String string) {
+                return null;
+            }
+            
+            @Override public String toString(Object object) {
+                return "CONVERTED";
+            }
+        });
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("CONVERTED", cell.getText());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * test checkbox selection state is bound
+     * 
+     **************************************************************************/
+    
+    @Test public void test_booleanPropertyChangeUpdatesCheckBoxSelection() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>(callback);
+        cell.updateItem("TEST", false);
+        CheckBox cb = (CheckBox)cell.getGraphic();
+        
+        assertFalse(cb.isSelected());
+        booleanProperty.set(true);
+        assertTrue(cb.isScaleShape());
+
+        booleanProperty.set(false);
+        assertFalse(cb.isSelected());
+    }
+    
+    @Test public void test_checkBoxSelectionUpdatesBooleanProperty() {
+        CheckBoxListCell<Object> cell = new CheckBoxListCell<>(callback);
+        cell.updateItem("TEST", false);
+        CheckBox cb = (CheckBox)cell.getGraphic();
+        
+        assertFalse(booleanProperty.get());
+        cb.setSelected(true);
+        assertTrue(booleanProperty.get());
+
+        cb.setSelected(false);
+        assertFalse(booleanProperty.get());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/CheckBoxTableCellTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javafx.scene.control.cell;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import javafx.beans.property.ReadOnlyObjectWrapper;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.TableCell;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.util.Callback;
+import javafx.util.StringConverter;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class CheckBoxTableCellTest {
+    
+    private SimpleBooleanProperty booleanProperty;
+    private Callback<Integer, ObservableValue<Boolean>> callback;
+    private StringConverter<Object> converter;
+    private TableView<Object> tableView;
+    private TableColumn<Object, Object> tableColumn;
+    
+    @Before public void setup() {
+        tableView = new TableView<>();
+        tableColumn = new TableColumn<>();
+        booleanProperty = new SimpleBooleanProperty(false);
+        callback = new Callback<Integer, ObservableValue<Boolean>>() {
+            public ObservableValue<Boolean> call(Integer param) {
+                return booleanProperty;
+            }
+        };
+        converter = new StringConverter<Object>() {
+            @Override public String toString(Object object) {
+                return null;
+            }
+            
+            @Override public Object fromString(String string) {
+                return null;
+            }
+        };
+    }
+    
+    private void setTableViewAndTableColumn(TableCell cell) {
+        cell.updateTableView(tableView);
+        cell.updateTableColumn(tableColumn);
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TableView<T>, TableCell<T>> forTableColumn(
+     *       final Callback<T, ObservableValue<Boolean>> getSelectedProperty)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTableColumn_callback_ensureCellFactoryIsNotNull() {
+        assertFalse(booleanProperty.get());
+        Callback<TableColumn<Object, Object>, TableCell<Object, Object>> cellFactory = CheckBoxTableCell.forTableColumn(callback);
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTableColumn_callback_ensureCellFactoryCreatesCells() {
+        assertFalse(booleanProperty.get());
+        Callback<TableColumn<Object, Object>, TableCell<Object, Object>> cellFactory = CheckBoxTableCell.forTableColumn(callback);
+        
+        TableColumn tableColumn = new TableColumn<>();
+        CheckBoxTableCell<Object, Object> cell = (CheckBoxTableCell<Object, Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+    
+    @Test public void testStatic_forTableColumn_callback_ensureCellHasNonNullSelectedStateCallback() {
+        assertFalse(booleanProperty.get());
+        Callback<TableColumn<Object, Object>, TableCell<Object, Object>> cellFactory = CheckBoxTableCell.forTableColumn(callback);
+        
+        TableColumn tableColumn = new TableColumn<>();
+        CheckBoxTableCell<Object, Object> cell = (CheckBoxTableCell<Object, Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testStatic_forTableColumn_callback_ensureCellHasNullStringConverter() {
+        assertFalse(booleanProperty.get());
+        Callback<TableColumn<Object, Object>, TableCell<Object, Object>> cellFactory = CheckBoxTableCell.forTableColumn(callback);
+        
+        TableColumn tableColumn = new TableColumn<>();
+        CheckBoxTableCell<Object, Object> cell = (CheckBoxTableCell<Object, Object>)cellFactory.call(tableColumn);
+        assertNull(cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TableView<T>, TableCell<T>> forTableColumn(
+     *       final Callback<T, ObservableValue<Boolean>> getSelectedProperty, 
+     *       final StringConverter<T> converter)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTableColumn_callback_2_ensureCellFactoryIsNotNull() {
+        assertFalse(booleanProperty.get());
+        Callback<TableColumn<Object, Object>, TableCell<Object, Object>> cellFactory = CheckBoxTableCell.forTableColumn(callback, converter);
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTableColumn_callback_2_ensureCellFactoryCreatesCells() {
+        assertFalse(booleanProperty.get());
+        Callback<TableColumn<Object, Object>, TableCell<Object, Object>> cellFactory = CheckBoxTableCell.forTableColumn(callback, converter);
+        
+        TableColumn tableColumn = new TableColumn<>();
+        CheckBoxTableCell<Object, Object> cell = (CheckBoxTableCell<Object, Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+    
+    @Test public void testStatic_forTableColumn_callback_2_ensureCellHasNonNullSelectedStateCallback() {
+        assertFalse(booleanProperty.get());
+        Callback<TableColumn<Object, Object>, TableCell<Object, Object>> cellFactory = CheckBoxTableCell.forTableColumn(callback, converter);
+        
+        TableColumn tableColumn = new TableColumn<>();
+        CheckBoxTableCell<Object, Object> cell = (CheckBoxTableCell<Object, Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testStatic_forTableColumn_callback_2_ensureCellHasSetStringConverter() {
+        assertFalse(booleanProperty.get());
+        Callback<TableColumn<Object, Object>, TableCell<Object, Object>> cellFactory = CheckBoxTableCell.forTableColumn(callback, converter);
+        
+        TableColumn tableColumn = new TableColumn<>();
+        CheckBoxTableCell<Object, Object> cell = (CheckBoxTableCell<Object, Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getConverter());
+        assertEquals(converter, cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testConstructor_noArgs_defaultCallbackIsNull() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>();
+        assertNull(cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNull() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>();
+        assertNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>();
+        assertTrue(cell.getStyleClass().contains("check-box-table-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsACheckBox() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>();
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for one-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_getSelectedProperty_selectedPropertyIsNotNull() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>(callback);
+        assertEquals(callback, cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_defaultStringConverterIsNull() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>(callback);
+        assertNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_defaultStyleClass() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>(callback);
+        assertTrue(cell.getStyleClass().contains("check-box-table-cell"));
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_defaultGraphicIsACheckBox() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>(callback);
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for two-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_getSelectedProperty_converter_selectedPropertyIsNotNull() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>(callback, converter);
+        assertEquals(callback, cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_converter_defaultStringConverterIsNotNull() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>(callback, converter);
+        assertNotNull(cell.getConverter());
+        assertEquals(converter, cell.getConverter());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_converter_defaultStyleClass() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>(callback, converter);
+        assertTrue(cell.getStyleClass().contains("check-box-table-cell"));
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_converter_defaultGraphicIsACheckBox() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>(callback, converter);
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test(expected=NullPointerException.class)
+    public void test_getSelectedPropertyIsNull() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>();
+        cell.updateItem("TEST", false);
+    }
+    
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_graphicIsNotNull() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>(callback);
+        setTableViewAndTableColumn(cell);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getGraphic());
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNullBecauseOfNullConverter_1() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>(callback);
+        setTableViewAndTableColumn(cell);
+        cell.updateItem("TEST", false);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNullBecauseOfNullConverter_2() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>(callback);
+        setTableViewAndTableColumn(cell);
+        cell.setConverter(null);
+        cell.updateItem("TEST", false);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>(callback);
+        setTableViewAndTableColumn(cell);
+        cell.setConverter(new StringConverter<Object>() {
+            @Override public Object fromString(String string) {
+                return "ERROR";
+            }
+            
+            @Override public String toString(Object object) {
+                return "CONVERTED";
+            }
+        });
+        cell.updateItem("TEST", false);
+        assertEquals("CONVERTED", cell.getText());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * test checkbox selection state is bound
+     * 
+     **************************************************************************/
+    
+    @Test public void test_booleanPropertyChangeUpdatesCheckBoxSelection() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>(callback);
+        setTableViewAndTableColumn(cell);
+        cell.updateItem("TEST", false);
+        CheckBox cb = (CheckBox)cell.getGraphic();
+        
+        assertFalse(cb.isSelected());
+        booleanProperty.set(true);
+        assertTrue(cb.isScaleShape());
+
+        booleanProperty.set(false);
+        assertFalse(cb.isSelected());
+    }
+    
+    @Test public void test_checkBoxSelectionUpdatesBooleanProperty() {
+        CheckBoxTableCell<Object, Object> cell = new CheckBoxTableCell<>(callback);
+        setTableViewAndTableColumn(cell);
+        cell.updateItem("TEST", false);
+        CheckBox cb = (CheckBox)cell.getGraphic();
+        
+        assertFalse(booleanProperty.get());
+        cb.setSelected(true);
+        assertTrue(booleanProperty.get());
+
+        cb.setSelected(false);
+        assertFalse(booleanProperty.get());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/CheckBoxTreeCellTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javafx.scene.control.cell;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import javafx.beans.property.ReadOnlyObjectWrapper;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.TreeCell;
+import javafx.scene.control.TreeView;
+import javafx.scene.control.TreeItem;
+import javafx.util.Callback;
+import javafx.util.StringConverter;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class CheckBoxTreeCellTest {
+    
+    private SimpleBooleanProperty booleanProperty;
+    private Callback<TreeItem<Object>, ObservableValue<Boolean>> callback;
+    private StringConverter<TreeItem<Object>> converter;
+    
+    @Before public void setup() {
+        booleanProperty = new SimpleBooleanProperty(false);
+        callback = new Callback<TreeItem<Object>, ObservableValue<Boolean>>() {
+            public ObservableValue<Boolean> call(TreeItem<Object> param) {
+                return booleanProperty;
+            }
+        };
+        converter = new StringConverter<TreeItem<Object>>() {
+            @Override public String toString(TreeItem<Object> object) {
+                return null;
+            }
+            
+            @Override public TreeItem<Object> fromString(String string) {
+                return null;
+            }
+        };
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TreeView<T>, TreeCell<T>> forTreeView()
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTreeView_callback_ensureCellFactoryIsNotNull() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeView<Object>, TreeCell<Object>> cellFactory = CheckBoxTreeCell.forTreeView();
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTreeView_callback_ensureCellFactoryCreatesCells() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeView<Object>, TreeCell<Object>> cellFactory = CheckBoxTreeCell.forTreeView();
+        
+        TreeView<Object> treeView = new TreeView<>();
+        CheckBoxTreeCell<Object> cell = (CheckBoxTreeCell<Object>)cellFactory.call(treeView);
+        assertNotNull(cell);
+    }
+    
+    @Test public void testStatic_forTreeView_callback_ensureCellHasNonNullSelectedStateCallback() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeView<Object>, TreeCell<Object>> cellFactory = CheckBoxTreeCell.forTreeView();
+        
+        TreeView<Object> treeView = new TreeView<>();
+        CheckBoxTreeCell<Object> cell = (CheckBoxTreeCell<Object>)cellFactory.call(treeView);
+        assertNotNull(cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testStatic_forTreeView_callback_ensureCellHasNonNullStringConverter() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeView<Object>, TreeCell<Object>> cellFactory = CheckBoxTreeCell.forTreeView();
+        
+        TreeView<Object> treeView = new TreeView<>();
+        CheckBoxTreeCell<Object> cell = (CheckBoxTreeCell<Object>)cellFactory.call(treeView);
+        assertNotNull(cell.getConverter());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TreeView<T>, TreeCell<T>> forTreeView(
+     *       final Callback<T, ObservableValue<Boolean>> getSelectedProperty)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTreeView_callback1_ensureCellFactoryIsNotNull() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeView<Object>, TreeCell<Object>> cellFactory = CheckBoxTreeCell.forTreeView(callback);
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTreeView_callback1_ensureCellFactoryCreatesCells() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeView<Object>, TreeCell<Object>> cellFactory = CheckBoxTreeCell.forTreeView(callback);
+        
+        TreeView<Object> treeView = new TreeView<>();
+        CheckBoxTreeCell<Object> cell = (CheckBoxTreeCell<Object>)cellFactory.call(treeView);
+        assertNotNull(cell);
+    }
+    
+    @Test public void testStatic_forTreeView_callback1_ensureCellHasNonNullSelectedStateCallback() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeView<Object>, TreeCell<Object>> cellFactory = CheckBoxTreeCell.forTreeView(callback);
+        
+        TreeView<Object> treeView = new TreeView<>();
+        CheckBoxTreeCell<Object> cell = (CheckBoxTreeCell<Object>)cellFactory.call(treeView);
+        assertNotNull(cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testStatic_forTreeView_callback1_ensureCellHasNonNullStringConverter() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeView<Object>, TreeCell<Object>> cellFactory = CheckBoxTreeCell.forTreeView(callback);
+        
+        TreeView<Object> treeView = new TreeView<>();
+        CheckBoxTreeCell<Object> cell = (CheckBoxTreeCell<Object>)cellFactory.call(treeView);
+        assertNotNull(cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TreeView<T>, TreeCell<T>> forTreeView(
+     *       final Callback<T, ObservableValue<Boolean>> getSelectedProperty, 
+     *       final StringConverter<T> converter)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTreeView_callback_2_ensureCellFactoryIsNotNull() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeView<Object>, TreeCell<Object>> cellFactory = CheckBoxTreeCell.forTreeView(callback, converter);
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTreeView_callback_2_ensureCellFactoryCreatesCells() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeView<Object>, TreeCell<Object>> cellFactory = CheckBoxTreeCell.forTreeView(callback, converter);
+        
+        TreeView<Object> treeView = new TreeView<>();
+        CheckBoxTreeCell<Object> cell = (CheckBoxTreeCell<Object>)cellFactory.call(treeView);
+        assertNotNull(cell);
+    }
+    
+    @Test public void testStatic_forTreeView_callback_2_ensureCellHasNonNullSelectedStateCallback() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeView<Object>, TreeCell<Object>> cellFactory = CheckBoxTreeCell.forTreeView(callback, converter);
+        
+        TreeView<Object> treeView = new TreeView<>();
+        CheckBoxTreeCell<Object> cell = (CheckBoxTreeCell<Object>)cellFactory.call(treeView);
+        assertNotNull(cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testStatic_forTreeView_callback_2_ensureCellHasSetStringConverter() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeView<Object>, TreeCell<Object>> cellFactory = CheckBoxTreeCell.forTreeView(callback, converter);
+        
+        TreeView<Object> treeView = new TreeView<>();
+        CheckBoxTreeCell<Object> cell = (CheckBoxTreeCell<Object>)cellFactory.call(treeView);
+        assertNotNull(cell.getConverter());
+        assertEquals(converter, cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testConstructor_noArgs_defaultCallbackIsNull() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>();
+        assertNotNull(cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNotNull() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>();
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>();
+        assertTrue(cell.getStyleClass().contains("check-box-tree-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsACheckBox() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>();
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for one-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_getSelectedProperty_selectedPropertyIsNotNull() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>(callback);
+        assertEquals(callback, cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_defaultStringConverterIsNotNull() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>(callback);
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_defaultStyleClass() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>(callback);
+        assertTrue(cell.getStyleClass().contains("check-box-tree-cell"));
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_defaultGraphicIsACheckBox() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>(callback);
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for two-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_getSelectedProperty_converter_selectedPropertyIsNotNull() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>(callback, converter);
+        assertEquals(callback, cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_converter_defaultStringConverterIsNotNull() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>(callback, converter);
+        assertNotNull(cell.getConverter());
+        assertEquals(converter, cell.getConverter());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_converter_defaultStyleClass() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>(callback, converter);
+        assertTrue(cell.getStyleClass().contains("check-box-tree-cell"));
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_converter_defaultGraphicIsACheckBox() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>(callback, converter);
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test(expected=NullPointerException.class)
+    public void test_getSelectedPropertyIsNull() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>(null);
+        cell.updateItem("TEST", false);
+    }
+    
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_graphicIsNotNull() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>(callback);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getGraphic());
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>(callback);
+        
+        TreeItem<Object> treeItem = new TreeItem<Object>("TREEITEM TEST");
+        cell.updateTreeItem(treeItem);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TREEITEM TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nullConverter() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>(callback);
+        cell.setConverter(null);
+        
+        TreeItem<Object> treeItem = new TreeItem<Object>("TREEITEM TEST");
+        cell.updateTreeItem(treeItem);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals(treeItem.toString(), cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>(callback);
+        cell.setConverter(new StringConverter<TreeItem<Object>>() {
+            @Override public TreeItem<Object> fromString(String string) {
+                return null;
+            }
+            
+            @Override public String toString(TreeItem<Object> object) {
+                return "CONVERTED";
+            }
+        });
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("CONVERTED", cell.getText());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * test checkbox selection state is bound
+     * 
+     **************************************************************************/
+    
+    @Test public void test_booleanPropertyChangeUpdatesCheckBoxSelection() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>(callback);
+        cell.updateItem("TEST", false);
+        CheckBox cb = (CheckBox)cell.getGraphic();
+        
+        assertFalse(cb.isSelected());
+        booleanProperty.set(true);
+        assertTrue(cb.isScaleShape());
+
+        booleanProperty.set(false);
+        assertFalse(cb.isSelected());
+    }
+    
+    @Test public void test_checkBoxSelectionUpdatesBooleanProperty() {
+        CheckBoxTreeCell<Object> cell = new CheckBoxTreeCell<>(callback);
+        cell.updateItem("TEST", false);
+        CheckBox cb = (CheckBox)cell.getGraphic();
+        
+        assertFalse(booleanProperty.get());
+        cb.setSelected(true);
+        assertTrue(booleanProperty.get());
+
+        cb.setSelected(false);
+        assertFalse(booleanProperty.get());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/CheckBoxTreeTableCellTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javafx.scene.control.cell;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import javafx.beans.property.ReadOnlyObjectWrapper;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.TableCell;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TreeTableCell;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TreeTableColumn;
+import javafx.scene.control.TreeTableView;
+import javafx.util.Callback;
+import javafx.util.StringConverter;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class CheckBoxTreeTableCellTest {
+    
+    private SimpleBooleanProperty booleanProperty;
+    private Callback<Integer, ObservableValue<Boolean>> callback;
+    private StringConverter<Object> converter;
+    private TreeTableView<Object> tableView;
+    private TreeTableColumn<Object, Object> tableColumn;
+    
+    @Before public void setup() {
+        tableView = new TreeTableView<>();
+        tableColumn = new TreeTableColumn<>();
+        booleanProperty = new SimpleBooleanProperty(false);
+        callback = new Callback<Integer, ObservableValue<Boolean>>() {
+            public ObservableValue<Boolean> call(Integer param) {
+                return booleanProperty;
+            }
+        };
+        converter = new StringConverter<Object>() {
+            @Override public String toString(Object object) {
+                return null;
+            }
+            
+            @Override public Object fromString(String string) {
+                return null;
+            }
+        };
+    }
+    
+    private void setTableViewAndTableColumn(TreeTableCell cell) {
+        cell.updateTreeTableView(tableView);
+        cell.updateTreeTableColumn(tableColumn);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TableView<T>, TreeTableCell<T>> forTreeTableColumn(
+     *       final Callback<T, ObservableValue<Boolean>> getSelectedProperty)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTreeTableColumn_callback_ensureCellFactoryIsNotNull() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeTableColumn<Object, Object>, TreeTableCell<Object, Object>> cellFactory = CheckBoxTreeTableCell.forTreeTableColumn(callback);
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTreeTableColumn_callback_ensureCellFactoryCreatesCells() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeTableColumn<Object, Object>, TreeTableCell<Object, Object>> cellFactory = CheckBoxTreeTableCell.forTreeTableColumn(callback);
+        
+        TreeTableColumn tableColumn = new TreeTableColumn<>();
+        CheckBoxTreeTableCell<Object, Object> cell = (CheckBoxTreeTableCell<Object, Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+    
+    @Test public void testStatic_forTreeTableColumn_callback_ensureCellHasNonNullSelectedStateCallback() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeTableColumn<Object, Object>, TreeTableCell<Object, Object>> cellFactory = CheckBoxTreeTableCell.forTreeTableColumn(callback);
+        
+        TreeTableColumn tableColumn = new TreeTableColumn<>();
+        CheckBoxTreeTableCell<Object, Object> cell = (CheckBoxTreeTableCell<Object, Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testStatic_forTreeTableColumn_callback_ensureCellHasNullStringConverter() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeTableColumn<Object, Object>, TreeTableCell<Object, Object>> cellFactory = CheckBoxTreeTableCell.forTreeTableColumn(callback);
+        
+        TreeTableColumn tableColumn = new TreeTableColumn<>();
+        CheckBoxTreeTableCell<Object, Object> cell = (CheckBoxTreeTableCell<Object, Object>)cellFactory.call(tableColumn);
+        assertNull(cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TableView<T>, TreeTableCell<T>> forTreeTableColumn(
+     *       final Callback<T, ObservableValue<Boolean>> getSelectedProperty, 
+     *       final StringConverter<T> converter)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTreeTableColumn_callback_2_ensureCellFactoryIsNotNull() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeTableColumn<Object, Object>, TreeTableCell<Object, Object>> cellFactory = CheckBoxTreeTableCell.forTreeTableColumn(callback, converter);
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTreeTableColumn_callback_2_ensureCellFactoryCreatesCells() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeTableColumn<Object, Object>, TreeTableCell<Object, Object>> cellFactory = CheckBoxTreeTableCell.forTreeTableColumn(callback, converter);
+        
+        TreeTableColumn tableColumn = new TreeTableColumn<>();
+        CheckBoxTreeTableCell<Object, Object> cell = (CheckBoxTreeTableCell<Object, Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+    
+    @Test public void testStatic_forTreeTableColumn_callback_2_ensureCellHasNonNullSelectedStateCallback() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeTableColumn<Object, Object>, TreeTableCell<Object, Object>> cellFactory = CheckBoxTreeTableCell.forTreeTableColumn(callback, converter);
+        
+        TreeTableColumn tableColumn = new TreeTableColumn<>();
+        CheckBoxTreeTableCell<Object, Object> cell = (CheckBoxTreeTableCell<Object, Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testStatic_forTreeTableColumn_callback_2_ensureCellHasSetStringConverter() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeTableColumn<Object, Object>, TreeTableCell<Object, Object>> cellFactory = CheckBoxTreeTableCell.forTreeTableColumn(callback, converter);
+        
+        TreeTableColumn tableColumn = new TreeTableColumn<>();
+        CheckBoxTreeTableCell<Object, Object> cell = (CheckBoxTreeTableCell<Object, Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getConverter());
+        assertEquals(converter, cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testConstructor_noArgs_defaultCallbackIsNull() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>();
+        assertNull(cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNull() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>();
+        assertNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>();
+        assertTrue(cell.getStyleClass().contains("check-box-tree-table-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsACheckBox() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>();
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for one-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_getSelectedProperty_selectedPropertyIsNotNull() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>(callback);
+        assertEquals(callback, cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_defaultStringConverterIsNull() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>(callback);
+        assertNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_defaultStyleClass() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>(callback);
+        assertTrue(cell.getStyleClass().contains("check-box-tree-table-cell"));
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_defaultGraphicIsACheckBox() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>(callback);
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for two-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_getSelectedProperty_converter_selectedPropertyIsNotNull() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>(callback, converter);
+        assertEquals(callback, cell.getSelectedStateCallback());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_converter_defaultStringConverterIsNotNull() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>(callback, converter);
+        assertNotNull(cell.getConverter());
+        assertEquals(converter, cell.getConverter());
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_converter_defaultStyleClass() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>(callback, converter);
+        assertTrue(cell.getStyleClass().contains("check-box-tree-table-cell"));
+    }
+    
+    @Test public void testConstructor_getSelectedProperty_converter_defaultGraphicIsACheckBox() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>(callback, converter);
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test(expected=NullPointerException.class)
+    public void test_getSelectedPropertyIsNull() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>();
+        cell.updateItem("TEST", false);
+    }
+    
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_graphicIsNotNull() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>(callback);
+        setTableViewAndTableColumn(cell);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getGraphic());
+        assertTrue(cell.getGraphic() instanceof CheckBox);
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNullBecauseOfNullConverter_1() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>(callback);
+        setTableViewAndTableColumn(cell);
+        cell.updateItem("TEST", false);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNullBecauseOfNullConverter_2() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>(callback);
+        setTableViewAndTableColumn(cell);
+        cell.setConverter(null);
+        cell.updateItem("TEST", false);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>(callback);
+        setTableViewAndTableColumn(cell);
+        cell.setConverter(new StringConverter<Object>() {
+            @Override public Object fromString(String string) {
+                return "ERROR";
+            }
+            
+            @Override public String toString(Object object) {
+                return "CONVERTED";
+            }
+        });
+        cell.updateItem("TEST", false);
+        assertEquals("CONVERTED", cell.getText());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * test checkbox selection state is bound
+     * 
+     **************************************************************************/
+    
+    @Test public void test_booleanPropertyChangeUpdatesCheckBoxSelection() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>(callback);
+        setTableViewAndTableColumn(cell);
+        cell.updateItem("TEST", false);
+        CheckBox cb = (CheckBox)cell.getGraphic();
+        
+        assertFalse(cb.isSelected());
+        booleanProperty.set(true);
+        assertTrue(cb.isScaleShape());
+
+        booleanProperty.set(false);
+        assertFalse(cb.isSelected());
+    }
+    
+    @Test public void test_checkBoxSelectionUpdatesBooleanProperty() {
+        CheckBoxTreeTableCell<Object, Object> cell = new CheckBoxTreeTableCell<>(callback);
+        setTableViewAndTableColumn(cell);
+        cell.updateItem("TEST", false);
+        CheckBox cb = (CheckBox)cell.getGraphic();
+        
+        assertFalse(booleanProperty.get());
+        cb.setSelected(true);
+        assertTrue(booleanProperty.get());
+
+        cb.setSelected(false);
+        assertFalse(booleanProperty.get());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/ParameterisedPrebuiltCellTest.java	Tue Mar 19 22:28:50 2013 +0100
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javafx.scene.control.cell;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.Node;
+import javafx.scene.control.Cell;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import static org.junit.Assert.*;
+
+@RunWith(Parameterized.class)
+public class ParameterisedPrebuiltCellTest {
+
+    @Parameters public static Collection implementations() {
+        return Arrays.asList(new Object[][] {
+            { CheckBoxListCell.class },
+            { CheckBoxTableCell.class },
+            { CheckBoxTreeCell.class },
+            { CheckBoxTreeTableCell.class },
+        });
+    }
+
+    private Class<? extends Cell> cellClass;
+    private Cell cell;
+    
+    private int count = 0;
+    
+    public ParameterisedPrebuiltCellTest(Class<? extends Cell> cellClass) {
+        this.cellClass = cellClass;
+    }
+    
+    @Before public void setup() {
+        count = 0;
+        
+        try {
+            cell = cellClass.newInstance();
+        } catch (InstantiationException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        }
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Text
+     * 
+     **************************************************************************/
+    
+    @Test public void testSetText() {
+        assertNull(cell.getText());
+        cell.setText("TEST");
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void testTextProperty() {
+        assertEquals(0, count);
+        cell.textProperty().addListener(new ChangeListener<Object>() {
+            @Override public void changed(ObservableValue observable, Object oldValue, Object newValue) {
+                count++;
+            }
+        });
+
+        cell.setText("TEST");
+        assertEquals(1, count);
+        
+        cell.setText("TEST");
+        assertEquals(1, count);
+        
+        cell.setText("TEST 2");
+        assertEquals(2, count);
+        
+        cell.textProperty().set("TEST");
+        assertEquals(3, count);
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Graphics
+     * 
+     **************************************************************************/
+    
+    @Test public void testSetGraphic() {
+        Rectangle rect = new Rectangle(10, 10, Color.RED);
+        cell.setGraphic(rect);
+        assertEquals(rect, cell.getGraphic());
+    }
+    
+    @Test public void testGraphicProperty() {
+        assertEquals(0, count);
+        cell.graphicProperty().addListener(new ChangeListener<Node>() {
+            @Override public void changed(ObservableValue observable, Node oldValue, Node newValue) {
+                count++;
+            }
+        });
+        
+        Rectangle rect1 = new Rectangle(10, 10, Color.RED);
+        Rectangle rect2 = new Rectangle(10, 10, Color.GREEN);
+
+        cell.setGraphic(rect1);
+        assertEquals(1, count);
+        
+        cell.setGraphic(rect1);
+        assertEquals(1, count);
+        
+        cell.setGraphic(rect2);
+        assertEquals(2, count);
+        
+        cell.graphicProperty().set(rect1);
+        assertEquals(3, count);
+    }
+}