         
         // Assumption: elements in rowSpanElements have one or more constraints touching a row.
         // This is enforced in parseElementConstraints().
-        if (rowSpanElements && hasContentSize)
-        {
-            var numRowSpanElements:Number = rowSpanElements.length;
-            
-            // Measure content size rows only single span for now.
-            // If multiple span, do nothing yet.
-            for (i = 0; i < numRowSpanElements; i++)
-            {
-                var elementInfo:ElementConstraintInfo = rowSpanElements[i];
-                var layoutElement:ILayoutElement = elementInfo.layoutElement;
-                var topIndex:int = -1;
-                var bottomIndex:int = -1;
-                var span:int;
-                
-                var extY:Number = 0;
-                var preferredHeight:Number = layoutElement.getPreferredBoundsHeight();
-                var maxExtent:Number;
-                var availableHeight:Number;
-                
-                var j:int;
-                var rowHeight:Number = 0;
-                
-                // Determine how much space the element needs to satisfy its
-                // constraints and be at its preferred height.
-                if (!isNaN(elementInfo.top))
-                {
-                    extY += elementInfo.top;
-                    if (elementInfo.topBoundary)
-                        topIndex = elementInfo.rowSpanTopIndex;
-                    else
-                        topIndex = 0; // constrained to parent
-                }
-                
-                if (!isNaN(elementInfo.bottom))
-                {
-                    extY += elementInfo.bottom;
-                    if (elementInfo.bottomBoundary)
-                        bottomIndex = elementInfo.rowSpanBottomIndex;
-                    else
-                        bottomIndex = numRows - 1; // constrained to parent
-                }
-                
-                // Only include baseline if at least one of top or bottom don't
-                // exist.
-                if (!isNaN(elementInfo.baseline) && (topIndex < 0 || bottomIndex < 0))
-                {
-                    extY += elementInfo.baseline - layoutElement.baselinePosition;
-                    
-                    if (!isNaN(elementInfo.top))
-                        extY -= elementInfo.top;
-                    
-                    if (elementInfo.baselineBoundary)
-                    {
-                        topIndex = elementInfo.baselineIndex;
-                        
-                        // add baseline offset.
-                        extY += Number(rowBaselines[topIndex][0]); 
-                            
-                        // add maxAscent. maxAscent is 0 if not specified on the row.
-                        if (rowMaxAscents)
-                            extY += rowMaxAscents[topIndex];
-                    }
-                    else
-                    {
-                        topIndex = 0;
-                    }
-                }
-                
-                maxExtent = extY + preferredHeight;
-                availableHeight = maxExtent
-                
-                // If either the top or the bottom constraint doesn't exist,
-                // we must find the span of the element. We do this by
-                // determining the index of the last column that the element
-                // occupies in the unconstrained direction.
-                if (topIndex < 0 || bottomIndex < 0)
-                {
-                    var isTop:Boolean = topIndex < 0;
-                    var startIndex:int = isTop ? bottomIndex : topIndex;
-                    var endIndex:int = isTop ? -1 : numRows;
-                    var increment:int = isTop ? -1 : 1;
-                    
-                    // defaults to 0
-                    if (isTop)
-                        topIndex = 0;
-                    else // defaults to numRows - 1
-                        bottomIndex = numRows - 1;
-                    
-                    for (j = startIndex; j != endIndex ; j += increment)
-                    {
-                        row = _constraintRows[j];
-                        
-                        // subtract fixed rows
-                        if (!isNaN(row.explicitHeight))
-                            availableHeight -= row.explicitHeight;
-                        
-                        if (row.contentSize || availableHeight < 0)
-                        {
-                            if (isTop)
-                                topIndex = j;
-                            else
-                                bottomIndex = j;
-                            break;
-                        }
-                    }
-                }
-                
-                // always 1 or positive.
-                span = bottomIndex - topIndex + 1;
-                //trace(span);
-                
-                if (span == 1)
-                {
-                    row = _constraintRows[topIndex];
-                    
-                    // only measure with when dealing with content size
-                    if (row.contentSize)
-                    {   
-                        rowHeight = Math.max(rowHeights[topIndex], extY + preferredHeight);
-                        
-                        if (constraintsDetermineHeight(elementInfo))
-                            rowHeight = Math.max(rowHeight, extY + layoutElement.getMinBoundsHeight());
-                        
-                        // bound with max height of row
-                        if (!isNaN(row.maxHeight))
-                            rowHeight = Math.min(rowHeight, row.maxHeight);
-                        
-                        rowHeights[topIndex] = Math.ceil(rowHeight);
-                    }
-                }
-                else
-                {
-                    // multiple spanning case. span >= 2.
-                    // 1) start from topIndex and subtract fixed rows
-                    // 2) divide space evenly into content size rows.
-                    var contentRows:Vector.<ConstraintRow> = new Vector.<ConstraintRow>();
-                    var contentRowsIndices:Vector.<int> = new Vector.<int>();
-                    
-                    availableHeight = maxExtent;
-                    
-                    for (j = topIndex; j <= bottomIndex; j++)
-                    {
-                        row = _constraintRows[j];
-                        
-                        if (!isNaN(row.explicitHeight))
-                        {
-                            availableHeight -= row.height;
-                            
-                            if (availableHeight < 0)
-                            {
-                                availableHeight += row.height;
-                                break;
-                            }
-                        }
-                        else if (row.contentSize)
-                        {
-                            contentRows.push(row);
-                            contentRowsIndices.push(j);
-                        }
-                    }
-                    
-                    var numContentRows:Number = contentRows.length;
-                    
-                    if (numContentRows > 0)
-                    {
-                        var splitHeight:Number = availableHeight / numContentRows;
-                        
-                        for (j = 0; j < numContentRows; j++)
-                        {
-                            row = contentRows[j];
-                            
-                            rowHeight = Math.max(rowHeights[contentRowsIndices[j]], splitHeight);
-                            if (!isNaN(row.maxHeight))
-                                rowHeight = Math.min(rowHeight, row.maxHeight);
-                            
-                            rowHeights[contentRowsIndices[j]] = Math.ceil(rowHeight);
-                        }
-                    }
-                }
-            }
+        if (rowSpanElements && (hasContentSize || hasPercentSize))
+        {
+            // Measure content/percent size columns.
+            for each (var elementInfo:ElementConstraintInfo in rowSpanElements)
+            {
+                updateRowHeightsForElement(rowHeights, elementInfo);
+            }
+        }
+        
+        // Adjust percent size rows to account for constraining height.
+        if (!isNaN(constrainedHeight) && hasPercentSize)
+        {
+            constrainPercentRegionSizes(rowHeights, constrainedHeight, false);
         }
         
         return rowHeights;

     *  current constraintCache. To update the constraintCache, one needs to call
     *  the parseConstraints() method.
     */
    private function measureRows():Vector.<Number>
    {
        if (_constraintRows.length <= 0)
            return new Vector.<Number>();

        var maxExtent:Number;
        var remainingWidth:Number;
        
        var j:int;
        var colWidth:Number = 0;
        
        // 1) Determine how much space the element needs to satisfy its
