     {
         if (_dataProvider == value)
             return;
-
+        
+        cleanUpDataProvider();
+        
+        _dataProvider = value;
+        dataProviderChanged = true;
+        invalidateProperties();
+    }
+    
+    /**
+     *  Cleans up all the old item renderers.
+     */ 
+    protected function cleanUpDataProvider():void
+    {
+        if (_dataProvider)
+            _dataProvider.removeEventListener(CollectionEvent.COLLECTION_CHANGE, dataProvider_collectionChangeHandler);
+        
+        var index:int;
+        var vLayout:Boolean = layout && layout.useVirtualLayout;
+        
         // if there's an old dataProvider, and we've created the item renderer for 
         // that dataProvider, then we need to clear out all those item renderers
-        if (!dataProviderChanged && _dataProvider)
-        {
-            var vLayout:Boolean = layout && layout.useVirtualLayout;
-            var startIndex:int = vLayout ? virtualLayoutStartIndex : 0;
-            var endIndex:int = vLayout ? virtualLayoutEndIndex : dataProvider.length - 1; 
-            for (var index:int = endIndex; index >= startIndex; index--)
-            {
-                mx_internal::itemRemoved(_dataProvider.getItemAt(index), index);
-            }
-            
-            if (vLayout)
-            {
+        if (indexToRenderer.length > 0)
+        {
+            var renderer:IVisualElement = indexToRenderer[index] as IVisualElement;
+            var item:Object;
+            
+            if (!vLayout)
+            {
+                for (index = indexToRenderer.length - 1; index >= 0; index--)
+                {
+                    // TODO (rfrishbe): we can't key off of the oldDataProvider for 
+                    // the item because it might not be there anymore (for instance, 
+                    // in a dataProvider reset where the new data is loaded into 
+                    // the dataProvider--the dataProvider doesn't actually change, 
+                    // but we still need to clean up).
+                    // Because of this, we are assuming the item is either:
+                    //   1.  The data property if the item implements IDataRenderer 
+                    //       and there is an itemRenderer or itemRendererFunction
+                    //   2.  The item itself
+                    
+                    renderer = indexToRenderer[index] as IVisualElement;
+                    if (renderer is IDataRenderer && (itemRenderer != null || itemRendererFunction != null))
+                        item = IDataRenderer(renderer).data;
+                    else
+                        item = renderer;
+                    mx_internal::itemRemoved(item, index);
+                }
+                indexToRenderer = [];
+            }
+            else
+            {
+                for (index = virtualLayoutEndIndex; index >= virtualLayoutStartIndex; index--)
+                {
+                    // TODO (rfrishbe): same as above
+                    
+                    renderer = indexToRenderer[index] as IVisualElement;
+                    if (renderer is IDataRenderer && (itemRenderer != null || itemRendererFunction != null))
+                        item = IDataRenderer(renderer).data;
+                    else
+                        item = renderer;
+                    mx_internal::itemRemoved(item, index);
+                }
+                indexToRenderer = [];
+                
                 virtualLayoutStartIndex = virtualLayoutEndIndex = -1;
                 oldVirtualLayoutStartIndex = oldVirtualLayoutEndIndex = -1;
                 

    {
        _itemRendererFunction = value;

        invalidateProperties();
        invalidateSize();
        invalidateDisplayList();
        
        itemRendererChanged = true;
        typicalItemChanged = true;
    }
    
    private var _dataProvider:IList;
    private var dataProviderChanged:Boolean = false;
    
    [Bindable("dataProviderChanged")]
    /**

import mx.layout.LayoutElementFactory;


/**
 *  Dispatched when a renderer is added to the content holder.
 * <code>event.renderer</code> is the renderer that was added.
