Show:
                            /**
                             * The TreeNode Utility
                             *
                             * @module aui-tree
                             * @submodule aui-tree-node
                             */
                            
                            var Lang = A.Lang,
                                isString = Lang.isString,
                                isBoolean = Lang.isBoolean,
                                isFunction = Lang.isFunction,
                            
                                isTreeNode = function(v) {
                                    return (v instanceof A.TreeNode);
                                },
                            
                                isTreeView = function(v) {
                                    return (v instanceof A.TreeView);
                                },
                            
                                getCN = A.getClassName,
                            
                                CSS_ICON = getCN('glyphicon'),
                                CSS_TREE_COLLAPSED = getCN('tree', 'collapsed'),
                                CSS_TREE_CONTAINER = getCN('tree', 'container'),
                                CSS_TREE_EXPANDED = getCN('tree', 'expanded'),
                                CSS_TREE_HITAREA = getCN('tree', 'hitarea'),
                                CSS_TREE_ICON = getCN('tree', 'icon'),
                                CSS_TREE_LABEL = getCN('tree', 'label'),
                                CSS_TREE_NODE = getCN('tree', 'node'),
                                CSS_TREE_NODE_CONTENT = getCN('tree', 'node', 'content'),
                                CSS_TREE_NODE_CONTENT_INVALID = getCN('tree', 'node', 'content', 'invalid'),
                                CSS_TREE_NODE_HIDDEN_HITAREA = getCN('tree', 'node', 'hidden', 'hitarea'),
                                CSS_TREE_NODE_LEAF = getCN('tree', 'node', 'leaf'),
                                CSS_TREE_NODE_OVER = getCN('tree', 'node', 'over'),
                                CSS_TREE_NODE_SELECTED = getCN('tree', 'node', 'selected'),
                                CSS_ICON_FOLDER_CLOSE = getCN('glyphicon', 'folder', 'close'),
                                CSS_ICON_FOLDER_OPEN = getCN('glyphicon', 'folder', 'open'),
                                CSS_ICON_ICON_PLUS = getCN('glyphicon', 'plus'),
                                CSS_ICON_ICON_MINUS = getCN('glyphicon', 'minus'),
                                CSS_ICON_ICON_FILE = getCN('glyphicon', 'file'),
                                CSS_ICON_ICON_REFRESH = getCN('glyphicon', 'refresh'),
                                CSS_ICON_OK_SIGN = getCN('glyphicon', 'ok', 'sign'),
                                CSS_ICON_CHECK = getCN('glyphicon', 'check'),
                            
                                HIT_AREA_TPL = '<span tabindex="0" class="' + CSS_TREE_HITAREA + '"></span>',
                                ICON_TPL = '<span class="' + CSS_TREE_ICON + '"></span>',
                                LABEL_TPL = '<span class="' + CSS_TREE_LABEL + '"></span>',
                                NODE_CONTAINER_TPL = '<ul></ul>',
                            
                                NODE_BOUNDING_TEMPLATE = '<li class="' + CSS_TREE_NODE + '"></li>',
                                NODE_CONTENT_TEMPLATE = '<div class="' + CSS_TREE_NODE_CONTENT + '"></div>';
                            
                            /**
                             * A base class for TreeNode, providing:
                             *
                             * - Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)
                             * - The node for the TreeView component
                             *
                             * Check the [live demo](http://alloyui.com/examples/tree/).
                             *
                             * @class A.TreeNode
                             * @extends Base
                             * @uses A.TreeData
                             * @param {Object} config Object literal specifying widget configuration
                             *     properties.
                             * @constructor
                             */
                            var TreeNode = A.Component.create({
                                /**
                                 * Static property provides a string to identify the class.
                                 *
                                 * @property NAME
                                 * @type String
                                 * @static
                                 */
                                NAME: 'tree-node',
                            
                                /**
                                 * Static property used to define the default attribute
                                 * configuration for the TreeNode.
                                 *
                                 * @property ATTRS
                                 * @type Object
                                 * @static
                                 */
                                ATTRS: {
                            
                                    /**
                                     * The widget's outermost node, used for sizing and positioning.
                                     *
                                     * @attribute boundingBox
                                     */
                                    boundingBox: {
                                        valueFn: function() {
                                            return A.Node.create(NODE_BOUNDING_TEMPLATE);
                                        }
                                    },
                            
                                    /**
                                     * The direct descendant of a widget's
                                     * bounding box and houses its content.
                                     *
                                     * @attribute contentBox
                                     */
                                    contentBox: {
                                        valueFn: function() {
                                            return A.Node.create(NODE_CONTENT_TEMPLATE);
                                        }
                                    },
                            
                                    /**
                                     * CSS classes used on TreeNode.
                                     *
                                     * @attribute cssClasses
                                     * @type Object
                                     */
                                    cssClasses: {
                                        value: {
                                            file: {
                                                iconCheck: [CSS_ICON, CSS_ICON_CHECK].join(' '),
                                                iconCollapsed: [CSS_ICON, CSS_ICON_FOLDER_CLOSE].join(' '),
                                                iconExpanded: [CSS_ICON, CSS_ICON_FOLDER_OPEN].join(' '),
                                                iconHitAreaCollapsed: [CSS_TREE_HITAREA, CSS_ICON_ICON_PLUS].join(' '),
                                                iconHitAreaExpanded: [CSS_TREE_HITAREA, CSS_ICON_ICON_MINUS].join(' '),
                                                iconLeaf: [CSS_ICON, CSS_ICON_ICON_FILE].join(' '),
                                                iconLoading: [CSS_ICON, CSS_ICON_ICON_REFRESH].join(' '),
                                                iconUncheck: [CSS_ICON, CSS_ICON_CHECK].join(' ')
                                            },
                                            normal: {
                                                iconCheck: [CSS_ICON, CSS_ICON_CHECK].join(' '),
                                                iconHitAreaCollapsed: [CSS_TREE_HITAREA, CSS_ICON_ICON_PLUS].join(' '),
                                                iconHitAreaExpanded: [CSS_TREE_HITAREA, CSS_ICON_ICON_MINUS].join(' '),
                                                iconLoading: [CSS_ICON, CSS_ICON_ICON_REFRESH].join(' '),
                                                iconUncheck: [CSS_ICON, CSS_ICON_CHECK].join(' ')
                                            }
                                        }
                                    },
                            
                                    /**
                                     * If true the TreeNode is draggable.
                                     *
                                     * @attribute draggable
                                     * @default true
                                     * @type Boolean
                                     */
                                    draggable: {
                                        value: true,
                                        validator: isBoolean
                                    },
                            
                                    /**
                                     * TreeView which contains the current TreeNode.
                                     *
                                     * @attribute ownerTree
                                     * @default null
                                     * @type TreeView
                                     */
                                    ownerTree: {
                                        value: null
                                    },
                            
                                    /**
                                     * Label of the TreeNode.
                                     *
                                     * @attribute label
                                     * @default ''
                                     * @type String
                                     */
                                    label: {
                                        value: '',
                                        validator: isString
                                    },
                            
                                    /**
                                     * Whether the TreeNode is expanded by default.
                                     *
                                     * @attribute expanded
                                     * @default false
                                     * @type Boolean
                                     */
                                    expanded: {
                                        value: false,
                                        validator: isBoolean
                                    },
                            
                                    /**
                                     * Id of the TreeNode.
                                     *
                                     * @attribute id
                                     * @default null
                                     * @type String
                                     */
                                    id: {
                                        validator: isString,
                                        valueFn: function() {
                                            return A.guid();
                                        }
                                    },
                            
                                    /**
                                     * Whether the TreeNode could have children or not (i.e. if any
                                     * children is present the TreeNode is a leaf).
                                     *
                                     * @attribute leaf
                                     * @default true
                                     * @type Boolean
                                     */
                                    leaf: {
                                        value: true,
                                        setter: function(v) {
                                            // if has children it's not a leaf
                                            if (v && this.get('children').length) {
                                                return false;
                                            }
                            
                                            return v;
                                        },
                                        validator: isBoolean
                                    },
                            
                                    /**
                                     * Next sibling of the current TreeNode.
                                     *
                                     * @attribute nextSibling
                                     * @default null
                                     * @type TreeNode
                                     */
                                    nextSibling: {
                                        getter: '_getSibling',
                                        value: null,
                                        validator: isTreeNode
                                    },
                            
                                    /**
                                     * Previous sibling of the current TreeNode.
                                     *
                                     * @attribute prevSibling
                                     * @default null
                                     * @type TreeNode
                                     */
                                    prevSibling: {
                                        getter: '_getSibling',
                                        value: null,
                                        validator: isTreeNode
                                    },
                            
                                    /**
                                     * Parent node of the current TreeNode.
                                     *
                                     * @attribute parentNode
                                     * @default null
                                     * @type TreeNode
                                     */
                                    parentNode: {
                                        value: null,
                                        validator: function(val) {
                                            return isTreeNode(val) || isTreeView(val);
                                        }
                                    },
                            
                                    /**
                                     * Label element to house the `label` attribute.
                                     *
                                     * @attribute labelEl
                                     * @default Generated DOM element.
                                     * @type Node | String
                                     */
                                    labelEl: {
                                        setter: A.one,
                                        valueFn: function() {
                                            var label = this.get('label');
                            
                                            return A.Node.create(LABEL_TPL).html(label).unselectable();
                                        }
                                    },
                            
                                    /**
                                     * Hitarea element.
                                     *
                                     * @attribute hitAreaEl
                                     * @default Generated DOM element.
                                     * @type Node | String
                                     */
                                    hitAreaEl: {
                                        setter: A.one,
                                        valueFn: function() {
                                            return A.Node.create(HIT_AREA_TPL);
                                        }
                                    },
                            
                                    /**
                                     * Always show the hitarea icon.
                                     *
                                     * @attribute alwaysShowHitArea
                                     * @default true
                                     * @type Boolean
                                     */
                                    alwaysShowHitArea: {
                                        value: true,
                                        validator: isBoolean
                                    },
                            
                                    /**
                                     * Icon element.
                                     *
                                     * @attribute iconEl
                                     * @type Node | String
                                     */
                                    iconEl: {
                                        setter: A.one,
                                        valueFn: function() {
                                            return A.Node.create(ICON_TPL);
                                        }
                                    },
                            
                                    /**
                                     * Specify the tab order.
                                     *
                                     * @attribute tabIndex
                                     * @default null
                                     */
                                    tabIndex: {
                                        value: null
                                    },
                            
                                    /**
                                     * If true the TreeNode is rendered.
                                     *
                                     * @attribute rendered
                                     * @default false
                                     * @type Boolean
                                     */
                                    rendered: {
                                        validator: isBoolean,
                                        value: false
                                    }
                                },
                            
                                AUGMENTS: [A.TreeData, A.TreeViewIO, A.TreeViewPaginator],
                            
                                EXTENDS: A.Base,
                            
                                prototype: {
                            
                                    /**
                                     * Replaced BOUNDING_TEMPLATE with NODE_BOUNDING_TEMPLATE.
                                     *
                                     * @property BOUNDING_TEMPLATE
                                     * @type String
                                     * @protected
                                     */
                                    BOUNDING_TEMPLATE: NODE_BOUNDING_TEMPLATE,
                                    /**
                                     * Replaced CONTENT_TEMPLATE with NODE_CONTENT_TEMPLATE.
                                     *
                                     * @property CONTENT_TEMPLATE
                                     * @type String
                                     * @protected
                                     */
                                    CONTENT_TEMPLATE: NODE_CONTENT_TEMPLATE,
                            
                                    /**
                                     * Construction logic executed during TreeNode instantiation. Lifecycle.
                                     *
                                     * @method initializer
                                     * @protected
                                     */
                                    initializer: function() {
                                        var instance = this;
                            
                                        var boundingBox = instance.get('boundingBox');
                            
                                        boundingBox.setData('tree-node', instance);
                            
                                        // Sync the Widget TreeNode id with the BOUNDING_BOX id
                                        instance._syncTreeNodeBBId();
                            
                                        instance._uiSetDraggable(instance.get('draggable'));
                                        instance._uiSetExpanded(instance.get('expanded'));
                                        instance._uiSetLeaf(instance.get('leaf'));
                                    },
                            
                                    /**
                                     * Bind the events on the TreeNode UI. Lifecycle.
                                     *
                                     * @method bindUI
                                     * @protected
                                     */
                                    bindUI: function() {
                                        var instance = this;
                            
                                        instance.after({
                                            childrenChange: instance._afterSetChildren,
                                            draggableChange: instance._afterDraggableChange,
                                            expandedChange: instance._afterExpandedChange,
                                            idChange: instance._afterSetId,
                                            leafChange: instance._afterLeafChange,
                                            loadingChange: instance._afterLoadingChange
                                        });
                                    },
                            
                                    /**
                                     * Render TreeNode.
                                     *
                                     * @method render
                                     * @param container
                                     */
                                    render: function(container) {
                                        var instance = this;
                            
                                        if (!instance.get('rendered')) {
                                            instance.renderUI();
                                            instance.bindUI();
                                            instance.syncUI();
                            
                                            instance.set('rendered', true);
                                        }
                            
                                        if (container) {
                                            var boundingBox = instance.get('boundingBox');
                                            var paginator = instance.get('paginator');
                            
                                            boundingBox.appendTo(container);
                            
                                            if (paginator) {
                                                boundingBox.insertBefore(paginator.element);
                                            }
                                        }
                                    },
                            
                                    /**
                                     * Create the DOM structure for the TreeNode. Lifecycle.
                                     *
                                     * @method renderUI
                                     * @protected
                                     */
                                    renderUI: function() {
                                        var instance = this;
                            
                                        instance._renderBoundingBox();
                                        instance._renderContentBox();
                                    },
                            
                                    /**
                                     * Sync the TreeNode UI. Lifecycle.
                                     *
                                     * @method syncUI
                                     * @protected
                                     */
                                    syncUI: function() {
                                        var instance = this;
                            
                                        instance._syncIconUI();
                                    },
                            
                                    /**
                                     * Fire after draggable change.
                                     *
                                     * @method _afterDraggableChange
                                     * @param {EventFacade} event
                                     * @protected
                                     */
                                    _afterDraggableChange: function(event) {
                                        var instance = this;
                            
                                        instance._uiSetDraggable(event.newVal);
                                        instance._syncIconUI();
                                    },
                            
                                    /**
                                     * Fire after expanded change.
                                     *
                                     * @method _afterExpandedChange
                                     * @param {EventFacade} event
                                     * @protected
                                     */
                                    _afterExpandedChange: function(event) {
                                        var instance = this;
                            
                                        instance._uiSetExpanded(event.newVal);
                                        instance._syncIconUI();
                                    },
                            
                                    /**
                                     * Fire after leaf change.
                                     *
                                     * @method _afterLeafChange
                                     * @param {EventFacade} event
                                     * @protected
                                     */
                                    _afterLeafChange: function(event) {
                                        var instance = this;
                            
                                        instance._uiSetLeaf(event.newVal);
                                        instance._syncIconUI();
                                    },
                            
                                    /**
                                     * Fire after loading change.
                                     *
                                     * @method _afterLoadingChange
                                     * @param {EventFacade} event
                                     * @protected
                                     */
                                    _afterLoadingChange: function() {
                                        var instance = this;
                            
                                        instance._syncIconUI();
                                    },
                            
                                    /**
                                     * Fire after set children.
                                     *
                                     * @method _afterSetChildren
                                     * @param {EventFacade} event
                                     * @protected
                                     */
                                    _afterSetChildren: function() {
                                        var instance = this;
                            
                                        instance._syncIconUI();
                                    },
                            
                                    /**
                                     * Render the `contentBox` node.
                                     *
                                     * @method _renderContentBox
                                     * @protected
                                     * @return {Node}
                                     */
                                    _renderContentBox: function() {
                                        var instance = this;
                            
                                        var contentBox = instance.get('contentBox');
                            
                                        if (!instance.isLeaf()) {
                                            var expanded = instance.get('expanded');
                            
                                            // add folder css classes state
                                            contentBox.addClass(
                                                expanded ? CSS_TREE_EXPANDED : CSS_TREE_COLLAPSED
                                            );
                            
                                            if (expanded) {
                                                instance.expand();
                                            }
                                        }
                            
                                        return contentBox;
                                    },
                            
                                    /**
                                     * Render the `boundingBox` node.
                                     *
                                     * @method _renderBoundingBox
                                     * @protected
                                     * @return {Node}
                                     */
                                    _renderBoundingBox: function() {
                                        var instance = this;
                            
                                        var boundingBox = instance.get('boundingBox');
                                        var contentBox = instance.get('contentBox');
                            
                                        contentBox.append(instance.get('iconEl'));
                                        contentBox.append(instance.get('labelEl'));
                                        boundingBox.append(contentBox);
                            
                                        var nodeContainer = instance.get('container');
                            
                                        if (nodeContainer) {
                                            if (!instance.get('expanded')) {
                                                nodeContainer.hide();
                                            }
                            
                                            boundingBox.append(nodeContainer);
                                        }
                            
                                        return boundingBox;
                                    },
                            
                                    /**
                                     * Render the node container.
                                     *
                                     * @method _createNodeContainer
                                     * @protected
                                     * @return {Node}
                                     */
                                    _createNodeContainer: function() {
                                        var instance = this;
                            
                                        // creating <ul class="tree-container">
                                        var nodeContainer = instance.get('container') || A.Node.create(NODE_CONTAINER_TPL);
                            
                                        nodeContainer.addClass(CSS_TREE_CONTAINER);
                            
                                        // when it's not a leaf it has a <ul> container
                                        instance.set('container', nodeContainer);
                            
                                        return nodeContainer;
                                    },
                            
                                    /**
                                     * Sync the hitarea UI.
                                     *
                                     * @method _syncHitArea
                                     * @protected
                                     */
                                    _syncHitArea: function() {
                                        var instance = this;
                            
                                        if (instance.get('alwaysShowHitArea') || instance.getChildrenLength()) {
                                            instance.showHitArea();
                                        }
                                        else {
                                            instance.hideHitArea();
                                        }
                                    },
                            
                                    /**
                                     * Sync the hitarea UI.
                                     *
                                     * @method _syncIconUI
                                     * @param {Array} children
                                     * @protected
                                     */
                                    _syncIconUI: function() {
                                        var instance = this,
                                            ownerTree = instance.get('ownerTree');
                            
                                        if (ownerTree) {
                                            var type = ownerTree.get('type'),
                                                cssClasses = instance.get('cssClasses.' + type);
                            
                                            if (!cssClasses) {
                                                return;
                                            }
                            
                                            var expanded = instance.get('expanded'),
                                                iconEl = instance.get('iconEl'),
                                                hitAreaEl = instance.get('hitAreaEl'),
                                                icon = instance.isLeaf() ?
                                                cssClasses.iconLeaf :
                                                (expanded ? cssClasses.iconExpanded : cssClasses.iconCollapsed),
                                                iconHitArea = expanded ?
                                                cssClasses.iconHitAreaExpanded :
                                                cssClasses.iconHitAreaCollapsed;
                            
                                            if (instance.get('loading')) {
                                                icon = cssClasses.iconLoading;
                                            }
                            
                                            iconEl.setAttribute('className', icon || '');
                                            hitAreaEl.setAttribute('className', iconHitArea || '');
                                        }
                            
                                        instance._syncHitArea();
                                    },
                            
                                    /**
                                     * Append child on TreeNode.
                                     *
                                     * @method appendChild
                                     */
                                    appendChild: function() {
                                        var instance = this;
                            
                                        if (!instance.isLeaf()) {
                                            A.TreeNode.superclass.appendChild.apply(instance, arguments);
                                        }
                                    },
                            
                                    /**
                                     * Collapse the current TreeNode.
                                     *
                                     * @method collapse
                                     */
                                    collapse: function() {
                                        var instance = this;
                            
                                        instance.set('expanded', false);
                                    },
                            
                                    /**
                                     * Collapse all TreeNodes.
                                     *
                                     * @method collapseAll
                                     */
                                    collapseAll: function() {
                                        var instance = this;
                            
                                        A.TreeNode.superclass.collapseAll.apply(instance, arguments);
                            
                                        // instance is also a node, so collapse itself
                                        instance.collapse();
                                    },
                            
                                    /**
                                     * Check if the current TreeNode contains the passed `node`.
                                     *
                                     * @method contains
                                     * @param {TreeNode} node
                                     * @return {Boolean}
                                     */
                                    contains: function(node) {
                                        return node.isAncestor(this);
                                    },
                            
                                    /**
                                     * Expand the current TreeNode.
                                     *
                                     * @method expand
                                     */
                                    expand: function() {
                                        var instance = this;
                            
                                        instance.set('expanded', true);
                                    },
                            
                                    /**
                                     * Expand all TreeNodes.
                                     *
                                     * @method expandAll
                                     */
                                    expandAll: function() {
                                        var instance = this;
                            
                                        A.TreeNode.superclass.expandAll.apply(instance, arguments);
                            
                                        // instance is also a node, so expand itself
                                        instance.expand();
                                    },
                            
                                    /**
                                     * Get the depth of the current TreeNode.
                                     *
                                     * @method getDepth
                                     * @return {Number}
                                     */
                                    getDepth: function() {
                                        var instance = this;
                            
                                        var depth = 0;
                            
                                        var parentNode = instance.get('parentNode');
                            
                                        while (parentNode) {
                                            ++depth;
                                            parentNode = parentNode.get('parentNode');
                                        }
                            
                                        return depth;
                                    },
                            
                                    /**
                                     * Check if it has child nodes.
                                     *
                                     * @method hasChildNodes
                                     */
                                    hasChildNodes: function() {
                                        var instance = this;
                            
                                        return (!instance.isLeaf() &&
                                            A.TreeNode.superclass.hasChildNodes.apply(this, arguments));
                                    },
                            
                                    /**
                                     * Whether the current TreeNode is selected or not.
                                     *
                                     * @method isSelected
                                     * @return {Boolean}
                                     */
                                    isSelected: function() {
                                        return this.get('contentBox').hasClass(CSS_TREE_NODE_SELECTED);
                                    },
                            
                                    /**
                                     * Whether the current TreeNode is a leaf or not.
                                     *
                                     * @method isLeaf
                                     * @return {Boolean}
                                     */
                                    isLeaf: function() {
                                        var instance = this;
                            
                                        return instance.get('leaf');
                                    },
                            
                                    /**
                                     * Whether the current TreeNode is ancestor of the passed `node` or not.
                                     *
                                     * @method isLeaf
                                     * @return {Boolean}
                                     */
                                    isAncestor: function(node) {
                                        var instance = this;
                            
                                        var parentNode = instance.get('parentNode');
                            
                                        while (parentNode) {
                                            if (parentNode === node) {
                                                return true;
                                            }
                                            parentNode = parentNode.get('parentNode');
                                        }
                            
                                        return false;
                                    },
                            
                                    /**
                                     * Toggle the current TreeNode, `collapsed` or `expanded`.
                                     *
                                     * @method toggle
                                     */
                                    toggle: function() {
                                        var instance = this;
                            
                                        if (instance.get('expanded')) {
                                            instance.collapse();
                                        }
                                        else {
                                            instance.expand();
                                        }
                                    },
                            
                                    /*
                                     * Select the current TreeNode.
                                     *
                                     * @method select
                                     */
                                    select: function() {
                                        var instance = this;
                            
                                        var ownerTree = instance.get('ownerTree');
                            
                                        if (ownerTree) {
                                            ownerTree.set('lastSelected', instance);
                                        }
                            
                                        instance.get('contentBox').addClass(CSS_TREE_NODE_SELECTED);
                            
                                        instance.fire('select');
                                    },
                            
                                    /*
                                     * Unselect the current TreeNode.
                                     *
                                     * @method unselect
                                     */
                                    unselect: function() {
                                        var instance = this;
                            
                                        instance.get('contentBox').removeClass(CSS_TREE_NODE_SELECTED);
                            
                                        instance.fire('unselect');
                                    },
                            
                                    /*
                                     * Fire when `mouseover` the current TreeNode.
                                     *
                                     * @method over
                                     */
                                    over: function() {
                                        this.get('contentBox').addClass(CSS_TREE_NODE_OVER);
                                    },
                            
                                    /*
                                     * Fire when `mouseout` the current TreeNode.
                                     *
                                     * @method over
                                     */
                                    out: function() {
                                        this.get('contentBox').removeClass(CSS_TREE_NODE_OVER);
                                    },
                            
                                    /*
                                     * Show hitarea icon.
                                     *
                                     * @method showHitArea
                                     */
                                    showHitArea: function() {
                                        var instance = this;
                            
                                        var hitAreaEl = instance.get('hitAreaEl');
                            
                                        hitAreaEl.removeClass(CSS_TREE_NODE_HIDDEN_HITAREA);
                                    },
                            
                                    /*
                                     * Hide hitarea icon.
                                     *
                                     * @method hideHitArea
                                     */
                                    hideHitArea: function() {
                                        var instance = this;
                            
                                        var hitAreaEl = instance.get('hitAreaEl');
                            
                                        hitAreaEl.addClass(CSS_TREE_NODE_HIDDEN_HITAREA);
                                    },
                            
                                    /**
                                     * Set the `boundingBox` id.
                                     *
                                     * @method _syncTreeNodeBBId
                                     * @param {String} id
                                     * @protected
                                     */
                                    _syncTreeNodeBBId: function() {
                                        var instance = this;
                            
                                        instance.get('boundingBox').attr(
                                            'id',
                                            instance.get('id')
                                        );
                                    },
                            
                                    /**
                                     * Get get sibling.
                                     *
                                     * @method _getSibling
                                     * @param value, attrName
                                     * @protected
                                     */
                                    _getSibling: function(value, attrName) {
                                        var instance = this;
                            
                                        var propName = '_' + attrName;
                                        var sibling = instance[propName];
                            
                                        if (sibling !== null && !isTreeNode(sibling)) {
                                            sibling = null;
                                            instance[propName] = sibling;
                                        }
                            
                                        return sibling;
                                    },
                            
                                    /**
                                     * Set `draggable` attribute on the UI.
                                     *
                                     * @method _uiSetDraggable
                                     * @param val
                                     * @protected
                                     */
                                    _uiSetDraggable: function(val) {
                                        var instance = this;
                                        var contentBox = instance.get('contentBox');
                            
                                        contentBox.toggleClass(CSS_TREE_NODE_CONTENT_INVALID, !val);
                                    },
                            
                                    /**
                                     * Set `expanded` attribute on the UI.
                                     *
                                     * @method _uiSetExpanded
                                     * @param val
                                     * @protected
                                     */
                                    _uiSetExpanded: function(val) {
                                        var instance = this;
                            
                                        if (!instance.isLeaf()) {
                                            var container = instance.get('container');
                                            var contentBox = instance.get('contentBox');
                                            var ownerTree = instance.get('ownerTree');
                                            var treeHitArea = contentBox.one('.' + CSS_TREE_HITAREA);
                            
                                            if (val) {
                                                contentBox.replaceClass(CSS_TREE_COLLAPSED, CSS_TREE_EXPANDED);
                            
                                                if (!ownerTree && treeHitArea) {
                                                    treeHitArea.replaceClass(CSS_ICON_ICON_PLUS, CSS_ICON_ICON_MINUS);
                                                }
                            
                                                if (container) {
                                                    container.show();
                                                }
                                            }
                                            else {
                                                contentBox.replaceClass(CSS_TREE_EXPANDED, CSS_TREE_COLLAPSED);
                            
                                                if (!ownerTree && treeHitArea) {
                                                    treeHitArea.replaceClass(CSS_ICON_ICON_MINUS, CSS_ICON_ICON_PLUS);
                                                }
                            
                                                if (container) {
                                                    container.hide();
                                                }
                                            }
                                        }
                                    },
                            
                                    /**
                                     * Set `leaf` attribute on the UI.
                                     *
                                     * @method _uiSetLeaf
                                     * @param val
                                     * @protected
                                     */
                                    _uiSetLeaf: function(val) {
                                        var instance = this;
                            
                                        var contentBox = instance.get('contentBox');
                            
                                        if (val) {
                                            instance.get('container').remove();
                                            instance.get('hitAreaEl').remove();
                                        }
                                        else {
                                            // append hitarea element
                                            contentBox.prepend(instance.get('hitAreaEl'));
                            
                                            // if has children append them to this model
                                            instance._createNodeContainer();
                            
                                            instance._uiSetExpanded(instance.get('expanded'));
                                        }
                            
                                        // add leaf css classes
                                        contentBox.toggleClass(CSS_TREE_NODE_LEAF, val);
                                    }
                                }
                            });
                            
                            A.TreeNode = TreeNode;
                            
                            /*
                             * TreeNodeIO
                             */
                            
                            /**
                             * A base class for TreeNodeIO, providing:
                             *
                             * - Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)
                             * - Ajax support to load the children of the current TreeNode
                             *
                             * @class A.TreeNodeIO
                             * @extends A.TreeNode
                             * @uses A.TreeViewPaginator, A.TreeViewIO
                             * @param {Object} config Object literal specifying widget configuration
                             *     properties.
                             * @constructor
                             */
                            var TreeNodeIO = A.Component.create({
                                /**
                                 * Static property provides a string to identify the class.
                                 *
                                 * @property NAME
                                 * @type String
                                 * @static
                                 */
                                NAME: 'tree-node-io',
                            
                                /**
                                 * Static property used to define the default attribute
                                 * configuration for the TreeNode.
                                 *
                                 * @property ATTRS
                                 * @type Object
                                 * @static
                                 */
                                ATTRS: {
                            
                                    /**
                                     * Whether the current TreeNode IO transaction is loading.
                                     *
                                     * @attribute loading
                                     * @default false
                                     * @type Boolean
                                     */
                                    loading: {
                                        value: false,
                                        validator: isBoolean
                                    },
                            
                                    /**
                                     * Whether the current TreeNode has loaded the content.
                                     *
                                     * @attribute loaded
                                     * @default false
                                     * @type Boolean
                                     */
                                    loaded: {
                                        value: false,
                                        validator: isBoolean
                                    },
                            
                                    /**
                                     * Whether the current TreeNode should cache the loaded content or not.
                                     *
                                     * @attribute cache
                                     * @default true
                                     * @type Boolean
                                     */
                                    cache: {
                                        value: true,
                                        validator: isBoolean
                                    },
                            
                                    /**
                                     * Whether the TreeNode could have children or not (i.e. if any
                                     * children is present the TreeNode is a leaf).
                                     *
                                     * @attribute leaf
                                     * @default false
                                     * @type Boolean
                                     */
                                    leaf: {
                                        value: false,
                                        validator: isBoolean
                                    }
                                },
                            
                                AUGMENTS: [A.TreeViewPaginator, A.TreeViewIO],
                            
                                EXTENDS: A.TreeNode,
                            
                                prototype: {
                            
                                    /**
                                     * Bind the events on the TreeNodeIO UI. Lifecycle.
                                     *
                                     * @method bindUI
                                     * @protected
                                     */
                                    bindUI: function() {
                                        var instance = this;
                            
                                        A.TreeNodeIO.superclass.bindUI.apply(this, arguments);
                            
                                        instance.on('ioRequestSuccess', instance._onIOSuccess, instance);
                                    },
                            
                                    /**
                                     * Sync the TreeNodeIO UI. Lifecycle.
                                     *
                                     * @method syncUI
                                     * @protected
                                     */
                                    syncUI: function() {
                                        A.TreeNodeIO.superclass.syncUI.apply(this, arguments);
                                    },
                            
                                    /**
                                     * Expand the current TreeNodeIO.
                                     *
                                     * @method expand
                                     */
                                    expand: function() {
                                        var instance = this;
                            
                                        var cache = instance.get('cache');
                                        var io = instance.get('io');
                                        var loaded = instance.get('loaded');
                                        var loading = instance.get('loading');
                            
                                        if (!cache) {
                                            // if cache is false on expand, always set LOADED to false
                                            instance.set('loaded', false);
                                        }
                            
                                        if (io && !loaded && !loading && !instance.hasChildNodes() && !instance.isLeaf()) {
                                            if (!cache) {
                                                // remove all children to reload
                                                instance.empty();
                                            }
                            
                                            instance.initIO();
                                        }
                                        else {
                                            A.TreeNodeIO.superclass.expand.apply(this, arguments);
                                        }
                                    },
                            
                                    /**
                                     * If not specified on the TreeNode some attributes are inherited from
                                     * the ownerTree by this method.
                                     *
                                     * @method _inheritOwnerTreeAttrs
                                     * @protected
                                     */
                                    _inheritOwnerTreeAttrs: function() {
                                        var instance = this;
                            
                                        var ownerTree = instance.get('ownerTree');
                            
                                        if (ownerTree) {
                                            if (!instance.get('io')) {
                                                var io = A.clone(
                                                    ownerTree.get('io'),
                                                    true,
                                                    function(value) {
                                                        if (isFunction(value) && (value.defaultFn || value.wrappedFn)) {
                                                            return false;
                                                        }
                            
                                                        return true;
                                                    }
                                                );
                            
                                                instance.set('io', io);
                                            }
                            
                                            if (!instance.get('paginator')) {
                                                var ownerTreePaginator = ownerTree.get('paginator');
                            
                                                var paginator = A.clone(ownerTreePaginator);
                            
                                                // make sure we are not using the same element passed to the
                                                // ownerTree on the TreeNode
                                                if (paginator && paginator.element) {
                                                    paginator.element = ownerTreePaginator.element.clone();
                                                }
                            
                                                instance.set('paginator', paginator);
                                            }
                                        }
                                    },
                            
                                    /**
                                     * Fire when IO success.
                                     *
                                     * @method _onIOSuccess
                                     * @param event
                                     */
                                    _onIOSuccess: function() {
                                        var instance = this;
                            
                                        instance.expand();
                                    }
                                }
                            });
                            
                            A.TreeNodeIO = TreeNodeIO;
                            
                            /*
                             * TreeNodeCheck
                             */
                            var CSS_TREE_NODE_CHECKBOX = getCN('tree', 'node', 'checkbox'),
                                CSS_TREE_NODE_CHECKBOX_CONTAINER = getCN('tree', 'node', 'checkbox', 'container'),
                                CSS_TREE_NODE_CHECKED = getCN('tree', 'node', 'checked'),
                            
                                CHECKBOX_CONTAINER_TPL = '<span class="' + CSS_TREE_NODE_CHECKBOX_CONTAINER + '"></span>',
                                CHECKBOX_TPL = '<input class="' + CSS_TREE_NODE_CHECKBOX + '" type="checkbox" />';
                            
                            /**
                             * A base class for TreeNodeCheck, providing:
                             *
                             * - Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)
                             * - Checkbox support for the TreeNode
                             *
                             * @class A.TreeNodeCheck
                             * @extends A.TreeNodeIO
                             * @param {Object} config Object literal specifying widget configuration
                             *     properties.
                             * @constructor
                             */
                            var TreeNodeCheck = A.Component.create({
                                /**
                                 * Static property provides a string to identify the class.
                                 *
                                 * @property NAME
                                 * @type String
                                 * @static
                                 */
                                NAME: 'tree-node-check',
                            
                                /**
                                 * Static property used to define the default attribute
                                 * configuration for the TreeNode.
                                 *
                                 * @property ATTRS
                                 * @type Object
                                 * @static
                                 */
                                ATTRS: {
                            
                                    /**
                                     * Whether the TreeNode is checked or not.
                                     *
                                     * @attribute checked
                                     * @default false
                                     * @type Boolean
                                     */
                                    checked: {
                                        value: false,
                                        validator: isBoolean
                                    },
                            
                                    /**
                                     * Name of the checkbox element used on the current TreeNode.
                                     *
                                     * @attribute checkName
                                     * @default 'tree-node-check'
                                     * @type String
                                     */
                                    checkName: {
                                        value: 'tree-node-check',
                                        validator: isString
                                    },
                            
                                    /**
                                     * Container element for the checkbox.
                                     *
                                     * @attribute checkContainerEl
                                     * @default Generated DOM element.
                                     * @type Node | String
                                     */
                                    checkContainerEl: {
                                        setter: A.one,
                                        valueFn: function() {
                                            return A.Node.create(CHECKBOX_CONTAINER_TPL);
                                        }
                                    },
                            
                                    /**
                                     * Checkbox element.
                                     *
                                     * @attribute checkEl
                                     * @default Generated DOM element.
                                     * @type Node | String
                                     */
                                    checkEl: {
                                        setter: A.one,
                                        valueFn: function() {
                                            var checkName = this.get('checkName');
                            
                                            return A.Node.create(CHECKBOX_TPL).attr('name', checkName);
                                        }
                                    }
                                },
                            
                                EXTENDS: A.TreeNodeIO,
                            
                                prototype: {
                            
                                    /**
                                     * Create the DOM structure for the TreeNodeCheck. Lifecycle.
                                     *
                                     * @method renderUI
                                     * @protected
                                     */
                                    renderUI: function() {
                                        var instance = this;
                            
                                        A.TreeNodeCheck.superclass.renderUI.apply(instance, arguments);
                            
                                        var labelEl = instance.get('labelEl');
                                        var checkEl = instance.get('checkEl');
                                        var checkContainerEl = instance.get('checkContainerEl');
                            
                                        checkEl.hide();
                            
                                        checkContainerEl.append(checkEl);
                            
                                        labelEl.placeBefore(checkContainerEl);
                            
                                        if (instance.isChecked()) {
                                            instance.check();
                                        }
                            
                                        instance._uiSetChecked(instance.get('checked'));
                                    },
                            
                                    /**
                                     * Bind the events on the TreeNodeCheck UI. Lifecycle.
                                     *
                                     * @method bindUI
                                     * @protected
                                     */
                                    bindUI: function() {
                                        var instance = this;
                            
                                        var contentBox = instance.get('contentBox');
                                        var labelEl = instance.get('labelEl');
                            
                                        A.TreeNodeCheck.superclass.bindUI.apply(instance, arguments);
                            
                                        instance.after('checkedChange', A.bind(instance._afterCheckedChange, instance));
                            
                                        contentBox.delegate('click', A.bind(instance.toggleCheck, instance), '.' +
                                            CSS_TREE_NODE_CHECKBOX_CONTAINER);
                                        contentBox.delegate('click', A.bind(instance.toggleCheck, instance), '.' + CSS_TREE_LABEL);
                            
                                        // cancel dblclick because of the check
                                        labelEl.swallowEvent('dblclick');
                                    },
                            
                                    /**
                                     * Check the current TreeNode.
                                     *
                                     * @method check
                                     */
                                    check: function(originalTarget) {
                                        var instance = this;
                            
                                        instance.set('checked', true, {
                                            originalTarget: originalTarget
                                        });
                                    },
                            
                                    /**
                                     * Uncheck the current TreeNode.
                                     *
                                     * @method uncheck
                                     */
                                    uncheck: function(originalTarget) {
                                        var instance = this;
                            
                                        instance.set('checked', false, {
                                            originalTarget: originalTarget
                                        });
                                    },
                            
                                    /**
                                     * Toggle the check status of the current TreeNode.
                                     *
                                     * @method toggleCheck
                                     */
                                    toggleCheck: function() {
                                        var instance = this;
                            
                                        var checkEl = instance.get('checkEl');
                                        var checked = checkEl.attr('checked');
                            
                                        if (!checked) {
                                            instance.check();
                                        }
                                        else {
                                            instance.uncheck();
                                        }
                                    },
                            
                                    /**
                                     * Whether the current TreeNodeCheck is checked.
                                     *
                                     * @method isChecked
                                     * @return Boolean
                                     */
                                    isChecked: function() {
                                        var instance = this;
                            
                                        return instance.get('checked');
                                    },
                            
                                    /**
                                     * Sync icon check on the UI.
                                     *
                                     * @method _syncIconCheckUI
                                     * @protected
                                     */
                                    _syncIconCheckUI: function() {
                                        var instance = this,
                                            ownerTree = instance.get('ownerTree');
                            
                                        if (ownerTree) {
                                            var type = ownerTree.get('type'),
                                                cssClasses = instance.get('cssClasses.' + type);
                            
                                            if (!cssClasses) {
                                                return;
                                            }
                            
                                            var checkContainerEl = instance.get('checkContainerEl'),
                                                isChecked = instance.isChecked();
                                            checkContainerEl.removeClass(
                                                isChecked ?
                                                cssClasses.iconUncheck : cssClasses.iconCheck);
                                            checkContainerEl.addClass(
                                                isChecked ?
                                                cssClasses.iconCheck : cssClasses.iconUncheck);
                                        }
                                    },
                            
                                    /**
                                     * Fire after `checked` change.
                                     *
                                     * @method _afterCheckedChange
                                     * @param event
                                     * @protected
                                     */
                                    _afterCheckedChange: function(event) {
                                        var instance = this;
                            
                                        instance._uiSetChecked(event.newVal);
                                    },
                            
                                    /**
                                     * Set the `checked` attribute on the UI.
                                     *
                                     * @method _uiSetChecked
                                     * @param val
                                     * @protected
                                     */
                                    _uiSetChecked: function(val) {
                                        var instance = this;
                            
                                        instance._syncIconCheckUI();
                                        instance.get('checkEl').attr('checked', val ? 'checked' : '');
                                        instance.get('contentBox').toggleClass(CSS_TREE_NODE_CHECKED, val);
                                    }
                                }
                            });
                            
                            A.TreeNodeCheck = TreeNodeCheck;
                            
                            /*
                             * TreeNodeTask
                             */
                            var CSS_TREE_NODE_CHILD_UNCHECKED = getCN('tree', 'node', 'child', 'unchecked'),
                            
                                isTreeNodeTask = function(node) {
                                    return node instanceof A.TreeNodeCheck;
                                };
                            
                            /**
                             * A base class for TreeNodeTask, providing:
                             *
                             * - Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)
                             * - 3 states checkbox support
                             * - Automatic check/uncheck the parent status based on the children checked
                             *   status
                             *
                             * @class A.TreeNodeTask
                             * @extends A.TreeNodeCheck
                             * @param {Object} config Object literal specifying widget configuration
                             *     properties.
                             * @constructor
                             */
                            var TreeNodeTask = A.Component.create({
                                /**
                                 * Static property provides a string to identify the class.
                                 *
                                 * @property NAME
                                 * @type String
                                 * @static
                                 */
                                NAME: 'tree-node-task',
                            
                                EXTENDS: A.TreeNodeCheck,
                            
                                prototype: {
                            
                                    /**
                                     * Check the current TreeNodeTask.
                                     *
                                     * @method check
                                     * @param originalTarget
                                     */
                                    check: function(originalTarget) {
                                        var instance = this;
                            
                                        var contentBox = instance.get('contentBox');
                            
                                        originalTarget = originalTarget || instance;
                            
                                        if (!instance.isLeaf()) {
                                            instance.eachChildren(function(child) {
                                                if (isTreeNodeTask(child)) {
                                                    child.check(originalTarget);
                                                }
                                            });
                                        }
                            
                                        instance._uncheckedAncestorChildRemoveClass();
                            
                                        contentBox.removeClass(CSS_TREE_NODE_CHILD_UNCHECKED);
                            
                                        // invoke default check logic
                                        A.TreeNodeTask.superclass.check.call(this, originalTarget);
                                    },
                            
                                    /**
                                     * Uncheck the current TreeNodeTask.
                                     *
                                     * @method uncheck
                                     * @param originalTarget
                                     */
                                    uncheck: function(originalTarget) {
                                        var instance = this;
                            
                                        var contentBox = instance.get('contentBox');
                            
                                        originalTarget = originalTarget || instance;
                            
                                        if (!instance.isLeaf()) {
                                            instance.eachChildren(function(child) {
                                                if (child instanceof A.TreeNodeCheck) {
                                                    child.uncheck(originalTarget);
                                                }
                                            });
                                        }
                            
                                        instance._uncheckedAncestorChildAddClass();
                            
                                        contentBox.removeClass(CSS_TREE_NODE_CHILD_UNCHECKED);
                            
                                        // invoke default uncheck logic
                                        A.TreeNodeTask.superclass.uncheck.call(this, originalTarget);
                                    },
                            
                                    /**
                                     * Adds the class `tree-node-child-unchecked` to all checked ancestor TreeNodeTasks.
                                     *
                                     * @method _uncheckedAncestorChildAddClass
                                     */
                                    _uncheckedAncestorChildAddClass: function() {
                                        var instance = this;
                            
                                        instance.eachParent(
                                            function(parentNode) {
                                                if (isTreeNodeTask(parentNode) && parentNode.isChecked()) {
                                                    parentNode.get('contentBox').addClass(CSS_TREE_NODE_CHILD_UNCHECKED);
                                                }
                                            }
                                        );
                                    },
                            
                                    /**
                                     * Removes the class `tree-node-child-unchecked` from ancestor TreeNodeTasks, when all descendant TreeNodeTasks are checked.
                                     *
                                     * @method _uncheckedAncestorChildRemoveClass
                                     */
                                    _uncheckedAncestorChildRemoveClass: function() {
                                        var instance = this,
                                            children,
                                            childHasUncheckedChild,
                                            parentHasUncheckedDescendants;
                            
                                        instance.eachParent(
                                            function(parentNode) {
                                                if (isTreeNodeTask(parentNode) && !parentHasUncheckedDescendants) {
                                                    children = parentNode.getChildren();
                            
                                                    parentHasUncheckedDescendants = A.Array.some(children, function(child) {
                                                        if ((child !== instance) && !child.isChecked()) {
                                                            return true;
                                                        }
                                                        else {
                                                            childHasUncheckedChild = child.get('contentBox').hasClass(CSS_TREE_NODE_CHILD_UNCHECKED);
                            
                                                            if (childHasUncheckedChild) {
                                                                return true;
                                                            }
                                                        }
                                                    });
                            
                                                    if (!parentHasUncheckedDescendants) {
                                                        parentNode.get('contentBox').removeClass(CSS_TREE_NODE_CHILD_UNCHECKED);
                                                    }
                                                }
                                            }
                                        );
                                    }
                                }
                            });
                            
                            A.TreeNodeTask = TreeNodeTask;
                            
                            /*
                             * TreeNodeRadio
                             */
                            
                            var CSS_NODE_RADIO = getCN('tree', 'node', 'radio'),
                            
                                isTreeNodeRadio = function(node) {
                                    return node instanceof A.TreeNodeRadio;
                                };
                            
                            /**
                             * A base class for TreeNodeRadio, providing:
                             *
                             * - Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)
                             * - 3 states checkbox support
                             * - Automatic check/uncheck the parent status based on the children checked
                             *   status
                             *
                             * @class A.TreeNodeRadio
                             * @extends A.TreeNodeTask
                             * @param {Object} config Object literal specifying widget configuration
                             *     properties.
                             * @constructor
                             */
                            var TreeNodeRadio = A.Component.create({
                                /**
                                 * Static property provides a string to identify the class.
                                 *
                                 * @property NAME
                                 * @type String
                                 * @static
                                 */
                                NAME: 'tree-node-radio',
                            
                                /**
                                 * Static property used to define the default attribute
                                 * configuration for the TreeNodeRadio.
                                 *
                                 * @property ATTRS
                                 * @type Object
                                 * @static
                                 */
                                ATTRS: {
                            
                                    /**
                                     * CSS classes used on TreeNodeRadio.
                                     *
                                     * @attribute cssClasses
                                     * @type Object
                                     */
                                    cssClasses: {
                                        value: {
                                            file: {
                                                iconCheck: [CSS_ICON, CSS_ICON_OK_SIGN].join(' '),
                                                iconCollapsed: [CSS_ICON, CSS_ICON_FOLDER_CLOSE].join(' '),
                                                iconExpanded: [CSS_ICON, CSS_ICON_FOLDER_OPEN].join(' '),
                                                iconHitAreaCollapsed: [CSS_TREE_HITAREA, CSS_ICON_ICON_PLUS].join(' '),
                                                iconHitAreaExpanded: [CSS_TREE_HITAREA, CSS_ICON_ICON_MINUS].join(' '),
                                                iconLeaf: [CSS_ICON, CSS_ICON_ICON_FILE].join(' '),
                                                iconLoading: [CSS_ICON, CSS_ICON_ICON_REFRESH].join(' '),
                                                iconUncheck: [CSS_ICON, CSS_ICON_OK_SIGN].join(' ')
                                            },
                                            normal: {
                                                iconCheck: [CSS_ICON, CSS_ICON_OK_SIGN].join(' '),
                                                iconHitAreaCollapsed: [CSS_TREE_HITAREA, CSS_ICON_ICON_PLUS].join(' '),
                                                iconHitAreaExpanded: [CSS_TREE_HITAREA, CSS_ICON_ICON_MINUS].join(' '),
                                                iconLoading: [CSS_ICON, CSS_ICON_ICON_REFRESH].join(' '),
                                                iconUncheck: [CSS_ICON, CSS_ICON_OK_SIGN].join(' ')
                                            }
                                        }
                                    }
                                },
                            
                                EXTENDS: A.TreeNodeCheck,
                            
                                prototype: {
                            
                                    /**
                                     * Create the DOM structure for the TreeNodeRadio. Lifecycle.
                                     *
                                     * @method renderUI
                                     * @protected
                                     */
                                    renderUI: function() {
                                        var instance = this;
                            
                                        A.TreeNodeRadio.superclass.renderUI.apply(instance, arguments);
                            
                                        instance.get('contentBox').addClass(CSS_NODE_RADIO);
                                    },
                            
                                    /**
                                     * Check the current TreeNodeRadio.
                                     *
                                     * @method check
                                     */
                                    check: function() {
                                        var instance = this;
                            
                                        instance._uncheckNodesRadio();
                            
                                        A.TreeNodeRadio.superclass.check.apply(this, arguments);
                                    },
                            
                                    /**
                                     * Uncheck radio nodes.
                                     *
                                     * @method _uncheckNodesRadio
                                     * @param node
                                     * @protected
                                     */
                                    _uncheckNodesRadio: function(node) {
                                        var instance = this;
                            
                                        var children;
                            
                                        if (node) {
                                            children = node.get('children');
                                        }
                                        else {
                                            var ownerTree = instance.get('ownerTree');
                            
                                            if (ownerTree) {
                                                children = ownerTree.get('children');
                                            }
                                            else {
                                                return;
                                            }
                                        }
                            
                                        A.Array.each(
                                            children,
                                            function(value) {
                                                if (!value.isLeaf()) {
                                                    instance._uncheckNodesRadio(value);
                                                }
                            
                                                if (isTreeNodeRadio(value)) {
                                                    value.uncheck();
                                                }
                                            }
                                        );
                                    }
                                }
                            });
                            
                            A.TreeNodeRadio = TreeNodeRadio;
                            
                            /**
                             * TreeNode types hash map.
                             *
                             * ```
                             * A.TreeNode.nodeTypes = {
                             *  radio: A.TreeNodeRadio,
                             *  task: A.TreeNodeTask,
                             *  check: A.TreeNodeCheck,
                             *  node: A.TreeNode,
                             *  io: A.TreeNodeIO
                             * };
                             * ```
                             *
                             * @for TreeNode
                             * @property nodeTypes
                             * @type Object
                             */
                            A.TreeNode.nodeTypes = {
                                radio: A.TreeNodeRadio,
                                task: A.TreeNodeTask,
                                check: A.TreeNodeCheck,
                                node: A.TreeNode,
                                io: A.TreeNodeIO
                            };