      */
     private function finishVirtualLayout():void
     {
-        var lastValidChildIndex:int = virtualLayoutEndIndex - virtualLayoutStartIndex;
-        
-        // At this point, insertion of new IRs has pushed all of the unneeded IRs
-        // past endIndex-startIndex.  Remove or recycle them without invalidating 
-        // this DataGroup's size or display list.
-        for(var i:int = super.numChildren - 1; i > lastValidChildIndex; i--)
-        {
-            var elt:IVisualElement = IVisualElement(super.getChildAt(i));
-            
-            // Skip IRs that are already on the free list, 
-            if (freeRenderers && (freeRenderers.indexOf(elt) != -1))
+        // At this point, we have renderers for the current rendering cycle at 
+        // [virtualLayoutStartIndex. virtualLayoutEndIndex], but we may also have old 
+        // ones that need to be removed at [oldVirtualLayoutStartIndex, oldVirtualLayoutEndIndex]
+        if (oldVirtualLayoutStartIndex == -1 || oldVirtualLayoutEndIndex == -1)
+            return;
+        
+        // We want to remove item renderers at 
+        // at [oldVirtualLayoutStartIndex, oldVirtualLayoutEndIndex]
+        // but excluding [virtualLayoutStartIndex. virtualLayoutEndIndex].
+        // Most of the time's we'll be removing one contiguous block 
+        // before or after our on-screen item renderers, but sometimes 
+        // we may be removing them before and after (in the case of 
+        // the list changing heights)
+
+        for (var index:int = oldVirtualLayoutStartIndex; index <= oldVirtualLayoutEndIndex; index++)
+        {
+            // if we encounter an IR in our current list of item renderers, 
+            // let's smart-skip to the end.
+            if (index >= virtualLayoutStartIndex && index <= virtualLayoutEndIndex)
+            {
+                index = virtualLayoutEndIndex;
                 continue;
+            }
+            
+            var elt:IVisualElement = indexToRenderer[index] as IVisualElement;
 
             // Remove previously "in view" IRs from the item=>IR table
-            var item:Object = elt;
-            if ((itemToRenderer[item] != elt) && (elt is IDataRenderer))
-            {
-                item = IDataRenderer(elt).data;
-                IDataRenderer(elt).data = null;  // reduce probability of leaks
-            }
-            delete itemToRenderer[item];
-              
+            delete indexToRenderer[index];
+            
+            var item:Object = dataProvider.getItemAt(index);
             // Free or remove the IR.
             if ((item != elt) && (elt is IDataRenderer))
             {
+                IDataRenderer(elt).data = null;  // reduce probability of leaks
                 elt.visible = false;
                 if (elt is UIComponent) 
                     UIComponent(elt).includeInLayout = false;

            }
            else
            {
                // TODO (rfrishbe): it's not quite i + startIndex, especially when considering the layer property.
                dispatchEvent(new RendererExistenceEvent(RendererExistenceEvent.RENDERER_REMOVE, 
                                false, false, elt, i + lastValidChildIndex, item));
                super.removeChild(DisplayObject(elt));
            }
        }

        return dataProvider ? dataProvider.length : 0;
    }

    private var indexToRenderer:Array = []; 

    /**
     *  @private 
