////////////////////////////////////////////////////////////////////////////////
//
//  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.collections
{

import flash.events.EventDispatcher;

import mx.collections.errors.ChildItemPendingError;
import mx.collections.errors.ItemPendingError;
import mx.core.mx_internal;
import mx.events.CollectionEvent;
import mx.events.CollectionEventKind;
import mx.events.FlexEvent;
import mx.utils.ObjectUtil;
import mx.utils.UIDUtil;

use namespace mx_internal;

/**
 *  The HierarchicalCollectionViewCursor class defines a 
 *  cursor for a hierarchical view of a standard collection. 
 *  The collection that this cursor walks across need not be hierarchical - it may be flat. 
 *  This class delegates to the IHierarchicalData for information regarding the tree 
 *  structure of the data it walks across. 
 *  
 *  @see HierarchicalCollectionView
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class HierarchicalCollectionViewCursor extends EventDispatcher
                                    implements IHierarchicalCollectionViewCursor
{
    include "../core/Version.as";
        
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor.
     *
     *  @param collection The HierarchicalCollectionView instance referenced by this cursor.
     *
     *  @param model The source data collection.
     *
     *  @param hierarchicalData The data used to create the HierarchicalCollectionView instance.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function HierarchicalCollectionViewCursor(
                            collection:HierarchicalCollectionView,
                            model:ICollectionView,
                            hierarchicalData:IHierarchicalData)
    {
        super();
        
        //fields
        this.collection = collection;
        this.hierarchicalData = hierarchicalData;
        this.model = model;
        
        //events
        collection.addEventListener(CollectionEvent.COLLECTION_CHANGE, collectionChangeHandler, false, 0, true);

        //init
        modelCursor = model.createCursor();
        
        //check to see if the model has more than one top level items
        more = model.length > 1;
    }
    
    //--------------------------------------------------------------------------
    //
    // Variables
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    private var hierarchicalData:IHierarchicalData;
    
    /**
     *  @private
     *  The bookmark representing the position of the current node in its siblings collection
     */
    private var currentChildBookmark:CursorBookmark = CursorBookmark.FIRST;

    /**
     *  @private
     *  Its effective offset into the "array".
     */
    private var currentIndex:int = 0;
    
    /**
     *  @private
     *  The depth of the current node.
     */
    private var _currentDepth:int = 1; 
    
    /**
     *  @private
     *  The current set of childNodes we are walking.
     */
    private var childNodes:ICollectionView;
    
    /**
     *  @private
     *  The current set of parentNodes that we have walked from
     */
    private var parentNodes:Array = [];
    
    /**
     *  @private
     *  A stack of the currentChildBookmark in all parents of the currentNode.
     */
    private var parentBookmarkStack:Array = [];

    /**
     *  @private
     *  The collection that stores the user data
     */
    private var model:ICollectionView;
    
    /**
     *  @private
     *  The collection wrapper of the model
     */
    private var collection:HierarchicalCollectionView;
    
    /**
     *  @private
     *  Flag indicating model has more data
     */ 
    private var more:Boolean;
    
    /**
     *  @private
     *  Cursor from the model
     */ 
    private var modelCursor:IViewCursor;

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    // index
    //----------------------------------
    /**
     * @private
     */
    public function get index():int
    {
        return currentIndex;
    }
    
    //----------------------------------
    //  bookmark
    //----------------------------------
    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get bookmark():CursorBookmark
    {
        return new CursorBookmark(currentIndex.toString());
    }

    //---------------------------------- 
    //  current
    //----------------------------------
    
    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get current():Object
    {
        if (parentBookmarkStack.length == 0)
        {
            return modelCursor.current;
        }
        else
        {
            var childCursor:IViewCursor = childNodes.createCursor();
            try
            {
                
                childCursor.seek(currentChildBookmark);
                return childCursor.current;
            }
            catch (e:ItemPendingError)
            {
                return null;
            }
        }
        
        return null;
    }


    //---------------------------------
    // currentDepth
    //---------------------------------
    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get currentDepth():int
    {
        return _currentDepth;
    }


    //----------------------------------
    //  beforeFirst
    //----------------------------------
    /**
     *  @copy mx.collections.IViewCursor#beforeFirst
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get beforeFirst():Boolean
    {
        return currentIndex < 0 && current == null;
    }
    
    //----------------------------------
    //  afterLast
    //----------------------------------
    /**
     *  @copy mx.collections.IViewCursor#afterLast
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get afterLast():Boolean
    {
        return currentIndex >= collection.length && current == null;
    } 
    
    //----------------------------------
    //  view
    //----------------------------------
    /**
     *  @copy mx.collections.IViewCursor#view
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get view():ICollectionView
    {
        return model;
    }

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  <p>Note that for this class, the view does not need to be sorted in order to
     *  call this method. Also, if the item cannot be found, the cursor location is
     *  left on the last queried object.</p>
     *
     *  @inheritDoc
     * 
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function findAny(valuesToMatch:Object):Boolean
    {
        seek(CursorBookmark.FIRST);
        
        do
        {
            if (ObjectUtil.valuesAreSubsetOfObject(valuesToMatch, hierarchicalData.getData(current)))
                return true;
        }
        while(moveNext());

        return false;
    }

    /**
     *  <p>Note that for this class, the view does not need to be sorted in order to
     *  call this method. Also, if the item cannot be found, the cursor location is
     *  left on the last queried object.</p>
     *
     *  @inheritDoc
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function findFirst(values:Object):Boolean
    {
        return findAny(values);
    }

    /**
     *  <p>Note that for this class, the view does not need to be sorted in order to
     *  call this method. Also, if the item cannot be found, the cursor location is
     *  left on the last queried object.</p>
     *
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function findLast(valuesToMatch:Object):Boolean
    {
        seek(CursorBookmark.LAST);
        
        do
        {
            if (ObjectUtil.valuesAreSubsetOfObject(valuesToMatch, hierarchicalData.getData(current)))
                return true;
        }
        while(movePrevious());

        return false;
    }


    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function moveNext():Boolean 
    {
        var currentNode:Object = current;
        //if there is no currentNode then we can't move forward and must be off the ends
        if (currentNode == null) 
            return false; 
        
        var childCursor:IViewCursor;
        var uid:String = UIDUtil.getUID(currentNode);

        // If current node is a branch and is open, the first child is our next item so return it
        if (collection.openNodes[uid] &&
            hierarchicalData.canHaveChildren(currentNode) && 
            hierarchicalData.hasChildren(currentNode))
        {
                var previousChildNodes:ICollectionView = childNodes;
                childNodes = collection.getChildren(currentNode);
                if (childNodes.length > 0)
                {
                    parentBookmarkStack.push(currentChildBookmark);
                    parentNodes.push(currentNode);
                    currentChildBookmark = CursorBookmark.FIRST;
                    childCursor = childNodes.createCursor();
                    try
                    {
                        currentNode = childCursor.current;
                        // update parent map
                        updateParentMap(currentNode);
                    }
                    catch (e:ItemPendingError)
                    {
                        currentNode = null;
                        throw new ChildItemPendingError(e.message);
                    }
                    currentIndex++;
                    _currentDepth++;
                    return true;
                }
                else
                {
                    childNodes = previousChildNodes;
                }
        }

        // Otherwise until we find the next child (could be on any level)
        while (true)
        {
            // If we hit the end of this list, pop up a level.
            if(childNodes != null)
            {
                childCursor = childNodes.createCursor();
                try
                {
                    childCursor.seek(currentChildBookmark);
                    childCursor.moveNext();
                }
                catch(e:ItemPendingError)
                {
                    childCursor.seek(CursorBookmark.FIRST);
                }
             }
             
             var grandParent:Object;
            
            if (childNodes != null && 
                childNodes.length > 0 && 
                (childCursor.bookmark == CursorBookmark.LAST || childCursor.afterLast))
            {
                //check for the end of the tree here.
                if (parentBookmarkStack.length < 1 && !more)  
                {
                    currentNode = null;
                    currentIndex++;
                    _currentDepth = 1;
                    return false;
                }
                else 
                {  
                    //pop up to parent
                    currentNode = parentNodes.pop(); 
                    //get parents siblings 
                    grandParent = parentNodes[parentNodes.length-1];
                    //we could probably assume that a non-null grandparent has descendants 
                    //but the analogy only goes so far... 
                    if (grandParent != null && 
                        hierarchicalData.canHaveChildren(grandParent) &&
                        hierarchicalData.hasChildren(grandParent))
                    {
                        childNodes = collection.getChildren(grandParent);
                    }
                    else
                    {
                        childNodes = null;
                    }
                    //get new current nodes index
                    currentChildBookmark = parentBookmarkStack.pop();
                    //pop the level up one
                    _currentDepth--;
                }
            }
            else
            {
                //if no childnodes then we're probably at the top level
                if (parentBookmarkStack.length == 0)
                {
                    //check for more top level siblings
                    //and if we're here the depth should be 1
                    _currentDepth = 1;
                    more = modelCursor.moveNext();
                    if (more) 
                    {
                        currentNode = modelCursor.current;
                        break;
                    } 
                    else 
                    {
                        //at the end of the tree
                        _currentDepth = 1;
                        currentIndex++;  //this should push us to afterLast
                        currentNode = null;
                        return false;
                    }
                }
                else 
                {
                    //get the next child node
                    try
                    {
                        childCursor = childNodes.createCursor();
                        childCursor.seek(currentChildBookmark);
                        
                        childCursor.moveNext();
                        currentChildBookmark = childCursor.bookmark;
                        
                        currentNode = childCursor.current;
                        break;
                    }
                    catch(e:ItemPendingError)
                    {
                        //pop up to parent
                        currentNode = parentNodes.pop(); 
                        //get parents siblings 
                        grandParent = parentNodes[parentNodes.length-1];
                        //we could probably assume that a non-null grandparent has descendants 
                        //but the analogy only goes so far... 
                        if (grandParent != null && 
                            hierarchicalData.canHaveChildren(grandParent) &&
                            hierarchicalData.hasChildren(grandParent))
                        {
                            childNodes = collection.getChildren(grandParent);
                        }
                        else
                        {
                            childNodes = null;
                        }
                        //get new current nodes index
                        currentChildBookmark = parentBookmarkStack.pop();
                        //pop the level up one
                        _currentDepth--;
                        
                        if (parentBookmarkStack.length == 0)
                        {
                            //check for more top level siblings
                            //and if we're here the depth should be 1
                            _currentDepth = 1;
                            more = modelCursor.moveNext();
                            if (more) 
                            {
                                currentNode = modelCursor.current;
                                throw new ChildItemPendingError(e.message);
                            } 
                            else 
                            {
                                //at the end of the tree
                                _currentDepth = 1;
                                currentIndex++;  //this should push us to afterLast
                                currentNode = null;
                                return false;
                            }
                        }
                        break;
                    }
                }
            } 
        }
        
        updateParentMap(currentNode);

        currentIndex++;
        return true;
    }
    
    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function movePrevious():Boolean
    {
        var currentNode:Object = current;
        // If there are no items, there's no current node, so return false.
        if (currentNode == null)
            return false;
        
        var childCursor:IViewCursor;
        
        //if not at top level
        if (parentNodes && parentNodes.length > 0)
        {
            if (currentChildBookmark == CursorBookmark.FIRST)
            {
                //at the first node in this branch so move to parent
                currentNode = parentNodes.pop();
                currentChildBookmark = parentBookmarkStack.pop();
                var grandParent:Object = parentNodes[parentNodes.length-1];
                //we could probably assume that a non-null grandparent has descendants 
                //but the analogy only goes so far... 
                if (grandParent != null && 
                    hierarchicalData.canHaveChildren(grandParent) &&
                    hierarchicalData.hasChildren(grandParent))
                {
                    childNodes = collection.getChildren(grandParent);
                }
                else
                {
                    childNodes = null;  
                }
                _currentDepth--;
                currentIndex--;
                return true;
            }
            else 
            {
                // get previous child sibling
                try 
                {
                    childCursor = childNodes.createCursor();
                    
                    childCursor.seek(currentChildBookmark);
                    childCursor.movePrevious();
                    currentChildBookmark = childCursor.bookmark;
                    currentNode = childCursor.current;
                    
                    try
                    {
                        // this is needed because the cursor bookmark for
                        // the zero position and CursorBookmark.FIRST is not 
                        // same. this condition is encountered while doing
                        // a movePrevious()
                        childCursor.movePrevious();
                        if (childCursor.bookmark == CursorBookmark.FIRST)
                            currentChildBookmark = CursorBookmark.FIRST;
                    }
                    catch (e:ItemPendingError)
                    {
                    }
                }
                catch(e:ItemPendingError)
                {
                    //lets try to recover
                    return false;
                }
            }   
        }
        //handle top level siblings
        else 
        {
            more = modelCursor.movePrevious();
            if (more)
            {
                //move back one node and then loop through children
                currentNode = modelCursor.current;
            }
            //if past the begining of the tree return false
            else 
            {
                //currentIndex--;  //should be before first
                currentIndex = -1;
                currentNode = null;
                return false;
            }
        }
        while (true)
        {
            // If there are children, walk backwards on the children
            // and consider youself after your children.
            if (collection.openNodes[UIDUtil.getUID(currentNode)] &&
                hierarchicalData.canHaveChildren(currentNode) &&
                hierarchicalData.hasChildren(currentNode))
            {
                var previousChildNodes:ICollectionView = childNodes;
                childNodes = collection.getChildren(currentNode);
                if (childNodes.length > 0)
                {
                    parentBookmarkStack.push(currentChildBookmark);
                    parentNodes.push(currentNode);
                    // if the child collection has only one item then set the
                    // bookmark to first
                    if (childNodes.length == 1)
                        currentChildBookmark = CursorBookmark.FIRST;
                    else
                        currentChildBookmark = CursorBookmark.LAST;
                    
                    childCursor = childNodes.createCursor();
                    try
                    {
                        childCursor.seek(currentChildBookmark);
                        currentNode = childCursor.current;
                    }
                    catch (e:ItemPendingError)
                    {
                        try
                        {
                            childCursor.seek(CursorBookmark.FIRST);
                            while (!childCursor.afterLast)
                            {
                                currentNode = childCursor.current;
                                childCursor.moveNext();
                            }
                        }
                        catch(e1:ItemPendingError)
                        {
                        }
                        
                        throw new ChildItemPendingError(e.message);
                    }
                    _currentDepth++;
                }
                else
                {
                    childNodes = previousChildNodes;
                    break;
                }
            }   
            else
            {
                //No more open branches so we'll bail
                break;
            }
        }

        updateParentMap(currentNode);

        currentIndex--;
        return true;
    }

    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function seek(bookmark:CursorBookmark, offset:int=0,
                         prefetch:int = 0):void
    {
        var value:int;
        
        if (bookmark == CursorBookmark.FIRST)
        {
            value = 0;
        }
        else if (bookmark == CursorBookmark.CURRENT)
        {
            value = currentIndex;
        }
        else if (bookmark == CursorBookmark.LAST)
        {
            value = collection.length - 1;
        }
        else
        {
            value = int(bookmark.value);
        }
        
        value = Math.max(Math.min(value + offset, collection.length), 0);
        var dc:int = Math.abs(currentIndex - value);
        var de:int = Math.abs(collection.length - value);
        var movedown:Boolean = true;
        // if we're closer to the current than the beginning
        if (dc < value)
        {
            // if we're closer to the end than the current position
            if (de < dc)
            {
                moveToLast();

                if (de == 0)
                {       
                    // if de = 0; we need to be "off the end"
                    moveNext();
                    value = 0;
                }
                else
                {
                    value = de - 1;
                }
                movedown = false;
            }
            else
            {
                movedown = currentIndex < value;
                value = dc;
                // if current is off the end, reset
                if (currentIndex == collection.length)
                {
                    value--;
                    moveToLast();
                }
            }
        }
        else // we're closer to the beginning than the current
        {
            // if we're closer to the end than the beginning
            if (de < value)
            {
                moveToLast();
                if (de == 0)
                {       
                    // if de = 0; we need to be "off the end"
                    moveNext();
                    value = 0;
                }
                else
                {
                    value = de - 1;
                }
                movedown = false;
            }
            else
            {
                moveToFirst();
            }
        }

        if (movedown)
        {
            while (value && value > 0) 
            {
                moveNext();
                value--;
            }
        }
        else
        {
            while (value && value > 0)  
            {
                movePrevious();
                value--;
            }
        }    
    }
    
    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function insert(item:Object):void
    {
        var parent:Object = collection.getParentItem(current);
        collection.addChildAt(parent, item, currentIndex);
    }
    
    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function remove():Object
    {
        var obj:Object = current;
        var parent:Object = collection.getParentItem(current);
        collection.removeChild(parent, current);
        return obj;
    }
    
    /**
     *  @private
     *  Determines if a node is visible on the screen
     */
    private function isItemVisible(node:Object):Boolean
    { 
        var parentNode:Object = collection.getParentItem(node);
        while (parentNode != null)
        {
            if (collection.openNodes[UIDUtil.getUID(parentNode)] == null)
                return false;
            
            parentNode = collection.getParentItem(parentNode);
        }
        return true;
    }
    
    /**
     * @private
     * Update the parent map.
     */ 
    private function updateParentMap(currentNode:Object):void
    {
        if (currentNode != null)
        {
            var uid:String = UIDUtil.getUID(currentNode);
            collection.addParentMapping(uid, parentNodes[parentNodes.length - 1], false);
        }
    }

    /**
     *  @private
     *  Creates a stack of parent nodes by walking upwards
     */
    private function getParentStack(node:Object):Array
    {
        var nodeParents:Array = [];
        
        // Make a list of parents of the node.
        var obj:Object = collection.getParentItem(node);
        while (obj != null)
        {
            nodeParents.unshift(obj);
            obj = collection.getParentItem(obj);
        }
        return nodeParents;
    }

    /**
     *  @private
     *  When something happens to the tree, find out if it happened
     *  to children that occur before the current child in the tree walk.
     */
    private function isNodeBefore(node:Object, currentNode:Object):Boolean
    {
        if (currentNode == null)
            return false;

        var i:int;
        var tmpChildNodes:ICollectionView;
        var sameParent:Object;

        var nodeParents:Array = getParentStack(node);
        var curParents:Array = getParentStack(currentNode);
        
        var cursor:IViewCursor;
        var child:Object;

        // Starting from the root, compare parents
        // (assumes the root must be the same).
        while (nodeParents.length != 0 && curParents.length != 0)
        {
            var nodeParent:Object = nodeParents.shift();
            var curParent:Object = curParents.shift();
            
            // If not the same parentm then which ever one is first
            // in the child list is before the other.
            if (nodeParent != curParent)
            {
                // The last parent must be common.
                sameParent = collection.getParentItem(nodeParent);
                
                // Get the child list.
                if (sameParent != null && 
                    hierarchicalData.canHaveChildren(sameParent) &&
                    hierarchicalData.hasChildren(sameParent))
                {
                    tmpChildNodes = collection.getChildren(sameParent);
                }
                else
                {
                    tmpChildNodes = model; 
                }
                // Walk it until you hit one or the other.
                {
                    cursor = tmpChildNodes.createCursor();
                    try
                    {
                        cursor.seek(CursorBookmark.FIRST, i);
                        child = cursor.current;
                    }
                    catch (e:ItemPendingError)
                    {
                        // item pending - this may never happen
                        return false;
                    }
                    
                    if (child == curParent)
                        return false;

                    if (child == nodeParent)
                        return true;
                }
            }
        }

        if (nodeParents.length)
            node = nodeParents.shift();
        if (curParents.length)
            currentNode = curParents.shift();

        // If we get here, they have the same parentage or one or both
        // had a root parent. Who's first?
        tmpChildNodes = model; 
        cursor = tmpChildNodes.createCursor();
        while (!cursor.afterLast)
        {
            child = cursor.current;

            if (child == currentNode)
                return false;

            if (child == node)
                return true;
            
            try
            {
                cursor.moveNext();
            }
            catch (e:ItemPendingError)
            {
                // item pending
                return false;
            }
        }
        return false;
    }
    
    /**
     *  @private
     */
    private function moveToFirst():void
    {
        childNodes = null;
        
        //first move to the begining of the top level collection
        // let it throw an IPE, the classes using this cursor will handle it
        modelCursor.seek(CursorBookmark.FIRST, 0);
        
        more = model.length > 1;
        currentChildBookmark = CursorBookmark.FIRST;
        parentNodes = [];
        parentBookmarkStack = [];
        currentIndex = 0;
        _currentDepth = 1;
    }
    
    /**
     *  @private
     */
    public function moveToLast():void
    {
        childNodes = null;
        parentBookmarkStack = [];
        _currentDepth = 1;
        parentNodes = [];

        //first move to the end of the top level collection
        // let it throw an IPE, the classes using this cursor will handle it
        modelCursor.seek(CursorBookmark.LAST, 0);
        
        //if its a branch and open then get children for the last item
        var currentNode:Object = modelCursor.current;
        //if current node is open get its children
        while (collection.openNodes[UIDUtil.getUID(currentNode)] &&
               hierarchicalData.canHaveChildren(currentNode) &&
               hierarchicalData.hasChildren(currentNode))
        {
            var previousChildNodes:ICollectionView = childNodes;
            childNodes = collection.getChildren(currentNode);
            if (childNodes != null && childNodes.length > 0)
            {
                var childCursor:IViewCursor = childNodes.createCursor();
                try
                {
                    childCursor.seek(CursorBookmark.LAST);
                }
                catch (e:ItemPendingError)
                {
                    // just break because if the last child item is pending
                    // return its parent
                    break;
                }
                parentNodes.push(currentNode);
                parentBookmarkStack.push(currentChildBookmark);                
                currentNode = childCursor.current;
                currentChildBookmark = CursorBookmark.LAST;
                try
                {
                    // this is needed because the cursor bookmark for
                    // the zero position and CursorBookmark.FIRST is not 
                    // same. this condition is encountered while doing
                    // a movePrevious()
                    childCursor.movePrevious();
                    if (childCursor.bookmark == CursorBookmark.FIRST)
                        currentChildBookmark = CursorBookmark.FIRST;
                }
                catch (e:ItemPendingError)
                {
                }
                _currentDepth++;
            }
            else 
            {
                childNodes = previousChildNodes;
                break;
            }
        }
        currentIndex = collection.length - 1;
    }
    
    //--------------------------------------------------------------------------
    //
    //  Event handlers
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    public function collectionChangeHandler(event:CollectionEvent):void
    {
        var i:int;
        var n:int;
        var changingNode:Object;
        var parentOfChangingNode:Object;
        var parentOfCurrentNode:Object;
        var parentStack:Array;
        var isBefore:Boolean = false;
        var parentOfChangingNodeIndex:int;
        var isChangingNodeParentAncestorOfSelectedNode:Boolean;
        var bookmarkInChangingCollection:CursorBookmark;
		var changingNodeCollectionBookmarkIndex:int;
        var changingNodeAndSiblings:ICollectionView;
        var changingCollectionCursor:IViewCursor;

        if (event.kind == CollectionEventKind.ADD)
        {
            n = event.items.length;
            if (event.location <= currentIndex)
            {
                currentIndex += n;
                isBefore = true;
            }

            parentStack = getParentStack(current);
            parentOfCurrentNode = parentStack[parentStack.length - 1];

            for (i = 0; i < n; i++)
            {
                changingNode = event.items[i];
                if (isBefore)
                {
                    // if the added node is before the current
                    // and they share parents then we have to
                    // adjust the currentChildIndex or
                    // the stack of child indexes.
                    parentOfChangingNode = collection.getParentItem(changingNode);
                    changingNodeAndSiblings = collection.getChildren(parentOfChangingNode); 

                    if (parentOfChangingNode == parentOfCurrentNode)
                    {
                        if (changingNodeAndSiblings != null)
                        {
                            changingCollectionCursor = changingNodeAndSiblings.createCursor();
                            try
                            {
                                changingCollectionCursor.seek(currentChildBookmark);
                                changingCollectionCursor.moveNext();
                                currentChildBookmark = changingCollectionCursor.bookmark;
                            }
                            catch (e:ItemPendingError)
                            {
                            }
                        }
                    }
                    else {
                        parentOfChangingNodeIndex = parentStack.indexOf(parentOfChangingNode);
                        isChangingNodeParentAncestorOfSelectedNode = parentOfChangingNodeIndex != -1;
                        if (isChangingNodeParentAncestorOfSelectedNode)
                        {
                            if (changingNodeAndSiblings != null)
                            {
                                changingNodeCollectionBookmarkIndex = parentOfChangingNodeIndex + 1;
                                changingCollectionCursor = changingNodeAndSiblings.createCursor();
                                bookmarkInChangingCollection = parentBookmarkStack[changingNodeCollectionBookmarkIndex];
                                try
                                {
                                    changingCollectionCursor.seek(bookmarkInChangingCollection);
                                    changingCollectionCursor.moveNext();
                                }
                                catch (e:ItemPendingError)
                                {
                                }
                                parentBookmarkStack[changingNodeCollectionBookmarkIndex] = changingCollectionCursor.bookmark;
                            }
                        }
                    }
                }
            }
            
        }
        else if (event.kind == CollectionEventKind.REMOVE)
        {
            n = event.items.length;
            if (event.location <= currentIndex)
            {
                var lastIndexAffectedByDeletion:int = event.location + n;
                var isCurrentIndexAmongRemovedNodes:Boolean = lastIndexAffectedByDeletion >= currentIndex;
                var currentItemNotFoundAmongItsSiblings:Boolean = isCurrentIndexAmongRemovedNodes ? false : (!afterLast && !beforeFirst && current == null);

                if (isCurrentIndexAmongRemovedNodes || currentItemNotFoundAmongItsSiblings)
                {
                    // the list classes expect that we
                    // leave the cursor on whatever falls
                    // into that slot
                    var indexToReturnTo:int = isCurrentIndexAmongRemovedNodes ? event.location : currentIndex - n;
                    moveToFirst();
                    seek(CursorBookmark.FIRST, indexToReturnTo);

                    return;
                }

                currentIndex -= n;
                isBefore = true;
            }

            parentStack = getParentStack(current);
            parentOfCurrentNode = parentStack[parentStack.length - 1];

            for (i = 0; i < n; i++)
            {
                changingNode = event.items[i];
                if (isBefore)
                {
                    // if the removed node is before the current
                    // and they share parents then we have to
                    // adjust the currentChildIndex or
                    // the stack of child indexes.
                    parentOfChangingNode = collection.getParentItem(changingNode);
                    changingNodeAndSiblings = collection.getChildren(parentOfChangingNode);

                    if (parentOfChangingNode == parentOfCurrentNode)
                    {
                        if(currentChildBookmark == CursorBookmark.LAST)
                            break;

                        if (changingNodeAndSiblings != null)
                        {
                            changingCollectionCursor = changingNodeAndSiblings.createCursor();
                            try
                            {
                                changingCollectionCursor.seek(currentChildBookmark);
                                changingCollectionCursor.movePrevious();
                                currentChildBookmark = changingCollectionCursor.bookmark;
                            }
                            catch (e:ItemPendingError)
                            {
                            }
                        }
                    }
                    else {
                        parentOfChangingNodeIndex = parentStack.indexOf(parentOfChangingNode);
                        isChangingNodeParentAncestorOfSelectedNode = parentOfChangingNodeIndex != -1;
                        if (isChangingNodeParentAncestorOfSelectedNode)
                        {
                            if (changingNodeAndSiblings != null)
                            {
                                changingNodeCollectionBookmarkIndex = parentOfChangingNodeIndex + 1;
                                changingCollectionCursor = changingNodeAndSiblings.createCursor();
                                bookmarkInChangingCollection = parentBookmarkStack[changingNodeCollectionBookmarkIndex];

                                if(bookmarkInChangingCollection == CursorBookmark.LAST)
                                    break;

                                try
                                {
                                    changingCollectionCursor.seek(bookmarkInChangingCollection);
                                    changingCollectionCursor.movePrevious();
                                }
                                catch (e:ItemPendingError)
                                {
                                }
                                parentBookmarkStack[changingNodeCollectionBookmarkIndex] = changingCollectionCursor.bookmark;
                            }
                        }
                    }
                }
            }
        }
        else if (event.kind == CollectionEventKind.RESET)
        {
            // update the source collection and the cursor
            model = collection.treeData;
            modelCursor = model.createCursor();
            // dispatch CURSOR_UPDATE event
            collection.dispatchEvent(new FlexEvent(FlexEvent.CURSOR_UPDATE));
        }
        else if (event.kind == CollectionEventKind.REFRESH)
        {
            // find the correct index of the item
            if (!(beforeFirst || afterLast))
            {
                findFirst(current);
            }
        }
    }
}
}
