changeset 4004:8c4c7f85a7c7

Automated merge with ssh://jfxsrc.us.oracle.com//javafx/8.0/MASTER/jfx/rt
author David Grieve<david.grieve@oracle.com>
date Wed, 19 Jun 2013 08:46:30 -0400
parents 64d0a96e0401 9d368dc0822d
children b1d681005b05 f4cb964fba96
files
diffstat 54 files changed, 5953 insertions(+), 1581 deletions(-) [+]
line wrap: on
line diff
--- a/javafx-ui-common/src/com/sun/javafx/css/BitSet.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/BitSet.java	Wed Jun 19 08:46:30 2013 -0400
@@ -345,8 +345,8 @@
     public boolean retainAll(Collection<?> c) {
 
         if (c == null) {
-            // this not modified!
-            return false;
+            clear();
+            return true;
         }
         
         boolean modified = false;
@@ -361,11 +361,19 @@
 
             final long[] intersection = new long[max];
 
+
+            //
+            // Make sure modified is set if maskOne has more bits than maskTwo.
+            // If max is zero, then the loop that does the intersection is
+            // never entered (since maskTwo is empty). If modified isn't set,
+            // then the if (modified) block isn't entered and this.bits isn't
+            // set to the intersection.
+            //
+            modified |= (maskOne.length > max);
+
             for(int n = 0; n < max; n++) {
                 intersection[n] = maskOne[n] & maskTwo[n];
-                
                 modified |= intersection[n] != maskOne[n];
-                
             }
 
             if (modified) {
--- a/javafx-ui-common/src/com/sun/javafx/css/CalculatedValue.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/CalculatedValue.java	Wed Jun 19 08:46:30 2013 -0400
@@ -25,17 +25,18 @@
 package com.sun.javafx.css;
 
 import javafx.css.StyleOrigin;
+import javafx.scene.text.Font;
 
 public final class CalculatedValue {
 
     public static final CalculatedValue SKIP = new CalculatedValue(new int[0], null, false);
 
+
     public CalculatedValue(Object value, StyleOrigin origin, boolean relative) {
             
         this.value = value;            
         this.origin = origin;
         this.relative = relative;
-        
     }
 
     public Object getValue() {
@@ -50,8 +51,45 @@
         return relative;
     }
 
+    @Override public String toString() {
+        return
+            (new StringBuilder()
+                .append('{')
+                .append(String.valueOf(value))
+                .append(", ").append(origin)
+                .append(", ").append(relative)
+                .append('}')
+            ).toString();
+    }
+
+    @Override public boolean equals(Object obj) {
+
+        if(obj == null) {
+            return false;
+        }
+
+        if (this.getClass() != obj.getClass()) {
+            return false;
+        }
+
+        CalculatedValue other = (CalculatedValue)obj;
+
+        if (this.relative != other.relative)  {
+            return false;
+        }
+
+        if (this.origin != other.origin) {
+            return false;
+        }
+
+        if (this.value != null ? other.value == null : !this.value.equals(other.value)) {
+            return false;
+        }
+
+        return true;
+    }
+
     private final Object value;
     private final StyleOrigin origin;
     private final boolean relative;
-        
 }
--- a/javafx-ui-common/src/com/sun/javafx/css/CompoundSelector.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/CompoundSelector.java	Wed Jun 19 08:46:30 2013 -0400
@@ -241,7 +241,7 @@
             while (parent != null) {
                 if (selectors.get(index-1).applies(parent)) { 
                     Set<PseudoClass> parentStates = parent.getPseudoClassStates();
-                    return stateMatches(parent, states, index - 1);
+                    return stateMatches(parent, parentStates, index - 1);
                 }
                 // Otherwise we need to get the next parent and try again
                 parent = parent.getStyleableParent();
--- a/javafx-ui-common/src/com/sun/javafx/css/ParsedValueImpl.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/ParsedValueImpl.java	Wed Jun 19 08:46:30 2013 -0400
@@ -113,36 +113,34 @@
         return containsLookupsFlag;
     }
 
-    private final boolean needsFont;
-    public boolean isNeedsFont() {
-        if (resolved != null && resolved != this) {
-            return resolved.needsFont;
-        }
-        return needsFont;
-    }
-
-    private static boolean getNeedsFontFlag(Object obj) {
+    public static boolean containsFontRelativeSize(ParsedValue parsedValue, boolean percentUnitsAreRelative) {
 
         // Assume the value does not need a font for conversion
         boolean needsFont = false;
 
+        Object obj = parsedValue.getValue();
+
         if (obj instanceof Size) {
-            needsFont = ((Size)obj).isAbsolute() == false;
+            Size size = (Size)obj;
+            // percent is only relative for font and font-size properties
+            needsFont = size.getUnits() == SizeUnits.PERCENT
+                    ? percentUnitsAreRelative
+                    : size.isAbsolute() == false;
         }
 
-        else if(obj instanceof ParsedValueImpl) {
-            ParsedValueImpl value = (ParsedValueImpl)obj;
-            needsFont = value.needsFont;
+        else if(obj instanceof ParsedValue) {
+            ParsedValue value = (ParsedValueImpl)obj;
+            needsFont = containsFontRelativeSize(value, percentUnitsAreRelative);
         }
 
-        else if(obj instanceof ParsedValueImpl[]) {
-            ParsedValueImpl[] values = (ParsedValueImpl[])obj;
+        else if(obj instanceof ParsedValue[]) {
+            ParsedValue[] values = (ParsedValue[])obj;
             for(int v=0;
                 v<values.length && !needsFont;
                 v++)
             {
                 if (values[v] == null) continue;
-                needsFont = values[v].needsFont;
+                needsFont = containsFontRelativeSize(values[v], percentUnitsAreRelative);
             }
 
         } else if(obj instanceof ParsedValueImpl[][]) {
@@ -157,7 +155,7 @@
                     v++)
                 {
                     if (values[l][v] == null) continue;
-                    needsFont = values[l][v].needsFont;
+                    needsFont = containsFontRelativeSize(values[l][v], percentUnitsAreRelative);
                 }
             }
         }
@@ -176,7 +174,6 @@
         super(value, converter);
         this.lookup = lookup;
         this.containsLookups = lookup || getContainsLookupsFlag(value);
-        this.needsFont = getNeedsFontFlag(value);
     }
 
     /**
--- a/javafx-ui-common/src/com/sun/javafx/css/StyleCache.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/StyleCache.java	Wed Jun 19 08:46:30 2013 -0400
@@ -24,8 +24,10 @@
  */
 package com.sun.javafx.css;
 
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
+import javafx.css.CssMetaData;
 
 /**
  * A cache to store values from lookup.
@@ -84,21 +86,26 @@
     
     public void clear() {
         if (entries == null) return;
+        Thread.dumpStack();
         entries.clear();
     }
         
-    public void putStyleCacheEntry(StyleCacheEntry.Key entryKey, StyleCacheEntry entry) {
+    public StyleCacheEntry getStyleCacheEntry(StyleCacheEntry.Key key) {
+
+        StyleCacheEntry entry = null;
+        if (entries != null) {
+            entry = entries.get(key);
+        }
+        return entry;
+    }
+
+    public void addStyleCacheEntry(StyleCacheEntry.Key key, StyleCacheEntry entry) {
         if (entries == null) {
-            this.entries = new HashMap<StyleCacheEntry.Key,StyleCacheEntry>();
+            entries = new HashMap<>(5);
         }
-        entries.put(entryKey, entry);
+        entries.put(key, entry);
     }
-    
-    public StyleCacheEntry getStyleCacheEntry(StyleCacheEntry.Key entryKey) {
-        if (entries == null) return null;
-        return entries.get(entryKey);
-    }
-    
+
     public static final class Key {
         
         public Key(int[] styleMapIds, int count) {
@@ -106,6 +113,14 @@
             System.arraycopy(styleMapIds, 0, this.styleMapIds, 0, count);
         }
 
+        public Key(Key other) {
+            this(other.styleMapIds, other.styleMapIds.length);
+        }
+
+        @Override public String toString() {
+            return Arrays.toString(styleMapIds);
+        }
+
         @Override
         public int hashCode() {
             int hash = 3;
@@ -120,37 +135,38 @@
 
         @Override
         public boolean equals(Object obj) {
-            
-            if (obj instanceof Key) {
 
-                final Key other = (Key) obj;
-            
-                // if one is null, so too must the other
-                if ((this.styleMapIds == null) ^ (other.styleMapIds == null)) {
+            if (obj == this) return true;
+
+            if (obj == null || obj.getClass() != this.getClass()) {
+                return false;
+            }
+
+            final Key other = (Key) obj;
+
+            // if one is null, so too must the other
+            if ((this.styleMapIds == null) ^ (other.styleMapIds == null)) {
+                return false;
+            }
+
+            // if one is null, so is the other
+            if (this.styleMapIds == null) {
+                return true;
+            }
+
+            for (int i=0; i<styleMapIds.length; i++) {
+                if (styleMapIds[i] != other.styleMapIds[i]) {
                     return false;
                 }
+            }
 
-                // if one is null, so is the other
-                if (this.styleMapIds == null) {
-                    return true;
-                }
+            return true;
 
-                for (int i=0; i<styleMapIds.length; i++) {
-                    if (styleMapIds[i] != other.styleMapIds[i]) {
-                        return false;
-                    }
-                }
-                
-                return true;
-            }
-            
-            return false;
-            
         }
         
         final int[] styleMapIds;
     }
     
     private Map<StyleCacheEntry.Key,StyleCacheEntry> entries;
-    
+
 }
--- a/javafx-ui-common/src/com/sun/javafx/css/StyleCacheEntry.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/StyleCacheEntry.java	Wed Jun 19 08:46:30 2013 -0400
@@ -24,13 +24,12 @@
  */
 package com.sun.javafx.css;
 
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 import javafx.css.PseudoClass;
-import javafx.css.StyleOrigin;
+import javafx.scene.text.Font;
 
 /**
  *
@@ -38,90 +37,50 @@
 public final class StyleCacheEntry {
     
     public StyleCacheEntry() {
-        this(null);
-    }
-    
-    public StyleCacheEntry(StyleCacheEntry sharedCacheEntry) {
-        this.sharedCacheRef = sharedCacheEntry != null ? new WeakReference<StyleCacheEntry>(sharedCacheEntry) : null;
-    }   
-    
-    public CalculatedValue getFont() {
-        return font;
-    }
-    
-    public void setFont(CalculatedValue font) {
-        this.font = font;
     }
     
     public CalculatedValue get(String property) {
-//        if (values == null) return null;
-        
+
         CalculatedValue cv = null;
-        
-        if (values != null && ! values.isEmpty()) {
-            cv = values.get(property);
-        }
-        if (cv == null && sharedCacheRef != null) {
-            final StyleCacheEntry ce = sharedCacheRef.get();
-            if (ce != null && ce.values != null) {
-                cv = ce.values.get(property);
-            }
-            // if referent is null, we should skip the value.
-            // else cv = CalculatedValue.SKIP;
+        if (calculatedValues != null && ! calculatedValues.isEmpty()) {
+            cv = calculatedValues.get(property);
         }
         return cv;
     }
 
-    public void put(String property, CalculatedValue cv) {
+    public void put(String property, CalculatedValue calculatedValue) {
 
-        // If the origin of the calculated value is inline or user,
-        // then use local cache.
-        // If the origin of the calculated value is not inline or user,
-        // then use local cache if the font origin is inline or user and
-        // the value was calculated from a relative size unit.
-        final boolean isLocal =
-            (cv.getOrigin() == StyleOrigin.INLINE || cv.getOrigin() == StyleOrigin.USER)            
-            || (cv.isRelative() &&
-                (font.getOrigin() == StyleOrigin.INLINE || 
-                 font.getOrigin() == StyleOrigin.USER));
-        
-        if (isLocal) {
-            makeValuesMap();
-            values.put(property, cv);
-        } else {
-            // if isLocal is false, then sharedCacheRef cannot be null.
-            final StyleCacheEntry ce = sharedCacheRef.get();
-            ce.makeValuesMap();
-            if (ce != null && ce.values.containsKey(property) == false) {
-                // don't override value already in shared cache.
-                ce.values.put(property, cv);
-            }
+        if (calculatedValues == null) {
+            this.calculatedValues = new HashMap<>(5);
         }
-    }
-    
-    private void makeValuesMap() {
-        if (values == null) {
-            this.values = new HashMap<String, CalculatedValue>();
-        }
+
+        calculatedValues.put(property, calculatedValue);
     }
 
     public final static class Key {
 
         private final Set<PseudoClass>[] pseudoClassStates;
+        private final double fontSize;
     
-        public Key(Set<PseudoClass>[] pseudoClassStates, int count) {
-                        
-            this.pseudoClassStates = new PseudoClassState[count];
-            
-            for (int n=0; n<count; n++) {
+        public Key(Set<PseudoClass>[] pseudoClassStates, Font font) {
+
+            this.pseudoClassStates = new Set[pseudoClassStates.length];
+            for (int n=0; n<pseudoClassStates.length; n++) {
                 this.pseudoClassStates[n] = new PseudoClassState();
                 this.pseudoClassStates[n].addAll(pseudoClassStates[n]);
             }
+            this.fontSize = font != null ? font.getSize() : Font.getDefault().getSize();
+            
         }
-        
+
+        @Override public String toString() {
+            return Arrays.toString(pseudoClassStates) + ", " + fontSize;
+        }
+
         @Override
         public int hashCode() {
-            int hash = 7;
+            int hash = Double.hashCode(fontSize);
+
             final int iMax = pseudoClassStates != null ? pseudoClassStates.length : 0;
             
             for (int i=0; i<iMax; i++) {
@@ -136,45 +95,58 @@
 
         @Override
         public boolean equals(Object obj) {
-            
-            if (obj instanceof Key) {
-                
-                final Key other = (Key) obj;
 
-                // either both must be null or both must be not-null
-                if ((pseudoClassStates == null) ^ (other.pseudoClassStates == null)) {
+            if (obj == this) return true;
+
+            if (obj == null || obj.getClass() != this.getClass()) return false;
+
+            final Key other = (Key) obj;
+
+            //
+            // double == double is not reliable since a double is kind of
+            // a fuzzy value. And Double.compare is too precise.
+            // For javafx, most sizes are rounded to the nearest tenth
+            // (see SizeUnits.round) so comparing  here to the nearest
+            // millionth is more than adequate.
+            //
+            // We assume that both fsize values are > 0, which is a safe assumption
+            // because Font doesn't allow sizes < 0.
+            final double diff = fontSize - other.fontSize;
+            if (Math.abs(diff) > 0.000001) {
+                return false;
+            }
+
+            // either both must be null or both must be not-null
+            if ((pseudoClassStates == null) ^ (other.pseudoClassStates == null)) {
+                return false;
+            }
+
+            // if one is null, the other is too.
+            if (pseudoClassStates == null) {
+                return true;
+            }
+
+            if (pseudoClassStates.length != other.pseudoClassStates.length) {
+                return false;
+            }
+
+            for (int i=0; i<pseudoClassStates.length; i++) {
+
+                final Set<PseudoClass> this_pcs = pseudoClassStates[i];
+                final Set<PseudoClass> other_pcs = other.pseudoClassStates[i];
+
+                // if one is null, the other must be too
+                if (this_pcs == null ? other_pcs != null : !this_pcs.equals(other_pcs)) {
                     return false;
                 }
+            }
 
-                // if one is null, the other is too. 
-                if (pseudoClassStates == null) {
-                    return true;
-                }
-
-                if (pseudoClassStates.length != other.pseudoClassStates.length) {
-                    return false;
-                }
-
-                for (int i=0; i<pseudoClassStates.length; i++) {
-
-                    final Set<PseudoClass> this_pcs = pseudoClassStates[i];
-                    final Set<PseudoClass> other_pcs = other.pseudoClassStates[i];
-
-                    // if one is null, the other must be too
-                    if (this_pcs == null ? other_pcs != null : !this_pcs.equals(other_pcs)) {
-                        return false;
-                    }
-                }
-
-                return true;
-            }
-            
-            return false;
+            return true;
         }
 
     }
         
-    private final Reference<StyleCacheEntry> sharedCacheRef;
-    private Map<String,CalculatedValue> values;
-    private CalculatedValue  font; // for use in converting font relative sizes
+//    private final Reference<StyleCacheEntry> sharedCacheRef;
+    private Map<String,CalculatedValue> calculatedValues;
+//    private CalculatedValue  font; // for use in converting font relative sizes
 }
--- a/javafx-ui-common/src/com/sun/javafx/css/StyleManager.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/StyleManager.java	Wed Jun 19 08:46:30 2013 -0400
@@ -170,13 +170,23 @@
     private static final Map<Scene, CacheContainer> cacheContainerMap
             = new WeakHashMap<Scene, CacheContainer>();
 
-    /**
-     * StyleHelper uses this cache but it lives here so it can be cleared
-     * when style-sheets change.
-     */
-    public Map<StyleCache.Key,StyleCache> getStyleCache(Scene scene) {
 
-        if (scene == null) return null;
+    private CacheContainer getCacheContainer(Styleable styleable) {
+
+        if (styleable == null) return null;
+
+        Scene scene = null;
+
+        if (styleable instanceof Node) {
+
+            Node node = (Node)styleable;
+            scene = node.getScene();
+
+        } else if (styleable instanceof Window) {
+            // this catches the PopupWindow case
+            scene = ((Window)styleable).getScene();
+        }
+        // todo: what other Styleables need to be handled here?
 
         CacheContainer container = cacheContainerMap.get(scene);
         if (container == null) {
@@ -184,14 +194,35 @@
             cacheContainerMap.put(scene, container);
         }
 
-        return container.getStyleCache();
+        return container;
+
     }
+    /** 
+     * StyleHelper uses this cache but it lives here so it can be cleared
+     * when style-sheets change.
+     */
+    public StyleCache getSharedCache(Styleable styleable, StyleCache.Key key) {
 
-    public StyleMap getStyleMap(Scene scene, int smapId) {
+        CacheContainer container = getCacheContainer(styleable);
+        if (container == null) return null;
 
-        if (scene == null || smapId == -1) return StyleMap.EMPTY_MAP;
+        Map<StyleCache.Key,StyleCache> styleCache = container.getStyleCache();
+        if (styleCache == null) return null;
 
-        CacheContainer container = cacheContainerMap.get(scene);
+        StyleCache sharedCache = styleCache.get(key);
+        if (sharedCache == null) {
+            sharedCache = new StyleCache();
+            styleCache.put(new StyleCache.Key(key), sharedCache);
+        }
+
+        return sharedCache;
+    }
+    
+    public StyleMap getStyleMap(Styleable styleable, int smapId) {
+
+        if (smapId == -1) return StyleMap.EMPTY_MAP;
+        
+        CacheContainer container = getCacheContainer(styleable);
         if (container == null) return StyleMap.EMPTY_MAP;
 
         return container.getStyleMap(smapId);
@@ -1287,6 +1318,24 @@
         return list;
     }
 
+    // return true if this node or any of its parents has an inline style.
+    private static Node nodeWithInlineStyles(Node node) {
+
+        Node parent = node;
+
+        while (parent != null) {
+
+            final String inlineStyle = parent.getStyle();
+            if (inlineStyle != null && inlineStyle.isEmpty() == false) {
+                return parent;
+            }
+            parent = parent.getParent();
+
+        }
+
+        return null;
+    }
+
     // reuse key to avoid creation of numerous small objects
     private Key key = null;
 
@@ -1300,10 +1349,10 @@
             return StyleMap.EMPTY_MAP;
         }
 
-        CacheContainer cacheContainer = cacheContainerMap.get(scene);
+        CacheContainer cacheContainer = getCacheContainer(node);
         if (cacheContainer == null) {
-            cacheContainer = new CacheContainer();
-            cacheContainerMap.put(scene, cacheContainer);
+            assert false : node.toString();
+            return StyleMap.EMPTY_MAP;
         }
 
         final Parent parent =
@@ -1318,14 +1367,17 @@
         final List<StylesheetContainer> sceneStylesheets =
                     gatherSceneStylesheets(scene);
 
-        boolean hasSceneStylesheets = sceneStylesheets.isEmpty() == false;
+        final boolean hasSceneStylesheets = sceneStylesheets.isEmpty() == false;
 
+        final String inlineStyle = node.getStyle();
+        final boolean hasInlineStyles = inlineStyle != null && inlineStyle.trim().isEmpty() == false;
         //
         // Are there any stylesheets at all?
         // If not, then there is nothing to match and the
         // resulting StyleMap is going to end up empty
         //
-        if (hasParentStylesheets == false
+        if (hasInlineStyles == false
+                && hasParentStylesheets == false
                 && hasSceneStylesheets == false
                 && userAgentStylesheets.isEmpty()) {
             return StyleMap.EMPTY_MAP;
@@ -1352,12 +1404,12 @@
         }
 
         Map<Key, Cache> cacheMap = cacheContainer.getCacheMap(parentStylesheets);
-
         Cache cache = cacheMap.get(key);
 
         if (cache != null) {
             // key will be reused, so clear the styleClasses for next use
             key.styleClasses.clear();
+
         } else {
 
             // If the cache is null, then we need to create a new Cache and
@@ -1418,7 +1470,7 @@
         //
         // Create a style helper for this node from the styles that match.
         //
-        StyleMap smap = cache.getStyleMap(cacheContainer, node, triggerStates);
+        StyleMap smap = cache.getStyleMap(cacheContainer, node, triggerStates, hasInlineStyles);
 
         return smap;
     }
@@ -1551,12 +1603,65 @@
             }
         }
 
+        /**
+         * Get the mapping of property to style from Node.style for this node.
+         */
+        private Selector getInlineStyleSelector(String inlineStyle) {
+
+            // If there are no styles for this property then we can just bail
+            if ((inlineStyle == null) || inlineStyle.trim().isEmpty()) return null;
+
+            if (inlineStylesCache != null && inlineStylesCache.containsKey(inlineStyle)) {
+                // Value of Map entry may be null!
+                return inlineStylesCache.get(inlineStyle);
+            }
+
+            //
+            // inlineStyle wasn't in the inlineStylesCache, or inlineStylesCache was null
+            //
+
+            if (inlineStylesCache == null) {
+                inlineStylesCache = new HashMap<>();
+            }
+
+            final Stylesheet inlineStylesheet =
+                    CSSParser.getInstance().parse("*{"+inlineStyle+"}");
+
+            if (inlineStylesheet != null) {
+
+                inlineStylesheet.setOrigin(StyleOrigin.INLINE);
+
+                List<Rule> rules = inlineStylesheet.getRules();
+                Rule rule = rules != null && !rules.isEmpty() ? rules.get(0) : null;
+
+                List<Selector> selectors = rule != null ? rule.getUnobservedSelectorList() : null;
+                Selector selector = selectors != null && !selectors.isEmpty() ? selectors.get(0) : null;
+                selector.setOrdinal(-1);
+
+                inlineStylesCache.put(inlineStyle, selector);
+                return selector;
+
+            } else {
+
+                // even if inlineStylesheet is null, put it in cache so we don't
+                // bother with trying to parse it again.
+                inlineStylesCache.put(inlineStyle, null);
+                return null;
+            }
+        }
+
         private Map<StyleCache.Key,StyleCache> styleCache;
 
         private Map<List<String>, Map<Key,Cache>> cacheMap;
 
         private List<StyleMap> styleMapList;
 
+        /**
+         * Cache of parsed, inline styles. The key is Node.style.
+         * The value is the Selector from the inline stylesheet.
+         */
+        private Map<String,Selector> inlineStylesCache;
+
         /*
          * A simple counter used to generate a unique id for a StyleMap.
          * This unique id is used by StyleHelper in figuring out which
@@ -1579,15 +1684,23 @@
 
         private static class Key {
             final long[] key;
+            final String inlineStyle;
 
-            Key(long[] key) {
+            Key(long[] key, String inlineStyle) {
                 this.key = key;
+                // let inlineStyle be null if it is empty
+                this.inlineStyle =  (inlineStyle != null && inlineStyle.trim().isEmpty() ? null : inlineStyle);
+            }
+
+            @Override public String toString() {
+                return Arrays.toString(key) + (inlineStyle != null ? "* {" + inlineStyle + "}" : "");
             }
 
             @Override
             public int hashCode() {
                 int hash = 3;
-                hash = 97 * hash + Arrays.hashCode(this.key);
+                hash = 17 * hash + Arrays.hashCode(this.key);
+                if (inlineStyle != null) hash = 17 * hash + inlineStyle.hashCode();
                 return hash;
             }
 
@@ -1600,6 +1713,9 @@
                     return false;
                 }
                 final Key other = (Key) obj;
+                if (inlineStyle == null ? other.inlineStyle != null : !inlineStyle.equals(other.inlineStyle)) {
+                    return false;
+                }
                 if (!Arrays.equals(this.key, other.key)) {
                     return false;
                 }
@@ -1621,9 +1737,9 @@
             this.cache = new HashMap<Key, Integer>();
         }
 
-        private StyleMap getStyleMap(CacheContainer cacheContainer, Node node, Set<PseudoClass>[] triggerStates) {
+        private StyleMap getStyleMap(CacheContainer cacheContainer, Node node, Set<PseudoClass>[] triggerStates, boolean hasInlineStyle) {
 
-            if (selectors == null || selectors.isEmpty()) {
+            if ((selectors == null || selectors.isEmpty()) && !hasInlineStyle) {
                 return StyleMap.EMPTY_MAP;
             }
 
@@ -1640,7 +1756,7 @@
             // where the selectors that match this particular node are
             // represented by bits on the long[].
             //
-            long key[] = new long[Long.SIZE/selectorDataSize + 1];
+            long key[] = new long[selectorDataSize/Long.SIZE + 1];
             boolean nothingMatched = true;
 
             for (int s = 0; s < selectorDataSize; s++) {
@@ -1674,19 +1790,28 @@
             }
 
             // nothing matched!
-            if (nothingMatched) {
+            if (nothingMatched && hasInlineStyle == false) {
                 return StyleMap.EMPTY_MAP;
             }
 
-            final Key keyObj = new Key(key);
+            final String inlineStyle = node.getStyle();
+            final Key keyObj = new Key(key, inlineStyle);
+
             if (cache.containsKey(keyObj)) {
-                Integer id = cache.get(keyObj);
-                final StyleMap styleMap = id != null ? cacheContainer.getStyleMap(id.intValue()) : null;
+                Integer styleMapId = cache.get(keyObj);
+                final StyleMap styleMap = styleMapId != null
+                        ? cacheContainer.getStyleMap(styleMapId.intValue())
+                        : StyleMap.EMPTY_MAP;
                 return styleMap;
             }
 
             final List<Selector> selectors = new ArrayList<>();
 
+            if (hasInlineStyle) {
+                Selector selector = cacheContainer.getInlineStyleSelector(inlineStyle);
+                if (selector != null) selectors.add(selector);
+            }
+
             for (int k = 0; k<key.length; k++) {
 
                 if (key[k] == 0) continue;
@@ -1704,10 +1829,11 @@
                 }
             }
 
-            final int id = cacheContainer.nextSmapId();
+            int id = cacheContainer.nextSmapId();
+            cache.put(keyObj, Integer.valueOf(id));
+
             final StyleMap styleMap = new StyleMap(id, selectors);
             cacheContainer.addStyleMap(styleMap);
-            cache.put(keyObj, Integer.valueOf(id));
             return styleMap;
         }
 
--- a/javafx-ui-common/src/com/sun/javafx/css/Stylesheet.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/Stylesheet.java	Wed Jun 19 08:46:30 2013 -0400
@@ -190,6 +190,7 @@
     public void readBinary(DataInputStream is, String[] strings)
         throws IOException 
     {
+        this.stringStore = strings;
         final int index = is.readShort();
         this.setOrigin(StyleOrigin.valueOf(strings[index]));
         final int nRules = is.readShort();
@@ -228,7 +229,6 @@
             final String[] strings = StringStore.readBinary(dataInputStream);
             // read binary data
             stylesheet = new Stylesheet(url);
-            stylesheet.stringStore = strings;
             stylesheet.readBinary(dataInputStream,strings);
 
         } catch (FileNotFoundException fnfe) {
--- a/javafx-ui-common/src/javafx/scene/CssStyleHelper.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-common/src/javafx/scene/CssStyleHelper.java	Wed Jun 19 08:46:30 2013 -0400
@@ -27,6 +27,7 @@
 import java.lang.ref.Reference;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -47,7 +48,6 @@
 import javafx.scene.text.Font;
 import javafx.scene.text.FontPosture;
 import javafx.scene.text.FontWeight;
-import javafx.stage.Window;
 import com.sun.javafx.Logging;
 import com.sun.javafx.Utils;
 import com.sun.javafx.css.CalculatedValue;
@@ -122,31 +122,25 @@
 
         if (styleMap == null || styleMap.isEmpty()) {
 
-            // If there are no styles at all, and no styles that inherit, then return
-            final String inlineStyle = node.getStyle();
-            if (inlineStyle == null || inlineStyle.trim().isEmpty()) {
+            boolean mightInherit = false;
+            final List<CssMetaData<? extends Styleable, ?>> props = node.getCssMetaData();
 
-                boolean mightInherit = false;
-                final List<CssMetaData<? extends Styleable, ?>> props = node.getCssMetaData();
+            final int pMax = props != null ? props.size() : 0;
+            for (int p=0; p<pMax; p++) {
 
-                final int pMax = props != null ? props.size() : 0;
-                for (int p=0; p<pMax; p++) {
+                final CssMetaData<? extends Styleable, ?> prop = props.get(p);
+                if (prop.isInherits()) {
+                    mightInherit = true;
+                    break;
+                }
+            }
 
-                    final CssMetaData<? extends Styleable, ?> prop = props.get(p);
-                    if (prop.isInherits()) {
-                        mightInherit = true;
-                        break;
-                    }
-                }
-
-                if (mightInherit == false) {
-                    return null;
-                }
+            if (mightInherit == false) {
+                return null;
             }
         }
 
         final CssStyleHelper helper = new CssStyleHelper();
-
         helper.triggerStates.addAll(triggerStates[0]);
 
         // make sure parent's transition states include the pseudo-classes
@@ -220,20 +214,7 @@
 
             }
 
-            this.localStyleCache = new StyleCache();
-
-            final Map<StyleCache.Key,StyleCache> styleCache =
-                    StyleManager.getInstance().getStyleCache(node.getScene());
-
-            final StyleCache.Key styleCacheKey = new StyleCache.Key(smapIds, ctr);
-            StyleCache sharedCache = styleCache.get(styleCacheKey);
-
-            if (sharedCache == null) {
-                sharedCache = new StyleCache();
-                styleCache.put(styleCacheKey, sharedCache);
-            }
-
-            this.sharedCacheRef = new WeakReference<StyleCache>(sharedCache);
+            this.styleCacheKey = new StyleCache.Key(smapIds, ctr);
 
             CssMetaData<Styleable,Font> styleableFontProperty = null;
 
@@ -250,135 +231,51 @@
             }
 
             this.fontProp = styleableFontProperty;
+            this.fontSizeCache = new HashMap<>();
 
             this.cssSetProperties = new HashMap<String,StyleableProperty>();
 
         }
 
         private StyleMap getStyleMap(Styleable styleable) {
-            Scene scene = null;
-            if (styleable instanceof Node) {
-                scene = ((Node)styleable).getScene();
-            } else if (styleable instanceof Window) {
-                // this catches the PopupWindow case
-                scene = ((Window)styleable).getScene();
-            }
-            // todo: what other Styleables need to be handled here?
-
-            if (scene != null) {
-                return StyleManager.getInstance().getStyleMap(scene, smapId);
+            if (styleable != null) {
+                return StyleManager.getInstance().getStyleMap(styleable, smapId);
             } else {
                 return StyleMap.EMPTY_MAP;
             }
 
         }
 
+        // This is the key we use to find the shared cache
+        private final StyleCache.Key styleCacheKey;
+
+        // If the node has a fontProperty, we hang onto the CssMetaData for it
+        // so we can get at it later.
+        // TBD - why not the fontProperty itself?
         private final CssMetaData<Styleable,Font> fontProp;
+
+        // The id of StyleMap that contains the styles that apply to this node
         private final int smapId;
-        private final StyleCache localStyleCache;
-        private final Reference<StyleCache> sharedCacheRef;
+
+        // All nodes with the same set of styles share the same cache of
+        // calculated values. But one node might have a different font-size
+        // than another so the values are stored in cache by font-size.
+        // This map associates a style cache entry with the font to use when
+        // getting a value from or putting a value into cache.
+        private final Map<StyleCacheEntry.Key, CalculatedValue> fontSizeCache;
+
+        // Any properties that have been set by this style helper are tracked
+        // here so the property can be reset without expanding properties that
+        // were not set by css.
         private Map<String, StyleableProperty> cssSetProperties;
     }
 
-    //
-    // Find the entry in local cache and in the shared cache that matches the
-    // states. Whether or not this is a newly created StyleCacheEntry is returned
-    // in isNewEntry[0].
-    private StyleCacheEntry.Key getStyleCacheEntryKey(Node node, Set<PseudoClass>[] transitionStates) {
+    private void resetToInitialValues(Styleable styleable) {
 
-        if (cacheContainer == null) return null;
+        if (cacheContainer == null ||
+                cacheContainer.cssSetProperties == null ||
+                cacheContainer.cssSetProperties.isEmpty()) return;
 
-        //
-        // StyleHelper#triggerStates is the set of pseudo-classes that appear
-        // in the style maps of this StyleHelper. Calculated values are
-        // cached by pseudo-class state, but only the pseudo-class states
-        // that mater are used in the search. So we take the transition states
-        // and intersect them with triggerStates to remove the
-        // transition states that don't matter when it comes to matching states
-        // on a  selector. For example if the style map contains only
-        // .foo:hover { -fx-fill: red; } then only the hover state matters
-        // but the transtion state could be [hover, focused]
-        //
-        final Set<PseudoClass>[] pclassMask = new PseudoClassState[transitionStates.length];
-
-        int count = 0;
-        int depth = 0;
-        Node parent = node;
-        while (parent != null) {
-            final CssStyleHelper helper = parent.styleHelper;
-            if (helper != null) {
-                pclassMask[count] = new PseudoClassState();
-                pclassMask[count].addAll(transitionStates[depth]);
-                pclassMask[count].retainAll(helper.triggerStates);
-                count += 1;
-            }
-            depth += 1;
-            parent = parent.getParent();
-        }
-
-        StyleCacheEntry.Key key = new StyleCacheEntry.Key(pclassMask, count);
-
-        return key;
-
-    }
-
-    void inlineStyleChanged(Node node) {
-
-        // Clear local cache so styles will be recalculated.
-        // Since we're clearing the cache and getting (potentially)
-        // new styles, reset the properties to initial values.
-        if (cacheContainer != null) {
-
-            cacheContainer.localStyleCache.clear();
-
-            // do we have any styles at all now?
-            final String inlineStyle = node.getStyle();
-            if(inlineStyle == null || inlineStyle.isEmpty()) {
-
-                StyleMap smap = getStyleMap(node);
-                if (smap == null || smap.isEmpty()) {
-                    // We have no styles! Reset this StyleHelper to its
-                    // initial state so that calls to transitionToState
-                    // become a no-op.
-                    cacheContainer = null;
-                    resetToInitialValues(node);
-                }
-
-                // If smap isn't empty, then there are styles that
-                // apply to the node. There isn't a need to remap the styles
-                // since we've only removed an inline style and inline styles
-                // aren't part of the style map.
-            }
-
-
-
-
-        } else {
-            // if cacheContainer was null
-            final String inlineStyle = node.getStyle();
-            if (inlineStyle == null || inlineStyle.isEmpty()) {
-                return;
-            }
-            // if we don't have a cacheContainer, that means this
-            // node doesn't have any applicable styles and it didn't
-            // have an inline style before. If it did have an inline
-            // style before, then there would be cacheContainer.
-            // But now the  node does have an inline style and so it
-            // needs to have an smap and localStyleCache for the logic
-            // in transitionToState to work.
-            Node parent = node;
-            int depth = 0;
-            while(parent != null) {
-                depth++;
-                parent = parent.getParent();
-            }
-
-            cacheContainer = new CacheContainer(node, StyleMap.EMPTY_MAP, depth);
-        }
-
-    }
-
-    private void resetToInitialValues(Styleable styleable) {
         for (StyleableProperty styleableProperty : cacheContainer.cssSetProperties.values()) {
             final StyleOrigin origin = styleableProperty.getStyleOrigin();
             if (origin != null && origin != StyleOrigin.USER) {
@@ -406,76 +303,6 @@
     }
 
     /**
-     * Cache of parsed, inline styles. The key is Node.style.
-     * The value is the set of property styles from parsing Node.style.
-     */
-    private static final Map<String,Map<String,CascadingStyle>> inlineStylesCache =
-        new HashMap<String,Map<String,CascadingStyle>>();
-
-    /**
-     * Get the map of property to style from the rules and declarations
-     * in the stylesheet. There is no need to do selector matching here since
-     * the stylesheet is from parsing Node.style.
-     */
-    private static Map<String,CascadingStyle> getInlineStyleMap(Stylesheet inlineStylesheet) {
-
-        final Map<String,CascadingStyle> inlineStyleMap = new HashMap<String,CascadingStyle>();
-        if (inlineStylesheet != null) {
-            // Order in which the declaration of a CascadingStyle appears (see below)
-            int ordinal = 0;
-            // For each declaration in the matching rules, create a CascadingStyle object
-            final List<Rule> stylesheetRules = inlineStylesheet.getRules();
-            for (int i = 0, imax = stylesheetRules.size(); i < imax; i++) {
-                final Rule rule = stylesheetRules.get(i);
-                final List<Declaration> declarations = rule.getUnobservedDeclarationList();
-                for (int k = 0, kmax = declarations.size(); k < kmax; k++) {
-                    Declaration decl = declarations.get(k);
-
-                    CascadingStyle s = new CascadingStyle(
-                        new Style(Selector.getUniversalSelector(), decl),
-                        NULL_PSEUDO_CLASS_STATE, // no pseudo classes
-                        0, // specificity is zero
-                        // ordinal increments at declaration level since
-                        // there may be more than one declaration for the
-                        // same attribute within a rule or within a stylesheet
-                        ordinal++
-                    );
-
-                    inlineStyleMap.put(decl.getProperty(),s);
-                }
-            }
-        }
-        return inlineStyleMap;
-    }
-
-    /**
-     * Get the mapping of property to style from Node.style for this node.
-     */
-    private static Map<String,CascadingStyle> getInlineStyleMap(Styleable styleable) {
-
-        final String inlineStyles = styleable.getStyle();
-
-        // If there are no styles for this property then we can just bail
-        if ((inlineStyles == null) || inlineStyles.isEmpty()) return null;
-
-        Map<String,CascadingStyle> styles = inlineStylesCache.get(inlineStyles);
-
-        if (styles == null) {
-
-            Stylesheet inlineStylesheet =
-                CSSParser.getInstance().parseInlineStyle(styleable);
-            if (inlineStylesheet != null) {
-                inlineStylesheet.setOrigin(StyleOrigin.INLINE);
-            }
-            styles = getInlineStyleMap(inlineStylesheet);
-
-            inlineStylesCache.put(inlineStyles, styles);
-        }
-
-        return styles;
-    }
-
-    /**
      * A Set of all the pseudo-class states which, if they change, need to
      * cause the Node to be set to UPDATE its CSS styles on the next pulse.
      * For example, your stylesheet might have:
@@ -504,41 +331,66 @@
     }
 
     /**
-     * dynamic pseudo-class state of the node and its parents.
+     * Dynamic pseudo-class state of the node and its parents.
      * Only valid during a pulse.
      *
-     * The StyleCacheEntry to choose depends on the Node's state and
-     * the state of its parents. Without the parent state, the fact that
-     * the the node in this state matched foo:blah bar { } is lost.
-     *
+     * The StyleCacheEntry to choose depends on the Node's pseudo-class state
+     * and the pseudo-class state of its parents. Without the parent
+     * pseudo-class state, the fact that the the node in this pseudo-class state
+     * matched foo:blah bar { } is lost.
      */
+    // TODO: this should work on Styleable, not Node
     private Set<PseudoClass>[] getTransitionStates(Node node) {
 
+        // if cacheContainer is null, then CSS just doesn't apply to this node
+        if (cacheContainer == null) return null;
+
+        int depth = 0;
+        Node parent = node;
+        while (parent != null) {
+            depth += 1;
+            parent = parent.getParent();
+        }
+
+        //
+        // StyleHelper#triggerStates is the set of pseudo-classes that appear
+        // in the style maps of this StyleHelper. Calculated values are
+        // cached by pseudo-class state, but only the pseudo-class states
+        // that mater are used in the search. So we take the transition states
+        // and intersect them with triggerStates to remove the
+        // transition states that don't matter when it comes to matching states
+        // on a  selector. For example if the style map contains only
+        // .foo:hover { -fx-fill: red; } then only the hover state matters
+        // but the transtion state could be [hover, focused]
+        //
+        final Set<PseudoClass>[] retainedStates = new PseudoClassState[depth];
+
         //
         // Note Well: The array runs from leaf to root. That is,
-        // transitionStates[0] is the pseudo-class state for node and
-        // transitionStates[1..(states.length-1)] are the pseudoclassStates for the
+        // retainedStates[0] is the pseudo-class state for node and
+        // retainedStates[1..(states.length-1)] are the retainedStates for the
         // node's parents.
         //
 
         int count = 0;
-        Node parent = node;
+        parent = node;
         while (parent != null) {
-            count += 1;
+            final CssStyleHelper helper = (parent instanceof Node) ? ((Node)parent).styleHelper : null;
+            if (helper != null) {
+                final Set<PseudoClass> pseudoClassState = ((Node)parent).pseudoClassStates;
+                retainedStates[count] = new PseudoClassState();
+                retainedStates[count].addAll(pseudoClassState);
+                // retainAll method takes the intersection of pseudoClassState and helper.triggerStates
+                retainedStates[count].retainAll(helper.triggerStates);
+                count += 1;
+            }
             parent = parent.getParent();
         }
 
-        Set<PseudoClass>[] states = new PseudoClassState[count];
+        final Set<PseudoClass>[] transitionStates = new PseudoClassState[count];
+        System.arraycopy(retainedStates, 0, transitionStates, 0, count);
 
-        count = 0;
-        parent = node;
-        while (parent != null) {
-            states[count] = parent.pseudoClassStates;
-            count += 1;
-            parent = parent.getParent();
-        }
-
-        return states;
+        return transitionStates;
 
     }
 
@@ -559,7 +411,6 @@
          this.observableStyleMap = observableStyleMap;
      }
 
-
     /**
      * Called by the Node whenever it has transitioned from one set of
      * pseudo-class states to another. This function will then lookup the
@@ -575,83 +426,52 @@
             return;
         }
 
-        Set<PseudoClass>[] transitionStates = getTransitionStates(node);
-
         //
         // Styles that need lookup can be cached provided none of the styles
         // are from Node.style.
         //
-        StyleCacheEntry.Key cacheEntryKey = getStyleCacheEntryKey(node, transitionStates);
-        StyleCacheEntry cacheEntry = cacheContainer.localStyleCache.getStyleCacheEntry(cacheEntryKey);
+        final StyleCache sharedCache = StyleManager.getInstance().getSharedCache(node, cacheContainer.styleCacheKey);
 
-        boolean fastpath = cacheEntry != null;
-
-        if (cacheEntry == null) {
-
-            StyleCache sharedCache = cacheContainer.sharedCacheRef.get();
-            if (sharedCache != null) {
-
-                StyleCacheEntry sharedCacheEntry = sharedCache.getStyleCacheEntry(cacheEntryKey);
-                if (sharedCacheEntry == null) {
-                    sharedCacheEntry = new StyleCacheEntry();
-                    sharedCache.putStyleCacheEntry(cacheEntryKey, sharedCacheEntry);
-                }
-
-                cacheEntry = new StyleCacheEntry(sharedCacheEntry);
-                cacheContainer.localStyleCache.putStyleCacheEntry(cacheEntryKey, cacheEntry);
-
-            } else {
-                // Shared cache reference was null.
-                // This CssStyleHelper is, therefore, no good.
-                cacheContainer.localStyleCache.clear();
-                cacheContainer = null;
-                node.impl_reapplyCSS();
-                return;
-            }
-        }
-        //
-        // inlineStyles is this node's Node.style. This is passed along and is
-        // used in getStyle. Importance being the same, an author style will
-        // trump a user style and a user style will trump a user_agent style.
-        //
-        final Map<String,CascadingStyle> inlineStyles =
-                CssStyleHelper.getInlineStyleMap(node);
-
-        CalculatedValue fontForRelativeSizes = cacheEntry.getFont();
-
-        if (fontForRelativeSizes == null) {
-
-            fontForRelativeSizes =
-                getFontForUseInConvertingRelativeSize(
-                    node,
-                    cacheEntry,
-                    transitionStates[0],
-                    inlineStyles
-                );
-
-            cacheEntry.setFont(fontForRelativeSizes);
+        if (sharedCache == null) {
+            // Shared cache was blown away by StyleManager.
+            // Therefore, this CssStyleHelper is no good.
+            cacheContainer = null;
+            node.impl_reapplyCSS();
+            return;
 
         }
 
-        // origin of the font used for converting font-relative sizes
-        final StyleOrigin fontOrigin = fontForRelativeSizes.getOrigin();
+        final Set<PseudoClass>[] transitionStates = getTransitionStates(node);
 
-        fastpath =
-                fastpath &&
-                // If someone is watching the styles,
-                //   then we have to take the slow path.
-                observableStyleMap == null &&
-                // If this node has inline-styles,
-                //   then we might not be able to use the value in shared cache.
-                inlineStyles == null &&
-                // If the relative font came from a user-set value,
-                //   then we might not be able to use the value in shared cache.
-                fontOrigin != StyleOrigin.USER &&
-                // If the relative font came from an inline-style,
-                //   then we might not be able to use the value in shared cache.
-                fontOrigin != StyleOrigin.INLINE;
+        final StyleCacheEntry.Key fontCacheKey = new StyleCacheEntry.Key(transitionStates, Font.getDefault());
+        CalculatedValue cachedFont = cacheContainer.fontSizeCache.get(fontCacheKey);
 
-        final List<CssMetaData<? extends Styleable, ?>> styleables = node.getCssMetaData();
+        if (cachedFont == null) {
+
+            cachedFont = lookupFont(node, "-fx-font", true, null);
+
+            if (cachedFont == SKIP) cachedFont = getCachedFont(node.getStyleableParent());
+            if (cachedFont == null) cachedFont = new CalculatedValue(Font.getDefault(), null, false);
+
+            cacheContainer.fontSizeCache.put(fontCacheKey,cachedFont);
+
+        }
+
+        final Font fontForRelativeSizes = (Font)cachedFont.getValue();
+
+        final StyleCacheEntry.Key cacheEntryKey = new StyleCacheEntry.Key(transitionStates, fontForRelativeSizes);
+        StyleCacheEntry cacheEntry = sharedCache.getStyleCacheEntry(cacheEntryKey);
+
+        // if no one is watching for styles and the cacheEntry already exists,
+        // then we can definitely take the fastpath
+        final boolean fastpath = this.observableStyleMap == null && cacheEntry != null;
+
+        if (cacheEntry == null) {
+            cacheEntry = new StyleCacheEntry();
+            sharedCache.addStyleCacheEntry(cacheEntryKey, cacheEntry);
+        }
+
+        final List<CssMetaData<? extends Styleable,  ?>> styleables = node.getCssMetaData();
 
         // Used in the for loop below, and a convenient place to stop when debugging.
         final int max = styleables.size();
@@ -687,23 +507,23 @@
                     ? new ArrayList<Style>()
                     : null;
 
-            CalculatedValue calculatedValue = null;
+            CalculatedValue calculatedValue = cacheEntry.get(property);
+            boolean addToCache = !fastpath && calculatedValue == null;
 
             if (fastpath) {
 
-                calculatedValue = cacheEntry.get(property);
-
-                // caclculatedValue may be null,
+                // calculatedValue may be null,
                 // but we should never put SKIP in cache.
                 if (calculatedValue == SKIP) {
                     assert false : "cache returned SKIP for " + property;
                     continue;
                 }
 
-            } else {
+            } else if (calculatedValue == null) {
 
-                calculatedValue = lookup(node, cssMetaData, node.pseudoClassStates,
-                        inlineStyles, node, fontForRelativeSizes, styleList);
+                // slowpath!
+                calculatedValue = lookup(node, cssMetaData, transitionStates[0],
+                        node, cachedFont, styleList);
 
                 // lookup is not supposed to return null.
                 if (calculatedValue == null) {
@@ -739,17 +559,15 @@
                     // there was no style for the property in the current
                     // state, so reset the property to its initial value.
                     if (styleableProperty != null) {
-
                         Object initial = cssMetaData.getInitialValue(node);
                         styleableProperty.applyStyle(null, initial);
-
                     }
 
                     continue;
 
                 }
 
-                if (fastpath == false) {
+                if (addToCache) {
 
                     // If we're not on the fastpath, then add the calculated
                     // value to cache.
@@ -801,7 +619,6 @@
                                 String.valueOf(value) + ", originOfCalculatedValue=" + originOfCalculatedValue);
                     }
 
-
                     styleableProperty.applyStyle(originOfCalculatedValue, value);
                 }
 
@@ -839,8 +656,6 @@
         // RT-20643
         CssError.setCurrentScene(null);
 
-        // If the list weren't empty, we'd worry about animations at this
-        // point. TODO need to implement animation trickery here
     }
 
     /**
@@ -853,21 +668,19 @@
      * @param states
      * @return
      */
-    private CascadingStyle getStyle(Styleable styleable, String property, Set<PseudoClass> states, Map<String,CascadingStyle> inlineStyles){
-
-        final CascadingStyle inlineStyle = (inlineStyles != null) ? inlineStyles.get(property) : null;
+    private CascadingStyle getStyle(Styleable styleable, String property, Set<PseudoClass> states){
 
         // Get all of the Styles which may apply to this particular property
         final StyleMap smap = getStyleMap(styleable);
-        if (smap == null || smap.isEmpty()) return inlineStyle;
+        if (smap == null || smap.isEmpty()) return null;
 
         final Map<String, List<CascadingStyle>> cascadingStyleMap = smap.getCascadingStyles();
-        if (cascadingStyleMap == null || cascadingStyleMap.isEmpty()) return inlineStyle;
+        if (cascadingStyleMap == null || cascadingStyleMap.isEmpty()) return null;
 
         List<CascadingStyle> styles = cascadingStyleMap.get(property);
 
         // If there are no styles for this property then we can just bail
-        if ((styles == null) || styles.isEmpty()) return inlineStyle;
+        if ((styles == null) || styles.isEmpty()) return null;
 
         // Go looking for the style. We do this by visiting each CascadingStyle in
         // order finding the first that matches the current node & set of
@@ -886,14 +699,6 @@
             }
         }
 
-        if (inlineStyle != null) {
-
-            // is inlineStyle more specific than style?
-            if (style == null || inlineStyle.compareTo(style) < 0) {
-                style = inlineStyle;
-            }
-
-        }
         return style;
     }
 
@@ -908,21 +713,22 @@
      * @param states
      * @return
      */
-    private CalculatedValue lookup(Node node, CssMetaData styleable,
+    private CalculatedValue lookup(Node node,
+                                   CssMetaData styleable,
                                    Set<PseudoClass> states,
-                                   Map<String, CascadingStyle> userStyles, Node originatingNode,
-                                   CalculatedValue cachedFont, List<Style> styleList) {
+                                   Node originatingNode,
+                                   CalculatedValue cachedFont,
+                                   List<Style> styleList) {
 
         if (styleable.getConverter() == FontConverter.getInstance()) {
 
-            return lookupFont(node, styleable,
-                    originatingNode, cachedFont, styleList);
+            return lookupFont(node, styleable.getProperty(), false, styleList);
         }
 
         final String property = styleable.getProperty();
 
         // Get the CascadingStyle which may apply to this particular property
-        CascadingStyle style = getStyle(node, property, states, userStyles);
+        CascadingStyle style = getStyle(node, property, states);
 
         // If no style was found and there are no sub styleables, then there
         // are no matching styles for this property. We will then either SKIP
@@ -934,7 +740,7 @@
 
             if (numSubProperties == 0) {
 
-                return handleNoStyleFound(node, styleable, userStyles,
+                return handleNoStyleFound(node, styleable,
                         originatingNode, cachedFont, styleList);
 
             } else {
@@ -957,7 +763,7 @@
                 for (int i=0; i<numSubProperties; i++) {
                     CssMetaData subkey = subProperties.get(i);
                     CalculatedValue constituent =
-                        lookup(node, subkey, states, userStyles,
+                        lookup(node, subkey, states,
                             originatingNode, cachedFont, styleList);
                     if (constituent != SKIP) {
                         if (subs == null) {
@@ -981,7 +787,7 @@
 
                 // If there are no subkeys which apply...
                 if (subs == null || subs.isEmpty()) {
-                    return handleNoStyleFound(node, styleable, userStyles,
+                    return handleNoStyleFound(node, styleable,
                             originatingNode, cachedFont, styleList);
                 }
 
@@ -1031,8 +837,10 @@
             final ParsedValueImpl cssValue = style.getParsedValueImpl();
             if (cssValue != null && "inherit".equals(cssValue.getValue())) {
                 if (styleList != null) styleList.add(style.getStyle());
-                return inherit(node, styleable, userStyles,
-                        originatingNode, cachedFont, styleList);
+                style = getInheritedStyle(node, property);
+
+                if (style == null) return SKIP;
+
             }
         }
 
@@ -1044,21 +852,23 @@
             styleList.add(style.getStyle());
         }
 
-        return calculateValue(style, node, styleable, states, userStyles,
+        return calculateValue(style, node, styleable, states,
                 originatingNode, cachedFont, styleList);
     }
 
     /**
      * Called when there is no style found.
      */
-    private CalculatedValue handleNoStyleFound(Node node, CssMetaData styleable,
-                                               Map<String, CascadingStyle> userStyles,
-                                               Node originatingNode, CalculatedValue cachedFont, List<Style> styleList) {
+    private CalculatedValue handleNoStyleFound(Node node,
+                                               CssMetaData cssMetaData,
+                                               Node originatingNode,
+                                               CalculatedValue cachedFont,
+                                               List<Style> styleList) {
 
-        if (styleable.isInherits()) {
+        if (cssMetaData.isInherits()) {
 
 
-            StyleableProperty styleableProperty = styleable.getStyleableProperty(node);
+            StyleableProperty styleableProperty = cssMetaData.getStyleableProperty(node);
             StyleOrigin origin = styleableProperty != null ? styleableProperty.getStyleOrigin() : null;
 
             // RT-16308: if there is no matching style and the user set
@@ -1069,9 +879,13 @@
 
             }
 
+            CascadingStyle style = getInheritedStyle(node, cssMetaData.getProperty());
+            if (style == null) return SKIP;
+
             CalculatedValue cv =
-                inherit(node, styleable, userStyles,
-                    originatingNode, cachedFont, styleList);
+                    calculateValue(style, node, cssMetaData,
+                                   node.pseudoClassStates, originatingNode,
+                                   cachedFont, styleList );
 
             return cv;
 
@@ -1083,29 +897,40 @@
         }
     }
     /**
-     * Called when we must inherit a value from a parent node in the scenegraph.
+     * Called when we must getInheritedStyle a value from a parent node in the scenegraph.
      */
-    private CalculatedValue inherit(Node node, CssMetaData styleable,
-            Map<String,CascadingStyle> userStyles,
-            Node originatingNode, CalculatedValue cachedFont, List<Style> styleList) {
+    private CascadingStyle getInheritedStyle(
+            Node styleable,
+            String property) {
 
-        // Locate the first parentStyleHelper in the hierarchy
-        Node parent = node.getParent();
-        CssStyleHelper parentStyleHelper = parent == null ? null : parent.styleHelper;
-        while (parent != null && parentStyleHelper == null) {
+        Node parent = styleable != null ? styleable.getParent() : null;
+
+        while (parent != null) {
+
+            CssStyleHelper parentStyleHelper = parent.styleHelper;
+            if (parentStyleHelper != null) {
+
+                Set<PseudoClass> transitionStates = parent.pseudoClassStates;
+                CascadingStyle cascadingStyle = parentStyleHelper.getStyle(parent, property, transitionStates);
+
+                if (cascadingStyle != null) {
+
+                    final ParsedValueImpl cssValue = cascadingStyle.getParsedValueImpl();
+
+                    if ("inherit".equals(cssValue.getValue())) {
+                        return getInheritedStyle(parent, property);
+                    }
+                    return cascadingStyle;
+                }
+
+                return null;
+            }
+
             parent = parent.getParent();
-            if (parent != null) {
-                parentStyleHelper = parent.styleHelper;
-            }
+
         }
 
-        if (parent == null) {
-            return SKIP;
-        }
-
-        return parentStyleHelper.lookup(parent, styleable,
-                parent.pseudoClassStates,
-                getInlineStyleMap(parent), originatingNode, cachedFont, styleList);
+        return null;
     }
 
 
@@ -1115,10 +940,9 @@
     /**
      * Find the property among the styles that pertain to the Node
      */
-    private CascadingStyle resolveRef(Styleable styleable, String property, Set<PseudoClass> states,
-            Map<String,CascadingStyle> inlineStyles) {
+    private CascadingStyle resolveRef(Styleable styleable, String property, Set<PseudoClass> states) {
 
-        final CascadingStyle style = getStyle(styleable, property, states, inlineStyles);
+        final CascadingStyle style = getStyle(styleable, property, states);
         if (style != null) {
             return style;
         } else {
@@ -1127,7 +951,7 @@
             if (states != null && states.size() > 0) {
                 // if states > 0, then we need to check this node again,
                 // but without any states.
-                return resolveRef(styleable,property,NULL_PSEUDO_CLASS_STATE,inlineStyles);
+                return resolveRef(styleable,property,NULL_PSEUDO_CLASS_STATE);
             } else {
                 // TODO: This block was copied from inherit. Both should use same code somehow.
                 Styleable styleableParent = styleable.getStyleableParent();
@@ -1151,8 +975,7 @@
                         : styleable.getPseudoClassStates();
 
                 return parentStyleHelper.resolveRef(styleableParent, property,
-                        styleableParentPseudoClassStates,
-                        getInlineStyleMap(styleableParent));
+                        styleableParentPseudoClassStates);
             }
         }
     }
@@ -1162,7 +985,6 @@
             Styleable styleable,
             ParsedValueImpl parsedValue,
             Set<PseudoClass> states,
-            Map<String,CascadingStyle> inlineStyles,
             ObjectProperty<StyleOrigin> whence,
             List<Style> styleList) {
 
@@ -1180,7 +1002,7 @@
                 final String sval = (String)val;
 
                 CascadingStyle resolved =
-                    resolveRef(styleable, sval, states, inlineStyles);
+                    resolveRef(styleable, sval, states);
 
                 if (resolved != null) {
 
@@ -1206,7 +1028,7 @@
                     // the resolved value may itself need to be resolved.
                     // For example, if the value "color" resolves to "base",
                     // then "base" will need to be resolved as well.
-                    return resolveLookups(styleable, resolved.getParsedValueImpl(), states, inlineStyles, whence, styleList);
+                    return resolveLookups(styleable, resolved.getParsedValueImpl(), states, whence, styleList);
                 }
             }
         }
@@ -1224,7 +1046,7 @@
                 for (int ll=0; ll<layers[l].length; ll++) {
                     if (layers[l][ll] == null) continue;
                     layers[l][ll].setResolved(
-                        resolveLookups(styleable, layers[l][ll], states, inlineStyles, whence, styleList)
+                        resolveLookups(styleable, layers[l][ll], states, whence, styleList)
                     );
                 }
             }
@@ -1235,7 +1057,7 @@
             for (int l=0; l<layer.length; l++) {
                 if (layer[l] == null) continue;
                 layer[l].setResolved(
-                    resolveLookups(styleable, layer[l], states, inlineStyles, whence, styleList)
+                    resolveLookups(styleable, layer[l], states, whence, styleList)
                 );
             }
         }
@@ -1335,7 +1157,6 @@
             final Styleable node,
             final CssMetaData cssMetaData,
             final Set<PseudoClass> states,
-            final Map<String,CascadingStyle> inlineStyles,
             final Styleable originatingNode,
             final CalculatedValue fontFromCacheEntry,
             final List<Style> styleList) {
@@ -1345,12 +1166,19 @@
 
             ObjectProperty<StyleOrigin> whence = new SimpleObjectProperty<StyleOrigin>(style.getOrigin());
             final ParsedValueImpl resolved =
-                resolveLookups(node, cssValue, states, inlineStyles, whence, styleList);
+                resolveLookups(node, cssValue, states, whence, styleList);
 
             try {
+
+                final String property = cssMetaData.getProperty();
+
                 // The computed value
                 Object val = null;
-                Font fontForFontRelativeSizes = null;
+                boolean isFontProperty =
+                        "-fx-font".equals(property) ||
+                        "-fx-font-size".equals(property);
+
+                boolean isRelative = ParsedValueImpl.containsFontRelativeSize(resolved, isFontProperty);
 
                 //
                 // Avoid using a font calculated from a relative size
@@ -1366,11 +1194,10 @@
                 // a font size of 19.5.
                 // In this situation, then, we use the font from the parent's
                 // cache entry.
-                final String property = cssMetaData.getProperty();
-                if (resolved.isNeedsFont() &&
-                    (fontFromCacheEntry == null || fontFromCacheEntry.isRelative()) &&
-                    ("-fx-font".equals(property) ||
-                     "-fx-font-size".equals(property)))  {
+                Font fontForFontRelativeSizes = null;
+
+                if (isRelative && isFontProperty &&
+                    (fontFromCacheEntry == null || fontFromCacheEntry.isRelative())) {
 
                     Styleable parent = node;
                     CalculatedValue childsCachedFont = fontFromCacheEntry;
@@ -1386,7 +1213,7 @@
                                 // If the cached fonts are the same, then the cached font came from the same
                                 // style and we need to keep looking. Otherwise, use the font we found.
                                 //
-                                if (parentsCachedFont.equals(childsCachedFont)) {
+                                if (childsCachedFont == null || parentsCachedFont.equals(childsCachedFont)) {
                                     childsCachedFont = parentsCachedFont;
                                 } else {
                                     fontForFontRelativeSizes = (Font)parentsCachedFont.getValue();
@@ -1419,7 +1246,7 @@
                     val = cssMetaData.getConverter().convert(resolved, fontForFontRelativeSizes);
 
                 final StyleOrigin origin = whence.get();
-                return new CalculatedValue(val, origin, resolved.isNeedsFont());
+                return new CalculatedValue(val, origin, isRelative);
 
             } catch (ClassCastException cce) {
                 final String msg = formatUnresolvedLookupMessage(node, cssMetaData, style.getStyle(),resolved);
@@ -1505,275 +1332,125 @@
         // there is a parent helper and a cacheContainer,
         } else  {
 
-            Set<PseudoClass>[] transitionStates = getTransitionStates(parent);
-            StyleCacheEntry.Key parentCacheEntryKey = parentHelper.getStyleCacheEntryKey(parent, transitionStates);
-            StyleCacheEntry parentCacheEntry = parentHelper.cacheContainer.localStyleCache.getStyleCacheEntry(parentCacheEntryKey);
+            CacheContainer parentCacheContainer = parentHelper.cacheContainer;
+            if ( parentCacheContainer != null
+                    && parentCacheContainer.fontSizeCache != null
+                    && parentCacheContainer.fontSizeCache.isEmpty() == false) {
 
-            if (parentCacheEntry != null) {
-
-                cachedFont = parentCacheEntry.getFont();
+                Set<PseudoClass>[] transitionStates = parentHelper.getTransitionStates(parent);
+                StyleCacheEntry.Key parentCacheEntryKey = new StyleCacheEntry.Key(transitionStates, Font.getDefault());
+                cachedFont = parentCacheContainer.fontSizeCache.get(parentCacheEntryKey);
 
             } else {
 
                 Set<PseudoClass> pseudoClassState = parent.getPseudoClassStates();
-                Map<String, CascadingStyle> inlineStyles = CssStyleHelper.getInlineStyleMap(styleable);
-                StyleCacheEntry tempEntry = new StyleCacheEntry();
-                cachedFont = parentHelper.getFontForUseInConvertingRelativeSize(styleable, tempEntry, pseudoClassState, inlineStyles);
+                cachedFont = parentHelper.lookup(parent, dummyFontProperty, pseudoClassState, parent, null, null);
             }
-
         }
 
         return cachedFont;
     }
 
-    private CalculatedValue getFontForUseInConvertingRelativeSize(
-             final Styleable styleable,
-             final StyleCacheEntry cacheEntry,
-             Set<PseudoClass> pseudoclassState,
-            Map<String,CascadingStyle> inlineStyles)
-     {
+    /*package access for testing*/ FontPosture getFontPosture(Font font) {
+        if (font == null) return FontPosture.REGULAR;
 
-        // To make the code easier to read, define CONSIDER_INLINE_STYLES as true.
-        // Passed to lookupFontSubProperty to tell it whether or not
-        // it should look for inline styles
-        final boolean CONSIDER_INLINE_STYLES = true;
+        String fontName = font.getName().toLowerCase();
 
-        StyleOrigin origin = null;
-        Font foundFont = null;
-        CalculatedValue foundSize = null;
-        CalculatedValue foundShorthand = null;
-        boolean isRelative = false;
-
-        // RT-20145 - if looking for font size and the node has a font,
-        // use the font property's value if it was set by the user and
-        // there is not an inline or author style.
-        if (cacheContainer.fontProp != null) {
-            StyleableProperty<Font> styleableProp = cacheContainer.fontProp.getStyleableProperty(styleable);
-            StyleOrigin fpOrigin = styleableProp.getStyleOrigin();
-            if (fpOrigin == StyleOrigin.USER) {
-                origin = fpOrigin;
-                foundFont = styleableProp.getValue();
-            }
+        if (fontName.contains("italic")) {
+            return FontPosture.ITALIC;
         }
 
-        final CascadingStyle fontShorthand =
-            getStyle(styleable, "-fx-font", pseudoclassState, inlineStyles);
+        return FontPosture.REGULAR;
+    }
 
-        if (fontShorthand != null) {
+    /*package access for testing*/ FontWeight getFontWeight(Font font) {
+        if (font == null) return FontWeight.NORMAL;
 
-            final CalculatedValue cv =
-                calculateValue(fontShorthand, styleable, dummyFontProperty,
-                    pseudoclassState, inlineStyles,
-                    styleable, null, null);
+        String fontName = font.getName().toLowerCase();
 
-            // If we don't have an existing font, or if the origin of the
-            // existing font is less than that of the shorthand, then
-            // take the shorthand. If the origins compare equals, then take
-            // the shorthand since the fontProp value will not have been
-            // updated yet.
-            // Man, this drove me nuts!
-            if (origin == null || origin.compareTo(cv.getOrigin()) <= 0) {
+        if (fontName.contains("bold")) {
+            if (fontName.contains("extra")) return FontWeight.EXTRA_BOLD;
+            if (fontName.contains("ultra")) return FontWeight.EXTRA_BOLD;
+            else if (fontName.contains("semi")) return FontWeight.SEMI_BOLD;
+            else if (fontName.contains("demi")) return FontWeight.SEMI_BOLD;
+            else return FontWeight.BOLD;
 
-                // cv could be SKIP
-                if (cv.getValue() instanceof Font) {
-                    origin = cv.getOrigin();
-                    foundShorthand = cv;
-                    foundFont = null;
-                }
+        } else if (fontName.contains("light")) {
+            if (fontName.contains("extra")) return FontWeight.EXTRA_LIGHT;
+            if (fontName.contains("ultra")) return FontWeight.EXTRA_LIGHT;
+            else return FontWeight.LIGHT;
 
-            }
-         }
+        } else if (fontName.contains("black")) {
+            return FontWeight.BLACK;
 
-        final boolean isUserSet =
-                origin == StyleOrigin.USER || origin == StyleOrigin.INLINE;
+        } else if (fontName.contains("heavy")) {
+            return FontWeight.BLACK;
 
-        // now look for -fx-size, but don't look past the current node (hence
-        // distance == 0 and negation of CONSIDER_INLINE_STYLES)
-        CascadingStyle fontSize = lookupFontSubPropertyStyle(styleable, "-fx-font-size",
-                isUserSet, fontShorthand, 0, !CONSIDER_INLINE_STYLES);
-
-        if (fontSize != null) {
-
-            final CalculatedValue cv =
-                calculateValue(fontSize, styleable, dummyFontProperty, pseudoclassState, inlineStyles,
-                    styleable, null, null);
-
-            if (cv.getValue() instanceof Double) {
-                if (origin == null || origin.compareTo(cv.getOrigin()) <= 0) {
-                    origin = cv.getOrigin();
-                    foundSize = cv;
-                    foundShorthand = null;
-                    foundFont = null;
-                }
-             }
-
-         }
-
-
-        if (foundShorthand != null) {
-
-            return foundShorthand;
-
-        } else if (foundSize != null) {
-
-            Font font = Font.font("system", ((Double)foundSize.getValue()).doubleValue());
-            return new CalculatedValue(font, foundSize.getOrigin(), foundSize.isRelative());
-
-        } else if (foundFont != null) {
-
-            // Did this found font come from a style?
-            // If so, then the font used to convert it from a relative size
-            // (if conversion was needed) comes from the parent.
-            if (origin != null && origin != StyleOrigin.USER) {
-
-                CalculatedValue cachedFont = getCachedFont(styleable.getStyleableParent());
-
-                if (cachedFont != null) {
-                    isRelative = cachedFont.isRelative();
-                }
-            }
-            return new CalculatedValue(foundFont, origin, isRelative);
-
-        } else {
-
-            // no font, font-size or fontProp.
-            // inherit by taking the parent's cache entry font.
-            CalculatedValue cachedFont = getCachedFont(styleable.getStyleableParent());
-
-            if (cachedFont != null) {
-                return cachedFont;
-            }
-        }
-        // last ditch effort -  take the default font.
-        return new CalculatedValue(Font.getDefault(), null, false);
-     }
-
-
-    private CascadingStyle lookupFontSubPropertyStyle(final Styleable styleable,
-            final String subProperty, final boolean isUserSet,
-            final CascadingStyle csShorthand,
-            final int distance,
-            boolean considerInlineStyles) {
-
-        Styleable parent = styleable;
-        CssStyleHelper helper = this;
-        int nlooks = 0;
-        CascadingStyle returnValue = null;
-        StyleOrigin origin = null;
-        boolean consideringInline = false;
-
-        while (parent != null && (consideringInline || nlooks <= distance)) {
-
-            final Set<PseudoClass> states = parent instanceof Node ? ((Node)parent).pseudoClassStates : parent.getPseudoClassStates();
-            final Map<String,CascadingStyle> inlineStyles = CssStyleHelper.getInlineStyleMap(parent);
-
-            CascadingStyle cascadingStyle =
-                helper.getStyle(parent, subProperty, states, inlineStyles);
-
-            if (isUserSet) {
-                //
-                // Don't look past this node if the user set the property.
-                //
-                if (cascadingStyle != null) {
-
-                    origin = cascadingStyle.getOrigin();
-
-                    // if the user set the property and the origin is the
-                    // user agent stylesheet, then we can't use the style
-                    // since ua styles shouldn't override user set values
-                    if (origin == StyleOrigin.USER_AGENT) {
-                        returnValue = null;
-                    }
-                }
-
-                break;
-
-            } else if (cascadingStyle != null) {
-
-                //
-                // If isUserSet is false, then take the style if we found one.
-                // If csShorthand is not null, then were looking for an inline
-                // style. In this case, if the origin is INLINE, we'll take it.
-                // If it isn't INLINE we'll keep looking for an INLINE style.
-                //
-                final boolean isInline = cascadingStyle.getOrigin() == StyleOrigin.INLINE;
-                if (returnValue == null || isInline) {
-                    origin = cascadingStyle.getOrigin();
-                    returnValue = cascadingStyle;
-
-                    // If we found and inline style, then we don't need to look
-                    // further. Also, if the style is not an inline style and we
-                    // don't want to consider inline styles, then look no further.
-                    if (isInline || considerInlineStyles == false) {
-
-                        break;
-
-                    } else {
-                        //
-                        // If we are here, then the style is not an inline style
-                        // and we do want to consider inline styles. Setting
-                        // this flag will cause the code to look beyond nlooks
-                        // to see if there is an inline style
-                        //
-                        consideringInline = true;
-                    }
-                }
-
-            }
-
-            //
-            // haven't found it yet, or we're looking for an inline style
-            // so keep looking up the parent chain.
-            //
-            do {
-                parent = parent.getStyleableParent();
-                nlooks += 1;
-                helper = parent instanceof Node ? ((Node)parent).styleHelper : null;
-            } while (parent != null && helper == null);
+        } else if (fontName.contains("medium")) {
+            return FontWeight.MEDIUM;
         }
 
-        if (csShorthand != null && returnValue != null) {
+        return FontWeight.NORMAL;
 
-            final boolean shorthandImportant =
-                    csShorthand.getStyle().getDeclaration().isImportant();
+    }
 
-            final Style style = returnValue.getStyle();
-            final boolean returnValueIsImportant =
-                style.getDeclaration().isImportant();
+    /*package access for testing*/ String getFontFamily(Font font) {
+        if (font == null) return Font.getDefault().getFamily();
+        return font.getFamily();
+    }
 
-            if (nlooks < distance) {
-                //
-                // if we found a font sub-property closer to the node than
-                // the font shorthand, then the sub-property style
-                // wins provided the fontShorthand isn't important.
-                // If font shorthand is important and sub-property style is
-                // important, then sub-property style wins (since, being closer
-                // to the node, it is more specific)
-                //
-                if (shorthandImportant == true && returnValueIsImportant == false) {
-                    returnValue = null;
-                }
 
-            } else if (csShorthand.compareTo(returnValue) < 0) {
-                //
-                // CascadingStyle.compareTo is such that a return value less
-                // than zero means the style is more specific than the arg.
-                // So if csShorthand is more specific than the return value,
-                // return null.
-                //
-                // if we found font sub-property at the same distance from the
-                // node as the font shortand, then do a normal compare
-                // to see if the sub-property is more specific. If it isn't
-                // then return null.
-                //
-                returnValue = null;
+    /*package access for testing*/ Font deriveFont(
+            String fontFamily, FontWeight fontWeight, FontPosture fontPosture, double fontSize) {
 
-            }
+        return  Font.font(
+                Utils.stripQuotes(fontFamily),
+                fontWeight != FontWeight.NORMAL ? fontWeight : null,
+                fontPosture != FontPosture.REGULAR ? fontPosture : null,
+                fontSize);
+    }
 
-        }
+    /*package access for testing*/ Font deriveFont(Font font, String fontFamily) {
 
-        return returnValue;
+        if (font == null) return Font.getDefault();
 
+        FontPosture fontPosture = getFontPosture(font);
+        FontWeight fontWeight = getFontWeight(font);
+        double fontSize = font.getSize();
+
+        return deriveFont(fontFamily, fontWeight, fontPosture, fontSize);
+    }
+
+    /*package access for testing*/ Font deriveFont(Font font, double fontSize) {
+        if (font == null) return Font.getDefault();
+
+        String fontFamily = getFontFamily(font);
+        FontPosture fontPosture = getFontPosture(font);
+        FontWeight fontWeight = getFontWeight(font);
+
+        return deriveFont(fontFamily, fontWeight, fontPosture, fontSize);
+    }
+
+    /*package access for testing*/ Font deriveFont(Font font, FontPosture fontPosture) {
+
+        if (font == null) return Font.getDefault();
+
+        String fontFamily = getFontFamily(font);
+        FontWeight fontWeight = getFontWeight(font);
+        double fontSize = font.getSize();
+
+        return deriveFont(fontFamily, fontWeight, fontPosture, fontSize);
+    }
+
+    /*package access for testing*/ Font deriveFont(Font font, FontWeight fontWeight) {
+
+        if (font == null) return Font.getDefault();
+
+        String fontFamily = getFontFamily(font);
+        FontPosture fontPosture = getFontPosture(font);
+        double fontSize = font.getSize();
+
+        return deriveFont(fontFamily, fontWeight, fontPosture, fontSize);
     }
 
     /**
@@ -1789,278 +1466,272 @@
      * group.setStyle("-fx-font: 12px Arial;");
      * group.getChildren().add(text);
      * </pre>
-     *
-     * @param node
-     * @param styleable
-     * @param originatingNode
-     * @param fontFromCacheEntry
-     * @param styleList
-     * @return
      */
-    private CalculatedValue lookupFont(Styleable node, CssMetaData styleable,
-                                       Styleable originatingNode,
-                                       CalculatedValue fontFromCacheEntry, List<Style> styleList) {
-
-        // To make the code easier to read, define CONSIDER_INLINE_STYLES as true.
-        // Passed to lookupFontSubProperty to tell it whether or not
-        // it should look for inline styles
-        final boolean CONSIDER_INLINE_STYLES = true;
+     /*package access for testing*/ CalculatedValue lookupFont(
+            final Node styleable,
+            final String property,
+            boolean lookupForFontCache,
+            final List<Style> styleList)
+    {
 
         StyleOrigin origin = null;
-        boolean isRelative = false;
+        int distance = 0;
 
-        // distance keeps track of how far up the parent chain we had to go
-        // to find a font shorthand. We'll look no further than this
-        // for the missing pieces. nlooks is used to keep track of how
-        // many parents we've looked at. nlooks should never exceed distance.
-        int distance = 0, nlooks = 0;
+        // Each time a sub-property is encountered, cvFont is passed along to
+        // calculateValue and the resulting font becomes cvFont. In the end
+        // cvFont is returned.
+        CalculatedValue cvFont = null;
 
-        Styleable parent = node;
-        CssStyleHelper helper = this;
-        String property = styleable == null ? null : styleable.getProperty();
-        CascadingStyle csShorthand = null;
+        // Whether or not to look past the current node for inherited styles
+        // Will be false if the user set the font or there is a font-shorthand
+        boolean lookupInherited = true;
 
-        StyleableProperty styleableProperty = styleable.getStyleableProperty(node);
-        boolean isUserSet = styleableProperty.getStyleOrigin() == StyleOrigin.USER;
+        Set<PseudoClass> states = styleable.pseudoClassStates;
 
+        // RT-20145 - if looking for font size and the node has a font,
+        // use the font property's value if it was set by the user and
+        // there is not an inline or author style.
 
-        while (parent != null) {
+        if (lookupForFontCache && cacheContainer.fontProp != null) {
+            StyleableProperty<Font> styleableProp = cacheContainer.fontProp.getStyleableProperty(styleable);
+            StyleOrigin fpOrigin = styleableProp.getStyleOrigin();
+            if (fpOrigin == StyleOrigin.USER) {
+                origin = fpOrigin;
+                Font font = styleableProp.getValue();
+                cvFont = new CalculatedValue(font, origin, false);
+            }
+        }
 
-            final Set<PseudoClass> states = parent.getPseudoClassStates();
-            final Map<String,CascadingStyle> inlineStyles = CssStyleHelper.getInlineStyleMap(parent);
+        //
+        // Look up the font- properties
+        //
+        CascadingStyle fontShorthand = getStyle(styleable, property, states);
+        if (fontShorthand == null && lookupForFontCache == false) {
 
-            final CascadingStyle cascadingStyle =
-                helper.getStyle(parent, property, states, inlineStyles);
+            Node parent = styleable != null ? styleable.getParent() : null;
 
-            if (isUserSet) {
+            while (parent != null) {
 
-                //
-                // If current StyleOrigin is USER, then we don't look beyond the current node.
-                // Only if the user did not set the font will we inherit.
-                //
-                if (cascadingStyle != null) {
+                CssStyleHelper parentStyleHelper = parent.styleHelper;
+                if (parentStyleHelper != null) {
 
-                    origin = cascadingStyle.getOrigin();
+                    distance += 1;
 
-                    // if the user set font and the origin of the font shorthand
-                    // is the user agent stylesheet, then we can't use the style
-                    // since ua styles shouldn't override setFont
-                    if (origin != StyleOrigin.USER_AGENT) {
-                        csShorthand = cascadingStyle;
+                    Set<PseudoClass> transitionStates = parent.pseudoClassStates;
+                    CascadingStyle cascadingStyle = parentStyleHelper.getStyle(parent, property, transitionStates);
+
+                    if (cascadingStyle != null) {
+
+                        final ParsedValueImpl cssValue = cascadingStyle.getParsedValueImpl();
+
+                        if ("inherit".equals(cssValue.getValue()) == false) {
+                            fontShorthand = cascadingStyle;
+                            break;
+                        }
                     }
 
                 }
 
-                break;
-
-            } else if (cascadingStyle != null) {
-                //
-                // If current StyleOrigin is not USER, then take the style if we found one.
-                // If csShorthand is not null, then were looking for an inline
-                // style. In this case, if the origin is INLINE, we'll take it.
-                // If it isn't INLINE we'll keep looking for an INLINE style.
-                //
-                final boolean isInline = origin == StyleOrigin.INLINE;
-                if (csShorthand == null || isInline) {
-                    origin = cascadingStyle.getOrigin();
-                    csShorthand = cascadingStyle;
-                    distance = nlooks;
-
-                    if (isInline) {
-                        break;
-                    }
-                }
-
+                parent = parent.getParent();
 
             }
 
-            //
-            // If were here, then we either didn't find a style or we did find
-            // one but it wasn't inline. Either way, we need to keep looking
-            // up the parent chain for the next -fx-font.
-            //
-            do {
-                parent = parent.getStyleableParent();
-                nlooks += 1;
-                helper = parent instanceof Node ? ((Node)parent).styleHelper : null;
-            } while (parent != null && helper == null);
-
         }
 
-        if (csShorthand == null) {
-            distance = nlooks;
+        // if user set the font, then fontShorthand must be at zero
+        if (fontShorthand != null) {
+
+            //
+            // If we don't have an existing font, or if the origin of the
+            // existing font is less than that of the shorthand, then
+            // take the shorthand. If the origins compare equals, then take
+            // the shorthand since the fontProp value will not have been
+            // updated yet.
+            //
+            if (origin == null || origin.compareTo(fontShorthand.getOrigin()) <= 0) {
+
+                final CalculatedValue cv =
+                        calculateValue(fontShorthand, styleable, dummyFontProperty,
+                                       states, styleable, cvFont, styleList);
+
+                // cv could be SKIP
+                if (cv.getValue() instanceof Font) {
+                    origin = cv.getOrigin();
+                    cvFont = cv;
+                }
+
+            }
         }
-        nlooks = 0;
 
-        final Map<String,CascadingStyle> inlineStyles = getInlineStyleMap(node);
-        final Set<PseudoClass> states = node.getPseudoClassStates();
+        CascadingStyle fontSize = getStyle(styleable, property.concat("-size"), states);
+        if (fontSize == null && lookupForFontCache == false) {
+            fontSize = lookupInheritedFont(styleable, property.concat("-size"), distance);
+        }
 
-        String family = null;
-        double size = -1;
-        FontWeight weight = null;
-        FontPosture style = null;
+        // font-size must be closer and more specific than font shorthand
+        if (fontSize != null) {
 
-        if (csShorthand != null) {
+            if (origin == null || origin.compareTo(fontSize.getOrigin()) <= 0) {
 
-            if (styleList != null) {
-                styleList.add(csShorthand.getStyle());
-            }
+                final CalculatedValue cv =
+                        calculateValue(fontSize, styleable, dummyFontProperty,
+                                       states, styleable, cvFont, styleList);
 
-            // pull out the pieces.
-            final CalculatedValue cv =
-                calculateValue(csShorthand, node, styleable, states, inlineStyles,
-                    originatingNode, fontFromCacheEntry, styleList);
-
-            // UA < AUTHOR < INLINE
-            if (origin == null || origin.compareTo(cv.getOrigin()) <= 0) {
-
-                if (cv.getValue() instanceof Font) {
-                    Font f = (Font)cv.getValue();
-                    isRelative = cv.isRelative();
+                if (cv.getValue() instanceof Double) {
                     origin = cv.getOrigin();
 
-                    // what did font shorthand specify?
-                    ParsedValueImpl[] vals =
-                            (ParsedValueImpl[])csShorthand.getParsedValueImpl().getValue();
-                    // Use family and size from converted font since the actual
-                    // values may have been resolved. The weight and posture,
-                    // however, are hard to get reliably from the font so use
-                    // the parsed value instead.
-                    if (vals[0] != null) family = f.getFamily();
-                    if (vals[1] != null) size   = f.getSize();
-                    if (vals[2] != null) weight = (FontWeight)vals[2].convert(null);
-                    if (vals[3] != null) style  = (FontPosture)vals[3].convert(null);
-
+                    if (cvFont != null) {
+                        boolean isRelative = cvFont.isRelative() || cv.isRelative();
+                        Font font = deriveFont((Font) cvFont.getValue(), ((Double) cv.getValue()).doubleValue());
+                        cvFont = new CalculatedValue(font, origin, isRelative);
+                    } else {
+                        boolean isRelative = cv.isRelative();
+                        Font font = deriveFont(Font.getDefault(), ((Double) cv.getValue()).doubleValue());
+                        cvFont = new CalculatedValue(font, origin, isRelative);
+                    }
                 }
             }
 
         }
 
-        CascadingStyle csFamily = null;
-        if ((csFamily = lookupFontSubPropertyStyle(node, property+"-family",
-                isUserSet, csShorthand, distance, CONSIDER_INLINE_STYLES)) != null) {
+        if (lookupForFontCache == false ) {
 
-            if (styleList != null) {
-                styleList.add(csFamily.getStyle());
+            CascadingStyle fontWeight = getStyle(styleable, property.concat("-weight"), states);
+            if (fontWeight == null) {
+                fontWeight = lookupInheritedFont(styleable,property.concat("-weight"), distance);
             }
 
-            final CalculatedValue cv =
-                calculateValue(csFamily, node, styleable, states, inlineStyles,
-                    originatingNode, fontFromCacheEntry, styleList);
+            if (fontWeight != null) {
 
-            if (origin == null || origin.compareTo(cv.getOrigin()) <= 0) {
-                if (cv.getValue() instanceof String) {
-                    family = Utils.stripQuotes((String)cv.getValue());
-                    origin = cv.getOrigin();
+                if (origin == null || origin.compareTo(fontWeight.getOrigin()) <= 0) {
+
+                    final CalculatedValue cv =
+                            calculateValue(fontWeight, styleable, dummyFontProperty,
+                                           states, styleable, null, null);
+
+                    if (cv.getValue() instanceof FontWeight) {
+                        origin = cv.getOrigin();
+
+                        if (cvFont != null) {
+                            boolean isRelative = cvFont.isRelative();
+                            Font font = deriveFont((Font) cvFont.getValue(), (FontWeight) cv.getValue());
+                            cvFont = new CalculatedValue(font, origin, isRelative);
+                        } else {
+                            Font font = deriveFont(Font.getDefault(), (FontWeight) cv.getValue());
+                            cvFont = new CalculatedValue(font, origin, false);
+                        }
+                    }
                 }
+
             }
 
+            CascadingStyle fontStyle = getStyle(styleable, property.concat("-style"), states);
+            if (fontStyle == null) {
+                fontStyle = lookupInheritedFont(styleable, property.concat("-style"), distance);
+            }
+
+            if (fontStyle != null) {
+
+                if (origin == null || origin.compareTo(fontStyle.getOrigin()) <= 0) {
+
+                    final CalculatedValue cv =
+                            calculateValue(fontStyle, styleable, dummyFontProperty,
+                                           states, styleable, null, null);
+
+                    if (cv.getValue() instanceof FontPosture) {
+                        origin = cv.getOrigin();
+
+                        if (cvFont != null) {
+                            boolean isRelative = cvFont.isRelative();
+                            Font font = deriveFont((Font) cvFont.getValue(), (FontPosture) cv.getValue());
+                            cvFont = new CalculatedValue(font, origin, isRelative);
+                        } else {
+                            boolean isRelative = cv.isRelative();
+                            Font font = deriveFont(Font.getDefault(), (FontPosture) cv.getValue());
+                            cvFont = new CalculatedValue(font, origin, false);
+                        }
+                    }
+                }
+
+            }
+
+            CascadingStyle fontFamily = getStyle(styleable, property.concat("-family"), states);
+            if (fontFamily == null) {
+                fontFamily = lookupInheritedFont(styleable,property.concat("-family"), distance);
+            }
+
+            if (fontFamily != null) {
+
+                if (origin == null || origin.compareTo(fontFamily.getOrigin()) <= 0) {
+
+                    final CalculatedValue cv =
+                            calculateValue(fontFamily, styleable, dummyFontProperty,
+                                           states, styleable, null, null);
+
+                    if (cv.getValue() instanceof String) {
+                        origin = cv.getOrigin();
+
+                        if (cvFont != null) {
+                            boolean isRelative = cvFont.isRelative();
+                            Font font = deriveFont((Font) cvFont.getValue(), (String) cv.getValue());
+                            cvFont = new CalculatedValue(font, origin, isRelative);
+                        } else {
+                            Font font = deriveFont(Font.getDefault(), (String) cv.getValue());
+                            cvFont = new CalculatedValue(font, origin, false);
+                        }
+                    }
+                }
+
+            }
+        }
+
+        if (cvFont != null) {
+            return cvFont;
+
+        } else {
+            return SKIP;
+        }
+    }
+
+    /**
+     * Called when we must getInheritedStyle a value from a parent node in the scenegraph.
+     */
+    private CascadingStyle lookupInheritedFont(
+            Node styleable,
+            String property,
+            int distance) {
+
+        Node parent = styleable != null ? styleable.getParent() : null;
+
+        int nlooks = distance;
+        while (parent != null && nlooks >= 0) {
+
+            CssStyleHelper parentStyleHelper = parent.styleHelper;
+            if (parentStyleHelper != null) {
+
+                nlooks -= 1;
+
+                Set<PseudoClass> transitionStates = parent.pseudoClassStates;
+                CascadingStyle cascadingStyle = parentStyleHelper.getStyle(parent, property, transitionStates);
+
+                if (cascadingStyle != null) {
+
+                    final ParsedValueImpl cssValue = cascadingStyle.getParsedValueImpl();
+
+                    if ("inherit".equals(cssValue.getValue()) == false) {
+                        return cascadingStyle;
+                    }
+                }
+
+            }
+
+            parent = parent.getParent();
+
         }
 
-        CascadingStyle csSize = null;
-        if ((csSize = lookupFontSubPropertyStyle(node, property+"-size",
-                isUserSet, csShorthand, distance, CONSIDER_INLINE_STYLES))!= null) {
+        return null;
+    }
 
-            if (styleList != null) {
-                styleList.add(csSize.getStyle());
-            }
-
-            final CalculatedValue cv =
-                calculateValue(csSize, node, styleable, states, inlineStyles,
-                    originatingNode, fontFromCacheEntry, styleList);
-
-            // UA < AUTHOR < INLINE
-            if (origin == null || origin.compareTo(cv.getOrigin()) <= 0) {
-                if (cv.getValue() instanceof Double) {
-                    size = ((Double)cv.getValue()).doubleValue();
-                    isRelative = cv.isRelative();
-                    origin = cv.getOrigin();
-                }
-            }
-
-        }
-
-        CascadingStyle csWeight = null;
-        if ((csWeight = lookupFontSubPropertyStyle(node, property+"-weight",
-                isUserSet, csShorthand, distance, CONSIDER_INLINE_STYLES))!= null) {
-
-            if (styleList != null) {
-                styleList.add(csWeight.getStyle());
-            }
-
-            final CalculatedValue cv =
-                calculateValue(csWeight, node, styleable, states, inlineStyles,
-                    originatingNode, fontFromCacheEntry, styleList);
-
-            // UA < AUTHOR < INLINE
-            if (origin == null || origin.compareTo(cv.getOrigin()) <= 0) {
-                if (cv.getValue() instanceof FontWeight) {
-                    weight = (FontWeight)cv.getValue();
-                    origin = cv.getOrigin();
-                }
-            }
-
-        }
-
-        CascadingStyle csStyle = null;
-        if ((csStyle = lookupFontSubPropertyStyle(node, property+"-style",
-                isUserSet, csShorthand, distance, CONSIDER_INLINE_STYLES))!= null) {
-
-            if (styleList != null) {
-                styleList.add(csStyle.getStyle());
-            }
-
-            final CalculatedValue cv =
-                calculateValue(csStyle, node, styleable, states, inlineStyles,
-                    originatingNode, fontFromCacheEntry, styleList);
-
-            // UA < AUTHOR < INLINE
-            if (origin == null || origin.compareTo(cv.getOrigin()) <= 0) {
-                if (cv.getValue() instanceof FontPosture) {
-                    style = (FontPosture)cv.getValue();
-                    origin = cv.getOrigin();
-                }
-            }
-
-        }
-
-        // if no styles were found, then skip...
-        if (family == null &&
-            size   == -1   &&
-            weight == null &&
-            style  == null) {
-            return SKIP;
-        }
-
-        // Now we have all the pieces from the stylesheet
-        // still be some missing. We'll grab those from the node.
-        Font f = null;
-        if (styleableProperty != null) {
-            f = (Font)styleableProperty.getValue();
-        }
-        if (f == null) f = Font.getDefault();
-
-        if (family == null) {
-            family = f.getFamily();
-        }
-
-        if (size == -1) {
-            size = f.getSize();
-        }
-
-        Font val = null;
-        if (weight != null && style != null) {
-            val = Font.font(family, weight, style, size);
-        } else if (weight != null) {
-            val = Font.font(family, weight, size);
-        } else if (style != null) {
-            val = Font.font(family, style, size);
-        } else {
-            val = Font.font(family, size);
-        }
-
-        return new CalculatedValue(val, origin, isRelative);
-    }
 
     /**
      * Called from CssMetaData getMatchingStyles
@@ -2097,41 +1768,6 @@
 
         if (node != null) {
 
-            Map<String,List<CascadingStyle>> inlineStyleMap = null;
-
-            // create a map of inline styles.
-            Styleable parent = node;
-            while (parent != null) {
-
-                CssStyleHelper parentHelper = (parent instanceof Node) ?
-                        ((Node)parent).styleHelper
-                        : null;
-
-                if (parentHelper != null) {
-
-                    Map<String,CascadingStyle> inlineStyles = CssStyleHelper.getInlineStyleMap(parent);
-
-                    if (inlineStyles != null) {
-
-                        if (inlineStyleMap == null) {
-                            inlineStyleMap = new HashMap<String,List<CascadingStyle>>();
-                        }
-
-                        for(Entry<String,CascadingStyle> entry : inlineStyles.entrySet()) {
-                            String kee = entry.getKey();
-
-                            List<CascadingStyle> inlineStyleList = inlineStyleMap.get(kee);
-                            if (inlineStyleList == null) {
-                                inlineStyleList = new ArrayList<CascadingStyle>();
-                                inlineStyleMap.put(kee, inlineStyleList);
-                            }
-                            inlineStyleList.add(entry.getValue());
-                        }
-                    }
-                }
-                parent = parent.getStyleableParent();
-            }
-
             String property = styleableProperty.getProperty();
             Node _node = node instanceof Node ? (Node)node : null;
             final Map<String, List<CascadingStyle>> smap = getCascadingStyles(_node);
@@ -2139,25 +1775,17 @@
 
              List<CascadingStyle> styles = smap.get(property);
 
-//            if (inlineStyleMap != null) {
-//               if (inlineStyleMap.containsKey(property)) {
-//                    List<CascadingStyle> inlineStyleList = inlineStyleMap.get(property);
-//                    if (styles == null) styles = new ArrayList<CascadingStyle>();
-//                    styles.addAll(inlineStyleList);
-//                }
-//            }
-
             if (styles != null) {
                 styleList.addAll(styles);
                 for (int n=0, nMax=styles.size(); n<nMax; n++) {
                     final CascadingStyle style = styles.get(n);
                     final ParsedValueImpl parsedValue = style.getParsedValueImpl();
-                    getMatchingLookupStyles(node, parsedValue, inlineStyleMap, styleList);
+                    getMatchingLookupStyles(node, parsedValue, styleList);
                 }
             }
 
             if (styleableProperty.isInherits()) {
-                parent = node.getStyleableParent();
+                Styleable parent = node.getStyleableParent();
                 while (parent != null) {
                     CssStyleHelper parentHelper = parent instanceof Node
                             ? ((Node)parent).styleHelper
@@ -2174,7 +1802,7 @@
     }
 
     // Pretty much a duplicate of resolveLookups, but without the state
-    private void getMatchingLookupStyles(Styleable node, ParsedValueImpl parsedValue, Map<String,List<CascadingStyle>> inlineStyleMap, List<CascadingStyle> styleList) {
+    private void getMatchingLookupStyles(Styleable node, ParsedValueImpl parsedValue, List<CascadingStyle> styleList) {
 
         if (parsedValue.isLookup()) {
 
@@ -2205,19 +1833,11 @@
 
                         }
 
-                        List<CascadingStyle> inlineStyles = (inlineStyleMap != null)
-                            ? inlineStyleMap.get(property)
-                            : null;
-
-                        if (inlineStyles != null) {
-                            styleList.addAll(inlineStyles);
-                        }
-
                         final int end = styleList.size();
 
                         for (int index=start; index<end; index++) {
                             final CascadingStyle style = styleList.get(index);
-                            getMatchingLookupStyles(parent, style.getParsedValueImpl(), inlineStyleMap, styleList);
+                            getMatchingLookupStyles(parent, style.getParsedValueImpl(), styleList);
                         }
                     }
 
@@ -2238,7 +1858,7 @@
             for (int l=0; l<layers.length; l++) {
                 for (int ll=0; ll<layers[l].length; ll++) {
                     if (layers[l][ll] == null) continue;
-                        getMatchingLookupStyles(node, layers[l][ll], inlineStyleMap, styleList);
+                        getMatchingLookupStyles(node, layers[l][ll], styleList);
                 }
             }
 
@@ -2247,7 +1867,7 @@
             final ParsedValueImpl[] layer = (ParsedValueImpl[])val;
             for (int l=0; l<layer.length; l++) {
                 if (layer[l] == null) continue;
-                    getMatchingLookupStyles(node, layer[l], inlineStyleMap, styleList);
+                    getMatchingLookupStyles(node, layer[l], styleList);
             }
         }
 
--- a/javafx-ui-common/src/javafx/scene/Node.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-common/src/javafx/scene/Node.java	Wed Jun 19 08:46:30 2013 -0400
@@ -8529,6 +8529,7 @@
             case CLEAN:
                 break;
             case DIRTY_BRANCH:
+            {
                 Parent me = (Parent)this;
                 // clear the flag first in case the flag is set to something
                 // other than clean by downstream processing.
@@ -8538,8 +8539,10 @@
                     children.get(i).processCSS();
                 }
                 break;
+            }
+            case RECALCULATE:
+                cssFlag = CssFlags.REAPPLY; // TODO
             case REAPPLY:
-            case RECALCULATE:
             case UPDATE:
             default:
                 impl_processCSS();
@@ -8619,18 +8622,11 @@
         } else if (cssFlag == CssFlags.RECALCULATE) {
 
             // Recalculate means that the in-line style has changed.
-            if (styleHelper != null) {
-                styleHelper.inlineStyleChanged(this);
-            } else {
-                // If there isn't a styleHelper now, there might need to be.
-                // Note that it is not necessary to REAPPLY css to children
-                // since the stylesheets haven't changed. The children only
-                // need to RECALCULATE their styles. A child that didn't
-                // have a styleHelper before will drop into this block, but if
-                // there are no matching style or inline styles, the child's
-                // styleHelper will still be null.
-                styleHelper = CssStyleHelper.createStyleHelper(this);
-            }
+
+            // Note: recalculate used to do something different than reapply,
+            // but the way calculated values are cached has changed.
+            // TODO: re-evalutate handling of CssFlags.RECALCULATE
+            styleHelper = CssStyleHelper.createStyleHelper(this);
 
         }
 
@@ -8640,7 +8636,7 @@
 
         // Transition to the new state and apply styles
         if (styleHelper != null) {
-            styleHelper.transitionToState(this);
+                styleHelper.transitionToState(this);
         }
     }
 
--- a/javafx-ui-common/src/javafx/scene/Parent.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-common/src/javafx/scene/Parent.java	Wed Jun 19 08:46:30 2013 -0400
@@ -849,7 +849,7 @@
             }
         } else {
             final Parent parent = getParent();
-            if (parent != null) {
+            if (parent != null && !parent.performingLayout) {
                 parent.requestLayout();
             }
         }
@@ -1030,8 +1030,6 @@
 
             // layout the children in this parent.
             layoutChildren();
-            // clear flag before recursing down so requestLayout calls arn't swallowed
-            setNeedsLayout(false);
 
             // Perform layout on each child, hoping it has random access performance!
             for (int i=0, max=children.size(); i<max; i++) {
@@ -1040,6 +1038,8 @@
                     ((Parent) child).layout();
                 }
             }
+            setNeedsLayout(false);
+
             performingLayout = false;
         } else {
             if (PULSE_LOGGING_ENABLED) PULSE_LOGGER.fxIncrementCounter("Parent#layout() on clean Node");
--- a/javafx-ui-common/src/javafx/scene/Scene.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-common/src/javafx/scene/Scene.java	Wed Jun 19 08:46:30 2013 -0400
@@ -2034,23 +2034,6 @@
         }
 
         getKeyHandler().process(e);
-
-        // our little secret...
-        if (!e.isConsumed() && e.getCode() == KeyCode.DIGIT8 &&
-             e.getEventType() == KeyEvent.KEY_PRESSED && e.isControlDown() && e.isShiftDown()) {
-            try {
-                Class scenicview = Class.forName("com.javafx.experiments.scenicview.ScenicView");
-                Class params[] = new Class[1];
-                params[0] = Scene.class;
-                java.lang.reflect.Method method = scenicview.getDeclaredMethod("show", params);
-                method.invoke(null, this);
-
-            } catch (Exception ex) {
-                // oh well
-                //System.out.println("exception instantiating ScenicView:"+ex);
-
-            }
-        }
     }
 
     void requestFocus(Node node) {
--- a/javafx-ui-common/test/unit/com/sun/javafx/css/HonorDeveloperSettingsTest.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-common/test/unit/com/sun/javafx/css/HonorDeveloperSettingsTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -26,6 +26,9 @@
 package com.sun.javafx.css;
 
 import static org.junit.Assert.*;
+
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
 import javafx.scene.Cursor;
 import javafx.scene.Group;
 import javafx.scene.Scene;
@@ -36,8 +39,10 @@
 import javafx.stage.Stage;
 import javafx.stage.Window;
 
+import com.sun.javafx.Logging;
 import org.junit.Before;
 import org.junit.Test;
+import sun.util.logging.PlatformLogger;
 
 /**
  * AKA: RT-7401. Tests that the pattern used works by testing opacity
@@ -116,7 +121,7 @@
         assertEquals(.873, rect.getOpacity(), 0.01);
     }
 
-    @Test @org.junit.Ignore("fails, but works from an application")
+    @Test
     public void testOpacityWithManuallyChangedValueAndInlineStyleIsSetToInlineStyle() {
         rect.impl_processCSS(true);
         assertEquals(.76, rect.getOpacity(), 0.01);
@@ -257,7 +262,7 @@
         
     }
     
-    @Test @org.junit.Ignore("fails, but works from an application")
+    @Test
     public void testInlineStyleInheritedFromParentApplies() {
 
         // Must remove the id so we don't match on the ua style.
@@ -354,7 +359,7 @@
 
         // want text to get font style from .root
         // assuming here that test_FontInheritsFromDotRootStyle passed
-        text.setId(null);        
+        text.setId(null);
         text.setStyle("-fx-font-size: 24;");
 
         scene.getRoot().impl_processCSS(true);
--- a/javafx-ui-common/test/unit/com/sun/javafx/css/parser/CSSParserTest.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-common/test/unit/com/sun/javafx/css/parser/CSSParserTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -155,7 +155,6 @@
         assertTrue(Double.compare(size, 12) == 0);
     }
     
-    @Ignore("RT-31042")
     @Test public void test_RT_18126() {
         // CSS cannot write binary -fx-background-repeat: repeat, no-repeat;
         String data = "#rt18126 {"
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/accessible/AccessibleList.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/accessible/AccessibleList.java	Wed Jun 19 08:46:30 2013 -0400
@@ -122,32 +122,6 @@
      */
     @Override
     public Object[] getSelection() {
-        /**
-         * For now the following code is being commented out due to the use of getMethod
-         * as flagged by findbugs and reported in RT-28367.  When this code is finally
-         * implemented the issue raised by RT-28367 should be resolved in some manner
-         * other than throwing UnsupportedOperationException.
-         * 
-         * 
-        // Fix this later to allocate and fill the correctly sized array.
-        //      For now it will work for single selection lists.
-        Object[] selection = new Object[1];  // it'll be a Glass AccessibleBaseProvider
-        //  selection[1] = null;  // Is this needed?  Probably already null.
-        Object selected = listView.getSelectionModel().getSelectedItem();
-        try {
-            java.lang.reflect.Method method = selected.getClass().getMethod("impl_getAccessible");
-            AccessibleProvider provider = (AccessibleProvider)method.invoke(selected);
-        // if (selected instanceof Accessible) {
-           // AccessibleProvider provider = ((Accessible)selected).impl_getAccessible();
-            if (provider instanceof AccessibleNode) {
-                selection[1] = ((AccessibleNode)provider).getAccessibleElement();
-            }
-        } catch (Exception ex) {
-        }
-        return selection;
-         * 
-         *
-         */
         throw new UnsupportedOperationException();
     }
 
@@ -187,32 +161,6 @@
      */
     @Override   
     public Object getItem(int row, int col) {
-        Object item = null;
-        // get the cell and then its associated provider
-        /**
-         * For now the following code is being commented out due to the use of getMethod
-         * as flagged by findbugs and reported in RT-28367.  When this code is finally
-         * implemented the issue raised by RT-28367 should be resolved in some manner
-         * other than throwing UnsupportedOperationException.
-         * 
-         * 
-        // TODO fix this to return the appropriate item
-        listView.getItems().get(row);
-        for (Node cell : listView.lookupAll(".cell")) {
-            if (cell instanceof Cell) {
-                try {
-                    java.lang.reflect.Method method = cell.getClass().getMethod("impl_getAccessible");
-                    AccessibleProvider provider = (AccessibleProvider)method.invoke(cell);
-                    if (provider instanceof AccessibleNode) {
-                        item = ((AccessibleNode)provider).getAccessibleElement();
-                    }
-                } catch (Exception ex) {}
-            }
-        }
-        return item;
-         *
-         * 
-         */
         throw new UnsupportedOperationException();
     }
 
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/accessible/AccessibleListItem.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/accessible/AccessibleListItem.java	Wed Jun 19 08:46:30 2013 -0400
@@ -140,23 +140,6 @@
      */
     @Override
     public Object getSelectionContainer() {
-        /**
-         * For now the following code is being commented out due to the use of getMethod
-         * as flagged by findbugs and reported in RT-28367.  When this code is finally
-         * implemented the issue raised by RT-28367 should be resolved in some manner
-         * other than throwing UnsupportedOperationException.
-         *
-         * 
-        Object item = null;
-        try {
-            java.lang.reflect.Method method = listView.getClass().getMethod("impl_getAccessible");
-            AccessibleProvider provider = (AccessibleProvider)method.invoke(listView);
-            item = ((AccessibleNode)provider).getAccessibleElement();
-            } catch (Exception ex) {}
-        return item;
-         *
-         * 
-         */
         throw new UnsupportedOperationException();
     }
 
@@ -209,26 +192,6 @@
      */
     @Override
     public Object getContainingGrid() {
-        /**
-         * For now the following code is being commented out due to the use of getMethod
-         * as flagged by findbugs and reported in RT-28367.  When this code is finally
-         * implemented the issue raised by RT-28367 should be resolved in some manner
-         * other than throwing UnsupportedOperationException.
-         *
-         *
-        Object container = null;
-        try {
-            java.lang.reflect.Method method =
-                listView.getClass().getMethod("impl_getAccessible");
-            AccessibleProvider provider = (AccessibleProvider)method.invoke(listView);
-            if (provider instanceof AccessibleNode) {
-                container = ((AccessibleNode)provider).getAccessibleElement();
-            }                   
-        } catch (Exception ex) {}
-        return container;
-         *
-         * 
-         */
         throw new UnsupportedOperationException();
     }
     
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ContextMenuContent.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ContextMenuContent.java	Wed Jun 19 08:46:30 2013 -0400
@@ -601,29 +601,6 @@
                 // on the Menu whose submenu is open.
                 if (submenu != null && submenu.isShowing()) return;
                   
-                // RT-15339 : if this context menu has another context menu part 
-                // of its content, then do nothing similar to the submenu case.
-                // walk thru all windows open to see if if this context menu is
-                // the owner window for another context menu, if so return.
-                final Iterator<Window> iter =
-                        AccessController.doPrivileged(
-                                new PrivilegedAction<Iterator<Window>>() {
-                                    @Override
-                                    public Iterator<Window> run() {
-                                        return Window.impl_getWindows();
-                                    }
-                                });
-                while(iter.hasNext()) {
-                    Window w = iter.next();
-                    if (w instanceof ContextMenu && !(contextMenu == w)) {
-                        Window ownerWin = ((ContextMenu)w).getOwnerWindow();
-                        if (contextMenu == ownerWin && ownerWin.isShowing()) {
-                            return;
-                        }
-                        
-                    }
-                    
-                }
                 requestFocus();
             }
         });
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/DatePickerContent.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/DatePickerContent.java	Wed Jun 19 08:46:30 2013 -0400
@@ -247,19 +247,6 @@
                     }
                 }
 
-                // our little secret... borrowed from Scene.java
-                if (!e.isConsumed() && e.getCode() == KeyCode.DIGIT8 &&
-                     e.getEventType() == KeyEvent.KEY_PRESSED && e.isControlDown() && e.isShiftDown()) {
-                    try {
-                        Class scenicview = Class.forName("com.javafx.experiments.scenicview.ScenicView");
-                        Class params[] = new Class[] { getScene().getClass() };
-                        java.lang.reflect.Method method = scenicview.getDeclaredMethod("show", params);
-                        method.invoke(null, getScene());
-                    } catch (Exception ex) {
-                        //System.out.println("exception instantiating ScenicView:"+ex);
-                    }
-                }
-
                 // Consume all key events except those that control
                 // showing the popup.
                 switch (e.getCode()) {
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/EmbeddedTextContextMenuContent.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/EmbeddedTextContextMenuContent.java	Wed Jun 19 08:46:30 2013 -0400
@@ -25,6 +25,7 @@
 
 package com.sun.javafx.scene.control.skin;
 
+import java.util.Map;
 import javafx.beans.InvalidationListener;
 import javafx.beans.Observable;
 import javafx.collections.ListChangeListener;
@@ -132,19 +133,25 @@
         double pointerX = 0;
 
         // Get the positions of the cursor from the TextArea/TextField and draw the arrow underneath it.
+        Map properties = null;
         if (contextMenu.getOwnerNode() instanceof TextArea) {
-            TextArea ta = (TextArea)contextMenu.getOwnerNode();
-            TextAreaSkin tas = (TextAreaSkin)ta.getSkin();
-            sceneX = Double.valueOf(tas.getSkinnable().getProperties().get("CONTEXT_MENU_SCENE_X").toString());
-            screenX = Double.valueOf(tas.getSkinnable().getProperties().get("CONTEXT_MENU_SCREEN_X").toString());
-            tas.getSkinnable().getProperties().clear();
+            properties = ((TextArea)contextMenu.getOwnerNode()).getProperties();
         } else if (contextMenu.getOwnerNode() instanceof TextField) {
-            TextField tf = (TextField)contextMenu.getOwnerNode();
-            TextFieldSkin tfs = (TextFieldSkin)tf.getSkin();
-            sceneX = Double.valueOf(tfs.getSkinnable().getProperties().get("CONTEXT_MENU_SCENE_X").toString());
-            screenX = Double.valueOf(tfs.getSkinnable().getProperties().get("CONTEXT_MENU_SCREEN_X").toString());
-            tfs.getSkinnable().getProperties().clear();
+            properties = ((TextField)contextMenu.getOwnerNode()).getProperties();
         }
+
+        if (properties != null) {
+            if (properties.containsKey("CONTEXT_MENU_SCENE_X")) {
+                sceneX = Double.valueOf(properties.get("CONTEXT_MENU_SCENE_X").toString());
+                properties.remove("CONTEXT_MENU_SCENE_X");
+            }
+
+            if (properties.containsKey("CONTEXT_MENU_SCREEN_X")) {
+                screenX = Double.valueOf(properties.get("CONTEXT_MENU_SCREEN_X").toString());
+                properties.remove("CONTEXT_MENU_SCREEN_X");
+            }
+        }
+
         if (sceneX == 0) {
             pointerX = width/2;
         } else {
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/FXVKSkin.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/FXVKSkin.java	Wed Jun 19 08:46:30 2013 -0400
@@ -29,8 +29,6 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.lang.reflect.Field;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -138,28 +136,6 @@
         }
     }
 
-
-    /**
-     * If true, places the virtual keyboard(s) in a new root wrapper
-     * on the scene instead of in a popup. The children of the wrapper
-     * are the original root container and a Group of one or more
-     * keyboards.
-     *
-     * This is suitable for a fullscreen application that does not use
-     * dialogs with text input controls.
-     *
-     * The root wrapper pans up/down automatically as needed to keep
-     * the focused input control visible, and allows the user to drag
-     * up/down with mouse or touch.
-     */
-    private final static boolean inScene =
-        AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
-            @Override public Boolean run() {
-                String value = System.getProperty("com.sun.javafx.fxvkContainerType");
-                return ("inscene".equalsIgnoreCase(value));
-            }
-    });
-
     private final static boolean USE_SECONDARY_POPUP = false;
 
     private static Region oldRoot;
@@ -204,13 +180,6 @@
         });
     }
 
-    private static Boolean enableCaching = AccessController.doPrivileged(
-    new PrivilegedAction<Boolean>() {
-        @Override public Boolean run() {
-            return Boolean.getBoolean("com.sun.javafx.scene.control.skin.FXVK.cache");
-        }
-    });
-
     private static void startSlideIn() {
         slideOutTimeline.stop();
         winY.set(vkPopup.getY());
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/LabeledText.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/LabeledText.java	Wed Jun 19 08:46:30 2013 -0400
@@ -273,8 +273,8 @@
             //    not override
             //
             if (propOrigin == null ||
-                    newOrigin == null ||
-                    propOrigin.compareTo(newOrigin) <= 0) {
+                   (newOrigin != null &&
+                    propOrigin.compareTo(newOrigin) <= 0)) {
                 super.applyStyle(newOrigin, value);
             }
         }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/NestedTableColumnHeader.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/NestedTableColumnHeader.java	Wed Jun 19 08:46:30 2013 -0400
@@ -75,6 +75,13 @@
             changeListenerHandler.registerChangeListener(getTableColumn().textProperty(), "TABLE_COLUMN_TEXT");
         }
         
+        // watching for changes to the view columns in either table or tableColumn.
+        if (getTableColumn() == null && getTableViewSkin() != null) {
+            setColumns(getTableViewSkin().getColumns());
+        } else if (getTableColumn() != null) {
+            setColumns(getTableColumn().getColumns());
+        }
+
         changeListenerHandler.registerChangeListener(skin.columnResizePolicyProperty(), "TABLE_VIEW_COLUMN_RESIZE_POLICY");
     }
 
@@ -141,18 +148,11 @@
         if (this.columns != null) {
             this.columns.addListener(weakColumnsListener);
         }
+
+        updateTableColumnHeaders();
     }
     
     void updateTableColumnHeaders() {
-        // watching for changes to the view columns in either table or tableColumn.
-        if (getTableColumn() == null && getTableViewSkin() != null) {
-            setColumns(getTableViewSkin().getColumns());
-        } else if (getTableColumn() != null) {
-            setColumns(getTableColumn().getColumns());
-        }
-        
-        // update the column headers....
-        
         // iterate through all current headers, telling them to clean up
         for (int i = 0; i < getColumnHeaders().size(); i++) {
             TableColumnHeader header = getColumnHeaders().get(i);
@@ -399,7 +399,6 @@
     /* **************************/
 
     void setHeadersNeedUpdate() {
-        updateColumns = true;
         // go through children columns - they should update too
         for (int i = 0; i < getColumnHeaders().size(); i++) {
             TableColumnHeader header = getColumnHeaders().get(i);
@@ -407,16 +406,12 @@
                 ((NestedTableColumnHeader)header).setHeadersNeedUpdate();
             }
         }
+        updateTableColumnHeaders();
         requestLayout();
     }
     
-    boolean updateColumns = true;
     @Override protected void layoutChildren() {
-        if (updateColumns) {
-            updateTableColumnHeaders();
-            updateColumns = false;
-            getParent().requestLayout();
-        }
+
         double w = getWidth() - snappedLeftInset() - snappedRightInset();
         double h = getHeight() - snappedTopInset() - snappedBottomInset();
         
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableColumnHeader.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableColumnHeader.java	Wed Jun 19 08:46:30 2013 -0400
@@ -143,11 +143,6 @@
             // visually adjusts its width as necessary.
             isSizeDirty = true;
             requestLayout();
-        } else if ("TABLE_COLUMN_WIDTH".equals(p)) {
-            // It is this that ensures that when a column is resized that the header
-            // visually adjusts its width as necessary.
-            isSizeDirty = true;
-            requestLayout();
         } else if ("TABLE_COLUMN_ID".equals(p)) {
             setId(column.getId());
         } else if ("TABLE_COLUMN_STYLE".equals(p)) {
@@ -429,6 +424,7 @@
         label.setAlignment(Pos.CENTER);
         label.setText(column.getText());
         label.setGraphic(column.getGraphic());
+        label.setVisible(column.isVisible());
 
         // ---- container for the sort arrow (which is not supported on embedded
         // platforms)
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/Utils.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/Utils.java	Wed Jun 19 08:46:30 2013 -0400
@@ -547,195 +547,6 @@
         }
     }
 
-
-    /*    private static Object KERNING;
-       private static Object KERNING_ON;
-       private static Object LIGATURES;
-       private static Object LIGATURES_ON;
-       private static Object TRACKING;
-
-       static {
-       try {
-       KERNING = TextAttribute.class.getField("KERNING").get(null);
-       KERNING_ON = TextAttribute.class.getField("KERNING_ON").get(null);
-       LIGATURES = TextAttribute.class.getField("LIGATURES").get(null);
-       LIGATURES_ON = TextAttribute.class.getField("LIGATURES_ON").get(null);
-       TRACKING = TextAttribute.class.getField("TRACKING").get(null);
-       }
-       catch (Exception e) {
-       // running on 1.5
-       KERNING = KERNING_ON = LIGATURES = LIGATURES_ON = TRACKING = "unsupported";
-       }
-       }
-
-       private static FontRenderContext DEFAULT_FRC = new FontRenderContext(null, false, false);
-
-       private Utils() {}
-
-       static FontMetrics getFontMetrics(Font font) {
-       return getFontMetrics(font, DEFAULT_FRC);
-       }
-
-       static double computeLineHeight(Font font) {
-       if (font == null) return 0;
-       FontMetrics metrics = getFontMetrics(font, DEFAULT_FRC);
-       return metrics.getMaxAscent() + metrics.getMaxDescent();
-       }
-
-       static double computeXHeight(Font font) {
-       if (font == null) return 0;
-       return font.createGlyphVector(DEFAULT_FRC, "x").getGlyphMetrics(0).getBounds2D().getHeight();
-       }
-
-       // computes an offset from the baseline that would be the location of
-       // the center of the font. basically, this is where strikthrough would
-       // happen
-       static double computeCenterline(Font font) {
-       FontMetrics metrics = getFontMetrics(font, DEFAULT_FRC);
-       return metrics.getAscent() / 2;
-       }*/
-
-    /**
-     * Computes the width of the string if displayed with a default font
-     * render context (typically useful for display but not for printing).
-     * Nodes in the scene graph don't have a way to fetch the font render
-     * context, and computation of string widths typically happens outside
-     * of a paint cycle (since the scene graph is a retained mode API and not
-     * an immediate mode API).
-     *
-     * @param font this is an AWT font because I cannot refer to the fx font
-     *        from this java file.
-     * @param string
-     * @return
-     */
-    /*    static double computeStringWidth(Font font, String string) {
-       if (string == null || string.equals("")) return 0;
-       FontMetrics metrics = getFontMetrics(font, DEFAULT_FRC);
-       return computeStringWidth(metrics, string);
-       }
-
-       static double computeStringWidth(FontMetrics metrics, String string) {
-       if (string == null || string.equals("")) return 0;
-       return metrics.stringWidth(string);
-       }
-
-       private static boolean contains(Map map, Object key, Object value) {
-       Object o = map.get(key);
-       return o != null && o.equals(value);
-       }
-
-       private static boolean fontDesignMetricsInitialized = false;
-       private static Class<?> fontDesignMetricsClass;
-       private static Method getFontDesignMetrics;
-       private static Constructor newFontDesignMetrics;
-
-       private static synchronized FontMetrics getFontMetrics(final Font font, final FontRenderContext frc) {
-       FontMetrics rv = null;
-       if (! fontDesignMetricsInitialized) {
-       AccessController.doPrivileged(
-       new PrivilegedAction<Void>() {
-       public Void run() {
-       fontDesignMetricsInitialized = true;
-       try {
-       fontDesignMetricsClass =
-       Class.forName("sun.font.FontDesignMetrics", true, null);
-       } catch (ClassNotFoundException e) {
-       return null;
-       }
-       try {
-       newFontDesignMetrics =
-       fontDesignMetricsClass.getConstructor(Font.class,
-       FontRenderContext.class);
-       getFontDesignMetrics =
-       fontDesignMetricsClass.getMethod("getMetrics",
-       Font.class, FontRenderContext.class);
-       } catch (NoSuchMethodException ignore) {
-       }
-       return null;
-       }
-       });
-       }
-       try {
-       if (getFontDesignMetrics != null) {
-       rv = (FontMetrics) getFontDesignMetrics.invoke(null, font, frc);
-       } else if (newFontDesignMetrics != null) {
-       rv = (FontMetrics) newFontDesignMetrics.newInstance(font, frc);
-       }
-       } catch(IllegalAccessException ignore) {
-       } catch(InstantiationException ignore) {
-       } catch(InvocationTargetException exception) {
-       if (exception.getTargetException() instanceof RuntimeException) {
-       throw (RuntimeException) exception.getTargetException();
-       }
-       }
-       if (rv == null) {
-       //can not create FontDesignMetrics. Fall back to toolkit's fontMetrics.
-       rv = Toolkit.getDefaultToolkit().getFontMetrics(font);
-       }
-       return rv;
-       }*/
-
-    // ---- begin code included from SwingUtilities2 ----
-    // This code is present in sun.swing.SwingUtilities2 in JRE 1.6 or higher, but
-    // was copied into our codebase to handle running on Java 1.5.  Arguably we
-    // shouldn't be depending on sun.* APIs if at all possible anyway.
-
-    /**
-     * Indic, Thai, and surrogate char values require complex
-     * text layout and cursor support.
-     *
-     * @param ch character to be tested
-     * @return <tt>true</tt> if TextLayout is required
-     */
-    /*    private static final boolean isComplexLayout(char ch) {
-       return (ch >= '\u0900' && ch <= '\u0D7F') || // Indic
-       (ch >= '\u0E00' && ch <= '\u0E7F') || // Thai
-       (ch >= '\u1780' && ch <= '\u17ff') || // Khmer
-       (ch >= '\uD800' && ch <= '\uDFFF');   // surrogate value range
-       }*/
-
-    /**
-     * Fast method to check that TextLayout is not required for the
-     * character.
-     * if returns <tt>true</tt> TextLayout is not required
-     * if returns <tt>false</tt> TextLayout might be required
-     *
-     * @param ch character to be tested
-     * @return <tt>true</tt> if TextLayout is not required
-     */
-    /*    private static final boolean isSimpleLayout(char ch) {
-       return ch < 0x590 || (0x2E00 <= ch && ch < 0xD800);
-       }*/
-
-    /**
-     * checks whether TextLayout is required to handle characters.
-     *
-     * @param text characters to be tested
-     * @param start start
-     * @param limit limit
-     * @return <tt>true</tt>  if TextLayout is required
-     *         <tt>false</tt> if TextLayout is not required
-     */
-    /*    public static final boolean isComplexLayout(char[] text, int start, int limit) {
-       boolean simpleLayout = true;
-       char ch;
-       for (int i = start; i < limit; ++i) {
-       ch = text[i];
-       if (isComplexLayout(ch)) {
-       return true;
-       }
-       if (simpleLayout) {
-       simpleLayout = isSimpleLayout(ch);
-       }
-       }
-       if (simpleLayout) {
-       return false;
-       } else {
-       return Bidi.requiresBidi(text, start, limit);
-       }
-       }*/
-    // ---- end code included from SwingUtilities2 ----
-
     private static boolean requiresComplexLayout(Font font, String string) {
         /*        Map attrs = font.getAttributes();
            if (contains(attrs, KERNING, KERNING_ON) ||
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/resources/ControlResources.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/resources/ControlResources.java	Wed Jun 19 08:46:30 2013 -0400
@@ -38,6 +38,10 @@
     // Do not cache the bundle here. It is cached by the ResourceBundle
     // class and may be updated if the default locale changes.
 
+    private ControlResources() {
+        // no-op
+    }
+
     /*
      * Look up a string in the properties file corresponding to the
      * default locale (i.e. the application's locale). If not found, the
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/resources/EmbeddedResources.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/resources/EmbeddedResources.java	Wed Jun 19 08:46:30 2013 -0400
@@ -31,6 +31,10 @@
 
     private static ResourceBundle embeddedResourceBundle;
 
+    private EmbeddedResources() {
+        // no-op
+    }
+
     public static ResourceBundle getBundle() {
         if (embeddedResourceBundle == null) {
             embeddedResourceBundle = ResourceBundle.getBundle("com/sun/javafx/scene/control/skin/resources/embedded");
--- a/javafx-ui-controls/src/javafx/scene/control/Labeled.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/Labeled.java	Wed Jun 19 08:46:30 2013 -0400
@@ -734,6 +734,13 @@
     //     * externalization will work as expected
     //     */
 
+    @Override public String toString() {
+        StringBuilder builder =
+            new StringBuilder(super.toString())
+                .append("'").append(getText()).append("'");
+        return builder.toString();
+    }
+
     /***************************************************************************
      *                                                                         *
      * Stylesheet Handling                                                     *
--- a/javafx-ui-controls/src/javafx/scene/control/SkinBase.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/SkinBase.java	Wed Jun 19 08:46:30 2013 -0400
@@ -113,15 +113,6 @@
         
         // Default behavior for controls is to consume all mouse events
         consumeMouseEvents(true);
-        
-        // RT-28337: request layout on prefWidth / prefHeight changes
-        InvalidationListener prefSizeListener = new InvalidationListener() {
-            @Override public void invalidated(Observable o) {
-                control.requestLayout();
-            }
-        };
-        this.control.prefWidthProperty().addListener(prefSizeListener);
-        this.control.prefHeightProperty().addListener(prefSizeListener);
     }
     
     
@@ -169,10 +160,12 @@
      */
     protected void layoutChildren(final double contentX, final double contentY,
             final double contentWidth, final double contentHeight) {
-        // By default simply sizes all children to fit within the space provided
+        // By default simply sizes all managed children to fit within the space provided
         for (int i=0, max=children.size(); i<max; i++) {
             Node child = children.get(i);
-            layoutInArea(child, contentX, contentY, contentWidth, contentHeight, -1, HPos.CENTER, VPos.CENTER);
+            if (child.isManaged()) {
+                layoutInArea(child, contentX, contentY, contentWidth, contentHeight, -1, HPos.CENTER, VPos.CENTER);
+            }
         }
     }
     
--- a/javafx-ui-controls/src/javafx/scene/control/cell/ChoiceBoxListCell.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/cell/ChoiceBoxListCell.java	Wed Jun 19 08:46:30 2013 -0400
@@ -295,8 +295,11 @@
         choiceBox.getSelectionModel().select(getItem());
         
         super.startEdit();
-        setText(null);
-        setGraphic(choiceBox);
+
+        if (isEditing()) {
+            setText(null);
+            setGraphic(choiceBox);
+        }
     }
 
     /** {@inheritDoc} */
--- a/javafx-ui-controls/src/javafx/scene/control/cell/ChoiceBoxTreeCell.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/cell/ChoiceBoxTreeCell.java	Wed Jun 19 08:46:30 2013 -0400
@@ -293,6 +293,12 @@
         if (! isEditable() || ! getTreeView().isEditable()) {
             return;
         }
+
+        TreeItem<T> treeItem = getTreeItem();
+        if (treeItem == null) {
+            return;
+        }
+
         if (choiceBox == null) {
             choiceBox = createChoiceBox(this, items);
         }
@@ -300,17 +306,20 @@
             hbox = new HBox(CellUtils.TREE_VIEW_HBOX_GRAPHIC_PADDING);
         }
         
-        choiceBox.getSelectionModel().select(getTreeItem().getValue());
+        choiceBox.getSelectionModel().select(treeItem.getValue());
         
         super.startEdit();
-        setText(null);
-        
-        Node graphic = getTreeItemGraphic();
-        if (graphic != null) {
-            hbox.getChildren().setAll(graphic, choiceBox);
-            setGraphic(hbox);
-        } else {
-            setGraphic(choiceBox);
+
+        if (isEditing()) {
+            setText(null);
+
+            Node graphic = getTreeItemGraphic();
+            if (graphic != null) {
+                hbox.getChildren().setAll(graphic, choiceBox);
+                setGraphic(hbox);
+            } else {
+                setGraphic(choiceBox);
+            }
         }
     }
 
--- a/javafx-ui-controls/src/javafx/scene/control/cell/ComboBoxListCell.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/cell/ComboBoxListCell.java	Wed Jun 19 08:46:30 2013 -0400
@@ -323,8 +323,11 @@
         comboBox.getSelectionModel().select(getItem());
         
         super.startEdit();
-        setText(null);
-        setGraphic(comboBox);
+
+        if (isEditing()) {
+            setText(null);
+            setGraphic(comboBox);
+        }
     }
 
     /** {@inheritDoc} */
--- a/javafx-ui-controls/src/javafx/scene/control/cell/ComboBoxTreeCell.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/cell/ComboBoxTreeCell.java	Wed Jun 19 08:46:30 2013 -0400
@@ -320,6 +320,12 @@
         if (! isEditable() || ! getTreeView().isEditable()) {
             return;
         }
+
+        TreeItem<T> treeItem = getTreeItem();
+        if (treeItem == null) {
+            return;
+        }
+
         if (comboBox == null) {
             comboBox = createComboBox(this, items, getConverter());
             comboBox.editableProperty().bind(comboBoxEditableProperty());
@@ -328,17 +334,20 @@
             hbox = new HBox(CellUtils.TREE_VIEW_HBOX_GRAPHIC_PADDING);
         }
         
-        comboBox.getSelectionModel().select(getTreeItem().getValue());
+        comboBox.getSelectionModel().select(treeItem.getValue());
         
         super.startEdit();
-        setText(null);
-        
-        Node graphic = CellUtils.getGraphic(getTreeItem());
-        if (graphic != null) {
-            hbox.getChildren().setAll(graphic, comboBox);
-            setGraphic(hbox);
-        } else {
-            setGraphic(comboBox);
+
+        if (isEditing()) {
+            setText(null);
+
+            Node graphic = CellUtils.getGraphic(treeItem);
+            if (graphic != null) {
+                hbox.getChildren().setAll(graphic, comboBox);
+                setGraphic(hbox);
+            } else {
+                setGraphic(comboBox);
+            }
         }
     }
 
--- a/javafx-ui-controls/src/javafx/scene/control/cell/TextFieldListCell.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/cell/TextFieldListCell.java	Wed Jun 19 08:46:30 2013 -0400
@@ -183,12 +183,14 @@
             return;
         }
         super.startEdit();
-        
-        if (textField == null) {
-            textField = CellUtils.createTextField(this, getConverter());
+
+        if (isEditing()) {
+            if (textField == null) {
+                textField = CellUtils.createTextField(this, getConverter());
+            }
+
+            CellUtils.startEdit(this, getConverter(), null, null, textField);
         }
-        
-        CellUtils.startEdit(this, getConverter(), null, null, textField);
     }
 
     /** {@inheritDoc} */
--- a/javafx-ui-controls/src/javafx/scene/control/cell/TextFieldTableCell.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/cell/TextFieldTableCell.java	Wed Jun 19 08:46:30 2013 -0400
@@ -186,12 +186,14 @@
             return;
         }
         super.startEdit();
-        
-        if (textField == null) {
-            textField = CellUtils.createTextField(this, getConverter());
+
+        if (isEditing()) {
+            if (textField == null) {
+                textField = CellUtils.createTextField(this, getConverter());
+            }
+
+            CellUtils.startEdit(this, getConverter(), null, null, textField);
         }
-        
-        CellUtils.startEdit(this, getConverter(), null, null, textField);
     }
 
     /** {@inheritDoc} */
--- a/javafx-ui-controls/src/javafx/scene/control/cell/TextFieldTreeCell.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/cell/TextFieldTreeCell.java	Wed Jun 19 08:46:30 2013 -0400
@@ -193,16 +193,18 @@
             return;
         }
         super.startEdit();
-        
-        StringConverter<T> converter = getConverter();
-        if (textField == null) {
-            textField = CellUtils.createTextField(this, converter);
+
+        if (isEditing()) {
+            StringConverter<T> converter = getConverter();
+            if (textField == null) {
+                textField = CellUtils.createTextField(this, converter);
+            }
+            if (hbox == null) {
+                hbox = new HBox(CellUtils.TREE_VIEW_HBOX_GRAPHIC_PADDING);
+            }
+
+            CellUtils.startEdit(this, converter, hbox, getTreeItemGraphic(), textField);
         }
-        if (hbox == null) {
-            hbox = new HBox(CellUtils.TREE_VIEW_HBOX_GRAPHIC_PADDING);
-        }
-        
-        CellUtils.startEdit(this, converter, hbox, getTreeItemGraphic(), textField);
     }
 
     /** {@inheritDoc} */
--- a/javafx-ui-controls/src/javafx/scene/control/cell/TextFieldTreeTableCell.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/cell/TextFieldTreeTableCell.java	Wed Jun 19 08:46:30 2013 -0400
@@ -188,12 +188,14 @@
             return;
         }
         super.startEdit();
-        
-        if (textField == null) {
-            textField = CellUtils.createTextField(this, getConverter());
+
+        if (isEditing()) {
+            if (textField == null) {
+                textField = CellUtils.createTextField(this, getConverter());
+            }
+
+            CellUtils.startEdit(this, getConverter(), null, null, textField);
         }
-        
-        CellUtils.startEdit(this, getConverter(), null, null, textField);
     }
 
     /** {@inheritDoc} */
--- a/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/LabeledTextTest.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/LabeledTextTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -73,7 +73,7 @@
     public void testLabeledTextAlignmentStyleAffectsLabeledText() {
         
         label.setStyle("-fx-text-alignment: right;");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         assertEquals(TextAlignment.RIGHT, label.getTextAlignment());
         assertEquals(TextAlignment.RIGHT, labeledText.getTextAlignment());
     
@@ -93,7 +93,7 @@
     public void testLabeledFontStyleAffectsLabeledText() {
         
         label.setStyle("-fx-font: 10px Amble;");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         Font expected = Font.font("Amble", 10);
         assertEquals(expected, label.getFont());
         assertEquals(expected, labeledText.getFont());
@@ -114,7 +114,7 @@
     public void testLabeledTextFillStyleAffectsLabeledText() {
         
         label.setStyle("-fx-text-fill: rgb(255,0,0);");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         Color expected = Color.rgb(255, 0, 0);
         assertEquals(expected, label.getTextFill());
         assertEquals(expected, labeledText.getFill());
@@ -135,7 +135,7 @@
     public void testLabeledUnderlineStyleAffectsLabeledText() {
         
         label.setStyle("-fx-underline: true;");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         assert(label.isUnderline() == true);
         assert(labeledText.isUnderline() == true);
     
@@ -144,7 +144,7 @@
     @Test
     public void testLabeledBlendModeStyleDoesNotAffectLabeledText() {
         label.setStyle("-fx-blend-mode: color-burn;");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         assertEquals(BlendMode.COLOR_BURN,label.getBlendMode());
         assertFalse(BlendMode.COLOR_BURN.equals(labeledText.getBlendMode())); 
     }
@@ -152,7 +152,7 @@
     @Test
     public void testLabeledCursorStyleDoesNotAffectLabeledText() {
         label.setStyle("-fx-cursor: crosshair;");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         assertEquals(Cursor.CROSSHAIR,label.getCursor());
         assertFalse(Cursor.CROSSHAIR.equals(labeledText.getCursor()));
     }
@@ -160,7 +160,7 @@
     @Test
     public void testLabeledEffectStyleDoesNotAffectLabeledText() {
         label.setStyle("-fx-effect: dropshadow(one-pass-box, red, 64, .5, 2, 3);");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         assertNotNull(label.getEffect());
         assertNull(labeledText.getEffect()); 
     }
@@ -168,7 +168,7 @@
     @Test
     public void testLabeledFocusTraversableStyleDoesNotAffectLabeledText() {
         label.setStyle("-fx-focus-traversable: true;");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         assert(label.focusTraversableProperty().get() == true);   
         assert(labeledText.focusTraversableProperty().get() == false);   
     }
@@ -176,7 +176,7 @@
     @Test
     public void testLabeledOpacityStyleDoesNotAffectLabeledText() {
         label.setStyle("-fx-opacity: .5;");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         assertEquals(label.getOpacity(), .5, .0000001);   
         assertEquals(labeledText.getOpacity(), 1, .0000001);   
     }
@@ -184,7 +184,7 @@
     @Test
     public void testLabeledRotateStyleDoesNotAffectLabeledText() {
         label.setStyle("-fx-rotate: 180;");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         assertEquals(label.getRotate(), 180, .0000001);
         assertEquals(labeledText.getRotate(), 0, .0000001);   
     }
@@ -192,7 +192,7 @@
     @Test
     public void testLabeledScaleXStyleDoesNotAffectLabeledText() {
         label.setStyle("-fx-scale-x: .5;");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         assertEquals(label.getScaleX(), .5, .0000001);
         assertEquals(labeledText.getScaleX(), 1, .0000001);   
     }
@@ -200,7 +200,7 @@
     @Test
     public void testLabeledScaleYStyleDoesNotAffectLabeledText() {
         label.setStyle("-fx-scale-y: .5;");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         assertEquals(label.getScaleY(), .5, .0000001);
         assertEquals(labeledText.getScaleY(), 1, .0000001);   
     }
@@ -208,7 +208,7 @@
     @Test
     public void testLabeledScaleZStyleDoesNotAffectLabeledText() {
         label.setStyle("-fx-scale-z: .5;");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         assertEquals(label.getScaleZ(), .5, .0000001);
         assertEquals(labeledText.getScaleZ(), 1, .0000001);   
     }
@@ -216,7 +216,7 @@
     @Test
     public void testLabeledTranslateXStyleDoesNotAffectLabeledText() {
         label.setStyle("-fx-translate-x: .5;");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         assertEquals(label.getTranslateX(), .5, .0000001);
         assertEquals(labeledText.getTranslateX(), 0, .0000001);   
     }
@@ -224,7 +224,7 @@
     @Test
     public void testLabeledTranslateYStyleDoesNotAffectLabeledText() {
         label.setStyle("-fx-translate-y: .5;");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         assertEquals(label.getTranslateY(), .5, .0000001);
         assertEquals(labeledText.getTranslateY(), 0, .0000001);   
     }
@@ -232,7 +232,7 @@
     @Test
     public void testLabeledTranslateZStyleDoesNotAffectLabeledText() {
         label.setStyle("-fx-translate-z: .5;");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         assertEquals(label.getTranslateZ(), .5, .0000001);
         assertEquals(labeledText.getTranslateZ(), 0, .0000001);   
     }
@@ -240,7 +240,7 @@
     @Test
     public void testLabeledVisibilityStyleDoesNotAffectLabeledText() {
         label.setStyle("visibility: false;");
-        label.impl_processCSS(false);
+        label.impl_processCSS(true);
         assert(label.visibleProperty().get() == false);   
         assert(labeledText.visibleProperty().get() == true);   
     }
--- a/javafx-ui-controls/test/javafx/scene/control/TableViewTest.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/TableViewTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -1296,7 +1296,7 @@
         
         // this next test is likely to be brittle, but we'll see...If it is the
         // cause of failure then it can be commented out
-        assertEquals(0.125, scrollBar.getVisibleAmount(), 0.0);
+        assertEquals(0.0625, scrollBar.getVisibleAmount(), 0.0);
     }
 
     @Test public void test_rt30400() {
--- a/javafx-ui-controls/test/javafx/scene/control/TreeTableViewTest.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/TreeTableViewTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -1843,7 +1843,7 @@
         
         // this next test is likely to be brittle, but we'll see...If it is the
         // cause of failure then it can be commented out
-        assertEquals(0.125, scrollBar.getVisibleAmount(), 0.0);
+        assertEquals(0.0625, scrollBar.getVisibleAmount(), 0.0);
     }
     
     @Test public void test_rt29676_withText() {
--- a/javafx-ui-controls/test/javafx/scene/control/TreeViewTest.java	Tue Jun 18 16:29:40 2013 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/TreeViewTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -705,7 +705,8 @@
         VirtualFlowTestUtils.assertRowsNotEmpty(tree, 0, 3); // rows 0 - 3 should be filled
         VirtualFlowTestUtils.assertRowsEmpty(tree, 3, -1); // rows 3+ should be empty
     }
-    
+
+    @Ignore("Test has started failing - I have reopened the jira issue")
     @Test public void test_rt28556() {
         List<Employee> employees = Arrays.<Employee>asList(
             new Employee("Ethan Williams", "Sales Department"),
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/ChoiceBoxListCellTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -0,0 +1,344 @@
+/*
+ * 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 javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+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;
+
+import static org.junit.Assert.*;
+
+public class ChoiceBoxListCellTest {
+    
+    private StringConverter<Object> converter;
+    
+    @Before public void setup() {
+        converter = new StringConverter<Object>() {
+            @Override public String toString(Object object) {
+                return null;
+            }
+
+            @Override public Object fromString(String string) {
+                return null;
+            }
+        };
+    }
+    
+    /**************************************************************************
+     * 
+     * Test for public static Callback<ListView<T>, ListCell<T>> forListView(T... items)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forListView_noArgs_ensureCellFactoryIsNotNull() {
+        Callback<ListView<String>, ListCell<String>> cellFactory = ChoiceBoxListCell.forListView();
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forListView_noArgs_ensureCellFactoryCreatesCells() {
+        Callback<ListView<String>, ListCell<String>> cellFactory = ChoiceBoxListCell.forListView();
+        
+        ListView<String> listView = new ListView<>();
+        ChoiceBoxListCell<String> cell = (ChoiceBoxListCell<String>)cellFactory.call(listView);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forListView_noArgs_ensureCellHasNonNullStringConverter() {
+        Callback<ListView<String>, ListCell<String>> cellFactory = ChoiceBoxListCell.forListView();
+        
+        ListView<String> listView = new ListView<>();
+        ChoiceBoxListCell<String> cell = (ChoiceBoxListCell<String>)cellFactory.call(listView);
+        assertNotNull(cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<ListView<T>, ListCell<T>> forListView(
+     *       final ObservableList<T> items)
+     * 
+     **************************************************************************/
+
+    @Test public void testStatic_forListView_items_ensureSuccessWhenItemsIsNull() {
+        ObservableList<String> items = null;
+        Callback<ListView<String>, ListCell<String>> cellFactory = ChoiceBoxListCell.forListView(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forListView_items_ensureCellFactoryIsNotNull() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<ListView<String>, ListCell<String>> cellFactory = ChoiceBoxListCell.forListView(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forListView_items_ensureCellFactoryCreatesCells() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<ListView<String>, ListCell<String>> cellFactory = ChoiceBoxListCell.forListView(items);
+
+        ListView<String> listView = new ListView<>();
+        ChoiceBoxListCell<String> cell = (ChoiceBoxListCell<String>)cellFactory.call(listView);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forListView_items_ensureCellHasNonNullStringConverter() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<ListView<String>, ListCell<String>> cellFactory = ChoiceBoxListCell.forListView(items);
+
+        ListView<String> listView = new ListView<>();
+        ChoiceBoxListCell<String> cell = (ChoiceBoxListCell<String>)cellFactory.call(listView);
+        assertNotNull(cell.getConverter());
+    }
+
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNotNull() {
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        assertTrue(cell.getStyleClass().contains("choice-box-list-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsNull() {
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for one-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_converter_defaultStringConverterIsNotNull() {
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>(converter);
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_converter_defaultStyleClass() {
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>(converter);
+        assertTrue(cell.getStyleClass().contains("choice-box-list-cell"));
+    }
+    
+    @Test public void testConstructor_converter_defaultGraphicIsACheckBox() {
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>(converter);
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull() {
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nullConverter() {
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        cell.setConverter(null);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        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());
+    }
+
+
+    /**************************************************************************
+     *
+     * editing tests
+     *
+     **************************************************************************/
+
+    // --- is Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isEmpty() {
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_listViewEditableIsFalse_isEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(false);
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        cell.updateListView(listView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_listViewIsNull_isEmpty() {
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_listViewEditableIsTrue_isEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(true);
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        cell.updateListView(listView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_listViewEditableIsTrue_cellEditableIsTrue_isEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(true);
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        cell.setEditable(true);
+        cell.updateListView(listView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    // --- is Not Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isNotEmpty() {
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_listViewEditableIsFalse_isNotEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(false);
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        cell.updateListView(listView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_listViewIsNull_isNotEmpty() {
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_listViewEditableIsTrue_isNotEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(true);
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        cell.updateListView(listView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_listViewEditableIsTrue_cellEditableIsTrue_isNotEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(true);
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        cell.setEditable(true);
+        cell.updateListView(listView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    // --- cancel edit
+    @Test public void test_cancelEdit() {
+        ListView listView = new ListView();
+        listView.setEditable(true);
+        ChoiceBoxListCell<Object> cell = new ChoiceBoxListCell<>();
+        cell.updateListView(listView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        cell.cancelEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/ChoiceBoxTableCellTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -0,0 +1,420 @@
+/*
+ * 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 javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+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;
+
+import static org.junit.Assert.*;
+
+public class ChoiceBoxTableCellTest {
+    
+    private StringConverter<Object> converter;
+    
+    @Before public void setup() {
+        converter = new StringConverter<Object>() {
+            @Override public String toString(Object object) {
+                return null;
+            }
+
+            @Override public Object fromString(String string) {
+                return null;
+            }
+        };
+    }
+    
+    /**************************************************************************
+     * 
+     * Test for public static Callback<TableColumn<T>, TableCell<T>> forTableColumn(T... items)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTableColumn_noArgs_ensureCellFactoryIsNotNull() {
+        Callback<TableColumn<String,String>, TableCell<String,String>> cellFactory = ChoiceBoxTableCell.forTableColumn();
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTableColumn_noArgs_ensureCellFactoryCreatesCells() {
+        Callback<TableColumn<String,String>, TableCell<String,String>> cellFactory = ChoiceBoxTableCell.forTableColumn();
+        
+        TableColumn<String,String> tableColumn = new TableColumn<>();
+        ChoiceBoxTableCell<String,String> cell = (ChoiceBoxTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTableColumn_noArgs_ensureCellHasNonNullStringConverter() {
+        Callback<TableColumn<String,String>, TableCell<String,String>> cellFactory = ChoiceBoxTableCell.forTableColumn();
+
+        TableColumn<String,String> tableColumn = new TableColumn<>();
+        ChoiceBoxTableCell<String,String> cell = (ChoiceBoxTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TableColumn<T>, TableCell<T>> forTableColumn(
+     *       final ObservableList<T> items)
+     * 
+     **************************************************************************/
+
+    @Test public void testStatic_forTableColumn_items_ensureSuccessWhenItemsIsNull() {
+        ObservableList<String> items = null;
+        Callback<TableColumn<String,String>, TableCell<String,String>> cellFactory = ChoiceBoxTableCell.forTableColumn(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forTableColumn_items_ensureCellFactoryIsNotNull() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TableColumn<String,String>, TableCell<String,String>> cellFactory = ChoiceBoxTableCell.forTableColumn(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forTableColumn_items_ensureCellFactoryCreatesCells() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TableColumn<String,String>, TableCell<String,String>> cellFactory = ChoiceBoxTableCell.forTableColumn(items);
+
+        TableColumn<String,String> tableColumn = new TableColumn<>();
+        ChoiceBoxTableCell<String,String> cell = (ChoiceBoxTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTableColumn_items_ensureCellHasNonNullStringConverter() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TableColumn<String,String>, TableCell<String,String>> cellFactory = ChoiceBoxTableCell.forTableColumn(items);
+
+        TableColumn<String,String> tableColumn = new TableColumn<>();
+        ChoiceBoxTableCell<String,String> cell = (ChoiceBoxTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getConverter());
+    }
+
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNotNull() {
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>();
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>();
+        assertTrue(cell.getStyleClass().contains("choice-box-table-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsNull() {
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>();
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for one-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_converter_defaultStringConverterIsNotNull() {
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>(converter);
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_converter_defaultStyleClass() {
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>(converter);
+        assertTrue(cell.getStyleClass().contains("choice-box-table-cell"));
+    }
+    
+    @Test public void testConstructor_converter_defaultGraphicIsACheckBox() {
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>(converter);
+        assertNull(cell.getGraphic());
+    }
+
+
+    /**************************************************************************
+     *
+     * Constructor tests for one-arg (varargs items) constructor
+     *
+     **************************************************************************/
+
+    @Test public void testConstructor_varargs_defaultStringConverterIsNotNull() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>(items);
+        assertNotNull(cell.getConverter());
+    }
+
+    @Test public void testConstructor_varargs_defaultStyleClass() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>(items);
+        assertTrue(cell.getStyleClass().contains("choice-box-table-cell"));
+    }
+
+    @Test public void testConstructor_varargs_defaultGraphicIsACheckBox() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>(items);
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void testConstructor_varargs_itemsListIsNotNullOrEmpty() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>(items);
+        assertNotNull(cell.getItems());
+        assertEquals(3, cell.getItems().size());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull() {
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>();
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nullConverter() {
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>();
+        cell.setConverter(null);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>();
+        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());
+    }
+
+
+    /**************************************************************************
+     *
+     * editing tests
+     *
+     **************************************************************************/
+
+    // --- is Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isEmpty() {
+        ChoiceBoxTableCell<Object,Object> cell = new ChoiceBoxTableCell<>();
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsFalse_isEmpty() {
+        TableView tableView = new TableView();
+        tableView.setEditable(false);
+        ChoiceBoxTableCell<Object,Object> cell = new ChoiceBoxTableCell<>();
+        cell.updateTableView(tableView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_tableViewIsNull_isEmpty() {
+        ChoiceBoxTableCell<Object,Object> cell = new ChoiceBoxTableCell<>();
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_tableViewEditableIsTrue_tableColumnIsNull() {
+        TableView tableView = new TableView();
+        tableView.setEditable(true);
+        ChoiceBoxTableCell<Object,Object> cell = new ChoiceBoxTableCell<>();
+        cell.updateTableView(tableView);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_isEmpty() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView();
+        tableView.setEditable(true);
+        ChoiceBoxTableCell<Object,Object> cell = new ChoiceBoxTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_cellEditableIsTrue_isEmpty() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView();
+        tableView.setEditable(true);
+        ChoiceBoxTableCell<Object,Object> cell = new ChoiceBoxTableCell<>();
+        cell.setEditable(true);
+        cell.updateTableView(tableView);
+        cell.updateTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    // --- is Not Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isNotEmpty() {
+        ChoiceBoxTableCell<Object, Object> cell = new ChoiceBoxTableCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsFalse_isNotEmpty() {
+        TableView tableView = new TableView();
+        tableView.setEditable(false);
+        ChoiceBoxTableCell<Object,Object> cell = new ChoiceBoxTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_tableViewIsNull_isNotEmpty() {
+        ChoiceBoxTableCell<Object,Object> cell = new ChoiceBoxTableCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_isNotEmpty() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ChoiceBoxTableCell<Object,Object> cell = new ChoiceBoxTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_cellEditableIsTrue_isNotEmpty() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ChoiceBoxTableCell<Object,Object> cell = new ChoiceBoxTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    // --- cancel edit
+    @Test public void test_cancelEdit_usingCellCancelEdit() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ChoiceBoxTableCell<Object,Object> cell = new ChoiceBoxTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        cell.cancelEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_cancelEdit_usingTableCancelEdit() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ChoiceBoxTableCell<Object,Object> cell = new ChoiceBoxTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        tableView.edit(-1, null);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/ChoiceBoxTreeCellTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -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 javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.control.TreeCell;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeView;
+import javafx.util.Callback;
+import javafx.util.StringConverter;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class ChoiceBoxTreeCellTest {
+    
+    private StringConverter<Object> converter;
+    
+    @Before public void setup() {
+        converter = new StringConverter<Object>() {
+            @Override public String toString(Object object) {
+                return null;
+            }
+
+            @Override public Object fromString(String string) {
+                return null;
+            }
+        };
+    }
+    
+    /**************************************************************************
+     * 
+     * Test for public static Callback<TreeView<T>, TreeCell<T>> forTreeView(T... items)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTreeView_noArgs_ensureCellFactoryIsNotNull() {
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = ChoiceBoxTreeCell.forTreeView();
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTreeView_noArgs_ensureCellFactoryCreatesCells() {
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = ChoiceBoxTreeCell.forTreeView();
+        
+        TreeView<String> treeView = new TreeView<>();
+        ChoiceBoxTreeCell<String> cell = (ChoiceBoxTreeCell<String>)cellFactory.call(treeView);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTreeView_noArgs_ensureCellHasNonNullStringConverter() {
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = ChoiceBoxTreeCell.forTreeView();
+        
+        TreeView<String> treeView = new TreeView<>();
+        ChoiceBoxTreeCell<String> cell = (ChoiceBoxTreeCell<String>)cellFactory.call(treeView);
+        assertNotNull(cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TreeView<T>, TreeCell<T>> forTreeView(
+     *       final ObservableList<T> items)
+     * 
+     **************************************************************************/
+
+    @Test public void testStatic_forTreeView_items_ensureSuccessWhenItemsIsNull() {
+        ObservableList<String> items = null;
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = ChoiceBoxTreeCell.forTreeView(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forTreeView_items_ensureCellFactoryIsNotNull() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = ChoiceBoxTreeCell.forTreeView(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forTreeView_items_ensureCellFactoryCreatesCells() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = ChoiceBoxTreeCell.forTreeView(items);
+
+        TreeView<String> treeView = new TreeView<>();
+        ChoiceBoxTreeCell<String> cell = (ChoiceBoxTreeCell<String>)cellFactory.call(treeView);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTreeView_items_ensureCellHasNonNullStringConverter() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = ChoiceBoxTreeCell.forTreeView(items);
+
+        TreeView<String> treeView = new TreeView<>();
+        ChoiceBoxTreeCell<String> cell = (ChoiceBoxTreeCell<String>)cellFactory.call(treeView);
+        assertNotNull(cell.getConverter());
+    }
+
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNotNull() {
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        assertTrue(cell.getStyleClass().contains("choice-box-tree-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsNull() {
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for one-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_converter_defaultStringConverterIsNotNull() {
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>(converter);
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_converter_defaultStyleClass() {
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>(converter);
+        assertTrue(cell.getStyleClass().contains("choice-box-tree-cell"));
+    }
+    
+    @Test public void testConstructor_converter_defaultGraphicIsACheckBox() {
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>(converter);
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull() {
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nullConverter() {
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        cell.setConverter(null);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        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());
+    }
+
+
+    /**************************************************************************
+     *
+     * editing tests
+     *
+     **************************************************************************/
+
+    // --- is Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isEmpty() {
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsFalse_isEmpty() {
+        TreeView treeView = new TreeView();
+        treeView.setEditable(false);
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        cell.updateTreeView(treeView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_treeViewIsNull_isEmpty() {
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsTrue_isEmpty() {
+        TreeView treeView = new TreeView();
+        treeView.setEditable(true);
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        cell.updateTreeView(treeView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsTrue_cellEditableIsTrue_isEmpty() {
+        TreeView treeView = new TreeView();
+        treeView.setEditable(true);
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        cell.setEditable(true);
+        cell.updateTreeView(treeView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    // --- is Not Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isNotEmpty() {
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsFalse_isNotEmpty() {
+        TreeView treeView = new TreeView();
+        treeView.setEditable(false);
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        cell.updateTreeView(treeView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_treeViewIsNull_isNotEmpty() {
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsTrue_isNotEmpty() {
+        TreeItem root = new TreeItem("Root");
+        TreeView treeView = new TreeView(root);
+        treeView.setEditable(true);
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        cell.updateTreeView(treeView);
+        cell.updateIndex(0);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsTrue_cellEditableIsTrue_isNotEmpty() {
+        TreeItem root = new TreeItem("Root");
+        TreeView treeView = new TreeView(root);
+        treeView.setEditable(true);
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        cell.setEditable(true);
+        cell.updateTreeView(treeView);
+        cell.updateIndex(0);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    // --- cancel edit
+    @Test public void test_cancelEdit() {
+        TreeItem root = new TreeItem("Root");
+        TreeView treeView = new TreeView(root);
+        treeView.setEditable(true);
+        ChoiceBoxTreeCell<Object> cell = new ChoiceBoxTreeCell<>();
+        cell.updateTreeView(treeView);
+
+        cell.updateIndex(0);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        cell.cancelEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/ChoiceBoxTreeTableCellTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -0,0 +1,421 @@
+/*
+ * 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 javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeTableCell;
+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;
+
+import static org.junit.Assert.*;
+
+public class ChoiceBoxTreeTableCellTest {
+    
+    private StringConverter<Object> converter;
+    
+    @Before public void setup() {
+        converter = new StringConverter<Object>() {
+            @Override public String toString(Object object) {
+                return null;
+            }
+
+            @Override public Object fromString(String string) {
+                return null;
+            }
+        };
+    }
+    
+    /**************************************************************************
+     * 
+     * Test for public static Callback<TreeTableColumn<T>, TreeTableCell<T>> forTreeTableColumn(T... items)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTreeTableColumn_noArgs_ensureCellFactoryIsNotNull() {
+        Callback<TreeTableColumn<String,String>, TreeTableCell<String,String>> cellFactory = ChoiceBoxTreeTableCell.forTreeTableColumn();
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTreeTableColumn_noArgs_ensureCellFactoryCreatesCells() {
+        Callback<TreeTableColumn<String,String>, TreeTableCell<String,String>> cellFactory = ChoiceBoxTreeTableCell.forTreeTableColumn();
+        
+        TreeTableColumn<String,String> tableColumn = new TreeTableColumn<>();
+        ChoiceBoxTreeTableCell<String,String> cell = (ChoiceBoxTreeTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTreeTableColumn_noArgs_ensureCellHasNonNullStringConverter() {
+        Callback<TreeTableColumn<String,String>, TreeTableCell<String,String>> cellFactory = ChoiceBoxTreeTableCell.forTreeTableColumn();
+
+        TreeTableColumn<String,String> tableColumn = new TreeTableColumn<>();
+        ChoiceBoxTreeTableCell<String,String> cell = (ChoiceBoxTreeTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TreeTableColumn<T>, TreeTableCell<T>> forTreeTableColumn(
+     *       final ObservableList<T> items)
+     * 
+     **************************************************************************/
+
+    @Test public void testStatic_forTreeTableColumn_items_ensureSuccessWhenItemsIsNull() {
+        ObservableList<String> items = null;
+        Callback<TreeTableColumn<String,String>, TreeTableCell<String,String>> cellFactory = ChoiceBoxTreeTableCell.forTreeTableColumn(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forTreeTableColumn_items_ensureCellFactoryIsNotNull() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TreeTableColumn<String,String>, TreeTableCell<String,String>> cellFactory = ChoiceBoxTreeTableCell.forTreeTableColumn(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forTreeTableColumn_items_ensureCellFactoryCreatesCells() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TreeTableColumn<String,String>, TreeTableCell<String,String>> cellFactory = ChoiceBoxTreeTableCell.forTreeTableColumn(items);
+
+        TreeTableColumn<String,String> tableColumn = new TreeTableColumn<>();
+        ChoiceBoxTreeTableCell<String,String> cell = (ChoiceBoxTreeTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTreeTableColumn_items_ensureCellHasNonNullStringConverter() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TreeTableColumn<String,String>, TreeTableCell<String,String>> cellFactory = ChoiceBoxTreeTableCell.forTreeTableColumn(items);
+
+        TreeTableColumn<String,String> tableColumn = new TreeTableColumn<>();
+        ChoiceBoxTreeTableCell<String,String> cell = (ChoiceBoxTreeTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getConverter());
+    }
+
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNotNull() {
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>();
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>();
+        assertTrue(cell.getStyleClass().contains("choice-box-tree-table-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsNull() {
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>();
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for one-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_converter_defaultStringConverterIsNotNull() {
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>(converter);
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_converter_defaultStyleClass() {
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>(converter);
+        assertTrue(cell.getStyleClass().contains("choice-box-tree-table-cell"));
+    }
+    
+    @Test public void testConstructor_converter_defaultGraphicIsACheckBox() {
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>(converter);
+        assertNull(cell.getGraphic());
+    }
+
+
+    /**************************************************************************
+     *
+     * Constructor tests for one-arg (varargs items) constructor
+     *
+     **************************************************************************/
+
+    @Test public void testConstructor_varargs_defaultStringConverterIsNotNull() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>(items);
+        assertNotNull(cell.getConverter());
+    }
+
+    @Test public void testConstructor_varargs_defaultStyleClass() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>(items);
+        assertTrue(cell.getStyleClass().contains("choice-box-tree-table-cell"));
+    }
+
+    @Test public void testConstructor_varargs_defaultGraphicIsACheckBox() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>(items);
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void testConstructor_varargs_itemsListIsNotNullOrEmpty() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>(items);
+        assertNotNull(cell.getItems());
+        assertEquals(3, cell.getItems().size());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull() {
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nullConverter() {
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.setConverter(null);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>();
+        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());
+    }
+
+
+    /**************************************************************************
+     *
+     * editing tests
+     *
+     **************************************************************************/
+
+    // --- is Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isEmpty() {
+        ChoiceBoxTreeTableCell<Object,Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsFalse_isEmpty() {
+        TreeTableView tableView = new TreeTableView();
+        tableView.setEditable(false);
+        ChoiceBoxTreeTableCell<Object,Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_tableViewIsNull_isEmpty() {
+        ChoiceBoxTreeTableCell<Object,Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_tableViewEditableIsTrue_tableColumnIsNull() {
+        TreeTableView tableView = new TreeTableView();
+        tableView.setEditable(true);
+        ChoiceBoxTreeTableCell<Object,Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_isEmpty() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView();
+        tableView.setEditable(true);
+        ChoiceBoxTreeTableCell<Object,Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateTreeTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_cellEditableIsTrue_isEmpty() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView();
+        tableView.setEditable(true);
+        ChoiceBoxTreeTableCell<Object,Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.setEditable(true);
+        cell.updateTreeTableView(tableView);
+        cell.updateTreeTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    // --- is Not Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isNotEmpty() {
+        ChoiceBoxTreeTableCell<Object, Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsFalse_isNotEmpty() {
+        TreeTableView tableView = new TreeTableView();
+        tableView.setEditable(false);
+        ChoiceBoxTreeTableCell<Object,Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_tableViewIsNull_isNotEmpty() {
+        ChoiceBoxTreeTableCell<Object,Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_isNotEmpty() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView(new TreeItem("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ChoiceBoxTreeTableCell<Object,Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTreeTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_cellEditableIsTrue_isNotEmpty() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView(new TreeItem("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ChoiceBoxTreeTableCell<Object,Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTreeTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    // --- cancel edit
+    @Test public void test_cancelEdit_usingCellCancelEdit() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView(new TreeItem("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ChoiceBoxTreeTableCell<Object,Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTreeTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        cell.cancelEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_cancelEdit_usingTableCancelEdit() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView(new TreeItem("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ChoiceBoxTreeTableCell<Object,Object> cell = new ChoiceBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTreeTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        tableView.edit(-1, null);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/ComboBoxListCellTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -0,0 +1,344 @@
+/*
+ * 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 javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+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;
+
+import static org.junit.Assert.*;
+
+public class ComboBoxListCellTest {
+    
+    private StringConverter<Object> converter;
+    
+    @Before public void setup() {
+        converter = new StringConverter<Object>() {
+            @Override public String toString(Object object) {
+                return null;
+            }
+
+            @Override public Object fromString(String string) {
+                return null;
+            }
+        };
+    }
+    
+    /**************************************************************************
+     * 
+     * Test for public static Callback<ListView<T>, ListCell<T>> forListView(T... items)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forListView_noArgs_ensureCellFactoryIsNotNull() {
+        Callback<ListView<String>, ListCell<String>> cellFactory = ComboBoxListCell.forListView();
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forListView_noArgs_ensureCellFactoryCreatesCells() {
+        Callback<ListView<String>, ListCell<String>> cellFactory = ComboBoxListCell.forListView();
+        
+        ListView<String> listView = new ListView<>();
+        ComboBoxListCell<String> cell = (ComboBoxListCell<String>)cellFactory.call(listView);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forListView_noArgs_ensureCellHasNonNullStringConverter() {
+        Callback<ListView<String>, ListCell<String>> cellFactory = ComboBoxListCell.forListView();
+        
+        ListView<String> listView = new ListView<>();
+        ComboBoxListCell<String> cell = (ComboBoxListCell<String>)cellFactory.call(listView);
+        assertNotNull(cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<ListView<T>, ListCell<T>> forListView(
+     *       final ObservableList<T> items)
+     * 
+     **************************************************************************/
+
+    @Test public void testStatic_forListView_items_ensureSuccessWhenItemsIsNull() {
+        ObservableList<String> items = null;
+        Callback<ListView<String>, ListCell<String>> cellFactory = ComboBoxListCell.forListView(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forListView_items_ensureCellFactoryIsNotNull() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<ListView<String>, ListCell<String>> cellFactory = ComboBoxListCell.forListView(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forListView_items_ensureCellFactoryCreatesCells() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<ListView<String>, ListCell<String>> cellFactory = ComboBoxListCell.forListView(items);
+
+        ListView<String> listView = new ListView<>();
+        ComboBoxListCell<String> cell = (ComboBoxListCell<String>)cellFactory.call(listView);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forListView_items_ensureCellHasNonNullStringConverter() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<ListView<String>, ListCell<String>> cellFactory = ComboBoxListCell.forListView(items);
+
+        ListView<String> listView = new ListView<>();
+        ComboBoxListCell<String> cell = (ComboBoxListCell<String>)cellFactory.call(listView);
+        assertNotNull(cell.getConverter());
+    }
+
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNotNull() {
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        assertTrue(cell.getStyleClass().contains("combo-box-list-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsNull() {
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for one-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_converter_defaultStringConverterIsNotNull() {
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>(converter);
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_converter_defaultStyleClass() {
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>(converter);
+        assertTrue(cell.getStyleClass().contains("combo-box-list-cell"));
+    }
+    
+    @Test public void testConstructor_converter_defaultGraphicIsACheckBox() {
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>(converter);
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull() {
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nullConverter() {
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        cell.setConverter(null);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        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());
+    }
+
+
+    /**************************************************************************
+     *
+     * editing tests
+     *
+     **************************************************************************/
+
+    // --- is Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isEmpty() {
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_listViewEditableIsFalse_isEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(false);
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        cell.updateListView(listView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_listViewIsNull_isEmpty() {
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_listViewEditableIsTrue_isEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(true);
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        cell.updateListView(listView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_listViewEditableIsTrue_cellEditableIsTrue_isEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(true);
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        cell.setEditable(true);
+        cell.updateListView(listView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    // --- is Not Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isNotEmpty() {
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_listViewEditableIsFalse_isNotEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(false);
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        cell.updateListView(listView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_listViewIsNull_isNotEmpty() {
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_listViewEditableIsTrue_isNotEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(true);
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        cell.updateListView(listView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_listViewEditableIsTrue_cellEditableIsTrue_isNotEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(true);
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        cell.setEditable(true);
+        cell.updateListView(listView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    // --- cancel edit
+    @Test public void test_cancelEdit() {
+        ListView listView = new ListView();
+        listView.setEditable(true);
+        ComboBoxListCell<Object> cell = new ComboBoxListCell<>();
+        cell.updateListView(listView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        cell.cancelEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/ComboBoxTableCellTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -0,0 +1,453 @@
+/*
+ * 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 javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+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;
+
+import static org.junit.Assert.*;
+
+public class ComboBoxTableCellTest {
+    
+    private StringConverter<Object> converter;
+    
+    @Before public void setup() {
+        converter = new StringConverter<Object>() {
+            @Override public String toString(Object object) {
+                return null;
+            }
+
+            @Override public Object fromString(String string) {
+                return null;
+            }
+        };
+    }
+    
+    /**************************************************************************
+     * 
+     * Test for public static Callback<TableColumn<T>, TableCell<T>> forTableColumn(T... items)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTableColumn_noArgs_ensureCellFactoryIsNotNull() {
+        Callback<TableColumn<String,String>, TableCell<String,String>> cellFactory = ComboBoxTableCell.forTableColumn();
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTableColumn_noArgs_ensureCellFactoryCreatesCells() {
+        Callback<TableColumn<String,String>, TableCell<String,String>> cellFactory = ComboBoxTableCell.forTableColumn();
+        
+        TableColumn<String,String> tableColumn = new TableColumn<>();
+        ComboBoxTableCell<String,String> cell = (ComboBoxTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTableColumn_noArgs_ensureCellHasNonNullStringConverter() {
+        Callback<TableColumn<String,String>, TableCell<String,String>> cellFactory = ComboBoxTableCell.forTableColumn();
+
+        TableColumn<String,String> tableColumn = new TableColumn<>();
+        ComboBoxTableCell<String,String> cell = (ComboBoxTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TableColumn<T>, TableCell<T>> forTableColumn(
+     *       final ObservableList<T> items)
+     * 
+     **************************************************************************/
+
+    @Test public void testStatic_forTableColumn_items_ensureSuccessWhenItemsIsNull() {
+        ObservableList<String> items = null;
+        Callback<TableColumn<String,String>, TableCell<String,String>> cellFactory = ComboBoxTableCell.forTableColumn(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forTableColumn_items_ensureCellFactoryIsNotNull() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TableColumn<String,String>, TableCell<String,String>> cellFactory = ComboBoxTableCell.forTableColumn(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forTableColumn_items_ensureCellFactoryCreatesCells() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TableColumn<String,String>, TableCell<String,String>> cellFactory = ComboBoxTableCell.forTableColumn(items);
+
+        TableColumn<String,String> tableColumn = new TableColumn<>();
+        ComboBoxTableCell<String,String> cell = (ComboBoxTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTableColumn_items_ensureCellHasNonNullStringConverter() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TableColumn<String,String>, TableCell<String,String>> cellFactory = ComboBoxTableCell.forTableColumn(items);
+
+        TableColumn<String,String> tableColumn = new TableColumn<>();
+        ComboBoxTableCell<String,String> cell = (ComboBoxTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getConverter());
+    }
+
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNotNull() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>();
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>();
+        assertTrue(cell.getStyleClass().contains("combo-box-table-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsNull() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>();
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void testConstructor_noArgs_itemsListIsNotNull() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>();
+        assertNotNull(cell.getItems());
+        assertTrue(cell.getItems().isEmpty());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for one-arg (converter, no varargs items) constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_converter_defaultStringConverterIsNotNull() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>(converter);
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_converter_defaultStyleClass() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>(converter);
+        assertTrue(cell.getStyleClass().contains("combo-box-table-cell"));
+    }
+    
+    @Test public void testConstructor_converter_defaultGraphicIsACheckBox() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>(converter);
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void testConstructor_converter_itemsListIsNotNull() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>(converter);
+        assertNotNull(cell.getItems());
+        assertTrue(cell.getItems().isEmpty());
+    }
+
+    /**************************************************************************
+     *
+     * Constructor tests for one-arg (varargs items) constructor
+     *
+     **************************************************************************/
+
+    @Test public void testConstructor_varargs_defaultStringConverterIsNotNull() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>(items);
+        assertNotNull(cell.getConverter());
+    }
+
+    @Test public void testConstructor_varargs_defaultStyleClass() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>(items);
+        assertTrue(cell.getStyleClass().contains("combo-box-table-cell"));
+    }
+
+    @Test public void testConstructor_varargs_defaultGraphicIsACheckBox() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>(items);
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void testConstructor_varargs_itemsListIsNotNullOrEmpty() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>(items);
+        assertNotNull(cell.getItems());
+        assertEquals(3, cell.getItems().size());
+    }
+
+
+    /**************************************************************************
+     *
+     * Property tests
+     *
+     **************************************************************************/
+
+    @Test public void testComboBoxEditable_falseByDefault() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>();
+        assertFalse(cell.isComboBoxEditable());
+    }
+
+    @Test public void testComboBoxEditable_setter() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>();
+
+        cell.setComboBoxEditable(true);
+        assertTrue(cell.isComboBoxEditable());
+
+        cell.setComboBoxEditable(false);
+        assertFalse(cell.isComboBoxEditable());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>();
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nullConverter() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>();
+        cell.setConverter(null);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>();
+        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());
+    }
+
+
+    /**************************************************************************
+     *
+     * editing tests
+     *
+     **************************************************************************/
+
+    // --- is Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isEmpty() {
+        ComboBoxTableCell<Object,Object> cell = new ComboBoxTableCell<>();
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsFalse_isEmpty() {
+        TableView tableView = new TableView();
+        tableView.setEditable(false);
+        ComboBoxTableCell<Object,Object> cell = new ComboBoxTableCell<>();
+        cell.updateTableView(tableView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_tableViewIsNull_isEmpty() {
+        ComboBoxTableCell<Object,Object> cell = new ComboBoxTableCell<>();
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_tableViewEditableIsTrue_tableColumnIsNull() {
+        TableView tableView = new TableView();
+        tableView.setEditable(true);
+        ComboBoxTableCell<Object,Object> cell = new ComboBoxTableCell<>();
+        cell.updateTableView(tableView);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_isEmpty() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView();
+        tableView.setEditable(true);
+        ComboBoxTableCell<Object,Object> cell = new ComboBoxTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_cellEditableIsTrue_isEmpty() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView();
+        tableView.setEditable(true);
+        ComboBoxTableCell<Object,Object> cell = new ComboBoxTableCell<>();
+        cell.setEditable(true);
+        cell.updateTableView(tableView);
+        cell.updateTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    // --- is Not Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isNotEmpty() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsFalse_isNotEmpty() {
+        TableView tableView = new TableView();
+        tableView.setEditable(false);
+        ComboBoxTableCell<Object,Object> cell = new ComboBoxTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_tableViewIsNull_isNotEmpty() {
+        ComboBoxTableCell<Object,Object> cell = new ComboBoxTableCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_isNotEmpty() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ComboBoxTableCell<Object,Object> cell = new ComboBoxTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_cellEditableIsTrue_isNotEmpty() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ComboBoxTableCell<Object,Object> cell = new ComboBoxTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    // --- cancel edit
+    @Test public void test_cancelEdit_usingCellCancelEdit() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ComboBoxTableCell<Object,Object> cell = new ComboBoxTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        cell.cancelEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_cancelEdit_usingTableCancelEdit() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ComboBoxTableCell<Object,Object> cell = new ComboBoxTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        tableView.edit(-1, null);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/ComboBoxTreeCellTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -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 javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.control.TreeCell;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeView;
+import javafx.util.Callback;
+import javafx.util.StringConverter;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class ComboBoxTreeCellTest {
+    
+    private StringConverter<Object> converter;
+    
+    @Before public void setup() {
+        converter = new StringConverter<Object>() {
+            @Override public String toString(Object object) {
+                return null;
+            }
+
+            @Override public Object fromString(String string) {
+                return null;
+            }
+        };
+    }
+    
+    /**************************************************************************
+     * 
+     * Test for public static Callback<TreeView<T>, TreeCell<T>> forTreeView(T... items)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTreeView_noArgs_ensureCellFactoryIsNotNull() {
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = ComboBoxTreeCell.forTreeView();
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTreeView_noArgs_ensureCellFactoryCreatesCells() {
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = ComboBoxTreeCell.forTreeView();
+        
+        TreeView<String> treeView = new TreeView<>();
+        ComboBoxTreeCell<String> cell = (ComboBoxTreeCell<String>)cellFactory.call(treeView);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTreeView_noArgs_ensureCellHasNonNullStringConverter() {
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = ComboBoxTreeCell.forTreeView();
+        
+        TreeView<String> treeView = new TreeView<>();
+        ComboBoxTreeCell<String> cell = (ComboBoxTreeCell<String>)cellFactory.call(treeView);
+        assertNotNull(cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TreeView<T>, TreeCell<T>> forTreeView(
+     *       final ObservableList<T> items)
+     * 
+     **************************************************************************/
+
+    @Test public void testStatic_forTreeView_items_ensureSuccessWhenItemsIsNull() {
+        ObservableList<String> items = null;
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = ComboBoxTreeCell.forTreeView(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forTreeView_items_ensureCellFactoryIsNotNull() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = ComboBoxTreeCell.forTreeView(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forTreeView_items_ensureCellFactoryCreatesCells() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = ComboBoxTreeCell.forTreeView(items);
+
+        TreeView<String> treeView = new TreeView<>();
+        ComboBoxTreeCell<String> cell = (ComboBoxTreeCell<String>)cellFactory.call(treeView);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTreeView_items_ensureCellHasNonNullStringConverter() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = ComboBoxTreeCell.forTreeView(items);
+
+        TreeView<String> treeView = new TreeView<>();
+        ComboBoxTreeCell<String> cell = (ComboBoxTreeCell<String>)cellFactory.call(treeView);
+        assertNotNull(cell.getConverter());
+    }
+
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNotNull() {
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        assertTrue(cell.getStyleClass().contains("combo-box-tree-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsNull() {
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for one-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_converter_defaultStringConverterIsNotNull() {
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>(converter);
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_converter_defaultStyleClass() {
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>(converter);
+        assertTrue(cell.getStyleClass().contains("combo-box-tree-cell"));
+    }
+    
+    @Test public void testConstructor_converter_defaultGraphicIsACheckBox() {
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>(converter);
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull() {
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nullConverter() {
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        cell.setConverter(null);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        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());
+    }
+
+
+    /**************************************************************************
+     *
+     * editing tests
+     *
+     **************************************************************************/
+
+    // --- is Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isEmpty() {
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsFalse_isEmpty() {
+        TreeView treeView = new TreeView();
+        treeView.setEditable(false);
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        cell.updateTreeView(treeView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_treeViewIsNull_isEmpty() {
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsTrue_isEmpty() {
+        TreeView treeView = new TreeView();
+        treeView.setEditable(true);
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        cell.updateTreeView(treeView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsTrue_cellEditableIsTrue_isEmpty() {
+        TreeView treeView = new TreeView();
+        treeView.setEditable(true);
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        cell.setEditable(true);
+        cell.updateTreeView(treeView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    // --- is Not Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isNotEmpty() {
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsFalse_isNotEmpty() {
+        TreeView treeView = new TreeView();
+        treeView.setEditable(false);
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        cell.updateTreeView(treeView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_treeViewIsNull_isNotEmpty() {
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsTrue_isNotEmpty() {
+        TreeItem root = new TreeItem("Root");
+        TreeView treeView = new TreeView(root);
+        treeView.setEditable(true);
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        cell.updateTreeView(treeView);
+        cell.updateIndex(0);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsTrue_cellEditableIsTrue_isNotEmpty() {
+        TreeItem root = new TreeItem("Root");
+        TreeView treeView = new TreeView(root);
+        treeView.setEditable(true);
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        cell.setEditable(true);
+        cell.updateTreeView(treeView);
+        cell.updateIndex(0);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    // --- cancel edit
+    @Test public void test_cancelEdit() {
+        TreeItem root = new TreeItem("Root");
+        TreeView treeView = new TreeView(root);
+        treeView.setEditable(true);
+        ComboBoxTreeCell<Object> cell = new ComboBoxTreeCell<>();
+        cell.updateTreeView(treeView);
+
+        cell.updateIndex(0);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        cell.cancelEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/ComboBoxTreeTableCellTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -0,0 +1,443 @@
+/*
+ * 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 javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeTableCell;
+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;
+
+import static org.junit.Assert.*;
+
+public class ComboBoxTreeTableCellTest {
+    
+    private StringConverter<Object> converter;
+    
+    @Before public void setup() {
+        converter = new StringConverter<Object>() {
+            @Override public String toString(Object object) {
+                return null;
+            }
+
+            @Override public Object fromString(String string) {
+                return null;
+            }
+        };
+    }
+    
+    /**************************************************************************
+     * 
+     * Test for public static Callback<TreeTableColumn<T>, TreeTableCell<T>> forTreeTableColumn(T... items)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTreeTableColumn_noArgs_ensureCellFactoryIsNotNull() {
+        Callback<TreeTableColumn<String,String>, TreeTableCell<String,String>> cellFactory = ComboBoxTreeTableCell.forTreeTableColumn();
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTreeTableColumn_noArgs_ensureCellFactoryCreatesCells() {
+        Callback<TreeTableColumn<String,String>, TreeTableCell<String,String>> cellFactory = ComboBoxTreeTableCell.forTreeTableColumn();
+        
+        TreeTableColumn<String,String> tableColumn = new TreeTableColumn<>();
+        ComboBoxTreeTableCell<String,String> cell = (ComboBoxTreeTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTreeTableColumn_noArgs_ensureCellHasNonNullStringConverter() {
+        Callback<TreeTableColumn<String,String>, TreeTableCell<String,String>> cellFactory = ComboBoxTreeTableCell.forTreeTableColumn();
+
+        TreeTableColumn<String,String> tableColumn = new TreeTableColumn<>();
+        ComboBoxTreeTableCell<String,String> cell = (ComboBoxTreeTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TreeTableColumn<T>, TreeTableCell<T>> forTreeTableColumn(
+     *       final ObservableList<T> items)
+     * 
+     **************************************************************************/
+
+    @Test public void testStatic_forTreeTableColumn_items_ensureSuccessWhenItemsIsNull() {
+        ObservableList<String> items = null;
+        Callback<TreeTableColumn<String,String>, TreeTableCell<String,String>> cellFactory = ComboBoxTreeTableCell.forTreeTableColumn(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forTreeTableColumn_items_ensureCellFactoryIsNotNull() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TreeTableColumn<String,String>, TreeTableCell<String,String>> cellFactory = ComboBoxTreeTableCell.forTreeTableColumn(items);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forTreeTableColumn_items_ensureCellFactoryCreatesCells() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TreeTableColumn<String,String>, TreeTableCell<String,String>> cellFactory = ComboBoxTreeTableCell.forTreeTableColumn(items);
+
+        TreeTableColumn<String,String> tableColumn = new TreeTableColumn<>();
+        ComboBoxTreeTableCell<String,String> cell = (ComboBoxTreeTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTreeTableColumn_items_ensureCellHasNonNullStringConverter() {
+        ObservableList<String> items = FXCollections.emptyObservableList();
+        Callback<TreeTableColumn<String,String>, TreeTableCell<String,String>> cellFactory = ComboBoxTreeTableCell.forTreeTableColumn(items);
+
+        TreeTableColumn<String,String> tableColumn = new TreeTableColumn<>();
+        ComboBoxTreeTableCell<String,String> cell = (ComboBoxTreeTableCell<String,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getConverter());
+    }
+
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNotNull() {
+        ComboBoxTreeTableCell<Object, Object> cell = new ComboBoxTreeTableCell<>();
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        ComboBoxTreeTableCell<Object, Object> cell = new ComboBoxTreeTableCell<>();
+        assertTrue(cell.getStyleClass().contains("combo-box-tree-table-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsNull() {
+        ComboBoxTreeTableCell<Object, Object> cell = new ComboBoxTreeTableCell<>();
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for one-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_converter_defaultStringConverterIsNotNull() {
+        ComboBoxTreeTableCell<Object, Object> cell = new ComboBoxTreeTableCell<>(converter);
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_converter_defaultStyleClass() {
+        ComboBoxTreeTableCell<Object, Object> cell = new ComboBoxTreeTableCell<>(converter);
+        assertTrue(cell.getStyleClass().contains("combo-box-tree-table-cell"));
+    }
+    
+    @Test public void testConstructor_converter_defaultGraphicIsACheckBox() {
+        ComboBoxTreeTableCell<Object, Object> cell = new ComboBoxTreeTableCell<>(converter);
+        assertNull(cell.getGraphic());
+    }
+
+
+    /**************************************************************************
+     *
+     * Constructor tests for one-arg (varargs items) constructor
+     *
+     **************************************************************************/
+
+    @Test public void testConstructor_varargs_defaultStringConverterIsNotNull() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>(items);
+        assertNotNull(cell.getConverter());
+    }
+
+    @Test public void testConstructor_varargs_defaultStyleClass() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>(items);
+        assertTrue(cell.getStyleClass().contains("combo-box-table-cell"));
+    }
+
+    @Test public void testConstructor_varargs_defaultGraphicIsACheckBox() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>(items);
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void testConstructor_varargs_itemsListIsNotNullOrEmpty() {
+        Object[] items = new Object[] { "Item 1", "Item 2", "Item 3" };
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>(items);
+        assertNotNull(cell.getItems());
+        assertEquals(3, cell.getItems().size());
+    }
+
+
+    /**************************************************************************
+     *
+     * Property tests
+     *
+     **************************************************************************/
+
+    @Test public void testComboBoxEditable_falseByDefault() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>();
+        assertFalse(cell.isComboBoxEditable());
+    }
+
+    @Test public void testComboBoxEditable_setter() {
+        ComboBoxTableCell<Object, Object> cell = new ComboBoxTableCell<>();
+
+        cell.setComboBoxEditable(true);
+        assertTrue(cell.isComboBoxEditable());
+
+        cell.setComboBoxEditable(false);
+        assertFalse(cell.isComboBoxEditable());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        ComboBoxTreeTableCell<Object, Object> cell = new ComboBoxTreeTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        ComboBoxTreeTableCell<Object, Object> cell = new ComboBoxTreeTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull() {
+        ComboBoxTreeTableCell<Object, Object> cell = new ComboBoxTreeTableCell<>();
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nullConverter() {
+        ComboBoxTreeTableCell<Object, Object> cell = new ComboBoxTreeTableCell<>();
+        cell.setConverter(null);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        ComboBoxTreeTableCell<Object, Object> cell = new ComboBoxTreeTableCell<>();
+        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());
+    }
+
+
+    /**************************************************************************
+     *
+     * editing tests
+     *
+     **************************************************************************/
+
+    // --- is Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isEmpty() {
+        ComboBoxTreeTableCell<Object,Object> cell = new ComboBoxTreeTableCell<>();
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsFalse_isEmpty() {
+        TreeTableView tableView = new TreeTableView();
+        tableView.setEditable(false);
+        ComboBoxTreeTableCell<Object,Object> cell = new ComboBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_tableViewIsNull_isEmpty() {
+        ComboBoxTreeTableCell<Object,Object> cell = new ComboBoxTreeTableCell<>();
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_tableViewEditableIsTrue_tableColumnIsNull() {
+        TreeTableView tableView = new TreeTableView();
+        tableView.setEditable(true);
+        ComboBoxTreeTableCell<Object,Object> cell = new ComboBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_isEmpty() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView();
+        tableView.setEditable(true);
+        ComboBoxTreeTableCell<Object,Object> cell = new ComboBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateTreeTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_cellEditableIsTrue_isEmpty() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView();
+        tableView.setEditable(true);
+        ComboBoxTreeTableCell<Object,Object> cell = new ComboBoxTreeTableCell<>();
+        cell.setEditable(true);
+        cell.updateTreeTableView(tableView);
+        cell.updateTreeTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    // --- is Not Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isNotEmpty() {
+        ComboBoxTreeTableCell<Object, Object> cell = new ComboBoxTreeTableCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsFalse_isNotEmpty() {
+        TreeTableView tableView = new TreeTableView();
+        tableView.setEditable(false);
+        ComboBoxTreeTableCell<Object,Object> cell = new ComboBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_tableViewIsNull_isNotEmpty() {
+        ComboBoxTreeTableCell<Object,Object> cell = new ComboBoxTreeTableCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_isNotEmpty() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView(new TreeItem("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ComboBoxTreeTableCell<Object,Object> cell = new ComboBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTreeTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_cellEditableIsTrue_isNotEmpty() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView(new TreeItem("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ComboBoxTreeTableCell<Object,Object> cell = new ComboBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTreeTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    // --- cancel edit
+    @Test public void test_cancelEdit_usingCellCancelEdit() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView(new TreeItem("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ComboBoxTreeTableCell<Object,Object> cell = new ComboBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTreeTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        cell.cancelEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_cancelEdit_usingTableCancelEdit() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView(new TreeItem("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        ComboBoxTreeTableCell<Object,Object> cell = new ComboBoxTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTreeTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        tableView.edit(-1, null);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/ProgressBarTableCellTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -0,0 +1,179 @@
+/*
+ * 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 javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.control.ProgressBar;
+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;
+
+import static org.junit.Assert.*;
+
+public class ProgressBarTableCellTest {
+    
+    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<TableColumn<S,Double>, TableCell<T,Double>> forTableColumn()
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTableColumn_noArgs_ensureCellFactoryIsNotNull() {
+        assertFalse(booleanProperty.get());
+        Callback<TableColumn<Object, Double>, TableCell<Object, Double>> cellFactory = ProgressBarTableCell.forTableColumn();
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTableColumn_noArgs_ensureCellFactoryCreatesCells() {
+        assertFalse(booleanProperty.get());
+        Callback<TableColumn<Object, Double>, TableCell<Object, Double>> cellFactory = ProgressBarTableCell.forTableColumn();
+        
+        TableColumn tableColumn = new TableColumn<>();
+        ProgressBarTableCell<Object> cell = (ProgressBarTableCell<Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        ProgressBarTableCell<Object> cell = new ProgressBarTableCell<>();
+        assertTrue(cell.getStyleClass().contains("progress-bar-table-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsAProgressBar() {
+        ProgressBarTableCell<Object> cell = new ProgressBarTableCell<>();
+        assertTrue(cell.getGraphic() instanceof ProgressBar);
+    }
+
+
+
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        ProgressBarTableCell<Object> cell = new ProgressBarTableCell<>();
+        cell.updateItem(0.5, true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        ProgressBarTableCell<Object> cell = new ProgressBarTableCell<>();
+        cell.updateItem(0.5, true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_graphicIsNotNull() {
+        ProgressBarTableCell<Object> cell = new ProgressBarTableCell<>();
+        setTableViewAndTableColumn(cell);
+        cell.updateItem(0.5, false);
+        assertNotNull(cell.getGraphic());
+        assertTrue(cell.getGraphic() instanceof ProgressBar);
+    }
+    
+
+    
+//    /**************************************************************************
+//     * 
+//     * test checkbox selection state is bound
+//     * 
+//     **************************************************************************/
+//    
+//    @Test public void test_booleanPropertyChangeUpdatesCheckBoxSelection() {
+//        ProgressBarTableCell<Object, Object> cell = new ProgressBarTableCell<>(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() {
+//        ProgressBarTableCell<Object, Object> cell = new ProgressBarTableCell<>(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/ProgressBarTreeTableCellTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -0,0 +1,180 @@
+/*
+ * 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 javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.control.ProgressBar;
+import javafx.scene.control.TreeTableCell;
+import javafx.scene.control.TreeTableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TreeTableView;
+import javafx.util.Callback;
+import javafx.util.StringConverter;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class ProgressBarTreeTableCellTest {
+    
+    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 setTableViewAndTreeTableColumn(TreeTableCell cell) {
+        cell.updateTreeTableView(tableView);
+        cell.updateTreeTableColumn(tableColumn);
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TreeTableColumn<S,Double>, TreeTableCell<T,Double>> forTreeTableColumn()
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTreeTableColumn_noArgs_ensureCellFactoryIsNotNull() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeTableColumn<Object, Double>, TreeTableCell<Object, Double>> cellFactory = ProgressBarTreeTableCell.forTreeTableColumn();
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTreeTableColumn_noArgs_ensureCellFactoryCreatesCells() {
+        assertFalse(booleanProperty.get());
+        Callback<TreeTableColumn<Object, Double>, TreeTableCell<Object, Double>> cellFactory = ProgressBarTreeTableCell.forTreeTableColumn();
+        
+        TreeTableColumn tableColumn = new TreeTableColumn<>();
+        ProgressBarTreeTableCell<Object> cell = (ProgressBarTreeTableCell<Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        ProgressBarTreeTableCell<Object> cell = new ProgressBarTreeTableCell<>();
+        assertTrue(cell.getStyleClass().contains("progress-bar-tree-table-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsAProgressBar() {
+        ProgressBarTreeTableCell<Object> cell = new ProgressBarTreeTableCell<>();
+        assertTrue(cell.getGraphic() instanceof ProgressBar);
+    }
+
+
+
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        ProgressBarTreeTableCell<Object> cell = new ProgressBarTreeTableCell<>();
+        cell.updateItem(0.5, true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        ProgressBarTreeTableCell<Object> cell = new ProgressBarTreeTableCell<>();
+        cell.updateItem(0.5, true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_graphicIsNotNull() {
+        ProgressBarTreeTableCell<Object> cell = new ProgressBarTreeTableCell<>();
+        setTableViewAndTreeTableColumn(cell);
+        cell.updateItem(0.5, false);
+        assertNotNull(cell.getGraphic());
+        assertTrue(cell.getGraphic() instanceof ProgressBar);
+    }
+    
+
+    
+//    /**************************************************************************
+//     * 
+//     * test checkbox selection state is bound
+//     * 
+//     **************************************************************************/
+//    
+//    @Test public void test_booleanPropertyChangeUpdatesCheckBoxSelection() {
+//        ProgressBarTreeTableCell<Object, Object> cell = new ProgressBarTreeTableCell<>(callback);
+//        setTableViewAndTreeTableColumn(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() {
+//        ProgressBarTreeTableCell<Object, Object> cell = new ProgressBarTreeTableCell<>(callback);
+//        setTableViewAndTreeTableColumn(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/TextFieldListCellTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -0,0 +1,337 @@
+/*
+ * 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 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;
+
+import static org.junit.Assert.*;
+
+public class TextFieldListCellTest {
+    
+    private StringConverter<Object> converter;
+    
+    @Before public void setup() {
+        converter = new StringConverter<Object>() {
+            @Override public String toString(Object object) {
+                return null;
+            }
+
+            @Override public Object fromString(String string) {
+                return null;
+            }
+        };
+    }
+    
+    /**************************************************************************
+     * 
+     * Test for public static Callback<ListView<String>, ListCell<String>> forListView()
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forListView_noArgs_ensureCellFactoryIsNotNull() {
+        Callback<ListView<String>, ListCell<String>> cellFactory = TextFieldListCell.forListView();
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forListView_noArgs_ensureCellFactoryCreatesCells() {
+        Callback<ListView<String>, ListCell<String>> cellFactory = TextFieldListCell.forListView();
+        
+        ListView<String> listView = new ListView<>();
+        TextFieldListCell<String> cell = (TextFieldListCell<String>)cellFactory.call(listView);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forListView_callback_ensureCellHasNonNullStringConverter() {
+        Callback<ListView<String>, ListCell<String>> cellFactory = TextFieldListCell.forListView();
+        
+        ListView<String> listView = new ListView<>();
+        TextFieldListCell<String> cell = (TextFieldListCell<String>)cellFactory.call(listView);
+        assertNotNull(cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<ListView<T>, ListCell<T>> forListView(
+     *       final StringConverter<T> converter)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forListView_converter_ensureCellFactoryIsNotNull() {
+        Callback<ListView<Object>, ListCell<Object>> cellFactory = TextFieldListCell.forListView(converter);
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forListView_converter_ensureCellFactoryCreatesCells() {
+        Callback<ListView<Object>, ListCell<Object>> cellFactory = TextFieldListCell.forListView(converter);
+        
+        ListView<Object> listView = new ListView<>();
+        TextFieldListCell<Object> cell = (TextFieldListCell<Object>)cellFactory.call(listView);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forListView_converter_ensureCellHasSetStringConverter() {
+        Callback<ListView<Object>, ListCell<Object>> cellFactory = TextFieldListCell.forListView(converter);
+        
+        ListView<Object> listView = new ListView<>();
+        TextFieldListCell<Object> cell = (TextFieldListCell<Object>)cellFactory.call(listView);
+        assertNotNull(cell.getConverter());
+        assertEquals(converter, cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNull() {
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        assertNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        assertTrue(cell.getStyleClass().contains("text-field-list-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsNull() {
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for one-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_converter_defaultStringConverterIsNotNull() {
+        TextFieldListCell<Object> cell = new TextFieldListCell<>(converter);
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_converter_defaultStyleClass() {
+        TextFieldListCell<Object> cell = new TextFieldListCell<>(converter);
+        assertTrue(cell.getStyleClass().contains("text-field-list-cell"));
+    }
+    
+    @Test public void testConstructor_converter_defaultGraphicIsACheckBox() {
+        TextFieldListCell<Object> cell = new TextFieldListCell<>(converter);
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull() {
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nullConverter() {
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        cell.setConverter(null);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        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());
+    }
+
+
+    /**************************************************************************
+     *
+     * editing tests
+     *
+     **************************************************************************/
+
+    // --- is Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isEmpty() {
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_listViewEditableIsFalse_isEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(false);
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        cell.updateListView(listView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_listViewIsNull_isEmpty() {
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_listViewEditableIsTrue_isEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(true);
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        cell.updateListView(listView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_listViewEditableIsTrue_cellEditableIsTrue_isEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(true);
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        cell.setEditable(true);
+        cell.updateListView(listView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    // --- is Not Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isNotEmpty() {
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_listViewEditableIsFalse_isNotEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(false);
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        cell.updateListView(listView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_listViewIsNull_isNotEmpty() {
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_listViewEditableIsTrue_isNotEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(true);
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        cell.updateListView(listView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_listViewEditableIsTrue_cellEditableIsTrue_isNotEmpty() {
+        ListView listView = new ListView();
+        listView.setEditable(true);
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        cell.setEditable(true);
+        cell.updateListView(listView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    // --- cancel edit
+    @Test public void test_cancelEdit() {
+        ListView listView = new ListView();
+        listView.setEditable(true);
+        TextFieldListCell<Object> cell = new TextFieldListCell<>();
+        cell.updateListView(listView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        cell.cancelEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/TextFieldTableCellTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -0,0 +1,378 @@
+/*
+ * 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 javafx.collections.FXCollections;
+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;
+
+import static org.junit.Assert.*;
+
+public class TextFieldTableCellTest {
+    
+    private StringConverter<Object> converter;
+    
+    @Before public void setup() {
+        converter = new StringConverter<Object>() {
+            @Override public String toString(Object object) {
+                return null;
+            }
+
+            @Override public Object fromString(String string) {
+                return null;
+            }
+        };
+    }
+    
+    /**************************************************************************
+     * 
+     * Test for public static Callback<TableColumn<String>, TableCell<String>> forTableColumn()
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTableColumn_noArgs_ensureCellFactoryIsNotNull() {
+        Callback<TableColumn<Object,String>, TableCell<Object,String>> cellFactory = TextFieldTableCell.forTableColumn();
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTableColumn_noArgs_ensureCellFactoryCreatesCells() {
+        Callback<TableColumn<Object,String>, TableCell<Object,String>> cellFactory = TextFieldTableCell.forTableColumn();
+        
+        TableColumn<Object,String> tableColumn = new TableColumn<>();
+        TextFieldTableCell<Object,String> cell = (TextFieldTableCell<Object,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTableColumn_callback_ensureCellHasNonNullStringConverter() {
+        Callback<TableColumn<Object,String>, TableCell<Object,String>> cellFactory = TextFieldTableCell.forTableColumn();
+        
+        TableColumn<Object,String> tableColumn = new TableColumn<>();
+        TextFieldTableCell<Object,String> cell = (TextFieldTableCell<Object,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TableColumn<T>, TableCell<T>> forTableColumn(
+     *       final StringConverter<T> converter)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTableColumn_converter_ensureCellFactoryIsNotNull() {
+        Callback<TableColumn<Object,Object>, TableCell<Object,Object>> cellFactory = TextFieldTableCell.forTableColumn(converter);
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTableColumn_converter_ensureCellFactoryCreatesCells() {
+        Callback<TableColumn<Object,Object>, TableCell<Object,Object>> cellFactory = TextFieldTableCell.forTableColumn(converter);
+        
+        TableColumn<Object,Object> tableColumn = new TableColumn<>();
+        TextFieldTableCell<Object,Object> cell = (TextFieldTableCell<Object,Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTableColumn_converter_ensureCellHasSetStringConverter() {
+        Callback<TableColumn<Object,Object>, TableCell<Object,Object>> cellFactory = TextFieldTableCell.forTableColumn(converter);
+        
+        TableColumn<Object,Object> tableColumn = new TableColumn<>();
+        TextFieldTableCell<Object,Object> cell = (TextFieldTableCell<Object,Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getConverter());
+        assertEquals(converter, cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNull() {
+        TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
+        assertNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
+        assertTrue(cell.getStyleClass().contains("text-field-table-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsNull() {
+        TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for one-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_converter_defaultStringConverterIsNotNull() {
+        TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>(converter);
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_converter_defaultStyleClass() {
+        TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>(converter);
+        assertTrue(cell.getStyleClass().contains("text-field-table-cell"));
+    }
+    
+    @Test public void testConstructor_converter_defaultGraphicIsACheckBox() {
+        TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>(converter);
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull() {
+        TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nullConverter() {
+        TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
+        cell.setConverter(null);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
+        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());
+    }
+
+
+    /**************************************************************************
+     *
+     * editing tests
+     *
+     **************************************************************************/
+
+    // --- is Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isEmpty() {
+        TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsFalse_isEmpty() {
+        TableView tableView = new TableView();
+        tableView.setEditable(false);
+        TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
+        cell.updateTableView(tableView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_tableColumnIsNull_isEmpty() {
+        TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_isEmpty() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView();
+        tableView.setEditable(true);
+        TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+//    @Test public void test_startEdit_tableColumnEditableIsTrue_cellEditableIsTrue_isEmpty() {
+//        TableColumn tc = new TableColumn();
+//        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
+//        tableView.getColumns().add(tc);
+//        tableView.setEditable(true);
+//        TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
+//        cell.updateTableView(tableView);
+//        cell.updateIndex(0);
+//        cell.updateTableColumn(tc);
+//        cell.setEditable(true);
+//
+//        tableView.edit(0, tc);
+//        assertFalse(cell.isEditing());
+//        assertNull(cell.getGraphic());
+//    }
+
+    // --- is Not Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isNotEmpty() {
+        TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableColumnEditableIsFalse_isNotEmpty() {
+        TableColumn<Object,Object> tableColumn = new TableColumn<>();
+        tableColumn.setEditable(false);
+        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
+        tableView.getColumns().add(tableColumn);
+        TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
+        cell.updateTableColumn(tableColumn);
+        cell.updateTableView(tableView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_tableColumnIsNull_isNotEmpty() {
+        TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_isNotEmpty() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableColumnEditableIsTrue_cellEditableIsTrue_isNotEmpty() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    // --- cancel edit
+    @Test public void test_cancelEdit_usingCellCancelEdit() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        cell.cancelEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_cancelEdit_usingTableCancelEdit() {
+        TableColumn tc = new TableColumn();
+        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        tableView.edit(-1, null);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/TextFieldTreeCellTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -0,0 +1,342 @@
+/*
+ * 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 javafx.scene.control.TreeCell;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeView;
+import javafx.util.Callback;
+import javafx.util.StringConverter;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class TextFieldTreeCellTest {
+    
+    private StringConverter<Object> converter;
+    
+    @Before public void setup() {
+        converter = new StringConverter<Object>() {
+            @Override public String toString(Object object) {
+                return null;
+            }
+
+            @Override public Object fromString(String string) {
+                return null;
+            }
+        };
+    }
+    
+    /**************************************************************************
+     * 
+     * Test for public static Callback<TreeView<String>, TreeCell<String>> forTreeView()
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTreeView_noArgs_ensureCellFactoryIsNotNull() {
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = TextFieldTreeCell.forTreeView();
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTreeView_noArgs_ensureCellFactoryCreatesCells() {
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = TextFieldTreeCell.forTreeView();
+        
+        TreeView<String> treeView = new TreeView<>();
+        TextFieldTreeCell<String> cell = (TextFieldTreeCell<String>)cellFactory.call(treeView);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTreeView_callback_ensureCellHasNonNullStringConverter() {
+        Callback<TreeView<String>, TreeCell<String>> cellFactory = TextFieldTreeCell.forTreeView();
+        
+        TreeView<String> treeView = new TreeView<>();
+        TextFieldTreeCell<String> cell = (TextFieldTreeCell<String>)cellFactory.call(treeView);
+        assertNotNull(cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Test for public static <T> Callback<TreeView<T>, TreeCell<T>> forTreeView(
+     *       final StringConverter<T> converter)
+     * 
+     **************************************************************************/
+
+    
+    @Test public void testStatic_forTreeView_converter_ensureCellFactoryIsNotNull() {
+        Callback<TreeView<Object>, TreeCell<Object>> cellFactory = TextFieldTreeCell.forTreeView(converter);
+        assertNotNull(cellFactory);
+    }
+    
+    @Test public void testStatic_forTreeView_converter_ensureCellFactoryCreatesCells() {
+        Callback<TreeView<Object>, TreeCell<Object>> cellFactory = TextFieldTreeCell.forTreeView(converter);
+        
+        TreeView<Object> treeView = new TreeView<>();
+        TextFieldTreeCell<Object> cell = (TextFieldTreeCell<Object>)cellFactory.call(treeView);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTreeView_converter_ensureCellHasSetStringConverter() {
+        Callback<TreeView<Object>, TreeCell<Object>> cellFactory = TextFieldTreeCell.forTreeView(converter);
+        
+        TreeView<Object> treeView = new TreeView<>();
+        TextFieldTreeCell<Object> cell = (TextFieldTreeCell<Object>)cellFactory.call(treeView);
+        assertNotNull(cell.getConverter());
+        assertEquals(converter, cell.getConverter());
+    }
+    
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for default constructor
+     * 
+     **************************************************************************/
+
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNull() {
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        assertNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        assertTrue(cell.getStyleClass().contains("text-field-tree-cell"));
+    }
+    
+    @Test public void testConstructor_noArgs_defaultGraphicIsNull() {
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * Constructor tests for one-arg constructor
+     * 
+     **************************************************************************/
+    
+    @Test public void testConstructor_converter_defaultStringConverterIsNotNull() {
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>(converter);
+        assertNotNull(cell.getConverter());
+    }
+    
+    @Test public void testConstructor_converter_defaultStyleClass() {
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>(converter);
+        assertTrue(cell.getStyleClass().contains("text-field-tree-cell"));
+    }
+    
+    @Test public void testConstructor_converter_defaultGraphicIsACheckBox() {
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>(converter);
+        assertNull(cell.getGraphic());
+    }
+    
+    
+    /**************************************************************************
+     * 
+     * updateItem tests
+     * 
+     **************************************************************************/
+
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+    
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull() {
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nullConverter() {
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        cell.setConverter(null);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+    
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        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());
+    }
+
+
+    /**************************************************************************
+     *
+     * editing tests
+     *
+     **************************************************************************/
+
+    // --- is Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isEmpty() {
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsFalse_isEmpty() {
+        TreeView treeView = new TreeView();
+        treeView.setEditable(false);
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        cell.updateTreeView(treeView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_treeViewIsNull_isEmpty() {
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsTrue_isEmpty() {
+        TreeView treeView = new TreeView();
+        treeView.setEditable(true);
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        cell.updateTreeView(treeView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsTrue_cellEditableIsTrue_isEmpty() {
+        TreeView treeView = new TreeView();
+        treeView.setEditable(true);
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        cell.setEditable(true);
+        cell.updateTreeView(treeView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    // --- is Not Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isNotEmpty() {
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsFalse_isNotEmpty() {
+        TreeView treeView = new TreeView();
+        treeView.setEditable(false);
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        cell.updateTreeView(treeView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_treeViewIsNull_isNotEmpty() {
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsTrue_isNotEmpty() {
+        TreeItem root = new TreeItem("Root");
+        TreeView treeView = new TreeView(root);
+        treeView.setEditable(true);
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        cell.updateTreeView(treeView);
+        cell.updateIndex(0);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_treeViewEditableIsTrue_cellEditableIsTrue_isNotEmpty() {
+        TreeItem root = new TreeItem("Root");
+        TreeView treeView = new TreeView(root);
+        treeView.setEditable(true);
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        cell.setEditable(true);
+        cell.updateTreeView(treeView);
+        cell.updateIndex(0);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    // --- cancel edit
+    @Test public void test_cancelEdit() {
+        TreeItem root = new TreeItem("Root");
+        TreeView treeView = new TreeView(root);
+        treeView.setEditable(true);
+        TextFieldTreeCell<Object> cell = new TextFieldTreeCell<>();
+        cell.updateTreeView(treeView);
+
+        cell.updateIndex(0);
+
+        cell.startEdit();
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        cell.cancelEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/cell/TextFieldTreeTableCellTest.java	Wed Jun 19 08:46:30 2013 -0400
@@ -0,0 +1,379 @@
+/*
+ * 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 javafx.collections.FXCollections;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeTableCell;
+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;
+
+import static org.junit.Assert.*;
+
+public class TextFieldTreeTableCellTest {
+
+    private StringConverter<Object> converter;
+
+    @Before public void setup() {
+        converter = new StringConverter<Object>() {
+            @Override public String toString(Object object) {
+                return null;
+            }
+
+            @Override public Object fromString(String string) {
+                return null;
+            }
+        };
+    }
+
+    /**************************************************************************
+     *
+     * Test for public static Callback<TreeTableColumn<String>, TreeTableCell<String>> forTreeTableColumn()
+     *
+     **************************************************************************/
+
+
+    @Test public void testStatic_forTreeTableColumn_noArgs_ensureCellFactoryIsNotNull() {
+        Callback<TreeTableColumn<Object,String>, TreeTableCell<Object,String>> cellFactory = TextFieldTreeTableCell.forTreeTableColumn();
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forTreeTableColumn_noArgs_ensureCellFactoryCreatesCells() {
+        Callback<TreeTableColumn<Object,String>, TreeTableCell<Object,String>> cellFactory = TextFieldTreeTableCell.forTreeTableColumn();
+
+        TreeTableColumn<Object,String> tableColumn = new TreeTableColumn<>();
+        TextFieldTreeTableCell<Object,String> cell = (TextFieldTreeTableCell<Object,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTreeTableColumn_callback_ensureCellHasNonNullStringConverter() {
+        Callback<TreeTableColumn<Object,String>, TreeTableCell<Object,String>> cellFactory = TextFieldTreeTableCell.forTreeTableColumn();
+
+        TreeTableColumn<Object,String> tableColumn = new TreeTableColumn<>();
+        TextFieldTreeTableCell<Object,String> cell = (TextFieldTreeTableCell<Object,String>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getConverter());
+    }
+
+
+
+    /**************************************************************************
+     *
+     * Test for public static <T> Callback<TreeTableColumn<T>, TreeTableCell<T>> forTreeTableColumn(
+     *       final StringConverter<T> converter)
+     *
+     **************************************************************************/
+
+
+    @Test public void testStatic_forTreeTableColumn_converter_ensureCellFactoryIsNotNull() {
+        Callback<TreeTableColumn<Object,Object>, TreeTableCell<Object,Object>> cellFactory = TextFieldTreeTableCell.forTreeTableColumn(converter);
+        assertNotNull(cellFactory);
+    }
+
+    @Test public void testStatic_forTreeTableColumn_converter_ensureCellFactoryCreatesCells() {
+        Callback<TreeTableColumn<Object,Object>, TreeTableCell<Object,Object>> cellFactory = TextFieldTreeTableCell.forTreeTableColumn(converter);
+
+        TreeTableColumn<Object,Object> tableColumn = new TreeTableColumn<>();
+        TextFieldTreeTableCell<Object,Object> cell = (TextFieldTreeTableCell<Object,Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell);
+    }
+
+    @Test public void testStatic_forTreeTableColumn_converter_ensureCellHasSetStringConverter() {
+        Callback<TreeTableColumn<Object,Object>, TreeTableCell<Object,Object>> cellFactory = TextFieldTreeTableCell.forTreeTableColumn(converter);
+
+        TreeTableColumn<Object,Object> tableColumn = new TreeTableColumn<>();
+        TextFieldTreeTableCell<Object,Object> cell = (TextFieldTreeTableCell<Object,Object>)cellFactory.call(tableColumn);
+        assertNotNull(cell.getConverter());
+        assertEquals(converter, cell.getConverter());
+    }
+
+
+
+    /**************************************************************************
+     *
+     * Constructor tests for default constructor
+     *
+     **************************************************************************/
+
+    @Test public void testConstructor_noArgs_defaultStringConverterIsNull() {
+        TextFieldTreeTableCell<?,Object> cell = new TextFieldTreeTableCell<>();
+        assertNull(cell.getConverter());
+    }
+
+    @Test public void testConstructor_noArgs_defaultStyleClass() {
+        TextFieldTreeTableCell<?,Object> cell = new TextFieldTreeTableCell<>();
+        assertTrue(cell.getStyleClass().contains("text-field-tree-table-cell"));
+    }
+
+    @Test public void testConstructor_noArgs_defaultGraphicIsNull() {
+        TextFieldTreeTableCell<?,Object> cell = new TextFieldTreeTableCell<>();
+        assertNull(cell.getGraphic());
+    }
+
+
+    /**************************************************************************
+     *
+     * Constructor tests for one-arg constructor
+     *
+     **************************************************************************/
+
+    @Test public void testConstructor_converter_defaultStringConverterIsNotNull() {
+        TextFieldTreeTableCell<?,Object> cell = new TextFieldTreeTableCell<>(converter);
+        assertNotNull(cell.getConverter());
+    }
+
+    @Test public void testConstructor_converter_defaultStyleClass() {
+        TextFieldTreeTableCell<?,Object> cell = new TextFieldTreeTableCell<>(converter);
+        assertTrue(cell.getStyleClass().contains("text-field-tree-table-cell"));
+    }
+
+    @Test public void testConstructor_converter_defaultGraphicIsACheckBox() {
+        TextFieldTreeTableCell<?,Object> cell = new TextFieldTreeTableCell<>(converter);
+        assertNull(cell.getGraphic());
+    }
+
+
+    /**************************************************************************
+     *
+     * updateItem tests
+     *
+     **************************************************************************/
+
+    @Test public void test_updateItem_isEmpty_graphicIsNull() {
+        TextFieldTreeTableCell<?,Object> cell = new TextFieldTreeTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_updateItem_isEmpty_textIsNull() {
+        TextFieldTreeTableCell<?,Object> cell = new TextFieldTreeTableCell<>();
+        cell.updateItem("TEST", true);
+        assertNull(cell.getText());
+    }
+
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull() {
+        TextFieldTreeTableCell<?,Object> cell = new TextFieldTreeTableCell<>();
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nullConverter() {
+        TextFieldTreeTableCell<?,Object> cell = new TextFieldTreeTableCell<>();
+        cell.setConverter(null);
+        cell.updateItem("TEST", false);
+        assertNotNull(cell.getText());
+        assertEquals("TEST", cell.getText());
+    }
+
+    @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
+        TextFieldTreeTableCell<?,Object> cell = new TextFieldTreeTableCell<>();
+        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());
+    }
+
+
+    /**************************************************************************
+     *
+     * editing tests
+     *
+     **************************************************************************/
+
+    // --- is Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isEmpty() {
+        TextFieldTreeTableCell<Object,Object> cell = new TextFieldTreeTableCell<>();
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsFalse_isEmpty() {
+        TreeTableView tableView = new TreeTableView();
+        tableView.setEditable(false);
+        TextFieldTreeTableCell<Object,Object> cell = new TextFieldTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_tableColumnIsNull_isEmpty() {
+        TextFieldTreeTableCell<Object,Object> cell = new TextFieldTreeTableCell<>();
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_isEmpty() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView();
+        tableView.setEditable(true);
+        TextFieldTreeTableCell<Object,Object> cell = new TextFieldTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateTreeTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    //    @Test public void test_startEdit_tableColumnEditableIsTrue_cellEditableIsTrue_isEmpty() {
+    //        TreeTableColumn tc = new TreeTableColumn();
+    //        TreeTableView tableView = new TreeTableView(FXCollections.observableArrayList("TEST"));
+    //        tableView.getColumns().add(tc);
+    //        tableView.setEditable(true);
+    //        TextFieldTreeTableCell<Object,Object> cell = new TextFieldTreeTableCell<>();
+    //        cell.updateTreeTableView(tableView);
+    //        cell.updateIndex(0);
+    //        cell.updateTreeTableColumn(tc);
+    //        cell.setEditable(true);
+    //
+    //        tableView.edit(0, tc);
+    //        assertFalse(cell.isEditing());
+    //        assertNull(cell.getGraphic());
+    //    }
+
+    // --- is Not Empty
+    @Test public void test_startEdit_cellEditableIsFalse_isNotEmpty() {
+        TextFieldTreeTableCell<Object,Object> cell = new TextFieldTreeTableCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(false);
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableColumnEditableIsFalse_isNotEmpty() {
+        TreeTableColumn<Object,Object> tableColumn = new TreeTableColumn<>();
+        tableColumn.setEditable(false);
+        TreeTableView tableView = new TreeTableView(new TreeItem("TEST"));
+        tableView.getColumns().add(tableColumn);
+        TextFieldTreeTableCell<Object,Object> cell = new TextFieldTreeTableCell<>();
+        cell.updateTreeTableColumn(tableColumn);
+        cell.updateTreeTableView(tableView);
+        cell.updateItem("TEST", false);
+
+        cell.startEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_startEdit_cellEditableIsTrue_tableColumnIsNull_isNotEmpty() {
+        TextFieldTreeTableCell<Object,Object> cell = new TextFieldTreeTableCell<>();
+        cell.updateItem("TEST", false);
+        cell.setEditable(true);
+        cell.startEdit();
+    }
+
+    @Test public void test_startEdit_tableViewEditableIsTrue_isNotEmpty() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView(new TreeItem("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        TextFieldTreeTableCell<Object,Object> cell = new TextFieldTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTreeTableColumn(tc);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    @Test public void test_startEdit_tableColumnEditableIsTrue_cellEditableIsTrue_isNotEmpty() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView(new TreeItem("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        TextFieldTreeTableCell<Object,Object> cell = new TextFieldTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTreeTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+    }
+
+    // --- cancel edit
+    @Test public void test_cancelEdit_usingCellCancelEdit() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView(new TreeItem("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        TextFieldTreeTableCell<Object,Object> cell = new TextFieldTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTreeTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        cell.cancelEdit();
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+
+    @Test public void test_cancelEdit_usingTableCancelEdit() {
+        TreeTableColumn tc = new TreeTableColumn();
+        TreeTableView tableView = new TreeTableView(new TreeItem("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        TextFieldTreeTableCell<Object,Object> cell = new TextFieldTreeTableCell<>();
+        cell.updateTreeTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTreeTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        tableView.edit(-1, null);
+        assertFalse(cell.isEditing());
+        assertNull(cell.getGraphic());
+    }
+}