////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package mx.controls.treeClasses
{

import flash.events.EventDispatcher;
import flash.utils.Dictionary;

import mx.collections.ICollectionView;
import mx.collections.IViewCursor;
import mx.collections.ISort;
import mx.collections.XMLListAdapter;
import mx.collections.XMLListCollection;
import mx.collections.errors.ItemPendingError;
import mx.core.EventPriority;
import mx.core.mx_internal;
import mx.events.CollectionEvent;
import mx.events.CollectionEventKind;
import mx.events.PropertyChangeEvent;
import mx.utils.IXMLNotifiable;
import mx.utils.XMLNotifier;

use namespace mx_internal;

[ExcludeClass]

/**
 *  @private
 *  This class provides a hierarchical view of a standard collection.
 *  It is used by Tree to parse user data.
 */
public class HierarchicalCollectionView extends EventDispatcher
										implements ICollectionView, IXMLNotifiable
{
    include "../../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

	/**
	 *  Constructor.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function HierarchicalCollectionView(
							model:ICollectionView,
							treeDataDescriptor:ITreeDataDescriptor,
							itemToUID:Function,
							argOpenNodes:Object = null)
	{
		super();

		parentMap = {};

		childrenMap = new Dictionary(true);

		treeData = model;

		// listen for add/remove events from developer as weak reference
		treeData.addEventListener(CollectionEvent.COLLECTION_CHANGE,
								  collectionChangeHandler,
								  false,
								  EventPriority.DEFAULT_HANDLER,
								  true);
								  
		addEventListener(CollectionEvent.COLLECTION_CHANGE, 
								  expandEventHandler, 
								  false, 
								  0, 
								  true);
				
		dataDescriptor = treeDataDescriptor;
		this.itemToUID = itemToUID;
		openNodes = argOpenNodes;
		//calc initial length
		currentLength = calculateLength();
	}

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

	/**
	 *  @private
	 */
	private var dataDescriptor:ITreeDataDescriptor;

	/**
	 *  @private
	 */
	private var treeData:ICollectionView;

	/**
	 *  @private
	 */
	private var cursor:HierarchicalViewCursor;

	/**
	 *  @private
	 *  The total number of nodes we know about.
	 */
	private var currentLength:int;

	/**
	 *  @private
	 */
	public var openNodes:Object;

	/**
	 *  @private
	 *  Mapping of UID to parents.  Must be maintained as things get removed/added
	 *  This map is created as objects are visited
	 */
	public var parentMap:Object;

	/**
	 *  @private
	 *  Top level XML node if there is one
	 */
	private var parentNode:XML;

	/**
	 *  @private
	 *  Mapping of nodes to children.  Used by getChildren.
	 */
	private var childrenMap:Dictionary;
	
	/**
	 *  @private
	 */
	private var itemToUID:Function;

    //----------------------------------
	//  filter
    //----------------------------------

    /**
     *  Not Supported in Tree.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get filterFunction():Function
    {
        return null;
    }

    /**
     *  Not Supported in Tree.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function set filterFunction(value:Function):void
    {
        //No Impl.
    }

    //----------------------------------
	//  length
    //----------------------------------

    /**
     *  The length of the currently parsed collection.  This
     *  length only includes nodes that we know about.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
	public function get length():int
	{
		return currentLength;
	}

    //----------------------------------
	//  sort
    //----------------------------------
    /**
    *  @private
     *  Not Supported in Tree.
     */
    public function get sort():ISort
	{
	    return null;
	}

    /**
     *  @private
     *  Not Supported in Tree.
     */
    public function set sort(value:ISort):void
	{
	    //No Impl
	}

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

	/**
	 *  Returns the parent of a node.  Top level node's parent is null
	 *  If we don't know the parent we return undefined.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
    public function getParentItem(node:Object):*
    {
		var uid:String = itemToUID(node);
		if (parentMap.hasOwnProperty(uid))
			return parentMap[uid];

		return undefined;
	}
	
	/**
	 *  @private
	 *  Calculate the total length of the collection, but only count nodes
	 *  that we can reach.
	 */
	public function calculateLength(node:Object = null, parent:Object = null):int
	{
		var length:int = 0;
		var childNodes:ICollectionView;
		var firstNode:Boolean = true;

		if (node == null)
		{
			var modelOffset:int = 0;
			// special case counting the whole thing
			// watch for page faults
			var modelCursor:IViewCursor = treeData.createCursor();
			if (modelCursor.beforeFirst)
			{
				// indicates that an IPE occured on the first item
				return treeData.length;
			}
			while (!modelCursor.afterLast)
			{
				node = modelCursor.current;
				if (node is XML)
				{
					if (firstNode)
					{	
						firstNode = false;
						var parNode:* = node.parent();
						if (parNode)
						{
							startTrackUpdates(parNode);
							childrenMap[parNode] = treeData;
							parentNode = parNode;
						}
					}
					startTrackUpdates(node);
				}
				
				if (node === null)
					length += 1;
				else
					length += calculateLength(node, null) + 1;
				
				modelOffset++;
				try
				{
					modelCursor.moveNext();
				}
				catch(e:ItemPendingError)
				{
					// just stop where we are, no sense paging
					// the whole thing just to get length. make a rough
					// guess assuming that all un-paged nodes are closed
					length += treeData.length - modelOffset;
					return length;
				}
			}
		}
		else
		{
			var uid:String = itemToUID(node);
			parentMap[uid] = parent;
			if (node != null &&
				openNodes[uid] &&
				dataDescriptor.isBranch(node, treeData) &&
				dataDescriptor.hasChildren(node, treeData))
			{
				childNodes = getChildren(node);
				if (childNodes != null)
				{
					var numChildren:int = childNodes.length;
					for (var i:int = 0; i < numChildren; i++)
					{
						if (node is XML)
							startTrackUpdates(childNodes[i]);
						length += calculateLength(childNodes[i], node) + 1;
					}
				}
			}
		}
		return length;
	}

	/**
	 *  @private
	 *  This method is merely for ICollectionView interface compliance.
	 */
	public function describeData():Object
	{
		return null;
	}

    /**
	 *  Returns a new instance of a view iterator over the items in this view
	 *
     *  @see mx.utils.IViewCursor
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function createCursor():IViewCursor
	{
		return new HierarchicalViewCursor(
			this, treeData, dataDescriptor, itemToUID, openNodes);
	}

    /**
     *  Checks the collection for item using standard equality test.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function contains(item:Object):Boolean
	{
		var cursor:IViewCursor = createCursor();
		var done:Boolean = false;
		while (!done)
		{
			if (cursor.current == item)
				return true;
			done = cursor.moveNext();
		}
		return false;
	}

    /**
     *  @private
     */
	public function disableAutoUpdate():void
	{
	    //no-op
    }

    /**
     *  @private
     */
    public function enableAutoUpdate():void
    {
        //no-op
    }

	/**
	 *  @private
	 */
	public function itemUpdated(item:Object, property:Object = null,
                                oldValue:Object = null,
                                newValue:Object = null):void
    {
	    var event:CollectionEvent =
			new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
	    event.kind = CollectionEventKind.UPDATE;

		var objEvent:PropertyChangeEvent =
			new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
	    objEvent.property = property;
	    objEvent.oldValue = oldValue;
	    objEvent.newValue = newValue;
	    event.items.push(objEvent);

		dispatchEvent(event);
    }

	/**
	 *  @private
	 */
	public function refresh():Boolean
	{
	    var event:CollectionEvent =
			new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
	    event.kind = CollectionEventKind.REFRESH;
	    dispatchEvent(event);

		return true;
    }
    
    /**
	 * @private
	 * delegate getchildren in order to add event listeners for nested collections
	 */
	private function getChildren(node:Object):ICollectionView
	{
		var children:ICollectionView = dataDescriptor.getChildren(node, treeData);
		var oldChildren:ICollectionView = childrenMap[node];
		if (oldChildren != children)
		{
		    if (oldChildren != null)
		    {
				oldChildren.removeEventListener(CollectionEvent.COLLECTION_CHANGE,
									  nestedCollectionChangeHandler);
			}
			if (children)
			{
    			children.addEventListener(CollectionEvent.COLLECTION_CHANGE,
    										  nestedCollectionChangeHandler, false, 0, true);
				childrenMap[node] = children;
			}
			else
				delete childrenMap[node];
		}
		return children;
	}
    
    /**
	 * @private
	 * Force a recalulation of length	
	 */
	 private function updateLength(node:Object = null, parent:Object = null):void
	 {
	 	currentLength = calculateLength();
	 }

	/**
	 * @private
	 *  Fill the node array with the node and all of its visible children
	 *  update the parentMap as you go.
	 */
	private function getVisibleNodes(node:Object, parent:Object, nodeArray:Array):void
	{
		var childNodes:ICollectionView;
		nodeArray.push(node);

		var uid:String = itemToUID(node);
		parentMap[uid] = parent;
		if (openNodes[uid] &&
			dataDescriptor.isBranch(node, treeData) &&
			dataDescriptor.hasChildren(node, treeData))
		{
			childNodes = getChildren(node);
			if (childNodes != null)
			{
				var numChildren:int = childNodes.length;
				for (var i:int = 0; i < numChildren; i++)
				{
					getVisibleNodes(childNodes[i], node, nodeArray);
				}
			}
		}
	}

	/**
	 *  @private
	 *  Factor in the open children before this location in the model
	 */
	private function getVisibleLocation(oldLocation:int):int
	{
		var newLocation:int = 0;
		var modelCursor:IViewCursor = treeData.createCursor();
		for (var i:int = 0; i < oldLocation && !modelCursor.afterLast; i++)
		{
			newLocation += calculateLength(modelCursor.current, null) + 1;
			modelCursor.moveNext();
		}
		return newLocation;
	}

	/**
	 * @private
	 * factor in the open children before this location in a sub collection
	 */
	private function getVisibleLocationInSubCollection(parent:Object, oldLocation:int):int
	{
		var newLocation:int = oldLocation;
		var target:Object = parent;
		parent = getParentItem(parent);
		var children:ICollectionView;
		var cursor:IViewCursor;
		while (parent != null)
		{
			children = childrenMap[parent];
			cursor = children.createCursor();
			while (!cursor.afterLast)
			{
				if (cursor.current == target)
				{
					newLocation++;
					break;
				}
				newLocation += calculateLength(cursor.current, parent) + 1;
				cursor.moveNext();
			}
			target = parent;
			parent = getParentItem(parent);
		}
		cursor = treeData.createCursor();
		while (!cursor.afterLast)
		{
			if (cursor.current == target)
			{
				newLocation++;
				break;
			}
			newLocation += calculateLength(cursor.current, parent) + 1;
			cursor.moveNext();
		}
		return newLocation;
	}

    //--------------------------------------------------------------------------
    //
    //  Event handlers
    //
    //--------------------------------------------------------------------------

	/**
	 *  @private
	 */
	public function collectionChangeHandler(event:CollectionEvent):void
	{
		var i:int;
		var n:int;
		var location:int;
		var uid:String;
		var parent:Object;
		var node:Object;
		var items:Array;

		var convertedEvent:CollectionEvent;
		
		if (event is CollectionEvent)
        {
            var ce:CollectionEvent = CollectionEvent(event);
            if (ce.kind == CollectionEventKind.RESET)
            {
            	updateLength();
            	dispatchEvent(event);
            }
            else if (ce.kind == CollectionEventKind.ADD)
            {
				n = ce.items.length;
				convertedEvent = new CollectionEvent(
        								CollectionEvent.COLLECTION_CHANGE,
										false, 
										true,
										ce.kind);
				convertedEvent.location = getVisibleLocation(ce.location);
				for (i = 0; i < n; i++)
				{
					node = ce.items[i];
					if (node is XML)
						startTrackUpdates(node);
					getVisibleNodes(node, null, convertedEvent.items);
				}
				currentLength += convertedEvent.items.length;
            	dispatchEvent(convertedEvent);
            }
            else if (ce.kind == CollectionEventKind.REMOVE)
            {
				n = ce.items.length;
				convertedEvent = new CollectionEvent(
        								CollectionEvent.COLLECTION_CHANGE,
										false, 
										true,
										ce.kind);
				convertedEvent.location = getVisibleLocation(ce.location);
				for (i = 0; i < n; i++)
				{
					node = ce.items[i];
					if (node is XML)
						stopTrackUpdates(node);
					getVisibleNodes(node, null, convertedEvent.items);
				}
				currentLength -= convertedEvent.items.length;
            	dispatchEvent(convertedEvent);
            }
            else if (ce.kind == CollectionEventKind.UPDATE)
            {
				// so far, nobody cares about the details so just
				// send it
				//updateLength();
            	dispatchEvent(event);
            }
            else if (ce.kind == CollectionEventKind.REPLACE)
            {
            	// someday handle case where node is marked as open
				// before it becomes the replacement.
				// for now, just pass on the data and remove
				// old visible rows
				n = ce.items.length;
				convertedEvent = new CollectionEvent(
        								CollectionEvent.COLLECTION_CHANGE,
										false, 
										true,
										CollectionEventKind.REMOVE);

				for (i = 0; i < n; i++)
				{
					node = ce.items[i].oldValue;
					if (node is XML)
						stopTrackUpdates(node);
					getVisibleNodes(node, null, convertedEvent.items);
				}

				// prune the replacements from this list
				var j:int = 0;
				for (i = 0; i < n; i++)
				{
					node = ce.items[i].oldValue;
					while (convertedEvent.items[j] != node)
						j++;
					convertedEvent.items.splice(j, 1);
				}
				if (convertedEvent.items.length)
				{
					currentLength -= convertedEvent.items.length;
					// nobody cares about location yet.
            		dispatchEvent(convertedEvent);
				}
            	dispatchEvent(event);
            }
        }
	}

	/**
	 *  @private
	 */
	public function nestedCollectionChangeHandler(event:CollectionEvent):void
	{
		var i:int;
		var n:int;
		var location:int;
		var uid:String;
		var parent:Object;
		var node:Object;
		var items:Array;
		var convertedEvent:CollectionEvent;

		if (event is CollectionEvent)
        {
            var ce:CollectionEvent = CollectionEvent(event);
            if (ce.kind == CollectionEventKind.EXPAND)
            {
            	event.stopImmediatePropagation();
            }
            else if (ce.kind == CollectionEventKind.ADD)
            {
				// optimize someday.  We do a full tree walk so we can
				// not only count how many but find the parents of the
				// new nodes.  A better scheme would be to just
				// increment by the number of visible nodes, but we
				// don't have a good way to get the parents.
            	updateLength();
				n = ce.items.length;
				convertedEvent = new CollectionEvent(
        								CollectionEvent.COLLECTION_CHANGE,
										false, 
										true,
										ce.kind);
				for (i = 0; i < n; i++)
				{
					node = ce.items[i];
					if (node is XML)
						startTrackUpdates(node);
					parent = getParentItem(node);
					if (parent != null)
						getVisibleNodes(node, parent, convertedEvent.items);
				}
				convertedEvent.location = getVisibleLocationInSubCollection(parent, ce.location);
            	dispatchEvent(convertedEvent);
            }
            else if (ce.kind == CollectionEventKind.REMOVE)
            {
				n = ce.items.length;
				convertedEvent = new CollectionEvent(
        								CollectionEvent.COLLECTION_CHANGE,
										false, 
										true,
										ce.kind);
				for (i = 0; i < n; i++)
				{
					node = ce.items[i];
					if (node is XML)
						stopTrackUpdates(node);
					parent = getParentItem(node);
					if (parent != null)
						getVisibleNodes(node, parent, convertedEvent.items);
				}
				convertedEvent.location = getVisibleLocationInSubCollection(parent, ce.location);
				currentLength -= convertedEvent.items.length;
            	dispatchEvent(convertedEvent);
            }
            else if (ce.kind == CollectionEventKind.UPDATE)
            {
				// so far, nobody cares about the details so just
				// send it
            	dispatchEvent(event);
            }
	        else if (ce.kind == CollectionEventKind.REPLACE)
            {
            	// someday handle case where node is marked as open
				// before it becomes the replacement.
				// for now, just pass on the data and remove
				// old visible rows
				n = ce.items.length;
				convertedEvent = new CollectionEvent(
        								CollectionEvent.COLLECTION_CHANGE,
										false, 
										true,
										CollectionEventKind.REMOVE);

				for (i = 0; i < n; i++)
				{
					node = ce.items[i].oldValue;
					parent = getParentItem(node);
					if (parent != null)
						getVisibleNodes(node, parent, convertedEvent.items);
				}

				// prune the replacements from this list
				var j:int = 0;
				for (i = 0; i < n; i++)
				{
					node = ce.items[i].oldValue;
					if (node is XML)
						stopTrackUpdates(node);
					while (convertedEvent.items[j] != node)
						j++;
					convertedEvent.items.splice(j, 1);
				}
				if (convertedEvent.items.length)
				{
					currentLength -= convertedEvent.items.length;
					// nobody cares about location yet.
            		dispatchEvent(convertedEvent);
				}
            	dispatchEvent(event);
            }
			else if (ce.kind == CollectionEventKind.RESET)
			{
				// removeAll() sends a RESET.
				// when we get a reset we don't know what went away
				// and we don't know how many things went away, so
				// we just fake a refresh as if there was a filter
				// applied that filtered out whatever went away
            	updateLength();
				convertedEvent = new CollectionEvent(
        								CollectionEvent.COLLECTION_CHANGE,
										false, 
										true,
										CollectionEventKind.REFRESH);
           		dispatchEvent(convertedEvent);
			}
        }
	}

    /**
     * Called whenever an XML object contained in our list is updated
     * in some way.  The initial implementation stab is very lenient,
     * any changeType will cause an update no matter how much further down
     * in a hierarchy.  
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function xmlNotification(currentTarget:Object, 
                                        type:String, 
                                        target:Object, 
                                        value:Object, 
                                        detail:Object):void
    {
        var prop:String;
        var oldValue:Object;
        var newValue:Object;
		var children:XMLListCollection;
		var location:int;
        var event:CollectionEvent;
		var list:XMLListAdapter;
        
		// trace("currentTarget", currentTarget.toXMLString());
		// trace("target", target.toXMLString());
		// trace("value", value.toXMLString());
		// trace("type", type);

		if (currentTarget === target)
        {
			
	        switch(type)
	        {
	            case "nodeAdded":
	            {
	            	for (var q:* in childrenMap)
					{
						if (q === currentTarget)
						{
							list = childrenMap[q].list as XMLListAdapter;
							break;
						}
					}
					
	            	if (!list && target is XML && XML(target).children().length() == 1)
	            	{
	            		// this is a special case (SDK-13807), when you add your first xml node
	            		// we need to add the listener, and getChildren() does it for us.
	            		list = (getChildren(target) as XMLListCollection).list as XMLListAdapter;
	            	}
	            	
					if (list && !list.busy())
					{
						if (childrenMap[q] === treeData)
						{
							children = treeData as XMLListCollection;
							if (parentNode)
							{
								children.dispatchResetEvent = false;
								children.source = parentNode.*;
							}
						}
						else
						{
							// this should refresh the collection
							children = getChildren(q) as XMLListCollection;
						}
						if (children)
						{
							// now we fake an event on behalf of the
							// child collection
							location = value.childIndex();
							event = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
							event.kind = CollectionEventKind.ADD;
							event.location = location;
							event.items = [ value ];
							children.dispatchEvent(event);
						}
					}

	                break;
	            }

				/* needed?
	            case "nodeChanged":
	            {
	                prop = value.localName();
	                oldValue = detail;
	                newValue = value;
	                break;
	            }
				*  
				*  @langversion 3.0
				*  @playerversion Flash 9
				*  @playerversion AIR 1.1
				*  @productversion Flex 3
				*/

	            case "nodeRemoved":
	            {
					// lookup doesn't work, must scan instead
					for (var p:* in childrenMap)
					{
						if (p === currentTarget)
						{
							children = childrenMap[p];
							list = children.list as XMLListAdapter;
							if (list && !list.busy())
							{
								var xmllist:XMLList = children.source as XMLList;

								if (childrenMap[p] === treeData)
								{
									children = treeData as XMLListCollection;
									if (parentNode)
									{
										children.dispatchResetEvent = false;
										children.source = parentNode.*;
									}
								}
								else
								{
									var oldChildren:XMLListCollection = children;
									// this should refresh the collection
									children = getChildren(p) as XMLListCollection;
									if (!children)
									{
										// last item got removed so there's no child collection
    									oldChildren.addEventListener(CollectionEvent.COLLECTION_CHANGE,
    																  nestedCollectionChangeHandler, false, 0, true);

										event = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
										event.kind = CollectionEventKind.REMOVE;
										event.location = 0;
										event.items = [ value ];
										oldChildren.dispatchEvent(event);
    									oldChildren.removeEventListener(CollectionEvent.COLLECTION_CHANGE,
    																  nestedCollectionChangeHandler);

									}
								}
								if (children)
								{
									var n:int = xmllist.length();
									for (var i:int = 0; i < n; i++)
									{
										if (xmllist[i] === value)
										{
											event = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
											event.kind = CollectionEventKind.REMOVE;
											event.location = location;
											event.items = [ value ];
											children.dispatchEvent(event);
											break;
										}
									}
								}
							}
							break;
						}
					}
	                break;
	            }

	            default:
				{
	                break;
				}
	        }
        }
    }

    /** 
     *  This is called by addItemAt and when the source is initially
     *  assigned.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    private function startTrackUpdates(item:Object):void
    {
        XMLNotifier.getInstance().watchXML(item, this);
    }
    
    /** 
     *  This is called by removeItemAt, removeAll, and before a new
     *  source is assigned.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    private function stopTrackUpdates(item:Object):void
    {
        XMLNotifier.getInstance().unwatchXML(item, this);
    }

	/**
	 *  @private
	 */
	public function expandEventHandler(event:CollectionEvent):void
	{
		if (event is CollectionEvent)
        {
            var ce:CollectionEvent = CollectionEvent(event);
            if (ce.kind == CollectionEventKind.EXPAND)
            {
            	event.stopImmediatePropagation();
            	updateLength();  
            }
        }
	}
}

}
