                 extY += isNaN(top) ? 0 : top;
                 extY += isNaN(bottom) ? 0 : bottom;
             }
-                
+
             width = Math.max(width, extX + layoutItem.preferredSize.x);
             height = Math.max(height, extY + layoutItem.preferredSize.y);
-                
+
             var itemMinWidth:Number = constraintsDetermineWidth(layoutItem) ? layoutItem.minSize.x : layoutItem.preferredSize.x;
             var itemMinHeight:Number = constraintsDetermineHeight(layoutItem) ? layoutItem.minSize.y : layoutItem.preferredSize.y;
-            
+
             minWidth = Math.max(minWidth, extX + itemMinWidth);
             minHeight = Math.max(minHeight, extY + itemMinHeight);
         }
 
         layoutTarget.measuredWidth = Math.max(width, minWidth);
         layoutTarget.measuredHeight = Math.max(height, minHeight);
-        
+
         layoutTarget.measuredMinWidth = minWidth;
         layoutTarget.measuredMinHeight = minHeight;
-        
+
         layoutTarget.setContentSize(layoutTarget.measuredWidth, layoutTarget.measuredHeight);
     }
 
+    /**
+     *  @return Returns the maximum value for an item's dimension so that the component doesn't
+     *  spill out of the container size. Calculations are based on the layout rules.
+     *  Pass in unscaledWidth, hCenter, left, right, childX to get a maxWidth value.
+     *  Pass in unscaledHeight, vCenter, top, bottom, childY to get a maxHeight value.
+     */
+    static private function maxSizeToFitIn(totalSize:Number,
+                                           center:Number,
+                                           lowConstraint:Number,
+                                           highConstraint:Number,
+                                           position:Number):Number
+    {
+        if (!isNaN(center))
+        {
+            // (1) x == (totalSize - childWidth) / 2 + hCenter
+            // (2) x + childWidth <= totalSize
+            // (3) x >= 0
+            //
+            // Substitue x in (2):
+            // (totalSize - childWidth) / 2 + hCenter + childWidth <= totalSize
+            // totalSize - childWidth + 2 * hCenter + 2 * childWidth <= 2 * totalSize
+            // 2 * hCenter + childWidth <= totalSize se we get:
+            // (3) childWidth <= totalSize - 2 * hCenter
+            //
+            // Substitute x in (3):
+            // (4) childWidth <= totalSize + 2 * hCenter
+            //
+            // From (3) & (4) above we get:
+            // childWidth <= totalSize - 2 * abs(hCenter)
+
+            return totalSize - 2 * Math.abs(center);
+        }
+        else if(!isNaN(lowConstraint))
+        {
+            // childWidth + left <= totalSize
+            return totalSize - lowConstraint;
+        }
+        else if(!isNaN(highConstraint))
+        {
+            // childWidth + right <= totalSize
+            return totalSize - highConstraint;
+        }
+        else
+        {
+            // childWidth + childX <= totalSize
+            return totalSize - position;
+        }
+    }
+
     public function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
     {
-        var layoutTarget:GroupBase = target; 
+        var layoutTarget:GroupBase = target;
         if (!layoutTarget)
             return;
 

            var top:Number     = LayoutItemHelper.getConstraint(layoutItem, "top");
            var bottom:Number  = LayoutItemHelper.getConstraint(layoutItem, "bottom");
            var itemMinSize:Point = layoutItem.minSize;
            var itemMaxSize:Point = layoutItem.maxSize;

            // Calculate size
            var childWidth:Number = NaN;
            var childHeight:Number = NaN;
            
            if (!isNaN(left) && !isNaN(right))
                childWidth = unscaledWidth - right - left;
            else
                childWidth = Math.max(itemMinSize.x, Math.min(itemMaxSize.x, childWidth));
            
            if (!isNaN(top) && !isNaN(bottom))
                childHeight = unscaledHeight - bottom - top;
            else
                childHeight = Math.max(itemMinSize.y, Math.min(itemMaxSize.y, childHeight));
            
            // Set size, no need to clip to min/max
            // TODO!!! incorporate min/maxSize
            var actualSize:Point = layoutItem.setActualSize(childWidth, childHeight);

            // Calculate the position            
            var childX:Number;
            var childY:Number;

            // Horizontal
            if (!isNaN(hCenter))
                childX = Math.round((unscaledWidth - actualSize.x) / 2 + hCenter);
            else if (!isNaN(left))
                childX = left;
            else if (!isNaN(right))
                childX = unscaledWidth - actualSize.x - right;
            else
                childX = layoutItem.actualPosition.x;
            
            // Vertical
            if (!isNaN(vCenter))
                childY = Math.round((unscaledHeight - actualSize.y) / 2 + vCenter);
            else if (!isNaN(top))
                childY = top;
            else if (!isNaN(bottom))
                childY = unscaledHeight - actualSize.y - bottom;
            else
                childY = layoutItem.actualPosition.y

            // Set position
            layoutItem.setActualPosition(childX, childY);
            
            // update content limits
            maxX = Math.max(maxX, childX + actualSize.x);
            maxY = Math.max(maxY, childY + actualSize.y);


    public function measure():void
    {
        var layoutTarget:GroupBase = target;
        if (!layoutTarget)
            return;

        var width:Number = 0;
        var height:Number = 0;
        var minWidth:Number = 0;
        var minHeight:Number = 0;

        var count:int = layoutTarget.numLayoutItems;
        for (var i:int = 0; i < count; i++)
        {
