     // inside the group
     private function get canShareDisplayObject():Boolean
     {
-    	return _blendMode == "normal";
-    }
-    
-    // This function assumes that the only displayObjects are either items in the content array
-    // or created directly for an item in the content array. 
-    private function assignDisplayObjects(startIndex:int = 0):void
-    {
-        var currentAssignableDO:DisplayObject = canShareDisplayObject ? this : null;
-        //trace("currADO: " + currentAssignableDO);
-        var lastDisplayObject:DisplayObject = this;
-        
+    	return blendMode == "normal" && (layeringMode == ITEM_ORDERED_LAYERING);
+    }
+    
+   private function assignDisplayObjects():void
+    {
+        var topLayerItems:Vector.<IVisualItem>;
+        var bottomLayerItems:Vector.<IVisualItem>;        
+        var keepLayeringEnabled:Boolean = false;
+        
+        mergeData.currentAssignableDO  = canShareDisplayObject ? this : null;
+        mergeData.lastDisplayObject = this;
+        mergeData.insertIndex = 0;
+
         // Iterate through all of the items
         var len:int = numItems; 
-        for (var i:int = startIndex; i < len; i++)
+        for (var i:int = 0; i < len; i++)
         {  
             var item:* = getItemAt(i);
-            var insertIndex:int;
-            
-        	if (lastDisplayObject == this)
-        		insertIndex = 0;
-        	else
-        		insertIndex = super.getChildIndex(lastDisplayObject) + 1;
-        		
-            if (item is DisplayObject)
-            {
-            	super.setChildIndex(item as DisplayObject, insertIndex);
-            	
-                lastDisplayObject = item as DisplayObject;
-                // Null this out so that we are forced to create one for the next item
-                currentAssignableDO = null; 
-            }           
-            else if (item is GraphicElement)
-            {
-                var element:GraphicElement = item as GraphicElement;
-                
-                if (currentAssignableDO == null || element.needsDisplayObject)
+            
+        	if(layeringMode != ITEM_ORDERED_LAYERING)
+        	{
+        		var layer:Number = 0;
+        		if (item is IVisualItem)
+        			layer = (item as IVisualItem).layer;
+        		if(layer != 0)
+        		{        		
+            		if (layer > 0)
+            		{
+            			if(topLayerItems == null) topLayerItems = new Vector.<IVisualItem>();
+            			topLayerItems.push(item);
+            			continue;            		
+            		}
+            		else
+            		{
+            			if(bottomLayerItems == null) bottomLayerItems = new Vector.<IVisualItem>();
+            			bottomLayerItems.push(item);
+            			continue;            		
+            		}
+            	}
+         	}
+			assignDisplayObjectTo(item,mergeData);
+        }
+        if(topLayerItems != null)
+        {
+        	keepLayeringEnabled = true;
+        	//topLayerItems.sortOn("layer",Array.NUMERIC);
+        	sortOnLayer(topLayerItems);
+        	len = topLayerItems.length;
+        	for(i=0;i<len;i++)
+        	{
+        		assignDisplayObjectTo(topLayerItems[i],mergeData);
+        	}
+        }
+        if(bottomLayerItems != null)
+        {
+        	keepLayeringEnabled = true;
+	        mergeData.currentAssignableDO  = null;
+	        mergeData.lastDisplayObject = this;
+	        mergeData.insertIndex = 0;
+
+        	//bottomLayerItems.sortOn("layer",Array.NUMERIC);
+        	sortOnLayer(bottomLayerItems);
+        	len = bottomLayerItems.length;
+
+        	for(i=0;i<len;i++)
+        	{
+        		assignDisplayObjectTo(bottomLayerItems[i],mergeData);
+        	}
+        }
+        if(keepLayeringEnabled == false)
+        	layeringMode = ITEM_ORDERED_LAYERING;        
+    }
+    
+    /**
+    * @private
+    * a simple insertion sort.  This works well for small lists (under 12 or so), uses
+    * no aditional memory, and most importantly, is stable, meaning items with comparable
+    * values will stay in the same order relative to each other. For layering, we guarantee
+    * first the layer property, and then the item order, so a stable sort is important (and the 
+    * built in flash sort is not stable).
+    */
+	private static function sortOnLayer(a:Vector.<IVisualItem>):void
+	{
+		var len:Number = a.length;
+		var tmp:*;
+		if(len<= 1)
+			return;
+		for(var i:int = 1;i<len;i++)
+		{
+			for (var j:int = i;j > 0;j--)
+			{
+				if( a[j].layer < a[j-1].layer )
+				{
+					tmp = a[j];
+					a[j] = a[j-1];
+					a[j-1] = tmp;
+				}
+				else
+					break;
+			}
+		}
+	}
+
+    private function assignDisplayObjectTo(item:*,mergeData:GroupDisplayObjectMergeData):void
+    {
+            
+    	if (mergeData.lastDisplayObject == this)
+    		mergeData.insertIndex = 0;
+    	else
+    		mergeData.insertIndex = super.getChildIndex(mergeData.lastDisplayObject) + 1;
+    		
+        if (item is DisplayObject)
+        {
+        	super.setChildIndex(item as DisplayObject, mergeData.insertIndex);
+        	
+            mergeData.lastDisplayObject = item as DisplayObject;
+            // Null this out so that we are forced to create one for the next item
+            mergeData.currentAssignableDO = null; 
+        }           
+        else if (item is GraphicElement)
+        {
+            var element:GraphicElement = item as GraphicElement;
+            
+            if (mergeData.currentAssignableDO == null || element.needsDisplayObject)
+            {
+                var newChild:DisplayObject = element.displayObject;
+                
+                if (newChild == null)
                 {
-                    var newChild:DisplayObject = element.displayObject;
-                    
-                    if (newChild == null)
-                    {
-                        newChild = element.createDisplayObject();
-                        element.displayObject = newChild; // TODO!! Handle this in createDisplayObject?                 
-                    }
-                    
-                    addItemToDisplayList(newChild, item, insertIndex); 
-                    // If the element is transformed, the next item needs its own DO        
-                    currentAssignableDO = element.nextSiblingNeedsDisplayObject ? null : newChild;
-                    lastDisplayObject = newChild;
+                    newChild = element.createDisplayObject();
+                    element.displayObject = newChild; // TODO!! Handle this in createDisplayObject?                 
                 }
-                else
+                
+                addItemToDisplayList(newChild, item, mergeData.insertIndex); 
+                // If the element is transformed, the next item needs its own DO        
+                mergeData.currentAssignableDO = element.nextSiblingNeedsDisplayObject ? null : newChild;
+                mergeData.lastDisplayObject = newChild;
+            }
+            else
+            {
+                // Item should be assigned the currentAssignableDO
+                // If it already has a DO, we need to remove it
+                if (element.displayObject)
                 {
-                    // Item should be assigned the currentAssignableDO
-                    // If it already has a DO, we need to remove it
-                    if (element.displayObject)
-                    {
-                        if (element.displayObject.parent == this)
-                            super.removeChild(element.displayObject);
-                        element.destroyDisplayObject();
-                    }
-                    
-                    element.sharedDisplayObject = currentAssignableDO;
-                    if (element.nextSiblingNeedsDisplayObject)
-                        currentAssignableDO = null;
+                    if (element.displayObject.parent == this)
+                        super.removeChild(element.displayObject);
+                    element.destroyDisplayObject();
                 }
+                
+                element.sharedDisplayObject = mergeData.currentAssignableDO;
+                if (element.nextSiblingNeedsDisplayObject)
+                    mergeData.currentAssignableDO = null;
             }
         }
     } 
-    
+   
     
     // Helper function to remove child from other Group or display list before 
     // adding to the display list. 

    private var _content:*;
    private var _contentType:int;
    private var contentCollection:ICollectionView;
    
    private static const CONTENT_TYPE_UNKNOWN:int = 0;
    private static const CONTENT_TYPE_ARRAY:int = 1;

    
}
}


import flash.display.DisplayObject;	

class GroupDisplayObjectMergeData
{
    public var currentAssignableDO:DisplayObject;
    public var lastDisplayObject:DisplayObject;
    public var insertIndex:int;
}

const mergeData:GroupDisplayObjectMergeData = new GroupDisplayObjectMergeData();
