 	
 	/**
 	 *  @private
-	 *  Compute the widths and indices of the columns that fit within the specified width, where the 
-	 *  first column's index is startIndex, and the left edge of the first column is startX.  The 
-	 *  widths and indices are returned in the vector parameters.   The vector parameters are 
-	 *  expected to be empty when this method is called.
-	 * 
-	 *  The returned width for GridColumns with an explicit width, is just the explicit width.
-	 *  Otherwise an item renderer is created for the column and the grid's typical item and
-	 *  the item renderer's preferred width is the column's width.    
+     *  Update the typicalCellWidth,Height for all of the columns starting 
+     *  with x coordinate startX and column startIndex that fit within the 
+     *  specified width.  Typical sizes are only updated if the current 
+     *  typical cell size is NaN. 
+     * 
+     *  The typicalCellWidth for GridColumns with an explicit width, is just 
+     *  the explicit width.  Otherwise an item renderer is created for the column 
+     *  and the item renderer's preferred bounds become the typical cell size.   
+     * 
+     *  Return the indices of the columns whose typicalCellWidth,Height was updated. 
 	 */
-	private function computeVisibleColumnWidths(width:Number, startX:Number, startIndex:int, indices:Vector.<int>, widths:Vector.<Number>):void
+	private function updateTypicalCellSizes(width:Number, startX:Number, startIndex:int):Vector.<int>
 	{
 		const gridDimensions:GridDimensions = gridDimensions;
 		const columnCount:int = gridDimensions.columnCount;
 		const columnGap:int = gridDimensions.columnGap;
-		const startCellR:Rectangle = gridDimensions.getCellBounds(0 /* rowIndex */, startIndex);        
-		
-		for (var index:int = startIndex; (width > 0) && (index < columnCount); index++)
+		const startCellX:Number = gridDimensions.getCellX(0 /* rowIndex */, startIndex);
+        const isFixedRowHeight:Boolean = !isNaN(grid.fixedRowHeight);
+        
+        // Update the typicalCellWidth,Height as needed.   Avoid creating renderers or
+        // the indices vector if possible
+        
+        var indices:Vector.<int> = null;  // return value       
+
+		for (var columnIndex:int = startIndex; (width > 0) && (columnIndex < columnCount); columnIndex++)
 		{
-			var gridColumn:GridColumn = getGridColumn(index);
-			var columnWidth:Number;
+            var cellHeight:Number = gridDimensions.getTypicalCellHeight(columnIndex);
+			var cellWidth:Number = gridDimensions.getTypicalCellWidth(columnIndex);
 			
-			if (isNaN(gridColumn.width)) // if this column's width wasn't explicitly specified	
-			{
-				var renderer:IVisualElement = createTypicalItemRenderer(index);
-				columnWidth = renderer.getPreferredBoundsWidth();
-				freeGridElement(renderer);
-			}
+            var column:GridColumn = getGridColumn(columnIndex);
+            if (!isNaN(column.width))
+                cellWidth = column.width;
+            
+            if (isNaN(cellWidth) || (!isFixedRowHeight && isNaN(cellHeight)))
+            {
+                var renderer:IVisualElement = createTypicalItemRenderer(columnIndex);
+                if (isNaN(cellWidth))
+                    cellWidth = renderer.getPreferredBoundsWidth();
+                if (isNaN(cellHeight))
+                    cellHeight = renderer.getPreferredBoundsHeight();
+                freeGridElement(renderer);
+                
+                gridDimensions.setTypicalCellWidth(columnIndex, cellWidth);
+                gridDimensions.setTypicalCellHeight(columnIndex, cellHeight);
+                
+                if (indices == null)
+                    indices = new Vector.<int>();
+                indices.push(columnIndex);                
+            }
+            
+			if (columnIndex == startIndex)
+				width -= startCellX + cellWidth - startX;
 			else
-				columnWidth = gridColumn.width;
-			
-			if (index == startIndex)
-				width -= startCellR.x + columnWidth - startX;
-			else
-				width -= columnWidth + columnGap;
-
-			indices.push(index);
-			widths.push(columnWidth);
-		}		
+				width -= cellWidth + columnGap;
+		}
+        
+        return indices;
 	}	
 	
 	/**

			
			gridDimensions.setColumnWidth(columnIndex, columnWidth);  // store the column width
		}
		
		columnIndices.length = 0;
		columnWidths.length = 0;
	}
	


	 * 
	 *  This method should be called *before* layoutItemRenderers(). 
	 */
 	private function updateGridDimensions(scrollX:Number, scrollY:Number, width:Number, height:Number):void
	{
        const gridDimensions:GridDimensions = gridDimensions;        
		const firstVisibleColumnIndex:int = gridDimensions.getColumnIndexAt(scrollX, scrollY);
        const columnIndices:Vector.<int> = updateTypicalCellSizes(width, scrollX, firstVisibleColumnIndex);
        
        if (!columnIndices)  // there no new typical item cell widths
            return;
        
		const columnCount:uint = columnIndices.length;
		for (var index:int = 0; index < columnCount; index++)
		{
			var columnIndex:int = columnIndices[index];
			var columnWidth:Number = gridDimensions.getTypicalCellWidth(columnIndex);
			var gridColumn:GridColumn = getGridColumn(columnIndex);
			
			if (isNaN(gridColumn.width)) // if this column's width wasn't explicitly specified
