      * 
      *  Updated by createGridElement().
      */
-    private const elementToFactoryMap:Dictionary = new Dictionary();    
+    private const elementToFactoryMap:Dictionary = new Dictionary();
+    
+    /**
+     *  @private
+     *  Used by scrollPositionChanged() to determine which scroll position properties changed.
+     */    
+    private var oldVerticalScrollPosition:Number = 0;
+    private var oldHorizontalScrollPosition:Number = 0;
     
     //--------------------------------------------------------------------------
     //


import mx.collections.IList;
import mx.core.ClassFactory;
import mx.core.IFactory;
import mx.core.IContainerInvalidating;
import mx.core.IInvalidating;
import mx.core.IUITextField;
import mx.core.IVisualElement;

        if (!columns || lastVisibleColumnIndex < 0)
            return;
        
        // Layers
        
        const backgroundLayer:GridLayer = getLayer("backgroundLayer");
        const selectionLayer:GridLayer = getLayer("selectionLayer");    
        const editorIndicatorLayer:GridLayer = getLayer("editorIndicatorLayer");
        const rendererLayer:GridLayer = getLayer("rendererLayer");
        const overlayLayer:GridLayer = getLayer("overlayLayer"); 
        
        // Relayout everything if the scroll position changed or if no 
        // "invalidateDisplayList reason" was specified.  See
        // Grid/invalidateDisplayListFor(reason)
        
        const completeLayoutNeeded:Boolean = 
            grid.isInvalidateDisplayListReason("verticalScrollPosition") ||
            grid.isInvalidateDisplayListReason("horizontalScrollPosition");
            
        
        // Layout the columns and item renderers; compute new values for visibleRowIndices et al.
        
        if (completeLayoutNeeded)
        {
            oldVisibleRowIndices = visibleRowIndices;
            oldVisibleColumnIndices = visibleColumnIndices;
            
            const scrollX:Number = horizontalScrollPosition;
            const scrollY:Number = verticalScrollPosition;
            
            visibleGridBounds.x = scrollX;
            visibleGridBounds.y = scrollY;
            visibleGridBounds.width = unscaledWidth;
            visibleGridBounds.height = unscaledHeight;
            
            layoutColumns(scrollX, scrollY, unscaledWidth);
            layoutItemRenderers(rendererLayer, scrollX, scrollY, unscaledWidth, unscaledHeight);
            
            // Update the content size.  Make sure that if the content spans partially 
            // over a pixel to the right/bottom, the content size includes the whole pixel.
            
            const contentWidth:Number = Math.ceil(gridDimensions.getContentWidth());
            const contentHeight:Number = Math.ceil(gridDimensions.getContentHeight());
            grid.setContentSize(contentWidth, contentHeight); 
            
            // If the grid's contentHeight is smaller than than the available height 
            // (unscaledHeight) then pad the visible rows
            
            var paddedRowCount:int = gridDimensions.rowCount;
            if ((scrollY == 0) && (contentHeight < unscaledHeight))
            {
                const unusedHeight:Number = unscaledHeight - gridDimensions.getContentHeight();
                paddedRowCount += Math.ceil(unusedHeight / gridDimensions.defaultRowHeight);
            }
            
            for (var rowIndex:int = gridDimensions.rowCount; rowIndex < paddedRowCount; rowIndex++)
                visibleRowIndices.push(rowIndex);
            
            // Layout the row backgrounds
            
            visibleRowBackgrounds = layoutLinearElements(grid.rowBackground, backgroundLayer,
                visibleRowBackgrounds, oldVisibleRowIndices, visibleRowIndices, layoutRowBackground);
    
            // Layout the row and column separators. 
            
            const lastRowIndex:int = paddedRowCount - 1;
    
            visibleRowSeparators = layoutLinearElements(grid.rowSeparator, overlayLayer, 
                visibleRowSeparators, oldVisibleRowIndices, visibleRowIndices, layoutRowSeparator, lastRowIndex);
            
            visibleColumnSeparators = layoutLinearElements(grid.columnSeparator, overlayLayer, 
                visibleColumnSeparators, oldVisibleColumnIndices, visibleColumnIndices, layoutColumnSeparator, lastVisibleColumnIndex);
            
            
            // The old visible row,column indices are no longer needed
            
            oldVisibleRowIndices.length = 0;
            oldVisibleColumnIndices.length = 0;            
        }
        
        // Layout the hoverIndicator, caretIndicator, and selectionIndicators        
        
        if (completeLayoutNeeded || grid.isInvalidateDisplayListReason("hoverIndicator"))
            layoutHoverIndicator(backgroundLayer);
        
        if (completeLayoutNeeded || grid.isInvalidateDisplayListReason("selectionIndicator"))
            layoutSelectionIndicators(selectionLayer);
        
        if (completeLayoutNeeded || grid.isInvalidateDisplayListReason("caretIndicator"))
            layoutCaretIndicator(overlayLayer);
        
        if (completeLayoutNeeded || grid.isInvalidateDisplayListReason("editorIndicator"))
            layoutEditorIndicator(editorIndicatorLayer);
        
        // To avoid flashing, force all of the layers to render now
        
        grid.validateNow();
                
        if (enablePerformanceStatistics)
        {
