         if (!grid)
             return;
         
-        // ToDo: Need to take typicalLayoutElement into account
-        //var rowCount:int = grid.dataProvider.length;
-        //var columnCount:int = grid.columns.length;
-        
-        var measuredWidth:Number = 640; //typicalLayoutElement.getPreferredBoundsWidth() * columnCount;
-        var measuredHeight:Number = 480; //typicalLayoutElement.getPreferredBoundsHeight() * rowCount;
-        var measuredMinWidth:Number = 640;
-        var measuredMinHeight:Number = 480;;
+        var measuredWidth:Number;
+        var measuredHeight:Number;
+
+        if (!isNaN(grid.explicitWidth))
+        {
+            measuredWidth = grid.explicitWidth;
+        }
+        else
+        {
+            const columns:IList = grid.columns;
+            const numColumns:int = columns.length;
+            var columnCount:int;
+            for (var i:int = 0; i < numColumns; i++)
+            {
+                var c:GridColumn = columns.getItemAt(i) as GridColumn;
+                if (c && c.visible)
+                    columnCount ++;
+            }
+            
+            const defaultColumnWidth:Number = 
+                typicalLayoutElement.getPreferredBoundsWidth();
+            const columnGap:Number = gridDimensions.columnGap;
+            
+            measuredWidth = (columnCount * (defaultColumnWidth + columnGap)) - columnGap;         
+        }
+        
+        if (!isNaN(grid.explicitHeight))
+        {
+            measuredHeight = grid.explicitWidth;
+        }
+        else
+        {
+            const rowCount:int = grid.dataProvider.length;
+            const rowGap:Number = gridDimensions.rowGap;
+            const defaultRowHeight:Number = 
+                typicalLayoutElement.getPreferredBoundsHeight();
+
+            measuredHeight = rowCount * (defaultRowHeight + rowGap);
+            
+            // One less row gap if there isn't a column header bar.
+            const columnHeaderBar:ColumnHeaderBar = getColumnHeaderBar();
+            if (!columnHeaderBar || !columnHeaderBar.visible)
+                measuredHeight -= rowGap;
+        }
+                    
+        // ToDo:(cframpto)  If there is a scroller without an explicit size, 
+        // what should the measured size of the grid?
+        
+        measuredWidth = Math.min(measuredWidth, 600);
+        measuredHeight = Math.min(measuredHeight, 480);
         
         // Use Math.ceil() to make sure that if the content partially occupies
         // the last pixel, we'll count it as if the whole pixel is occupied.
         
         grid.measuredWidth = Math.ceil(measuredWidth);    
-        grid.measuredHeight = Math.ceil(measuredHeight);    
-        grid.measuredMinWidth = Math.ceil(measuredMinWidth);    
-        grid.measuredMinHeight = Math.ceil(measuredMinHeight); 
-        
-       // trace("GridLayout.measure", grid.measuredWidth, grid.measuredHeight);        
+        grid.measuredHeight = Math.ceil(measuredHeight);
+        
+        // Not used if virtual layout so don't bother to calculate.
+        grid.measuredMinWidth = grid.measuredWidth;    
+        grid.measuredMinHeight = grid.measuredHeight; 
+        
+       //trace("GridLayout.measure", grid.measuredWidth, grid.measuredHeight);        
     }
     
     /**

        visibleColumnSeparators = layoutLinearElements(grid.columnSeparator, overlayGroup, 
            visibleColumnSeparators, oldVisibleColumnIndices, visibleColumnIndices, layoutColumnSeparator, lastColumnIndex);
        
        // Layout the hoverIndicator, caretIndicator, and selectionIndicators        
        
        layoutHoverIndicator(grid.backgroundGroup);

    private function getGridColumnHeader(columnIndex:int):IVisualElement
    {
        const headerBar:ColumnHeaderBar = getColumnHeaderBar();
        if (headerBar == null || headerBar.dataGroup == null)
            return null;
        
        return headerBar.dataGroup.getElementAt(columnIndex);
    }
    
    /**
