/*global AZCAT,YAHOO,waitStatus,
         doIEPNGFixImgFrom,recursivePurgeAndRemove,
         isFCKEditorBrowse,browseSelect,Shadowbox,doFileProperties,
         prefsClick,urllib_quote,
         createAutoComplete, portal_url,
         editOpensInNewWindow, show_action_buttons,alert,window,
         doIEPNGFix,clipboard,cancelPowerFilter,getPowerFilterFromServer */

/*jslint browser: true, unparam: true, sloppy: true, nomen: true, maxlen: 80,
         indent: 4 */

var object = (function () {
    function F() {}
    return function (o) {
        F.prototype = o;
        return new F();
    };
}()), $hasOwnProperty = function (o, p) {
    return !o.constructor().constructor.prototype.hasOwnProperty(p);
};

AZCAT.siteman.Data = (function () {
    // Shared resources, ALL instances
    // Cached singletons
    var $l = YAHOO.lang,
        _callback,
        _callback_scope,
        _allDirty;

    // Shared private functions

    function _mungeActionsToReturnCollection(item) {
        // Add return_collection_uid to the appropriate action's query string if
        // the URL does not live within the Collection.
        var root_location,
            x,
            xlen,
            action_path,
            action_indexes = [],
            action_paths = [],
            item_url = null,
            path_split,
            action_query,
            action_fragment;

        if (!item.hasOwnProperty('actions')) {
            return;
        }

        root_location = portal_url + this.root_path + this.root_id;

        if (root_location.search(/\/$/) === -1) {
            root_location = root_location + '/';
        }

        for (x = 0, xlen = item.actions.length; x < xlen; x += 1) {
            if (item.actions[x].passes_return_collection) {
                action_path = item.actions[x].href;
                if (action_path.length) {
                    // Let's not munge JS actions yet.
                    if (action_path.search(/^https?:\/\//) === -1) {
                        if (YAHOO.util.Lang.isNull(item_url)) {
                            item_url = item.path + item.id;
                            if (item_url === '/') {
                                item_url = '';
                            }
                        }
                        action_path = portal_url + item_url + action_path;
                    } else {
                        action_path = item.actions[x].href;
                    }
                    if (action_path.substr(0, root_location.length) !==
                            root_location) {
                        action_indexes.push(x);
                        action_paths.push(action_path);
                    }
                }
            }
        }

        for (x = 0, xlen = action_indexes.length; x < xlen; x += 1) {
            action_path = action_paths[x];
            path_split = action_path.split('#');
            action_path = path_split.shift();
            action_fragment = path_split.join('#');
            path_split = action_path.split('?');
            action_path = path_split.shift();
            action_query = path_split.join('?');

            if (action_query.length) {
                action_query = action_query + '&';
            }
            action_query =
                action_query +
                'return_collection_uid%3aint=' +
                this.root_cmf_uid.toString();

            action_path = action_path + '?' + action_query;
            if (action_fragment.length) {
                action_path = action_path + '#' + action_fragment;
            }
            item.actions[action_indexes[x]].href = action_path;
        }
    }

    function _addItem(obj) { // Also, replace
        var parentObj, alreadySubitem, i, ilen;
        this._items[obj.cmf_uid] = obj;
        _mungeActionsToReturnCollection.call(this, obj);
        // Add the item to the tree if appropriate
        if (this._tree.length) {
            parentObj = this._getParent(obj.cmf_uid);
            if (parentObj) {
                alreadySubitem = false;
                for (i = 0, ilen = parentObj.subitems.length;
                        i < ilen;
                        i += 1) {
                    if (parentObj.subitems[i].cmf_uid === obj.cmf_uid) {
                        alreadySubitem = true;
                        break;
                    }
                }
                if (!alreadySubitem) {
                    parentObj.subitems.push(obj);
                }
            }
        }
        this.itemAdded.fire(obj);
    }

    function _updateItem(id, obj) {
        var i;
        _mungeActionsToReturnCollection.call(this, obj);
        if ($l.isUndefined(this._items[id])) {
            this._items[id] = {};
        }
        if ($l.isObject(obj)) {
            for (i in obj) {
                // this is intentionally $hasOwnProperty, not .hasOwnProperty
                if ($hasOwnProperty(obj, i)) {
                    this._items[id][i] = obj[i];
                    // This should be replaced by a custom event that dataView 
                    // can subscribe to.
                    this._parent.dataView.addDirtyData(id, [i]);
                }
            }
        }
    }

    function _deleteItem(cmf_uid) {
        if (!$l.isUndefined(this._items[cmf_uid])) {
            this._parent.dataView.addWasRemoved(
                cmf_uid,
                this._getParent(cmf_uid)
            );
            return delete this._items[cmf_uid];
        }
        return false;
    }

    function _clearAllItems() {
        this._items = {};
        this._tree = [];
        this._list = [];
        this._treeDirty = true;
        this._listDirty = true;
    }

    function _buildList() {
        this._list = [];
        var items = [], i, iLen;
        for (i = 0, iLen = this._display_order.length; i < iLen; i += 1) {
            if (!YAHOO.lang.isUndefined(this._items[this._display_order[i]])) {
                items.push(object(this._items[this._display_order[i]]));
            }
        }
        this._list = items;
        this._listDirty = false;
    }

    function _buildTree() {
        var i, ilen, currentItem = null, items, parentItem;
        this._tree = [];
        items = [];
        for (i = 0, ilen = this._display_order.length; i < ilen; i += 1) {
            if (!YAHOO.lang.isUndefined(this._items[this._display_order[i]])) {
                if (
                    $l.isNull(currentItem) ||
                        currentItem.length >
                            this._items[this._display_order[i]].path.length
                ) {
                    currentItem = this._items[this._display_order[i]].path;
                }
                items.push(object(this._items[this._display_order[i]]));
            }
        }
        parentItem = this._tree;
        for (i = 0, ilen = items.length; i < ilen; i += 1) {
            if (items[i].path === currentItem) {
                parentItem.push(items[i]);
            } else {
                currentItem = items[i].path;
                parentItem = this._getParent(items[i].cmf_uid);
                // Customized here to allow sitemap to work if a folder is set
                // to exclude from sitemap but it's children aren't.
                if (parentItem === null) {
                    parentItem = [];
                } else {
                    parentItem = parentItem.subitems;
                    parentItem.push(items[i]);
                }
            }
        }
        this._treeDirty = false;
    }

    function _getItemsForUpdate() {
        var items = {}, i;
        for (i in this._items) {
            if (this._items.hasOwnProperty(i)) {
                items[i] = this._items[i].last_catalogued;
            }
        }
        return items;
    }

    function _invalidateDataLackingColumns(columns) {
        /* This is used if a column is added. We need to get a new version of
           items lacking that column */
        var i, iLen, thisColumn, j;
        for (i = 0, iLen = columns.length; i < iLen; i += 1) {
            thisColumn = columns[i];
            for (j in this._items) {
                if (this._items.hasOwnProperty(j)) {
                    if (YAHOO.util.Lang.isUndefined(
                            this._items[j][thisColumn]
                        )) {
                        this._items[j].last_catalogued = -1;
                    }
                }
            }
        }
    }

    function _getDataColumns() {
        var visible_columns = this._parent.prefs.getPreference(
                "columns",
                this._parent.data.prefs_id
            ),
            visible_columns_obj = {},
            i,
            iLen,
            j,
            jLen,
            data_columns = [],
            data_column_obj = {},
            mand_columns = [
                'cmf_uid',
                'last_catalogued',
                'path',
                'id',
                'is_folderish',
                'sort_order'
            ];

        for (i = 0, iLen = visible_columns.length; i < iLen; i += 1) {
            visible_columns_obj[visible_columns[i]] = true;
        }

        for (i in this._parent.dataToColumns) {
            if (this._parent.dataToColumns.hasOwnProperty(i)) {
                for (j = 0, jLen = this._parent.dataToColumns[i].length;
                         j < jLen; j += 1) {
                    if (!YAHOO.util.Lang.isUndefined(
                            visible_columns_obj[
                                this._parent.dataToColumns[i][j]
                            ]
                        )) {
                        data_column_obj[i] = true;
                        break;
                    }
                }
            }
        }
        // We always need these columns, no matter which columns are displayed
        for (i = 0, iLen = mand_columns.length; i < iLen; i += 1) {
            if (YAHOO.util.Lang.isUndefined(data_column_obj[mand_columns[i]])) {
                data_column_obj[mand_columns[i]] = true;
            }
        }

        for (i in data_column_obj) {
            if (data_column_obj.hasOwnProperty(i)) {
                data_columns.push(i);
            }
        }

        return data_columns;
    }

    function _updateFromServerCallback(o) {
        var items, temp_callback, temp_callback_scope, temp_allDirty,
            searchByString, searchBy;
        items = JSON.parse(o.responseText);
        this.updateItems(
            items.created,
            items.updated,
            items.deleted,
            items.displayed_uids,
            items.full_size
        );
        if (!$l.isUndefined(items.view_root_actions)) {
            this._root_actions = items.view_root_actions;
            this.rootActionsSet.fire(items.view_root_actions);
        }
        if (_callback) {
            temp_callback = _callback;
            temp_callback_scope = _callback_scope;
            temp_allDirty = _allDirty;
            _callback = null;
            _callback_scope = null;
            _allDirty = null;
            temp_callback.call(temp_callback_scope, temp_allDirty);
        }
        if (YAHOO.util.Cookie) {
            searchByString = YAHOO.util.Cookie.get("prefilter");
            if (searchByString) {
                searchBy = document.getElementById("search_by");
                searchBy.value = searchByString;
                YAHOO.util.Cookie.remove("prefilter");
                this._parent.dataView._doSearch();
            }
        }
    }

    function _getSearchResultsFromServerCallback(o) {
        var items = JSON.parse(o.responseText),
            temp_callback,
            temp_callback_scope,
            temp_allDirty;
        this.updateItems(
            items.created,
            items.updated,
            items.deleted,
            items.displayed_uids,
            items.full_size
        );
        if (_callback) {
            temp_callback = _callback;
            temp_callback_scope = _callback_scope;
            temp_allDirty = _allDirty;
            _callback = null;
            _callback_scope = null;
            _allDirty = null;
            temp_callback.call(temp_callback_scope, temp_allDirty);
        }
        waitStatus(false);
    }

    function _setInPowerFilterMode(inPowerFilterMode) {
        this._inPowerFilterMode = inPowerFilterMode;
    }

    function _getPowerFilterSearchResultsFromServerCallback(o) {
        var items = JSON.parse(o.responseText),
            temp_callback,
            temp_callback_scope,
            temp_allDirty;
        this.updateItems(
            items.created,
            items.updated,
            items.deleted,
            items.displayed_uids,
            items.full_size
        );
        if (_callback) {
            temp_callback = _callback;
            temp_callback_scope = _callback_scope;
            temp_allDirty = _allDirty;
            _callback = null;
            _callback_scope = null;
            _allDirty = null;
            temp_callback.call(temp_callback_scope, temp_allDirty);
        }
        waitStatus(false);
    }

    function _getPowerFilterFormCallback(o) {
        var formData, scripts, myDialog, that, x, xLen, funcName;
        waitStatus(false);
        formData = JSON.parse(o.responseText);
        myDialog = new AZCAT.Dialog();
        myDialog.setHeader(
            [
                myDialog.headerleft,
                "Power Filter",
                myDialog.headerright
            ].join("")
        );
        myDialog.setBody(formData.html);
        myDialog.setFooter(
            [myDialog.footerleft, myDialog.footerright].join("")
        );
        that = this;
        myDialog.hideEvent.subscribe(cancelPowerFilter, myDialog, that);
        myDialog.render(document.body);

        scripts = document.getElementById("power_filter_form");
        scripts = scripts.getElementsByTagName("script");

        // Load any scripts that are returned with the widgets
        AZCAT.scripts.add("powerFilter", scripts);

        // Initialize any widgets
        for (x = 0, xLen = formData.initScripts.length; x < xLen; x += 1) {
            funcName = formData.initScripts[x].fn;
            if (window[funcName]) {
                window[funcName]();
            }
        }

        this._setInPowerFilterMode(true);
        myDialog.show();
        YAHOO.util.Event.on(
            "power_filter_submit",
            "click",
            getPowerFilterFromServer,
            myDialog,
            that
        );
        YAHOO.util.Event.on(
            "power_filter_cancel",
            "click",
            cancelPowerFilter,
            myDialog,
            that
        );
        myDialog.changeBodyEvent.fire();
        myDialog.center();
    }

    function _climbTree(c, from) {
        var nextC, i, ilen;
        for (i = 0, ilen = from.length; i < ilen; i += 1) {
            // Mild Hack: We assume that the root of this._tree has been set
            if (from[i].id === c[0] ||
                    from[i].cmf_uid === this._tree[0].cmf_uid) {
                if ($l.isUndefined(from[i].subitems)) {
                    from[i].subitems = [];
                }
                nextC = c.slice(
                    from[i].cmf_uid === this._tree[0].cmf_uid ?
                            this._tree[0].path.split('/').length :
                            1
                );
                if (nextC.length) {
                    return this._climbTree(nextC, from[i].subitems);
                } else {
                    return from[i];
                }
            }
        }
        // Customized here to allow sitemap to work if a folder is set to
        // exclude from sitemap but it's children aren't.
        return null;
    }

    function _getParent(cmf_uid) {
        var path;
        if (this._tree.length && cmf_uid !== this._tree[0].cmf_uid) {
            path = this._items[cmf_uid].path.split('/').slice(0, -1);
            if (path.length) {
                return this._climbTree(path, this._tree);
            }
        }
        return null;
    }

    function _getAllActions() {
        var allActions = {},
            i,
            thisItem,
            x,
            xLen,
            thisAction;

        // If the view root is not in the items, we need to add its actions in
        // manually
        if ($l.isUndefined(this._items[this.root_cmf_uid]) &&
                !$l.isUndefined(this._root_actions)) {
            for (x = 0, xLen = this._root_actions.length; x < xLen; x += 1) {
                thisAction = this._root_actions[x];
                if ($l.isUndefined(allActions[thisAction.id])) {
                    allActions[thisAction.id] = {
                        title: thisAction.title,
                        icon: thisAction.icon
                    };
                }
            }
        }

        for (i in this._items) {
            if (this._items.hasOwnProperty(i)) {
                thisItem = this._items[i];
                if (thisItem.actions) {
                    for (x = 0, xLen = thisItem.actions.length;
                            x < xLen;
                            x += 1) {
                        thisAction = thisItem.actions[x];
                        if ($l.isUndefined(allActions[thisAction.id])) {
                            allActions[thisAction.id] = {
                                title: thisAction.title,
                                icon: thisAction.icon
                            };
                        }
                    }
                }
            }
        }
        return allActions;
    }

    function _clearEnabledActionRequests() {
        while (this._enabled_action_requests.length) {
            YAHOO.util.Connect.abort(this._enabled_action_requests.pop());
        }
    }

    function _getActionIdsByCmfUidCallback(conn_obj) {
        var i, ilen, callback, callback_scope,
            server_response = JSON.parse(conn_obj.responseText);
        for (i = 0, ilen = this._enabled_action_requests.length;
                i < ilen;
                i += 1) {
            if (this._enabled_action_requests[i].tld === conn_obj.tld) {
                this._enabled_action_requests.splice(i, 1);
                ilen = this._enabled_action_requests.length;
            }
        }
        callback = conn_obj.argument.callback;
        callback_scope = conn_obj.argument.callback_scope;
        callback.call(callback_scope, server_response.actions);
    }

    function _getActionIdsByCmfUid(cmf_uids, callback, callback_scope) {
        var data = this, action_list, action_ids, i, ilen, connection_obj;
        _clearEnabledActionRequests.call(this);
        if (cmf_uids.length < 2) {
            if (cmf_uids.length === 0) {
                action_list = this._root_actions;
            } else {
                action_list = this._items[cmf_uids[0]].actions;
            }
            action_ids = [];
            for (i = 0, ilen = action_list.length; i < ilen; i += 1) {
                action_ids.push(action_list[i].id);
            }
            callback.call(callback_scope, action_ids);
        } else {
            connection_obj = YAHOO.util.Connect.asyncRequest(
                'POST',
                [this.portal_url, '/getEnabledActionsForSelected'].join(""),
                {
                    scope: data,
                    success: _getActionIdsByCmfUidCallback,
                    failure: AZCAT.utils.connFail,
                    argument: {
                        callback: callback,
                        callback_scope: callback_scope
                    }
                },
                'cmf_uids=' + JSON.stringify(cmf_uids)
            );
            this._enabled_action_requests.push(connection_obj);
        }
    }

    function updateItems(created, updated, deleted, display_order, full_size) {
        var i, ilen;
        this._full_size = full_size;
        if (updated) {
            for (i = 0, ilen = updated.length; i < ilen; i += 1) {
                this._updateItem(updated[i].cmf_uid, updated[i]);
            }
        }
        if (deleted) {
            for (i = 0, ilen = deleted.length; i < ilen; i += 1) {
                this._deleteItem(deleted[i]);
            }
        }
        if (created) {
            for (i = 0, ilen = created.length; i < ilen; i += 1) {
                this._addItem(created[i]);
            }
        }
        if (display_order) {
            this._display_order = display_order;
        }
        if (deleted || created) {
            this._listDirty = true;
            this._treeDirty = true;
            this._searchResultsDirty = true;
        }
    }

    function getLast(data, myparent) {
        var p = myparent || this._getParent(data.cmf_uid);
        if (p === null) {
            return true;
        }
        return p.subitems[p.subitems.length - 1].cmf_uid === data.cmf_uid;
    }

    function sortList(sortOn, isDescending) {
        if (!$l.isUndefined(this._parent.sortCols[sortOn])) {
            if ($l.isBoolean(isDescending)) {
                this._isListSortDescending = isDescending;
            }
            this._listSortOn = sortOn;
            this._listDirty = true;
            // This should be replaced by a custom event that dataView can
            // subscibe to.
            this._parent.prefs.setPreferences(
                {
                    "lastSortedOn" : sortOn,
                    "lastSortedOrder" : $l.isBoolean(isDescending) ?
                            isDescending :
                            this._isListSortDescending
                },
                this.prefs_id
            );
            return true;
        } else {
            YAHOO.log('Tried to sort on unsortable column.');
            return false;
        }
    }

    function getList() {
        if (this._listDirty) {
            this._buildList();
        }
        return this._list;
    }

    function getTree() {
        if (this._treeDirty) {
            this._buildTree();
        }
        return this._tree;
    }

    function getTreeNode(id) {
        var path;
        if (this._treeDirty) {
            this._buildTree();
        }
        if (this._items[id]) {
            path = (this._items[id].path + this._items[id].id);
            if (path.charAt(path.length - 1) === '/') {
                path = path.slice(0, -1);
            }
            return object(this._climbTree(path.split('/'), this._tree));
        } else if (this._items[id.toString()]) {
            path = (
                this._items[id.toString()].path +
                this._items[id.toString()].id
            );
            if (path.charAt(path.length - 1) === '/') {
                path = path.slice(0, -1);
            }
            return object(this._climbTree(path.split('/'), this._tree));
        } else if ($l.isString(id) && this._items[id.slice(8)]) {
            path = this._items[id.slice(8)].path + this._items[id.slice(8)].id;
            if (path.charAt(path.length - 1) === '/') {
                path = path.slice(0, -1);
            }
            return object(this._climbTree(path.split('/'), this._tree));
        }
    }

    function getData(id) {
        if (this._items[id]) {
            return object(this._items[id]);
        } else if (this._items[id.toString()]) {
            return object(this._items[id.toString()]);
        } else if ($l.isString(id) && this._items[id.slice(8)]) {
            return object(this._items[id.slice(8)]);
        }
    }

    function updateFromServer(callback, callback_scope, allDirty) {
        var queryString = [], searchByType, searchBy, searchByTemp, that,
            filterType;
        if (_callback) {
            throw {
                name: 'BusyError',
                message: 'An asynchronous transaction is already in progress.'
            };
        }
        _callback = callback;
        _callback_scope = callback_scope;
        _allDirty = allDirty;
        if (YAHOO.util.Cookie) {
            searchByType = YAHOO.util.Cookie.get("prefilter_type");
            if (searchByType) {
                YAHOO.util.Cookie.remove("prefilter_type");
                this._parent.prefs.setPreferences(
                    {
                        "lastSearchedByType" : "powerFilter",
                        "lastSearchedBy"     : YAHOO.util.Cookie.get(
                            "prefilter"
                        )
                    },
                    this.prefs_id
                );
                this._parent.dataView.setIsSearch(true);
                YAHOO.util.Cookie.remove("prefilter");
            }
        }
        waitStatus(true);
        if (this._parent.dataView.isSearch()) {
            searchBy = this._parent.prefs.getPreference(
                "lastSearchedBy",
                this.prefs_id
            );
            if (searchBy) {
                try {
                    searchByTemp = JSON.parse(searchBy);
                } catch (err) {
                    searchBy = JSON.stringify({"SearchableText" : searchBy});
                }
                queryString.push("searchBy=" + urllib_quote(searchBy));
            }
        }
        if (!allDirty) {
            queryString.push(
                "itemsForUpdate=" +
                    JSON.stringify(this._getItemsForUpdate())
            );
        }
        if (this._parent.dataView._isTree) {
            queryString.push(
                "sort_on=" + urllib_quote(JSON.stringify(["tree"]))
            );
        } else if (this._listSortOn) {
            queryString.push(
                "sort_on=" +
                    urllib_quote(
                        JSON.stringify([
                            this._parent.sortCols[this._listSortOn]
                        ])
                    )
            );
            queryString.push(
                "sort_ascending%3aboolean=" +
                    (this._isListSortDescending ? 'False' : 'True')
            );
            queryString.push(
                "batch_data=" +
                    urllib_quote(
                        JSON.stringify(
                            {
                                batch_start: this._batching.start,
                                batch_size:
                                    this._batching.perPageSelect *
                                    this._batching.perRowSelect
                            }
                        )
                    )
            );
        }

        queryString.push(
            "columns=" + urllib_quote(JSON.stringify(this._getDataColumns()))
        );

        that = this;
        filterType = this._parent.prefs.getPreference(
            "lastSearchedByType",
            this.prefs_id
        );
        if (this._parent.dataView.isSearch() && filterType === "powerFilter") {
            YAHOO.util.Connect.asyncRequest(
                'POST',
                [this.context_url, '/getPowerFilterForm'].join(""),
                {
                    scope: that,
                    success:
                        that._getPowerFilterSearchResultsFromServerCallback,
                    failure: AZCAT.utils.connFail
                },
                queryString.join('&')
            );
        } else {
            YAHOO.util.Connect.asyncRequest(
                'POST',
                [this.context_url, '/updateJson'].join(""),
                {
                    scope: that,
                    success: that._updateFromServerCallback,
                    failure: AZCAT.utils.connFail
                },
                queryString.join("&")
            );
        }
    }

    function updateItemsFromServer(callback, callback_scope, items_for_update) {
        if (_callback) {
            throw {
                name: 'BusyError',
                message: 'An asynchronous transaction is already in progress.'
            };
        }
        _callback = callback;
        _callback_scope = callback_scope;
        _allDirty = true;
        waitStatus(true);
        var queryString = [], searchBy, that, filterType;
        if (this._parent.dataView.isSearch()) {
            searchBy = this._parent.prefs.getPreference(
                "lastSearchedBy",
                this.prefs_id
            );
            if (searchBy) {
                queryString.push("searchBy=" + urllib_quote(searchBy));
            }
        }
        if (items_for_update) {
            queryString.push(
                "itemsForUpdate=" + JSON.stringify(items_for_update)
            );
        }
        if (this._parent.dataView._isTree) {
            queryString.push(
                "sort_on=" + urllib_quote(JSON.stringify(["tree"]))
            );
        } else if (this._listSortOn) {
            queryString.push(
                "sort_on=" +
                    urllib_quote(
                        JSON.stringify([
                            this._parent.sortCols[this._listSortOn]
                        ])
                    )
            );
            queryString.push(
                "sort_ascending%3aboolean=" +
                    (this._isListSortDescending ? 'False' : 'True')
            );
            queryString.push(
                "batch_data=" +
                    urllib_quote(
                        JSON.stringify({
                            batch_start: this._batching.start,
                            batch_size:
                                this._batching.perPageSelect *
                                this._batching.perRowSelect
                        })
                    )
            );
        }

        queryString.push(
            "columns=" + urllib_quote(JSON.stringify(this._getDataColumns()))
        );

        that = this;
        filterType = this._parent.prefs.getPreference(
            "lastSearchedByType",
            this.prefs_id
        );
        if (this._parent.dataView.isSearch() && filterType === "powerFilter") {
            YAHOO.util.Connect.asyncRequest(
                'POST',
                [this.context_url, '/getPowerFilterForm'].join(""),
                {
                    scope: that,
                    success:
                        that._getPowerFilterSearchResultsFromServerCallback,
                    failure: AZCAT.utils.connFail
                },
                queryString.join('&')
            );
        } else {
            YAHOO.util.Connect.asyncRequest(
                'POST',
                [this.context_url, '/updateJson'].join(""),
                {
                    scope: that,
                    success: that._updateFromServerCallback,
                    failure: AZCAT.utils.connFail
                },
                queryString.join("&")
            );
        }
    }

    function getSearchResultsFromServer(callback, callback_scope) {
        if (_callback) {
            throw {
                name: 'BusyError',
                message: 'An asynchronous transaction is already in progress.'
            };
        }
        _callback = callback;
        _callback_scope = callback_scope;
        _allDirty = true;
        waitStatus(true);
        this._searchResultsDirty = true;
        this._parent.dataView.setIsSearch(true);
        var queryString = [
                "searchBy=" +
                    urllib_quote(
                        this._parent.prefs.getPreference(
                            "lastSearchedBy",
                            this.prefs_id
                        )
                    )
            ],
            that;
        if (this._parent.dataView._isTree) {
            queryString.push(
                "sort_on=" + urllib_quote(JSON.stringify(["tree"]))
            );
        } else if (this._listSortOn) {
            queryString.push(
                "sort_on=" +
                    urllib_quote(
                        JSON.stringify([
                            this._parent.sortCols[this._listSortOn]
                        ])
                    )
            );
            queryString.push(
                "sort_ascending%3aboolean=" +
                    (this._isListSortDescending ? 'False' : 'True')
            );
            queryString.push(
                "batch_data=" +
                    urllib_quote(
                        JSON.stringify({
                            batch_start: this._batching.start,
                            batch_size:
                                this._batching.perPageSelect *
                                this._batching.perRowSelect
                        })
                    )
            );
        }

        queryString.push(
            "columns=" + urllib_quote(JSON.stringify(this._getDataColumns()))
        );

        that = this;
        YAHOO.util.Connect.asyncRequest(
            'POST',
            [this.context_url, '/updateJson'].join(""),
            {
                scope: that,
                success: that._getSearchResultsFromServerCallback,
                failure: AZCAT.utils.connFail
            },
            queryString.join('&')
        );
    }

    function getPowerFilterFromServer(e, myDialog) {
        var searchBy, queryString, that;
        YAHOO.util.Event.stopEvent(e);
        YAHOO.util.Connect.setForm("power_filter_form");
        searchBy = JSON.stringify(YAHOO.util.Connect._sFormData);
        YAHOO.util.Connect.resetFormState();
        queryString = [
            "searchBy=" + urllib_quote(searchBy),
            "_submit_=" + urllib_quote(JSON.stringify(1))
        ];
        this.cancelPowerFilter(e, myDialog);
        _callback = this._parent.dataView.updateDisplay;
        _callback_scope = this._parent.dataView;
        _allDirty = true;
        waitStatus(true);
        this._searchResultsDirty = true;
        this._parent.dataView.setIsSearch(true);
        if (this._parent.dataView._isTree) {
            queryString.push(
                "sort_on=" + urllib_quote(JSON.stringify(["tree"]))
            );
        } else if (this._listSortOn) {
            queryString.push(
                "sort_on=" +
                    urllib_quote(
                        JSON.stringify([
                            this._parent.sortCols[this._listSortOn]
                        ])
                    )
            );
            queryString.push(
                "sort_ascending%3aboolean=" +
                    (this._isListSortDescending ? 'False' : 'True')
            );
            queryString.push(
                "batch_data=" +
                    urllib_quote(
                        JSON.stringify({
                            batch_start: this._batching.start,
                            batch_size:
                                this._batching.perPageSelect *
                                this._batching.perRowSelect
                        })
                    )
            );
        }

        queryString.push(
            "columns=" + urllib_quote(JSON.stringify(this._getDataColumns()))
        );

        if (this._searchedFromViewType === "") {
            this._searchedFromViewType = this.getViewType();
        }

        // Disable the current tab
        this._parent.dataView._changeActiveTab(false);

        // Change the state to List for the search
        this._parent.dataView.setViewType("List");
        this._parent.prefs.setPreferences(
            {"lastSearchedBy": searchBy},
            this._parent.data.prefs_id
        );

        // Enable the new tab
        this._parent.dataView._changeActiveTab(true);

        that = this;
        YAHOO.util.Connect.asyncRequest(
            'POST',
            [this.context_url, '/getPowerFilterForm'].join(""),
            {
                scope: that,
                success: that._getPowerFilterSearchResultsFromServerCallback,
                failure: AZCAT.utils.connFail
            },
            queryString.join('&')
        );
        this._parent.dataView._displayClearButton();
    }

    function getInPowerFilterMode() {
        return this._inPowerFilterMode;
    }

    function getPowerFilterForm() {
        var that, queryString;
        waitStatus(true);
        that = this;
        queryString = [];
        if (this._parent.dataView.isSearch()) {
            // We need to load the power filter form with the
            // search terms from the previous power filter.
            queryString.push(
                "powerFilterLastSearchedBy=" +
                    urllib_quote(
                        AZCAT.siteman.prefs.getPreference(
                            "lastSearchedBy",
                            this.prefs_id
                        )
                    )
            );
        }
        YAHOO.util.Connect.asyncRequest(
            "POST",
            this.context_url + "/getPowerFilterForm",
            {
                scope: that,
                success: that._getPowerFilterFormCallback,
                failure: AZCAT.utils.connFail
            },
            queryString.join('&')
        );
    }

    function cancelPowerFilter(e, myDialog) {
        AZCAT.editForm.main.clearEnabledFields();
        AZCAT.scripts.remove("powerFilter");
        this._setInPowerFilterMode(false);
        if (myDialog.hide) {
            myDialog.hide();
        }
        myDialog = null;
    }

    function batchPrevious() {
        var batchStart =
                this._batching.start - (
                    this._batching.perPageSelect *
                    this._batching.perRowSelect
                );
        if (batchStart < 0) {
            batchStart = 0;
        }
        this._batching.start = batchStart;
    }

    function batchNext() {
        var batchStart =
                this._batching.start + (
                    this._batching.perPageSelect *
                    this._batching.perRowSelect
                ),
            results_length = this.getListLength();
        if (batchStart > results_length) {
            batchStart = results_length;
        }
        this._batching.start = batchStart;
    }

    function resetBatchStart() {
        this._batching.start = 0;
        this._parent.dataView.resetBatchStart();
    }

    function getListLength() {
        return this._full_size;
    }

    function getLastArray(data, myparent) {
        data = myparent || this._getParent(data.cmf_uid);
        if (data === null) {
            return [];
        }
        return this.getLastArray(data).concat(this.getLast(data));
    }

    function doSort(e) {
        var img = YAHOO.util.Event.getTarget(e),
            newSortOn = img.parentNode.parentNode.id;
        if (this._listSortOn === newSortOn) {
            this.sortList(this._listSortOn, !this._isListSortDescending);
        } else {
            this.sortList(newSortOn, false);
        }
        if (this._parent.dataView.isSearch()) {
            this._searchResultsDirty = true;
        }
        this.getBatchDataAndUpdateItemsFromServer(this._isSearch);
    }

    function getInfo(row, override) {
        var myparent, i, isLast, last, root_cmf_uid, root_path, level, isOpen,
            openToLevel, hasSubitems, info;
        myparent = this._getParent(row.cmf_uid);
        isLast = !myparent ? true : getLast(row, myparent);
        // need to add one to the start to fix an assumption in getLastArray
        last = myparent ? this.getLastArray(row, myparent) : [];
        root_cmf_uid = this._tree && this._tree.length && this._tree[0].cmf_uid;
        root_path = this._tree && this._tree.length && this._tree[0].path;

        if (this._parent.sitemapOpenToLevel) {
            level = 0;
            if (row.cmf_uid !== root_cmf_uid) {
                level = (row.path + row.id).match(/\//g).length;
                if (root_path !== '') {
                    level -= root_path.match(/\//g).length;
                }
            }
            if (this._parent.sitemapOpenToLevel === "all") {
                this._parent.dataView._openTo[row.cmf_uid] = true;
            } else {
                openToLevel = parseInt(this._parent.sitemapOpenToLevel, 10);
                if (level < openToLevel) {
                    this._parent.dataView._openTo[row.cmf_uid] = true;
                }
            }
            AZCAT.siteman.prefs.setPreferences(
                {"openTo": AZCAT.siteman.dataView._openTo},
                AZCAT.siteman.data.prefs_id
            );
        }
        isOpen = !!this._parent.dataView._openTo[row.cmf_uid];

        hasSubitems = row.subitems && row.subitems.length !== 0;
        info = {
            row: row,
            isLast: isLast,
            isOpen: isOpen,
            hasSubitems: hasSubitems,
            last: last,
            root_id: this.root_id,
            root_cmf_uid: root_cmf_uid,
            root_path: root_path
        };
        for (i in override) {
            if (override.hasOwnProperty(i)) {
                info[i] = override[i];
            }
        }
        return info;
    }

    function getBatchDataAndUpdateItemsFromServer(isSearch) {
        var items_for_update = {},
            x;
        for (x in this._items) {
            if (this._items.hasOwnProperty(x)) {
                items_for_update[x] = this._items[x].last_catalogued;
            }
        }
        this.updateItemsFromServer(
            this._parent.dataView.updateDisplay,
            this._parent.dataView,
            items_for_update
        );
    }

    return function (parent, root_data) {
        // My resources, this instance
        // Private varables, actual

        return {//Private varables, by convention not actually hidden
            _parent : parent,
            _items : {},
            _list : [],
            _display_order: [],
            _full_size: 0,
            _listDirty : true,
            _listSortOn : '',
            _isListSortDescending : false,
            _tree : [],
            _treeDirty : true,
            _searchResults : [],
            _searchResultsDirty : true,
            _batching : {
                start : 0,
                perPageSelect : 10,
                perRowSelect : 3
            },
            _root_actions : [],
            _allow_power_filter: root_data.allow_power_filter,
            _inPowerFilterMode: false,
            _enabled_action_requests: [],
            // Should this be in dataView instead?
            _click_action : root_data.click_action,
            //Private Methods
            _addItem : _addItem,
            _updateItem : _updateItem,
            _deleteItem : _deleteItem,
            _clearAllItems : _clearAllItems,
            _buildList : _buildList,
            _buildTree : _buildTree,
            _getItemsForUpdate : _getItemsForUpdate,
            _invalidateDataLackingColumns : _invalidateDataLackingColumns,
            _getDataColumns : _getDataColumns,
            _updateFromServerCallback : _updateFromServerCallback,
            _getSearchResultsFromServerCallback :
                _getSearchResultsFromServerCallback,
            _setInPowerFilterMode: _setInPowerFilterMode,
            _getPowerFilterSearchResultsFromServerCallback :
                _getPowerFilterSearchResultsFromServerCallback,
            _getPowerFilterFormCallback : _getPowerFilterFormCallback,
            _climbTree : _climbTree,
            _getParent : _getParent,
            _getAllActions : _getAllActions,
            _getActionIdsByCmfUid : _getActionIdsByCmfUid,
            // Public methods
            updateItems : updateItems,
            getLast : getLast,
            sortList : sortList,
            getList : getList,
            getTree : getTree,
            getTreeNode : getTreeNode,
            getData : getData,
            updateFromServer : updateFromServer,
            updateItemsFromServer : updateItemsFromServer,
            getSearchResultsFromServer : getSearchResultsFromServer,
            getInPowerFilterMode: getInPowerFilterMode,
            getPowerFilterForm : getPowerFilterForm,
            cancelPowerFilter : cancelPowerFilter,
            getPowerFilterFromServer : getPowerFilterFromServer,
            batchPrevious : batchPrevious,
            batchNext : batchNext,
            resetBatchStart : resetBatchStart,
            getListLength : getListLength,
            getLastArray : getLastArray,
            doSort : doSort,
            getInfo : getInfo,
            getBatchDataAndUpdateItemsFromServer :
                getBatchDataAndUpdateItemsFromServer,
            // Public Variables
            root_cmf_uid : root_data.cmf_uid,
            root_path : root_data.path,
            root_id : root_data.id,
            prefs_id : root_data.prefs_id,
            context_url : portal_url + root_data.path + root_data.id,
            // Public Events
            rootActionsSet : new YAHOO.util.CustomEvent("rootActionsSet", this),
            itemAdded : new YAHOO.util.CustomEvent("itemAdded", this)
        };
    };
}());




AZCAT.siteman.DataView = (function () {
    // Shared resources; ALL instances
    // Cached singletons;
    var $l = YAHOO.lang, dialogEventHandlers;

    // Shared private functions

    function _setViewType(view) {
        if ($l.isString(view) &&
                ['List', 'Tree', 'Gallery'].indexOf(view) !== -1) {
            if (this._viewType) {
                YAHOO.util.Dom.removeClass(
                    ['refresh', this._viewType, 'LI'].join(""),
                    'highlight'
                );
            }
            this._viewType = view;
            this._isTree = (view === 'Tree');
            this._isList = (view === 'List');
            this._isGallery = (view === 'Gallery');
            YAHOO.util.Dom.addClass(
                ['refresh', this._viewType, 'LI'].join(""),
                'highlight'
            );
        }
    }

    function _drawTree(json_data, tbody) {
        var row, myid, tr, x, xlen, info,
            columns = this._parent.prefs.getPreference(
                "columns",
                this._parent.data.prefs_id
            ),
            i, ilen;
        for (i = 0, ilen = json_data.length; i < ilen; i += 1) {
            row = json_data[i];
            myid = ['cmf_uid_', row.cmf_uid].join("");
            tr = document.createElement('tr');
            tr.id = myid;
            tr.style.display = "none";
            tbody.appendChild(tr);
            info = this._parent.data.getInfo(row, {isTree: this._isTree});
            for (x = 0, xlen = columns.length; x < xlen; x += 1) {
                info.td = document.createElement('td');
                info.td.id = [myid, '|||', columns[x]].join('');
                if (this._isTree) {
                    info.td.className = "tree_" + columns[x];
                } else if (this._isList) {
                    info.td.className = "list_" + columns[x];
                }
                tr.appendChild(info.td);
                this._parent.displayCode[columns[x]](info);
                info.td = null;
            }
            doIEPNGFixImgFrom(tr);

            if (info.hasSubitems) {
                if (info.isOpen) {
                    this._drawTree(row.subitems, tbody);
                }
            }
            info = null;
            tr = null;
        }
        tbody = null;
    }

    function _createBatchFooter() {
        var tfoot = document.createElement("tfoot"),
            tr = document.createElement("tr"),
            td = document.createElement("td"),
            previous_a = document.createElement("a"),
            previous_text2 = document.createTextNode("<< Previous"),
            previous_span = document.createElement("span"),
            previous_text = document.createTextNode("<< Previous"),
            results_span = document.createElement("span"),
            results_showing_text = document.createTextNode("Showing results "),
            results_min = document.createElement("span"),
            results_min_text = document.createTextNode("0"),
            results_to_text = document.createTextNode(" to "),
            results_max = document.createElement("span"),
            results_max_text = document.createTextNode("0"),
            results_of_text = document.createTextNode(" of "),
            results_total = document.createElement("span"),
            results_total_text = document.createTextNode("0"),
            next_a = document.createElement("a"),
            next_text2 = document.createTextNode("Next >>"),
            next_span = document.createElement("span"),
            next_text = document.createTextNode("Next >>");

        YAHOO.util.Dom.setStyle(tfoot, "display", "none");
        tfoot.id = 'batching_container';
        td.id = 'batching_td';
        YAHOO.util.Dom.setAttribute(td, 'colSpan', this._getColumnsLength());
        YAHOO.util.Dom.setStyle(td, "padding", "10px");
        YAHOO.util.Dom.setStyle(td, "text-align", "center");
        previous_a.id = 'previous_a';
        YAHOO.util.Dom.setStyle(previous_a, "display", "none");
        YAHOO.util.Dom.setAttribute(previous_a, 'href', '#');
        YAHOO.util.Event.addListener(
            previous_a,
            "click",
            this.batchPreviousClick,
            this,
            true
        );
        previous_span.id = 'previous_span';
        YAHOO.util.Dom.setStyle(results_span, "paddingLeft", "15px");
        YAHOO.util.Dom.setStyle(results_span, "paddingRight", "15px");
        results_min.id = 'results_min';
        results_max.id = 'results_max';
        results_total.id = 'results_total';
        next_a.id = 'next_a';
        YAHOO.util.Dom.setStyle(next_a, "display", "none");
        YAHOO.util.Dom.setAttribute(next_a, 'href', '#');
        YAHOO.util.Event.addListener(
            next_a,
            "click",
            this.batchNextClick,
            this,
            true
        );
        next_span.id = 'next_span';

        tfoot.appendChild(tr);
        tr.appendChild(td);
        td.appendChild(previous_a);
        td.appendChild(previous_span);
        td.appendChild(results_span);
        td.appendChild(next_a);
        td.appendChild(next_span);

        previous_span.appendChild(previous_text);
        previous_a.appendChild(previous_text2);
        next_span.appendChild(next_text);
        next_a.appendChild(next_text2);
        results_span.appendChild(results_showing_text);
        results_span.appendChild(results_min);
        results_span.appendChild(results_to_text);
        results_span.appendChild(results_max);
        results_span.appendChild(results_of_text);
        results_span.appendChild(results_total);
        results_min.appendChild(results_min_text);
        results_max.appendChild(results_max_text);
        results_total.appendChild(results_total_text);

        this._batching.Container = tfoot.id;
        this._batching.TD = td.id;
        this._batching.Min = results_min.id;
        this._batching.Max = results_max.id;
        this._batching.Total = results_total.id;
        this._batching.PreviousSpan = previous_span.id;
        this._batching.PreviousA = previous_a.id;
        this._batching.NextSpan = next_span.id;
        this._batching.NextA = next_a.id;

        tr = null;
        td = null;
        previous_a = null;
        previous_text2 = null;
        previous_span = null;
        previous_text = null;
        results_span = null;
        results_showing_text = null;
        results_min = null;
        results_min_text = null;
        results_to_text = null;
        results_max = null;
        results_max_text = null;
        results_of_text = null;
        results_total = null;
        results_total_text = null;
        next_a = null;
        next_text2 = null;
        next_span = null;
        next_text = null;

        return tfoot;
    }

    function _showPreviousLink() {
        YAHOO.util.Dom.setStyle(this._batching.PreviousSpan, "display", "none");
        YAHOO.util.Dom.setStyle(this._batching.PreviousA, "display", "inline");
    }

    function _hidePreviousLink() {
        YAHOO.util.Dom.setStyle(this._batching.PreviousA, "display", "none");
        YAHOO.util.Dom.setStyle(
            this._batching.PreviousSpan,
            "display",
            "inline"
        );
    }

    function _showNextLink() {
        YAHOO.util.Dom.setStyle(this._batching.NextSpan, "display", "none");
        YAHOO.util.Dom.setStyle(this._batching.NextA, "display", "inline");
    }

    function _hideNextLink() {
        YAHOO.util.Dom.setStyle(this._batching.NextA, "display", "none");
        YAHOO.util.Dom.setStyle(this._batching.NextSpan, "display", "inline");
    }

    function _updatePerPage() {
        var perPageSelect = document.getElementById("perPageSelect"), x, xlen;
        if (!YAHOO.lang.isNull(perPageSelect)) {
            for (x = 0, xlen = perPageSelect.options.length; x < xlen; x += 1) {
                if (parseInt(
                        this._parent.data._batching.perPageSelect,
                        10
                    ) === parseInt(perPageSelect.options[x].value, 10)) {
                    perPageSelect.options[x].selected = true;
                    break;
                }
            }
        }
        perPageSelect = null;
    }

    function _updatePerRow() {
        var perRowSelect = document.getElementById("perRowSelect"), x;
        if (!YAHOO.lang.isNull(perRowSelect)) {
            for (x = 0; x < perRowSelect.options.length; x += 1) {
                if (parseInt(
                        this._parent.data._batching.perRowSelect,
                        10
                    ) === parseInt(perRowSelect.options[x].value, 10)) {
                    perRowSelect.options[x].selected = true;
                    break;
                }
            }
        }
        perRowSelect = null;
    }

    function _disablePerPage() {
        var selectEl, option;
        selectEl = document.getElementById(
            AZCAT.siteman.dataView._batching.perPageSelect
        );
        if (selectEl.options.length && selectEl.options[0].value !== "") {
            option = new Option("--", "", false, false);
            selectEl.insertBefore(option, selectEl.options[0]);
            selectEl.options[0].selected = true;
            selectEl.disabled = true;
        }
    }

    function _enablePerPage() {
        var selectEl;
        selectEl = document.getElementById(
            AZCAT.siteman.dataView._batching.perPageSelect
        );
        if (selectEl.options.length && selectEl.options[0].value === "") {
            selectEl.removeChild(selectEl.options[0]);
            selectEl.disabled = false;
        }
    }

    function _updateRow(row, dirtyColumns, allColumns) {
        var rowid = ['cmf_uid_', row.cmf_uid].join(''),
            x,
            xlen,
            rowele,
            i,
            colid,
            td,
            info;
        rowele = document.getElementById(rowid);
        if (rowele) {
            info = this._parent.data.getInfo(row, {isTree: this._isTree});
            for (i in dirtyColumns) {
                if (dirtyColumns.hasOwnProperty(i)) {
                    colid = [rowid, '|||', i].join('');
                    td = document.getElementById(colid);
                    if (td) {
                        YAHOO.util.Dom.batch(
                            YAHOO.util.Dom.getChildren(td),
                            recursivePurgeAndRemove
                        );
                        td.innerHTML = '';
                        info.td = td;
                        if (this._isTree) {
                            info.td.className = "tree_" + i;
                        } else if (this._isList) {
                            info.td.className = "list_" + i;
                        }
                        this._parent.displayCode[i](info);
                        info.td = null;
                        td = null;
                    }
                }
            }
        } else {
            rowele = document.createElement('tr');
            rowele.id = rowid;
            info = this._parent.data.getInfo(row, {isTree: this._isTree});
            for (x = 0, xlen = allColumns.length; x < xlen; x += 1) {
                td = document.createElement('td');
                rowele.appendChild(td);
                td.id = [rowid, '|||', allColumns[x]].join("");
                info.td = td;
                if (this._isTree) {
                    info.td.className = "tree_" + allColumns[x];
                } else if (this._isList) {
                    info.td.className = "list_" + allColumns[x];
                }
                this._parent.displayCode[allColumns[x]](info);
                info.td = null;
                td = null;
            }
        }
        info = null;
        doIEPNGFixImgFrom(rowele);
        return rowele;
    }

    function _recursiveOpenStateUpdate(items, myparent, isInsert) {
        var item, i, ilen;
        for (i = 0, ilen = items.length; i < ilen; i += 1) {
            item = document.getElementById(
                ['cmf_uid_', items[i].cmf_uid].join('')
            );
            if (isInsert && !item) {
                this.addWasInserted(items[i].cmf_uid);
            }
            if (!isInsert && item) {
                this.addWasRemoved(items[i].cmf_uid, myparent);
            }
            if (items[i].subitems && items[i].subitems.length) {
                if (this._openTo[items[i].cmf_uid] && isInsert) {
                    this._recursiveOpenStateUpdate(
                        items[i].subitems,
                        items[i],
                        true
                    );
                } else {
                    this._recursiveOpenStateUpdate(
                        items[i].subitems,
                        items[i],
                        false
                    );
                }
            }
        }
        item = null;
    }

    function _grabLastSubitem(items) {
        if (items[items.length - 1].subitems &&
                items[items.length - 1].subitems.length > 0 &&
                this._openTo[items[items.length - 1].cmf_uid]) {
            return this._grabLastSubitem(items[items.length - 1].subitems);
        } else {
            return items[items.length - 1];
        }
    }

    function _sortLevel(item) {
        var itemEle = document.getElementById(
                ['cmf_uid_', item.cmf_uid].join('')
            ),
            moveEle,
            x,
            xlen;
        if (itemEle) {
            for (x = 0, xlen = item.subitems.length - 1; x <= xlen; xlen -= 1) {
                moveEle = document.getElementById(
                    ['cmf_uid_', item.subitems[xlen].cmf_uid].join('')
                );
                if (moveEle) {
                    itemEle.parentNode.insertBefore(
                        moveEle,
                        itemEle.nextSibling
                    );
                    this.addDirtyData(item.subitems[xlen].cmf_uid, ['title']);
                    if (item.subitems[xlen].subitems &&
                            item.subitems[xlen].subitems.length) {
                        this._sortLevel(item.subitems[xlen]);
                    }
                }
            }
        }
        itemEle = null;
        moveEle = null;
    }

    function _updateColumns(row, order) {
        var i, ilen, colid, td, x, xlen, info, temp = [],
            rowid = ['cmf_uid_', row.cmf_uid].join(''),
            tr = document.getElementById(rowid);
        if (tr) {
            info = this._parent.data.getInfo(row, {isTree: this._isTree});
            for (i = 0, ilen = order.length; i < ilen; i += 1) {
                colid = [rowid, '|||', order[i]].join('');
                td = document.getElementById(colid);
                if (!td) {
                    td = document.createElement('td');
                    td.id = colid;
                    if (this._isTree) {
                        td.className = "tree_" + order[i];
                    } else if (this._isList) {
                        td.className = "list_" + order[i];
                    }
                    info.td = td;
                    if (this._parent.displayCode[order[i]]) {
                        this._parent.displayCode[order[i]](info);
                    }
                    info.td = null;
                }
                temp.push(td.cloneNode(true));
            }
            YAHOO.util.Dom.batch(
                YAHOO.util.Dom.getChildren(tr),
                recursivePurgeAndRemove
            );
            for (i = 0, ilen = temp.length; i < ilen; i += 1) {
                tr.appendChild(temp[i]);
            }
            doIEPNGFixImgFrom(tr);
            temp = null;
            if (row.subitems && row.subitems.length) {
                for (x = 0, xlen = row.subitems.length; x < xlen; x += 1) {
                    this._updateColumns(row.subitems[x], order);
                }
            }
        }
        tr = null;
        td = null;
        info = null;
    }

    function _refreshColumnHeaders(containing_element) {
        var i, ilen, header_list, thisHeader, listeners, listener, listenerlen,
            addListener;
        if ($l.isUndefined(containing_element)) {
            containing_element = document.getElementById(
                "site_manager_thead"
            ).firstChild;
        }
        header_list = containing_element.getElementsByTagName('TH');
        for (i = 0, ilen = header_list.length; i < ilen; i += 1) {
            thisHeader = header_list[i];
            if (i % 2 === 1) {
                thisHeader.className = 'odd';
            } else {
                thisHeader.className = 'even';
            }
            if (this._parent.columnInfo[thisHeader.id].column_header_onclick) {
                addListener = true;
                listeners = YAHOO.util.Event.getListeners(thisHeader, "click");
                if (listeners) {
                    for (listener = 0, listenerlen = listeners.length;
                            listener > listenerlen;
                            listener += 1) {
                        if (
                            listeners[listener].fn ===
                                this._parent.columnInfo[
                                    thisHeader.id
                                ].column_header_onclick
                        ) {
                            addListener = false;
                            break;
                        }
                    }
                }
                if (!addListener || !listeners) {
                    YAHOO.util.Event.on(
                        thisHeader,
                        "click",
                        this._parent.columnInfo[
                            thisHeader.id
                        ].column_header_onclick
                    );
                }
            }
        }
        header_list = null;
        containing_element = null;
        thisHeader = null;
    }

    function _getPerPageSelect() {
        return document.getElementById(
            "perPageSelect"
        ).options[document.getElementById("perPageSelect").selectedIndex].value;
    }

    function _getPerRowSelect() {
        return document.getElementById(
            "perRowSelect"
        ).options[document.getElementById("perRowSelect").selectedIndex].value;
    }

    function _updateBatchDisplay() {
        var display_to_use = YAHOO.env.supports_inline_block ?
                    "inline-block" :
                    "inline",
            td,
            results_length,
            batchStart,
            batchSize;
        if (this._batching.TD) {
            td = document.getElementById(this._batching.TD);
            YAHOO.util.Dom.setAttribute(
                td,
                'colSpan',
                this._getColumnsLength()
            );

            results_length = this._parent.data.getListLength();
            batchStart = this._parent.data._batching.start;
            batchSize =
                this._parent.data._batching.perPageSelect *
                this._parent.data._batching.perRowSelect;
            if (batchStart) {
                this._showPreviousLink();
            } else {
                this._hidePreviousLink();
            }
            document.getElementById(this._batching.Min).innerHTML = Math.min(
                batchStart + 1,
                results_length
            );

            if ((batchStart + batchSize) >= results_length) {
                this._hideNextLink();
                document.getElementById(this._batching.Max).innerHTML =
                    results_length;
            } else {
                this._showNextLink();
                document.getElementById(this._batching.Max).innerHTML = (
                    batchStart + batchSize
                );
            }

            document.getElementById(this._batching.Total).innerHTML =
                results_length;

            // TODO: Needs to be tested in IE6 to see if Yahoo is handling
            // conversion to block
            YAHOO.util.Dom.setStyle(
                this._batching.Container,
                "display",
                "table-footer-group"
            );
            YAHOO.util.Dom.setStyle("perPage", "display", display_to_use);
            if (this._isGallery) {
                YAHOO.util.Dom.setStyle("perRow", "display", display_to_use);
            } else {
                YAHOO.util.Dom.setStyle("perRow", "display", "none");
            }
        }
    }

    function _resetBatchSize() {
        this._updatePerPage();
        this._updatePerRow();
        this._updateBatchDisplay(true);
    }

    function _getColumnsLength() {
        if (this._isGallery) {
            return this._parent.data._batching.perRowSelect;
        } else {
            return this._parent.prefs.getPreference(
                "columns",
                this._parent.data.prefs_id
            ).length;
        }
    }

    function _isBlock(el) {
        return (YAHOO.util.Dom.getStyle(el, 'display') === 'block');
    }

    function _makeInline(el) {
        YAHOO.util.Dom.setStyle(el, 'display', 'inline');
    }

    function _clearControlButtons() {
        var i, current_button_data_len = this._controlButtons.length,
            divs_to_delete = ["filter", "perPage", "perRow"],
            divs_len = divs_to_delete.length, thisDiv,
            divContainer = document.getElementById(
                "siteman_control_buttons__" + this._parent.data.prefs_id
            );
        for (i = 0; i < current_button_data_len; i += 1) {
            this._controlButtons[i].destroy();
        }

        for (i = 0; i < divs_len; i += 1) {
            thisDiv = document.getElementById(divs_to_delete[i]);
            if (thisDiv !== null) {
                divContainer.removeChild(thisDiv);
            }
        }
    }

    function _createControlButtons() {
        var button_data, thisButtonData, i,
            column_list = AZCAT.siteman.columns[
                isFCKEditorBrowse ?
                        'FCKEditor' :
                        'site_manager'
            ][this._parent.data.prefs_id],
            new_button_span, new_button_data_len,
            divContainer = document.getElementById(
                "siteman_control_buttons__" + this._parent.data.prefs_id
            ),
            autoComplete, content, contentDiv,
            searchBy, searchByValue,
            display_to_use = YAHOO.env.supports_inline_block ?
                    "inline-block" :
                    "inline",
            option, selectEl, selectValues, text, z, zLen,
            elsWithDivs = ['filter', 'perPage', 'perRow'],
            newButton,
            setStyle = YAHOO.util.Dom.setStyle, showPerRow, showPerPage,
            filterContainer, filterMenuItemClick, filterType,
            filterButtonCfg, filterButton, clearContainer, clearButton,
            that = this,
            value;

        this._clearControlButtons();

        /* Some pages, such as sitemap, do not allow the user to specify which
           columns and views to use. Therefore, we do not create those buttons
           */
        if (divContainer && !$l.isUndefined(column_list)) {
            button_data = [
                {
                    label: 'Tree View',
                    id:                 'refreshTreeLI',
                    column_info_branch: 'Tree',
                    fn :                this.treeViewClick,
                    icon :              '/application_side_tree_list_view.png',
                    selected:           this._isTree
                }, {
                    label: 'List View',
                    id:                 'refreshListLI',
                    column_info_branch: 'List',
                    fn :                this.listViewClick,
                    icon :              '/application_view_columns.png',
                    selected:           this._isList
                }, {
                    label: 'Gallery View',
                    id:                 'refreshGalleryLI',
                    column_info_branch: 'Gallery',
                    fn :                this.galleryViewClick,
                    icon :              '/application_view_tile.png',
                    selected:           this._isGallery
                }
            ];
            new_button_data_len = button_data.length;
            for (i = 0; i < new_button_data_len; i += 1) {
                thisButtonData = button_data[i];
                if (!$l.isUndefined(
                        column_list[thisButtonData.column_info_branch]
                    )) {
                    new_button_span = document.createElement('span');
                    divContainer.appendChild(new_button_span);
                    newButton = new YAHOO.widget.Button({
                        id: thisButtonData.id,
                        type: "button",
                        label: thisButtonData.label,
                        srcelement: new_button_span,
                        onclick: {
                            "fn"    : thisButtonData.fn,
                            "scope" : this
                        }
                    });
                    if (thisButtonData.selected) {
                        newButton.addClass('default');
                    }
                    if (!$l.isUndefined(thisButtonData.icon)) {
                        setStyle(
                            newButton._button.parentNode,
                            'background',
                            [
                                'url(',
                                thisButtonData.icon,
                                ') no-repeat 4px 50%'
                            ].join('')
                        );
                        setStyle(newButton._button, 'paddingLeft', '24px');
                    }
                    this._controlButtons.push(newButton);
                }
            }
            new_button_span = document.createElement('span');
            divContainer.appendChild(new_button_span);
            newButton = new YAHOO.widget.Button({
                type: "button",
                id: "columnsButton",
                label: "Columns",
                srcelement: new_button_span,
                onclick: {
                    "fn" : prefsClick,
                    "obj": {prefs_id: this._parent.data.prefs_id}
                }
            });
            this._controlButtons.push(newButton);
            setStyle(
                newButton._button.parentNode,
                'background',
                'url(/table_edit.png) no-repeat 4px 50%'
            );
            setStyle(newButton._button, 'paddingLeft', '24px');
        }

        if (divContainer !== null) {
            showPerPage = this._isList || this._isGallery;
            contentDiv = document.createElement("DIV");
            divContainer.appendChild(contentDiv);
            this._batching.perPage = contentDiv.id = "perPage";
            setStyle(
                contentDiv,
                "display",
                showPerPage ? display_to_use : "none"
            );
            setStyle(contentDiv, "float", "none");
            content = document.createElement("div");
            contentDiv.appendChild(content);
            selectEl = document.createElement("select");
            content.appendChild(selectEl);
            this._batching.perPageSelect = selectEl.id = "perPageSelect";
            YAHOO.util.Event.on(
                selectEl,
                "change",
                this.perPageClick,
                this,
                true
            );
            selectValues = [5, 10, 15, 25, 50];
            for (z = 0, zLen = selectValues.length; z < zLen; z += 1) {
                option = new Option(
                    selectValues[z],
                    selectValues[z],
                    false,
                    false
                );
                selectEl.options[selectEl.length] = option;
            }
            text = document.createTextNode("Rows Per Page");
            content.appendChild(text);
            if (showPerPage) {
                this._updatePerPage();
            }

            showPerRow = this._isGallery;
            contentDiv = document.createElement("DIV");
            divContainer.appendChild(contentDiv);
            this._batching.perRow = contentDiv.id = "perRow";
            setStyle(
                contentDiv,
                "display",
                showPerRow ? display_to_use : "none"
            );
            setStyle(contentDiv, "float", "none");
            content = document.createElement("div");
            contentDiv.appendChild(content);
            selectEl = document.createElement("select");
            content.appendChild(selectEl);
            this._batching.perRowSelect = selectEl.id = "perRowSelect";
            YAHOO.util.Event.on(
                selectEl,
                "change",
                this.perRowClick,
                this,
                true
            );
            selectValues = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
            for (z = 0, zLen = selectValues.length; z < zLen; z += 1) {
                option = new Option(
                    selectValues[z],
                    selectValues[z],
                    false,
                    false
                );
                selectEl.options[selectEl.length] = option;
            }
            text = document.createTextNode("Items Per Row");
            content.appendChild(text);
            if (showPerRow) {
                this._updatePerRow();
            }

            contentDiv = document.createElement("DIV");
            divContainer.appendChild(contentDiv);
            setStyle(contentDiv, "display", display_to_use);
            contentDiv.id = "filter";
            content = document.createElement("div");
            contentDiv.appendChild(content);
            searchBy = document.createElement("input");
            YAHOO.util.Dom.setAttribute(searchBy, 'type', 'text');
            value = document.createAttribute("value");
            content.appendChild(searchBy);
            searchBy.id = "search_by";
            filterType = this._parent.prefs.getPreference(
                "lastSearchedByType",
                this._parent.data.prefs_id
            );
            if (this._isSearch) {
                searchByValue = this._parent.prefs.getPreference(
                    "lastSearchedBy",
                    this._parent.data.prefs_id
                );
                if (searchByValue) {
                    searchByValue = JSON.parse(searchByValue);
                    if (searchByValue.SearchableText) {
                        searchBy.value = searchByValue.SearchableText;
                    }
                }
            }
            filterContainer = document.createElement("SPAN");
            content.appendChild(filterContainer);
            filterMenuItemClick = function (p_sType, p_aArgs, p_oItem) {
                var title, doClearFilter, searchBy;
                title = p_oItem.cfg.getProperty("text");
                doClearFilter = filterButton.get("label") !== title;
                filterButton.set("label", title);
                searchBy = document.getElementById("search_by");
                // Does not exist on the inital setup
                if (this._parent) {
                    this._parent.prefs.setPreferences(
                        {
                            "lastSearchedByType": (title === "Filter") ?
                                    "filter" :
                                    "powerFilter"
                        },
                        this._parent.data.prefs_id
                    );
                    this._parent.prefs.savePreferences();
                }
                if (doClearFilter) {
                    this._clearFilterAndRefreshList();
                }
                if (title === "Power Filter") {
                    // Does not exist on the inital setup
                    if (this._doSearch) {
                        this._doSearch(null, filterButton);
                    }
                    YAHOO.util.Dom.addClass(searchBy, "disabled");
                    searchBy.value = "-disabled-";
                    searchBy.disabled = true;
                } else {
                    searchBy.disabled = false;
                    searchBy.value = "";
                    YAHOO.util.Dom.removeClass(searchBy, "disabled");
                }
            };
            filterButtonCfg = {
                "type"      : "push",
                "label"     : (filterType === "filter") ?
                        "Filter" :
                        "Power Filter",
                "id"        : "filterButton",
                "name"      : "filterButton",
                "container" : filterContainer
            };
            if (this._parent.data._allow_power_filter) {
                filterButtonCfg.menu = [
                    {
                        "text"    : "Filter",
                        "value"   : "filter",
                        "onclick" : {
                            "fn"    : filterMenuItemClick,
                            "scope" : that
                        }
                    }, {
                        "text"    : "Power Filter",
                        "value"   : "powerFilter",
                        "onclick" : {
                            "fn"    : filterMenuItemClick,
                            "scope" : that
                        }
                    }
                ];
                filterButtonCfg.type = "split";
            }
            filterButton = new YAHOO.widget.Button(filterButtonCfg);
            if (this._parent.data._allow_power_filter) {
                // filterButton.getMenu().getItems() returns undefined if the 
                // menu items are not yet created
                filterButton.getMenu().show();
                filterButton.getMenu().hide();
                filterMenuItemClick(
                    null,
                    null,
                    filterButton.getMenu().getItems()[
                        (filterType === "filter") ? 0 : 1
                    ]
                );
            }
            filterButton.on("click", this._doSearch, filterButton, that);
            clearContainer = document.createElement("SPAN");
            content.appendChild(clearContainer);
            clearButton = new YAHOO.widget.Button({
                "type"      : "push",
                "label"     : "Show All",
                "id"        : "showAll",
                "name"      : "showAll",
                "onclick"   : {
                    "fn"    : this._clearFilterAndRefreshList,
                    "scope" : that
                },
                "container" : clearContainer
            });
            setStyle(
                clearContainer,
                "display",
                this._isSearch ? display_to_use : "none"
            );
            autoComplete = document.createElement("div");
            content.appendChild(autoComplete);
            autoComplete.id = "search_by_auto_complete";
            createAutoComplete({
                "dataURL" : [
                    this._parent.data.context_url,
                    "/getAutoCompleteText"
                ].join(""),
                "dataStructure" : {resultsList: "ws", fields: ["w"]},
                "searchFieldID" : "search_by",
                "autoCompleteDivID" : "search_by_auto_complete",
                "searchFunc" : {fn: this._doSearch, scope: that}
            });

            if (!YAHOO.env.supports_inline_block) {
                for (i = 0; i < elsWithDivs.length; i += 1) {
                    YAHOO.util.Dom.getElementsBy(
                        _isBlock,
                        'DIV',
                        document.getElementById(elsWithDivs[i]),
                        _makeInline
                    );
                }
            }
        }
    }

    function __sortTitle(x, y) {
        if (x.title > y.title) {
            return 1;
        } else if (x.title < y.title) {
            return -1;
        } else {
            return 0;
        }
    }


    function _createActionsSidebar() {
        var allActions, allActionIds = [], thisAction, id, i, iLen, action_data,
            that = this;
        if (!this._suppress_sidebar && this._parent.sidebar) {
            this._parent.sidebar.removeAllActions(true);
            allActions = this._parent.data._getAllActions();
            for (id in allActions) {
                if (allActions.hasOwnProperty(id)) {
                    allActionIds.push({id: id, title: allActions[id].title});
                }
            }
            allActionIds.sort(__sortTitle);
            // this._parent.sidebar.render();
            for (i = 0, iLen = allActionIds.length; i < iLen; i += 1) {
                thisAction = allActions[allActionIds[i].id];
                action_data = {
                    id: allActionIds[i].id,
                    label: thisAction.title,
                    icon: thisAction.icon,
                    onclick: {
                        fn: this._handleSidebarButtonClick,
                        obj: allActionIds[i].id,
                        scope: that
                    }
                };
                this._parent.sidebar.addAction(action_data);
            }
            this._updateActiveSidebarActions();
            this._parent.sidebar.render();
        }
    }

    function _getSelectedCMFUids() {
        var i, thisItem, thisTD, thisCheckbox, checkedIds = [];
        for (i in this._parent.data._items) {
            if (this._parent.data._items.hasOwnProperty(i)) {
                thisItem = this._parent.data._items[i];
                thisTD = document.getElementById(
                    [
                        'cmf_uid_',
                        thisItem.cmf_uid,
                        '|||getMultiSelectCheckboxes'
                    ].join('')
                );
                if (thisTD) {
                    thisCheckbox = thisTD.getElementsByTagName('INPUT')[0];
                    if (thisCheckbox && thisCheckbox.checked) {
                        checkedIds.push(thisItem.cmf_uid);
                    }
                }
            }
        }
        return checkedIds;
    }

    function _updateActiveSidebarActions() {
        var selected_cmf_uids = this._getSelectedCMFUids();
        this._parent.sidebar.enableOverlay();
        this._parent.data._getActionIdsByCmfUid(
            selected_cmf_uids,
            this._setActiveSidebarButtons,
            this
        );
    }

    function _setActiveSidebarButtons(active_action_ids) {
        var data = this._parent.data,
            all_actions = data._getAllActions(),
            thisActionId,
            thisActionEnabled,
            x,
            xLen,
            selected_cmf_uids = this._getSelectedCMFUids(),
            j,
            jLen = selected_cmf_uids.length,
            k,
            kLen,
            thisObjActions,
            thisObjHasPaste;
        this._parent.sidebar.disableOverlay();
        if (active_action_ids) {
            xLen = active_action_ids.length;
        } else {
            return;
        }
        if (!selected_cmf_uids.length) {
            selected_cmf_uids = [data.root_cmf_uid];
            jLen = 1;
        }
        for (thisActionId in all_actions) {
            if (all_actions.hasOwnProperty(thisActionId)) {
                thisActionEnabled = false;
                if (thisActionId === 'pastehere') {
                    // Hard-coded HACK for Paste Here button
                    thisActionEnabled =
                        clipboard.items.length > 0 &&
                        selected_cmf_uids.length === 1;
                    if (thisActionEnabled) {
                        for (j = 0; j < jLen; j += 1) {
                            if (data._items.hasOwnProperty(
                                    selected_cmf_uids[j]
                                )) {
                                thisObjActions =
                                    data._items[selected_cmf_uids[j]].actions;
                            } else if (
                                selected_cmf_uids[j] === data.root_cmf_uid
                            ) {
                                thisObjActions = data._root_actions;
                            } else {
                                // It should never get here.
                                continue;
                            }
                            thisObjHasPaste = false;
                            for (k = 0, kLen = thisObjActions.length;
                                    k < kLen;
                                    k += 1) {
                                if (thisObjActions[k].id === 'pastehere') {
                                    thisObjHasPaste = true;
                                    break;
                                }
                            }
                            if (!thisObjHasPaste) {
                                thisActionEnabled = false;
                                break;
                            }
                        }
                    }
                } else {
                    for (x = 0; x < xLen; x += 1) {
                        if (thisActionId === active_action_ids[x]) {
                            thisActionEnabled = true;
                            break;
                        }
                    }
                }
                if (thisActionEnabled) {
                    this._parent.sidebar.enableAction(thisActionId);
                } else {
                    this._parent.sidebar.disableAction(thisActionId);
                }
            }
        }
    }

    function _handleSidebarButtonClick(e, action_id) {
        var selected_cmf_uids = this._getSelectedCMFUids(), i, iLen, x, xLen,
            thisAction, this_action_onclick, effective_ids, effective_id,
            hrefs, item_to_use, item_actions, item_url, is_onclick_action;
        if (!selected_cmf_uids.length) {
            selected_cmf_uids = [this._parent.data.root_cmf_uid];
        }
        if (selected_cmf_uids.length !== 1 &&
                AZCAT.powerEdit.actionCode[action_id]) {
            AZCAT.powerEdit.dialog.init(
                action_id,
                selected_cmf_uids,
                {
                    event_handlers: this.dialogEventHandlers,
                    callback_scope: this
                }
            );
        } else {
            effective_ids = [];
            hrefs = [];
            is_onclick_action = false;
            for (x = 0, xLen = selected_cmf_uids.length; x < xLen; x += 1) {
                item_to_use = this._parent.data._items[selected_cmf_uids[x]];
                if ($l.isUndefined(item_to_use) &&
                        selected_cmf_uids[x] ===
                            this._parent.data.root_cmf_uid) {
                    item_actions = this._parent.data._root_actions;
                    item_url =
                        this._parent.data.root_path +
                        this._parent.data.root_id;
                } else {
                    item_actions = item_to_use.actions;
                    item_url = item_to_use.path + item_to_use.id;
                }
                for (i = 0, iLen = item_actions.length; i < iLen; i += 1) {
                    thisAction = item_actions[i];
                    if (thisAction.id === action_id) {
                        YAHOO.util.Event.stopEvent(e);
                        if (item_url === '/') {
                            effective_id = '';
                        } else {
                            effective_id = item_url;
                        }
                        if (thisAction.onclick) {
                            is_onclick_action = true;
                            effective_ids.push(effective_id);
                            this_action_onclick =
                                AZCAT.dialog.actionCode[thisAction.id];
                        } else if (thisAction.href.match(/^https?:\/\//)) {
                            hrefs.push(thisAction.href);
                        } else if (thisAction.href) {
                            hrefs.push(
                                portal_url + effective_id + thisAction.href
                            );
                        }
                        break;
                    }
                }
            }
            if (is_onclick_action) {
                this_action_onclick(
                    e,
                    {
                        ids: effective_ids,
                        event_handlers: this.dialogEventHandlers,
                        callback_scope: this,
                        cmf_uids: selected_cmf_uids
                    }
                );
            } else {
                if (hrefs.length > 1) {
                    AZCAT.utils.reportError(
                        [
                            action_id,
                            " requested on multiple objects (",
                            selected_cmf_uids.join(", "),
                            ").  Hrefs: \"",
                            hrefs.join("\", \""),
                            "\"."
                        ].join("")
                    );
                    alert(
                        [
                            "You are not able to ",
                            action_id,
                            " multiple items.  Please select only one and ",
                            "try again."
                        ].join("")
                    );
                } else {
                    document.location.href = hrefs[0];
                }
            }
            // Prevent YUI default button handler:
            return false;
        }
    }

    /*
        -*********-
        |CopyPaste|
        -*********-
        + These are methods relating to the copy paste functionality.

    */


    /*
        -+++++++++++++-
        |pasteCallback|
        -+++++++++++++-
        + This is the callback function of pasteHere
    */

    function _pasteCallback(o) {
        AZCAT.nav.updateTabs();
        this._parent.data.updateFromServer(this.updateDisplay, this);
    }

    /*
        -+++++++++++++++++-
        |removePasteAction|
        -+++++++++++++++++-
        + This removes the 'Paste Here' action as the default action into
    */
    function _removePasteAction() {
        var list = this._parent.data.getList(),
            paste_here = "Paste Here",
            row,
            actions,
            i,
            ilen;
        for (i = 0, ilen = list.length; i < ilen; i += 1) {
            row = list[i];
            if (row.is_folderish) {
                actions = row.actions;
                if (actions[0].title === paste_here) {
                    actions.shift();
                    this._parent.data._updateItem(
                        row.cmf_uid,
                        {actions: actions}
                    );
                }
            }
        }
        this.updateDisplay();
    }

    /*
        -+++++++++++++++++-
        |insertPasteAction|
        -+++++++++++++++++-
        + This inserts the 'Paste Here' action as the default action into
    */
    function _insertCallback(o) {
        var list = this._parent.data.getList(), paste_here = "Paste Here", row,
            actions, myDialog, allowed = JSON.parse(o.responseText), i, ilen,
            objects_to_modify = [], foundRoot = false,
            root_cmf_uid = this._parent.data.root_cmf_uid, root_actions;
        if (allowed.length) {
            for (i = 0, ilen = list.length; i < ilen; i += 1) {
                row = list[i];
                if (row.is_folderish) {
                    if (allowed.indexOf(parseInt(row.cmf_uid, 10)) !== -1) {
                        if (row.actions[0].title !== paste_here) {
                            objects_to_modify.push(row);
                            // getList doesn't return the root in List View for
                            // Collections, so we need to check if we have found
                            // the root and modify it manually if not
                            if (row.cmf_uid === root_cmf_uid) {
                                foundRoot = true;
                            }
                        }
                    }
                }
            }
            for (i = 0, ilen = objects_to_modify.length; i < ilen; i += 1) {
                row = objects_to_modify[i];
                actions = row.actions;
                actions.unshift({
                    'id': 'pastehere',
                    'icon': '/folder_page.png',
                    'href': '',
                    'onclick':
                        'javascript:AZCAT.siteman.dataView.pasteHere(event);',
                    'title': paste_here
                });
                this._parent.data._updateItem(row.cmf_uid, {actions: actions});
            }

            if (!foundRoot &&
                    allowed.indexOf(root_cmf_uid) !== -1) {
                root_actions = this._parent.data._root_actions;
                if (root_actions[0].title !== paste_here) {
                    root_actions.unshift({
                        'id': 'pastehere',
                        'icon': '/folder_page.png',
                        'href': '',
                        'onclick':
                            'javascript:' +
                            'AZCAT.siteman.dataView.pasteHere(event);',
                        'title': paste_here
                    });
                }
            }
            this.updateDisplay();
        } else {
            myDialog = new AZCAT.Dialog();
            myDialog.setHeader(
                [
                    myDialog.headerleft,
                    "Cut / Copy",
                    myDialog.headerright
                ].join("")
            );
            myDialog.setBody(
                'The item or combination of items you have selected do not ' +
                    'have a valid place to be pasted.  Please select a ' +
                    'different item or combination of items.'
            );
            myDialog.setFooter(
                [myDialog.footerleft, myDialog.footerright].join("")
            );
            myDialog.render(document.body);
            myDialog.show();
        }
    }

    function _toggleItemSelection(origin, automate_checkbox,
                                  ignoreSidebarActions) {
        var item_container, isUnselecting, isSelectCheckbox, theCheckbox,
            selectAllCheckbox, tbody, inputs, allChecked, x, xLen, allOpen, tr,
            cmf_uid, imgs, y, yLen, src;
        if (this._isGallery) {
            item_container = YAHOO.util.Dom.getAncestorByTagName(origin, 'TD');
        } else {
            item_container = YAHOO.util.Dom.getAncestorByTagName(origin, 'TR');
        }
        /* Unfortunately, origin.checked may or may not have been updated yet,
           depending on timing. Therefore, we have to rely on the class
           instead. */
        isUnselecting = YAHOO.util.Dom.hasClass(item_container, 'selected');
        if (isUnselecting) {
            YAHOO.util.Dom.removeClass(item_container, 'selected');
        } else {
            YAHOO.util.Dom.addClass(item_container, 'selected');
        }

        if (automate_checkbox) {
            isSelectCheckbox = function (el) {
                if (el.name === 'copy_pasta_checkbox') {
                    return true;
                }
            };
            theCheckbox = YAHOO.util.Dom.getElementsBy(
                isSelectCheckbox,
                null,
                item_container
            );
            if (theCheckbox.length) {
                theCheckbox = theCheckbox[0];
            } else {
                return;
            }
            theCheckbox.checked = !isUnselecting;
        }
        if (!this._isGallery) {
            selectAllCheckbox = document.getElementById("headers_select_all");
            if (isUnselecting) {
                selectAllCheckbox.checked = !isUnselecting;
                if (this._isList) {
                    this._enablePerPage();
                    this._updatePerPage();
                }
            } else if (
                this._isList &&
                    (
                        AZCAT.siteman.data._batching.perPageSelect *
                        AZCAT.siteman.data._batching.perRowSelect
                    ) >= AZCAT.siteman.data.getListLength()
            ) {
                // If all items are selected, the select all box should be
                // checked as well.
                tbody = document.getElementById("site_manager_tbody");
                inputs = tbody.getElementsByTagName("input");
                allChecked = true;
                for (x = 0, xLen = inputs.length; x < xLen; x += 1) {
                    if (inputs[x].name === "copy_pasta_checkbox" &&
                            !inputs[x].checked) {
                        allChecked = false;
                    }
                }
                if (allChecked) {
                    selectAllCheckbox.checked = true;
                    this._disablePerPage();
                }
            }
            if (this._isTree) {
                if (isUnselecting) {
                    tbody = document.getElementById("site_manager_tbody");
                    inputs = tbody.getElementsByTagName("input");
                    for (x = 0, xLen = inputs.length; x < xLen; x += 1) {
                        if (inputs[x].name === "copy_pasta_checkbox") {
                            tr = YAHOO.util.Dom.getAncestorByTagName(
                                inputs[x],
                                "tr"
                            );
                            cmf_uid = tr.id.split("_");
                            cmf_uid = cmf_uid[cmf_uid.length - 1];
                            if (AZCAT.siteman.data.getTreeNode(
                                    cmf_uid
                                ).subitems.length) {
                                imgs = tr.getElementsByTagName("img");
                                for (y = 0, yLen = imgs.length;
                                        y < yLen;
                                        y += 1) {
                                    src = imgs[y].src.replace(portal_url, "");
                                    if (src === "/tree/tn.gif") {
                                        imgs[y].src = "/tree/tm.gif";
                                        imgs[y].className = "clickme";
                                    } else if (src === "/tree/ln.gif") {
                                        imgs[y].src = "/tree/lm.gif";
                                        imgs[y].className = "clickme";
                                    }
                                }
                            }
                        }
                    }
                    // If all were not open when we unselect in treeview the
                    // objects that were not open will not toggle properly
                    // because they are not in the openTo preference.  So we
                    // need to make sure they are there.
                    AZCAT.siteman.prefs.setPreferences(
                        {"openTo": AZCAT.siteman.dataView._openTo},
                        AZCAT.siteman.data.prefs_id
                    );
                } else {
                    // If all items are selected, the select all box should be
                    // checked as well. Must check that everything is open as
                    // well.
                    tbody = document.getElementById("site_manager_tbody");
                    inputs = tbody.getElementsByTagName("input");
                    allChecked = true;
                    allOpen = true;
                    for (x = 0, xLen = inputs.length; x < xLen; x += 1) {
                        if (inputs[x].name === "copy_pasta_checkbox") {
                            if (!inputs[x].checked) {
                                allChecked = false;
                            }
                            tr = YAHOO.util.Dom.getAncestorByTagName(
                                inputs[x],
                                "tr"
                            );
                            cmf_uid = tr.id.split("_");
                            cmf_uid = cmf_uid[cmf_uid.length - 1];
                            if (AZCAT.siteman.data.getTreeNode(
                                    cmf_uid
                                ).subitems.length &&
                                    !AZCAT.siteman.dataView._openTo[cmf_uid]) {
                                allOpen = false;
                            }
                        }
                    }
                    if (allChecked && allOpen) {
                        selectAllCheckbox.checked = true;
                        for (x = 0, xLen = inputs.length; x < xLen; x += 1) {
                            if (inputs[x].name === "copy_pasta_checkbox") {
                                tr = YAHOO.util.Dom.getAncestorByTagName(
                                    inputs[x],
                                    "tr"
                                );
                                cmf_uid = tr.id.split("_");
                                cmf_uid = cmf_uid[cmf_uid.length - 1];
                                if (
                                    AZCAT.siteman.data.getTreeNode(
                                        cmf_uid
                                    ).subitems.length
                                ) {
                                    imgs = tr.getElementsByTagName("img");
                                    for (y = 0, yLen = imgs.length;
                                            y < yLen;
                                            y += 1) {
                                        src = imgs[y].src.replace(
                                            portal_url,
                                            ""
                                        );
                                        if (src === "/tree/tm.gif") {
                                            imgs[y].src = "/tree/tn.gif";
                                            imgs[y].className = "";
                                        } else if (src === "/tree/lm.gif") {
                                            imgs[y].src = "/tree/ln.gif";
                                            imgs[y].className = "";
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        if (!ignoreSidebarActions) {
            this._updateActiveSidebarActions();
        }
    }

    function _displayClearButton() {
        var searchByEl = document.getElementById("search_by"),
            searchBy = searchByEl.value,
            showAll = document.getElementById("showAll");
        if (searchBy === "") {
            showAll.style.display = "none";
        } else {
            showAll.style.display = "inline";
        }
    }

    function _clearFilter() {
        var searchByEl = document.getElementById("search_by");
        searchByEl.value = "";
        if (!this._searchedFromViewType) {
            this._searchedFromViewType = this.getViewType();
        }
        this.setViewType(this._searchedFromViewType);
        this._parent.prefs.setPreferences(
            {"lastSearchedBy": ""},
            this._parent.data.prefs_id
        );
        this.setIsSearch(false);
        this._searchedFromViewType = "";
        this._displayClearButton();
    }

    function _clearFilterAndRefreshList() {
        this._clearFilter();
        this._parent.data.getBatchDataAndUpdateItemsFromServer(this._isSearch);
    }

    function _changeActiveTab(value) {
        if (!value) {
            value = true;
        }
        var refresh = document.getElementById(
            ["refresh", this.getViewType(), "LI"].join("")
        );
        if (refresh.className !== "") {
            if (value) {
                if (refresh.className !== "on" &&
                        refresh.className.indexOf(" on") === -1) {
                    refresh.className = refresh.className + " on";
                }
            } else {
                if (refresh.className === "on") {
                    refresh.className = "";
                } else if (refresh.className.indexOf(" on") === -1) {
                    refresh.className = refresh.className.substring(
                        0,
                        refresh.className.indexOf(" on")
                    );
                }
            }
        } else {
            if (value) {
                refresh.className = "on";
            }
        }
    }

    function _doSearch(e, filterButton) {
        var searchByEl, searchBy;
        if (filterButton && filterButton.get("label") === "Power Filter") {
            this._parent.data.getPowerFilterForm();
        } else {
            searchByEl = document.getElementById('search_by');
            searchBy = searchByEl.value;
            if (searchBy === "") {
                return;
            }

            if (this._searchedFromViewType === "") {
                this._searchedFromViewType = this.getViewType();
            }

            // Disable the current tab
            this._changeActiveTab(false);

            // Change the state to List for the search
            this.setViewType("List");
            this._parent.prefs.setPreferences(
                {
                    "lastSearchedBy": JSON.stringify({
                        "SearchableText" : searchBy
                    })
                },
                this._parent.data.prefs_id
            );

            // Enable the new tab
            this._changeActiveTab(true);

            this._parent.data.getSearchResultsFromServer(
                this.updateDisplay,
                this
            );
            this._displayClearButton();
        }
    }

    function _toggleSubItems(e) {
        YAHOO.util.Event.stopEvent(e);
        var img = YAHOO.util.Event.getTarget(e),
            tr = img.parentNode.parentNode,
            cmf_uid = tr.id.split('_');
        cmf_uid = cmf_uid[cmf_uid.length - 1];
        this._openTo = this._parent.prefs.getPreference(
            "openTo",
            this._parent.data.prefs_id
        );
        if (this._openTo[cmf_uid]) {
            delete this._openTo[cmf_uid];
        } else {
            this._openTo[cmf_uid] = true;
        }
        this._parent.prefs.setPreferences(
            {"openTo": this._openTo},
            this._parent.data.prefs_id
        );
        this.addDirtyData(cmf_uid, ['title']);
        this.updateDisplay();
    }

    function _processAddedItem(e, obj) {
        var parentObj;
        if (!obj.length) {
            return;
        }

        obj = obj[0];

        if (this._isTree) {
            parentObj = this._parent.data._getParent(obj.cmf_uid);
            if (!parentObj || this._openTo[parentObj.cmf_uid]) {
                this.addWasInserted(obj.cmf_uid);
            }
        } else {
            this.addWasInserted(obj.cmf_uid);
        }
    }

    // Shared public functions

    function setViewType(viewType, settingInitialView) {
        if ($l.isString(viewType)) {
            this._setViewType(viewType);
            if (!settingInitialView) {
                this._parent.prefs.setPreferences(
                    {"lastViewMethod": viewType},
                    this._parent.data.prefs_id
                );
            }
            this._parent.data.resetBatchStart();
        }
    }

    function getViewType() {
        return this._viewType;
    }

    function isTree() {
        return this._isTree;
    }

    function isList() {
        return this._isList;
    }

    function isGallery() {
        return this._isGallery;
    }

    function isSearch() {
        return this._isSearch;
    }

    function setIsSearch(isSearch) {
        this._isSearch = isSearch;
    }

    function updateGallery() {
        var filling, listeners, items_for_update, list, table, tbody,
            tfoot, x, xlen, columns, div, i, ilen, info, myid, mytd, perRow,
            row, tr, startAt, oddeven;
        filling = document.getElementById(
            'filling__' + this._parent.data.prefs_id
        );
        listeners = YAHOO.util.Event.getListeners(filling, "click");
        if (!listeners) {
            YAHOO.util.Event.addListener(
                filling,
                'click',
                this.displayClick,
                this,
                true
            );
        }

        // Clear out old elements & create new ones
        YAHOO.util.Dom.batch(
            YAHOO.util.Dom.getChildren(filling),
            recursivePurgeAndRemove
        );
        table = document.createElement('table');
        table.id = 'site_manager_table';
        table.className = 'main';
        tbody = document.createElement('tbody');
        tbody.id = 'site_manager_tbody';

        filling.appendChild(table);
        table.appendChild(tbody);

        tfoot = this._createBatchFooter();
        table.appendChild(tfoot);
        this._resetBatchSize();
        list = this._parent.data.getList();
        items_for_update = {};

        tr = document.createElement('tr');
        tr.style.display = 'none';
        tbody.appendChild(tr);
        columns = this._parent.prefs.getPreference(
            "columns",
            this._parent.data.prefs_id
        );
        perRow = this._parent.data._batching.perRowSelect;
        for (i = 0, ilen = list.length; i < ilen; i += 1) {
            row = list[i];
            myid = ['cmf_uid_', row.cmf_uid].join("");
            mytd = document.createElement('td');
            tr.appendChild(mytd);
            mytd.id = myid;
            info = this._parent.data.getInfo(row, {isTree: this._isTree});
            for (x = 0, xlen = columns.length; x < xlen; x += 1) {
                div = document.createElement('div');
                mytd.appendChild(div);
                div.id = [myid, '|||', columns[x]].join("");
                info.td = div;
                this._parent.displayCode[columns[x]](info);
                info.td = null;
            }
            if ((i + 1) % perRow === 0) {
                tr = document.createElement('tr');
                tr.style.display = 'none';
                tbody.appendChild(tr);
            }
        }
        if (!tr.childNodes) {
            tbody.removeChild(tr);
        }

        startAt = tbody.firstChild;
        oddeven = true;
        while (startAt) {
            if (startAt.nodeType === 1) {
                startAt.className = oddeven ? "lightgrey" : "grey";
                startAt.style.display = "";
                doIEPNGFixImgFrom(startAt);
                oddeven = !oddeven;
            }
            startAt = startAt.nextSibling;
        }

        filling = null;
        tbody = null;
        table = null;
        tfoot = null;
        tr = null;
        mytd = null;
        div = null;


        // Clean out dirtydata, wasremoved and wasinserted.
        this._dirtyData = {};
        this._wasRemoved = {};
        this._wasInserted = [];

        waitStatus(false);
    }

    function createTreeOrList() {
        var div, filling, i, my_data, table, tbody, tfoot, thead, tr, th, x,
            xlen, listeners, items_for_update,
            columns = this._parent.prefs.getPreference(
                "columns",
                this._parent.data.prefs_id
            ),
            listSort, startAt, oddeven;
        filling = document.getElementById(
            'filling__' + this._parent.data.prefs_id
        );
        listeners = YAHOO.util.Event.getListeners(filling, "click");
        if (!listeners) {
            YAHOO.util.Event.addListener(
                filling,
                'click',
                this.displayClick,
                this,
                true
            );
        }

        // Clear out old elements & create new ones
        table = document.createElement('table');
        table.id = 'site_manager_table';
        table.className = 'main';
        thead = document.createElement('thead');
        thead.id = 'site_manager_thead';
        tbody = document.createElement('tbody');
        tbody.id = 'site_manager_tbody';

        YAHOO.util.Dom.batch(
            YAHOO.util.Dom.getChildren(filling),
            recursivePurgeAndRemove
        );

        filling.appendChild(table);
        table.appendChild(thead);
        table.appendChild(tbody);

        if (this._isList) {
            my_data = this._parent.data.getList();
            tfoot = this._createBatchFooter();
            table.appendChild(tfoot);
            this._resetBatchSize();
            items_for_update = {};
            for (x = 0, xlen = my_data.length; x < xlen; x += 1) {
                items_for_update[my_data[x].cmf_uid] =
                    my_data[x].last_catalogued;
            }
        } else {
            my_data = this._parent.data.getTree();
        }

        // Make the header
        tr = document.createElement('tr');
        thead.appendChild(tr);
        for (x = 0, xlen = columns.length; x < xlen; x += 1) {
            th = document.createElement('th');
            tr.appendChild(th);
            th.id = columns[x];
            if (this._parent.columnInfo[columns[x]]) {
                div = this._parent.nodeTemplates.div_header();
                th.appendChild(div);
                div.innerHTML =
                    this._parent.columnInfo[columns[x]].column_header;
                if (this._isList &&
                        this._parent.columnInfo[columns[x]].sortable) {
                    i = this._parent.nodeTemplates.img_header();
                    i.src = (this._parent.data._listSortOn === columns[x]) ?
                            (
                                !this._parent.data._isListSortDescending ?
                                        'bullet_arrow_down.png' :
                                        'bullet_arrow_up.png'
                            ) :
                            'bullet_white.png';
                    div.appendChild(i);
                }
            }
        }
        doIEPNGFixImgFrom(tr);
        this._refreshColumnHeaders(tr);
        // Make the body
        //Recursivly draw the tree. 'Just Works'TM for list
        this._drawTree(my_data, tbody);
        listSort = new AZCAT.widgets.listSort(
            "site_manager_thead",
            "site_manager_headers",
            "th",
            {"constrainY" : [0, 0], "overriddenMove" : true}
        );
        listSort.endDragEvent.subscribe(
            function (type, args) {
                var srcEl = args[0];
                this._parent.dataView.moveColumn(srcEl.id, srcEl.cellIndex, 1);
            },
            this,
            true
        );
        listSort.onDragOverEvent.subscribe(
            function (type, args) {
                var srcEl = args[0],
                    destEl = args[1],
                    that = args[2],
                    currSwitch = [
                        srcEl.id,
                        "_",
                        destEl.id,
                        "_",
                        that.forwardOnAxis
                    ].join("");
                if (that.lastDraggedOverEl !== currSwitch) {
                    that.lastDraggedOverEl = currSwitch;
                    this._parent.dataView.moveColumn(
                        srcEl.id,
                        destEl.cellIndex,
                        0,
                        0,
                        1
                    );
                }
            },
            this,
            true
        );
        startAt = tbody.firstChild;
        oddeven = true;
        while (startAt) {
            if (startAt.nodeType === 1) {
                startAt.className = oddeven ? "lightgrey" : "grey";
                startAt.style.display = "";
                oddeven = !oddeven;
            }
            startAt = startAt.nextSibling;
        }

        // Clean out dirtydata, wasremoved and wasinserted.
        this._dirtyData = {};
        this._wasRemoved = {};
        this._wasInserted = [];

        waitStatus(false);

        filling = null;
        table = null;
        thead = null;
        tbody = null;
        tfoot = null;
        tr = null;
        th = null;
        div = null;
        i = null;
    }

    function updateTreeOrList() {
        var batching_td, c, clen, col, cols, div, i, ilen, img,
            insertBefore, insertedEle, insertedIndex, insertedItem,
            insertedParent, insertedParentEle, insertedSiblings, lastItem,
            my_data, order, removedEle, row, rowdata, s, siblings, slen,
            sort_order_parents, sortedItem, table, tbody, th, thead, tr, x,
            xlen, listSort, startAt, isSelectCheckbox, theCheckbox,
            oddeven = true,
            data = this._parent.data,
            data_to_columns = this._parent.dataToColumns;
        // Update whats marked dirty, insert new and delete old.
        // This will never happen for gallery view or batched list view.
        table = document.getElementById('site_manager_table');
        if (!table) {
            table = document.createElement('table');
            table.id = 'site_manager_table';
            table.className = 'main';
        }
        tbody = document.getElementById('site_manager_tbody');
        if (!tbody) {
            tbody = document.createElement('tbody');
            tbody.id = 'site_manager_tbody';
        }
        thead = document.getElementById('site_manager_thead');
        if (!thead) {
            thead = document.createElement('thead');
            thead.id = 'site_manager_thead';
        }

        if (this._isTree) {
            // Make sure all the correct tree nodes are open.
            this._recursiveOpenStateUpdate(data.getTree(), null, true);
        }

        // Remove WasRemoved elements. Make siblings dirty for getTitleAndView
        // to dirty if in tree view.
        for (i in this._wasRemoved) {
            if (this._wasRemoved.hasOwnProperty(i)) {
                removedEle = document.getElementById(['cmf_uid_', i].join(''));
                if (removedEle) {
                    recursivePurgeAndRemove(removedEle);
                    removedEle = null;
                    if (this._wasRemoved[i] &&
                            this._wasRemoved[i].cmf_uid !== undefined) {
                        this.addDirtyData(
                            this._wasRemoved[i].cmf_uid,
                            ['title']
                        );
                        if (!this._wasRemoved[i].subitems ||
                                this._wasRemoved[i].subitems.length === 0) {
                            delete this._openTo[this._wasRemoved[i].cmf_uid];
                        }
                        if (this._isTree &&
                                this._openTo[this._wasRemoved[i].cmf_uid]) {
                            siblings = this._wasRemoved[i].subitems;
                            for (s = 0, slen = siblings.length;
                                    s < slen;
                                    s += 1
                                    ) {
                                this.addDirtyData(
                                    siblings[s].cmf_uid,
                                    ['title']
                                );
                            }
                        }
                    }
                }
            }
        }

        // Insert WasInserted elements. Make siblings/parent dirty for
        // getTitleAndView to dirty if in tree view.
        for (i = 0, ilen = this._wasInserted.length; i < ilen; i += 1) {
            insertedItem = this._isList ?
                    data.getData(this._wasInserted[i]) :
                    data.getTreeNode(this._wasInserted[i]);
            insertedEle = this._updateRow(
                insertedItem,
                this._parent.prefs.getPreference(
                    "columns",
                    data.prefs_id
                ),
                this._parent.prefs.getPreference(
                    "columns",
                    data.prefs_id
                )
            );
            insertedParent = this._isList ?
                    null :
                    data._getParent(this._wasInserted[i]);
            insertedSiblings = this._isList ?
                    data.getList() :
                    insertedParent.subitems;
            /* find the ids of insertedItem's next sibling. */
            insertedIndex = -1;
            for (x = 0, xlen = insertedSiblings.length; x < xlen; x += 1) {
                if (insertedSiblings[x].cmf_uid === insertedItem.cmf_uid) {
                    insertedIndex = x - 1;
                }
            }
            insertBefore = null;
            if (insertedSiblings[insertedIndex]) {
                lastItem = (
                    this._openTo[insertedSiblings[insertedIndex].cmf_uid] &&
                        insertedSiblings[insertedIndex].subitems &&
                        insertedSiblings[insertedIndex].subitems.length &&
                        this._grabLastSubitem(
                            insertedSiblings[insertedIndex].subitems
                        )
                ) || insertedSiblings[insertedIndex];
                insertBefore = document.getElementById(
                    ['cmf_uid_', lastItem.cmf_uid].join('')
                );
            }
            if (insertBefore) {
                if (insertBefore.nextSibling) {
                    tbody.insertBefore(insertedEle, insertBefore.nextSibling);
                } else {
                    tbody.appendChild(insertedEle);
                }
            } else if (this._isList && insertedIndex === -1) {
                // We are adding to the beginning of List View
                if (tbody.firstChild) {
                    tbody.insertBefore(insertedEle, tbody.firstChild);
                } else {
                    tbody.appendChild(insertedEle);
                }
            } else {
                insertedParentEle = document.getElementById(
                    [
                        'cmf_uid_',
                        insertedParent.cmf_uid
                    ].join('')
                );
                this._openTo[insertedParent.cmf_uid] = true;
                if (insertedParentEle.nextSibling) {
                    tbody.insertBefore(
                        insertedEle,
                        insertedParentEle.nextSibling
                    );
                } else {
                    tbody.appendChild(insertedEle);
                }
            }
            if (this._isTree) {
                if (insertedParent.cmf_uid !== undefined) {
                    this.addDirtyData(insertedParent.cmf_uid, ['title']);
                }
                for (s = 0, slen = insertedSiblings.length; s < slen; s += 1) {
                    this.addDirtyData(insertedSiblings[s].cmf_uid, ['title']);
                }
            }
            insertedItem = null;
            insertedEle = null;
            insertedParentEle = null;
            insertBefore = null;
        }

        /* Don't care about updating items that got removed. */
        for (row in this._dirtyData) {
            if (this._dirtyData.hasOwnProperty(row)) {
                if (!document.getElementById(['cmf_uid_', row].join(''))) {
                    delete this._dirtyData[row];
                }
            }
        }
        // Loop through Dirty IDs and look for addition ids to dirty based on...
        // If columns that contain sort_order are dirty, deal with it D:
        sort_order_parents = [];
        for (row in this._dirtyData) {
            if (this._dirtyData.hasOwnProperty(row)) {
                if (this._dirtyData[row].sort_order && row !== 0) {
                    sortedItem = data._getParent(parseInt(row, 10));
                    if (sortedItem) {
                        sort_order_parents.push(sortedItem);
                    }
                }
            }
        }
        for (i = 0, ilen = sort_order_parents.length; i < ilen; i += 1) {
            if (
                (
                    i !== 0 &&
                        sort_order_parents[i].path.indexOf(
                            sort_order_parents[i - 1].path
                        ) !== 0
                ) ||
                    i === 0
            ) {
                this._sortLevel(sort_order_parents[i]);
            }
        }
        // Loop through Dirty IDs and update columns marked dirty. Else display
        // a clean version of the current view.
        for (row in this._dirtyData) {
            if (this._dirtyData.hasOwnProperty(row)) {
                rowdata = this._isTree ?
                        data.getTreeNode(parseInt(row, 10)) :
                        data.getData(parseInt(row, 10));
                if (rowdata.cmf_uid !== undefined) {
                    cols = {};
                    for (col in this._dirtyData[row]) {
                        // this is intentionally $hasOwnProperty, not
                        // .hasOwnProperty
                        if ($hasOwnProperty(this._dirtyData[row], col)) {
                            if (data_to_columns[col]) {
                                for (c = 0, clen = data_to_columns[col].length;
                                         c < clen; c += 1) {
                                    cols[data_to_columns[col][c]] = true;
                                }
                            }
                        }
                    }
                    this._updateRow(
                        rowdata,
                        cols,
                        this._parent.prefs.getPreference(
                            "columns",
                            data.prefs_id
                        )
                    );
                }
            }
        }
        // If the columns changed, reorder, delete and add columns as necessary
        if (this._columnsDirty) {
            order = this._parent.prefs.getPreference(
                'columns',
                data.prefs_id
            );

            //Add/Delete/Sort Headers
            thead = document.getElementById('site_manager_thead');
            tr = document.createElement('tr');
            thead.appendChild(tr);
            for (i = 0, ilen = order.length; i < ilen; i += 1) {
                th = document.getElementById(order[i]);
                if (!th) {
                    th = document.createElement('th');
                    tr.appendChild(th);
                    div = this._parent.nodeTemplates.div_header();
                    th.appendChild(div);
                    th.id = order[i];
                    if (this._parent.columnInfo[order[i]] &&
                            this._parent.columnInfo[order[i]].column_header) {
                        div.appendChild(
                            document.createTextNode(
                                this._parent.columnInfo[order[i]].column_header
                            )
                        );
                        if (this._isList &&
                                this._parent.columnInfo[order[i]].sortable) {
                            img = this._parent.nodeTemplates.img_header();
                            img.src = (data._listSortOn === order[i]) ?
                                    (
                                        !data._isListSortDescending ?
                                                'bullet_arrow_down.png' :
                                                'bullet_arrow_up.png'
                                    ) :
                                    'bullet_white.png';
                            div.appendChild(img);
                            img = null;
                        }
                    }
                } else {
                    tr.appendChild(th);
                }
            }
            this._refreshColumnHeaders(tr);
            tr = null;
            th = null;
            div = null;
            recursivePurgeAndRemove(thead.firstChild);

            //Add/Delete/Sort Columns
            if (this._isList) {
                my_data = data.getList();
            } else {
                my_data = data.getTree();
            }
            for (x = 0, xlen = my_data.length; x < xlen; x += 1) {
                this._updateColumns(my_data[x], order);
            }

            // Update the batch footer colspan
            if (this._isList) {
                batching_td = document.getElementById('batching_td');
                YAHOO.util.Dom.setAttribute(
                    batching_td,
                    'colSpan',
                    order.length
                );
                batching_td = null;
            }

            listSort = new AZCAT.widgets.listSort(
                "site_manager_thead",
                "site_manager_headers",
                "th",
                {
                    "constrainY" : [0, 0],
                    "overriddenMove" : true
                }
            );
            listSort.endDragEvent.subscribe(
                function (type, args) {
                    var srcEl = args[0],
                        that = args[2];
                    this._parent.dataView.moveColumn(
                        srcEl.id,
                        that.forwardOnAxis ?
                                srcEl.cellIndex :
                                srcEl.cellIndex + 1,
                        1
                    );
                },
                this,
                true
            );
            listSort.onDragOverEvent.subscribe(
                function (type, args) {
                    var srcEl = args[0],
                        destEl = args[1],
                        that = args[2],
                        currSwitch = [srcEl.id, "_", destEl.id].join("");
                    if (that.lastDraggedOverEl !== currSwitch) {
                        that.lastDraggedOverEl = currSwitch;
                        this._parent.dataView.moveColumn(
                            srcEl.id,
                            destEl.cellIndex,
                            0,
                            0,
                            1
                        );
                    }
                },
                this,
                true
            );
            this.setColumnsDirty(false);
        }
        table = null;
        thead = null;

        startAt = tbody.firstChild;

        isSelectCheckbox = function (el) {
            if (el.name === 'copy_pasta_checkbox') {
                return true;
            }
        };
        while (startAt) {
            if (startAt.nodeType === 1) {
                startAt.className = oddeven ? "lightgrey" : "grey";
                theCheckbox = YAHOO.util.Dom.getElementsBy(
                    isSelectCheckbox,
                    null,
                    startAt
                );
                if (theCheckbox.length && theCheckbox[0].checked) {
                    YAHOO.util.Dom.addClass(startAt, 'selected');
                }
                startAt.style.display = "";
                oddeven = !oddeven;
            }
            startAt = startAt.nextSibling;
        }
        if (this._isTree) {
            this._parent.prefs.setPreferences(
                {"openTo": this._openTo},
                data.prefs_id
            );
        }

        // Clean out dirtydata, wasremoved and wasinserted.
        this._dirtyData = {};
        this._wasRemoved = {};
        this._wasInserted = [];

        waitStatus(false);

        tbody = null;
    }

    function updateDisplay(allDirty) {
        if (this._isGallery) {
            this.updateGallery();
            this._createControlButtons();
        } else if (allDirty) { // We want a full redraw.
            this._createControlButtons();
            this.createTreeOrList();
        } else {
            this.updateTreeOrList();
        }

        this._createActionsSidebar();

        this.afterDisplayUpdateEvent.fire();
        if (this._parent.sitemapOpenToLevel) {
            this._parent.sitemapOpenToLevel = null;
        }
        this._parent.prefs.savePreferences();
    }

    function addDirtyData(id, dirt) {
        var i, ilen;
        if ($l.isString(id) && id.indexOf('cmf_uid_') === 0) {
            id = id.split('_');
            id = id[id.length - 1];
        }
        if ($l.isUndefined(this._dirtyData[id])) {
            this._dirtyData[id] = {};
        }
        for (i = 0, ilen = dirt.length; i < ilen; i += 1) {
            this._dirtyData[id][dirt[i]] = true;
        }
    }

    function addWasRemoved(id, dirt) {
        this._wasRemoved[id] = dirt;
    }

    function addWasInserted(id) {
        this._wasInserted.push(id);
    }

    function resetBatchStart() {
        var el = document.getElementById("perPage");
        if (this._isTree && el) {
            YAHOO.util.Dom.setStyle(el, "display", "none");
        }
        el = null;
    }

    function treeViewClick() {
        AZCAT.nav.updateTabs();
        this._clearFilter();
        this._parent.data._clearAllItems();
        this.setViewType('Tree');
        this._openTo = this._parent.prefs.getPreference(
            'openTo',
            this._parent.data.prefs_id
        );
        this._parent.data.updateFromServer(this.updateDisplay, this, true);
    }

    function listViewClick() {
        var getPref = this._parent.prefs.getPreference,
            prefs_id = this._parent.data.prefs_id;
        AZCAT.nav.updateTabs();
        this._clearFilter();
        this._parent.data._clearAllItems();
        this.setViewType('List');
        this._parent.data._batching.perPageSelect = getPref(
            'perPage',
            prefs_id
        );
        this._parent.data._batching.perRowSelect = getPref('perRow', prefs_id);
        this._parent.data.sortList(
            getPref('lastSortedOn', prefs_id),
            getPref('lastSortedOrder', prefs_id)
        );
        this._parent.data.getBatchDataAndUpdateItemsFromServer(this.isSearch());
    }

    function galleryViewClick() {
        var getPref = this._parent.prefs.getPreference,
            prefs_id = this._parent.data.prefs_id;
        AZCAT.nav.updateTabs();
        this._clearFilter();
        this._parent.data._clearAllItems();
        this.setViewType('Gallery');
        this._parent.data._batching.perPageSelect = getPref(
            'perPage',
            prefs_id
        );
        this._parent.data._batching.perRowSelect = getPref('perRow', prefs_id);
        this._parent.data.sortList(
            getPref('lastSortedOn', prefs_id),
            getPref('lastSortedOrder', prefs_id)
        );
        this._parent.data.getBatchDataAndUpdateItemsFromServer(this.isSearch());
    }

    function batchPreviousClick(e) {
        YAHOO.util.Event.stopEvent(e);
        this._parent.data.batchPrevious();
        this._parent.data.getBatchDataAndUpdateItemsFromServer(this.isSearch());
    }

    function batchNextClick(e) {
        YAHOO.util.Event.stopEvent(e);
        this._parent.data.batchNext();
        this._parent.data.getBatchDataAndUpdateItemsFromServer(this.isSearch());
    }

    function perPageClick() {
        var perPage = this._getPerPageSelect();
        if (perPage && parseInt(perPage, 10)) {
            perPage = parseInt(perPage, 10);
            this._parent.prefs.setPreferences(
                {"perPage" : perPage},
                this._parent.data.prefs_id
            );
            this._parent.data._batching.perPageSelect = perPage;
            this._parent.data.resetBatchStart();
            this._parent.data.getBatchDataAndUpdateItemsFromServer(
                this.isSearch()
            );
        }
    }

    function perRowClick() {
        var perRow = parseInt(
                this._isGallery ? this._getPerRowSelect() : 1,
                10
            );
        if (perRow) {
            this._parent.prefs.setPreferences(
                {"perRow" : perRow},
                this._parent.data.prefs_id
            );
            this._parent.data._batching.perRowSelect = perRow;
            this._parent.data.resetBatchStart();
            this._parent.data.getBatchDataAndUpdateItemsFromServer(
                this.isSearch()
            );
        }
    }

    function addColumn(colName, newPos, preserve_header, preserve_body,
                       preserve_preference) {
        // TODO: Write function to add a column. His currently just refreshes
        // from the server. Until this change is made, this method won't work
        // properly if preserve_preferences is set
        var oldPrefs, mycolumns;
        this._parent.data._invalidateDataLackingColumns([colName]);
        if (!preserve_preference) {
            oldPrefs = this._parent.prefs.getPreference(
                "columns",
                this._parent.data.prefs_id
            );
            mycolumns = oldPrefs.slice(0, newPos);
            mycolumns = mycolumns.concat(
                [colName],
                oldPrefs.slice(newPos, oldPrefs.length)
            );
            this._parent.prefs.setPreferences(
                {"columns": mycolumns},
                this._parent.data.prefs_id
            );
            this.setColumnsDirty(true);
        }

        this._parent.data.getBatchDataAndUpdateItemsFromServer(this.isSearch());
    }

    function deleteColumn(colPos, preserve_header, preserve_body,
                          preserve_preference) {
        var table_header, row_list, table_body, mycolumns, i, ilen;
        if (!preserve_header) {
            table_header = document.getElementById('site_manager_thead');
            row_list = table_header.getElementsByTagName('TR');
            for (i = 0, ilen = row_list.length; i < ilen; i += 1) {
                row_list[i].deleteCell(colPos);
            }
            this._refreshColumnHeaders(table_header);
        }

        if (!preserve_body) {
            table_body = document.getElementById('site_manager_tbody');
            row_list = table_body.getElementsByTagName('TR');
            for (i = 0, ilen = row_list.length; i < ilen; i += 1) {
                row_list[i].deleteCell(colPos);
            }
        }

        if (!preserve_preference) {
            mycolumns = this._parent.prefs.getPreference(
                "columns",
                this._parent.data.prefs_id
            );
            mycolumns.splice(colPos, 1);
            this._parent.prefs.setPreferences(
                {"columns": mycolumns},
                this._parent.data.prefs_id
            );
        }
        this.setColumnsDirty(true);
        table_header = null;
        table_body = null;
        row_list = null;
    }

    function moveColumn(colName, newPos, preserve_header, preserve_body,
                        preserve_preference) {
        var table_header, row_list, table_body, mycolumns, thisRow, i, ilen,
            movedCell, oldIndex, oldPrefs, curPos;
        if (!preserve_header) {
            table_header = document.getElementById('site_manager_thead');

            row_list = table_header.getElementsByTagName('TR');
            for (i = 0, ilen = row_list.length; i < ilen; i += 1) {
                thisRow = row_list[i];
                movedCell = document.getElementById(colName);
                oldIndex = movedCell.cellIndex;
                if (newPos < thisRow.childNodes.length - 1) {
                    thisRow.insertBefore(movedCell, thisRow.cells[newPos]);
                } else {
                    thisRow.appendChild(movedCell);
                }
            }
            this._refreshColumnHeaders(table_header);
        }
        if (!preserve_body) {
            table_body = document.getElementById('site_manager_tbody');
            row_list = table_body.getElementsByTagName('TR');
            for (i = 0, ilen = row_list.length; i < ilen; i += 1) {
                thisRow = row_list[i];
                movedCell = document.getElementById(
                    [thisRow.id, '|||', colName].join("")
                );
                oldIndex = movedCell.cellIndex;
                if (newPos < thisRow.childNodes.length - 1) {
                    thisRow.insertBefore(movedCell, thisRow.cells[newPos]);
                } else {
                    thisRow.appendChild(movedCell);
                }
            }
        }

        if (!preserve_preference) {
            oldPrefs = this._parent.prefs.getPreference(
                "columns",
                this._parent.data.prefs_id
            );
            // Some sanity checking done here in case the column ends up in the
            // array twice
            curPos = oldPrefs.indexOf(colName);
            while (curPos !== -1) {
                oldPrefs.splice(curPos, 1);
                curPos = oldPrefs.indexOf(colName);
            }
            mycolumns = oldPrefs.slice(0, newPos);
            mycolumns = mycolumns.concat(
                [colName],
                oldPrefs.slice(newPos, oldPrefs.length)
            );
            this._parent.prefs.setPreferences(
                {"columns": mycolumns},
                this._parent.data.prefs_id
            );
            this._parent.prefs.savePreferences();
        }
        this.setColumnsDirty(true);
        table_header = null;
        table_body = null;
        row_list = null;
        movedCell = null;
    }

    dialogEventHandlers = {
        onDeleteConfirm : function (e) {
            this._parent.data.getBatchDataAndUpdateItemsFromServer(
                this.isSearch()
            );
            waitStatus(false);
        },
        onRenameConfirm : function (e, renameData) {
            var items_for_update = {},
                my_data,
                x,
                xlen;
            my_data = this._parent.data.getList();
            for (x = 0, xlen = my_data.length; x < xlen; x += 1) {
                items_for_update[my_data[x].cmf_uid] =
                    my_data[x].last_catalogued;
            }
            this._parent.data.updateItemsFromServer(
                this.updateDisplay,
                this,
                items_for_update
            );
            waitStatus(false);
        },
        onSortConfirm : function (e, sortData) {
            this._parent.data.updateFromServer(this.updateDisplay, this);
            waitStatus(false);
        },
        onTransitionConfirm : function (e, transitionData) {
            this._parent.data.updateItems([], transitionData[0], []);
            this.updateDisplay();
        },
        onImportClose : function (e, sortData) {
            this._parent.data.updateFromServer(this.updateDisplay, this);
        },
        onAddConfirm : function (e) {
            this._parent.data.updateFromServer(this.updateDisplay, this);
        }
    };

    function displayClick(e) {
        var origin = YAHOO.util.Event.getTarget(e),
            td,
            column,
            firstAction,
            row,
            row_name,
            effective_id,
            first_action_onclick;
        // find out what column we are
        switch (origin.nodeName.toLowerCase()) {
        case 'img':
            td = origin;
            while (
                (
                    td.nodeName.toLowerCase() !== 'td' &&
                    td.nodeName.toLowerCase() !== 'th' &&
                    td.nodeName.toLowerCase() !== 'div' &&
                    td.parentNode
                ) || (
                    td.nodeName.toLowerCase() === 'div' &&
                    td.id && td.id.search('|||') === -1 &&
                    td.parentNode
                ) || (
                    td.nodeName.toLowerCase() === 'div' &&
                    !td.id && td.parentNode
                )
            ) {
                td = td.parentNode;
            }
            if (td.nodeName.toLowerCase() === 'th') {
                this._parent.data.doSort(e);
            } else {
                column = td.id.split('|||')[1];
                // dispatch event to handler who deals with the event.
                switch (column) {
                case 'getTitleAndView':
                case 'getTitleAndViewSitemap':
                case 'getTitleAndEdit':
                    if (origin.className.indexOf('clickme') !== -1) {
                        this._toggleSubItems(e);
                    } else if (origin.className === 'view_link_image') {
                        if (this._parent.data._click_action === 'shadowbox' &&
                                Shadowbox) {
                            YAHOO.util.Event.stopEvent(e);
                            Shadowbox.open(
                                YAHOO.util.Dom.getAncestorByTagName(
                                    YAHOO.util.Event.getTarget(e),
                                    'a'
                                )
                            );
                        } else if (
                            this._parent.data._click_action ===
                                'file_properties'
                        ) {
                            YAHOO.util.Event.stopEvent(e);
                            doFileProperties(e);
                        }
                    } else {
                        this._toggleItemSelection(origin, true);
                    }
                    break;
                case 'getActions':
                    row_name = td.id.split('|||')[0];
                    row = this._parent.data.getData(row_name);
                    firstAction = row.actions[0];
                    if (firstAction.onclick) {
                        YAHOO.util.Event.stopEvent(e);
                        first_action_onclick =
                            AZCAT.dialog.actionCode[firstAction.id];
                        effective_id = row.path + row.id;
                        if (effective_id === '/') {
                            effective_id = '';
                        }
                        first_action_onclick(
                            e,
                            {
                                ids: [effective_id],
                                event_handlers: this.dialogEventHandlers,
                                callback_scope: this
                            }
                        );
                    }
                    break;
                case 'getThumbnail':
                    if (isFCKEditorBrowse) {
                        browseSelect(e);
                    } else if (
                        this._parent.data._click_action === 'shadowbox' &&
                            Shadowbox
                    ) {
                        YAHOO.util.Event.stopEvent(e);
                        Shadowbox.open(
                            YAHOO.util.Dom.getAncestorByTagName(
                                YAHOO.util.Event.getTarget(e),
                                'a'
                            )
                        );
                    } else if (
                        this._parent.data._click_action === 'file_properties'
                    ) {
                        YAHOO.util.Event.stopEvent(e);
                        doFileProperties(e);
                    }
                    break;
                default:
                    this._toggleItemSelection(origin, true);
                    break;
                }
            }
            td = null;
            break;
        case 'input':
            YAHOO.util.Dom.getAncestorBy(
                origin,
                function (el) {
                    td = el.nodeName.toLowerCase();
                    return td === "td" || td === "th";
                }
            );
            if (td === "td") {
                if (origin.name === "copy_pasta_checkbox") {
                    this._toggleItemSelection(origin, false);
                } else {
                    this._toggleItemSelection(origin, true);
                }
            }
            break;
        case 'a':
            td = origin;
            while (
                (
                    td.nodeName.toLowerCase() !== 'td' &&
                    td.nodeName.toLowerCase() !== 'div' &&
                    td.parentNode
                ) || (
                    td.nodeName.toLowerCase() === 'div' &&
                    td.id && td.id.search('|||') === -1 &&
                    td.parentNode
                ) || (
                    td.nodeName.toLowerCase() === 'div' &&
                    !td.id &&
                    td.parentNode
                )
            ) {
                td = td.parentNode;
            }
            column = td.id.split('|||')[1];
            switch (column) {
            case 'getActions':
                row_name = td.id.split('|||')[0];
                row = this._parent.data.getData(row_name);
                firstAction = row.actions[0];
                if (firstAction.onclick) {
                    YAHOO.util.Event.stopEvent(e);
                    first_action_onclick =
                        AZCAT.dialog.actionCode[firstAction.id];
                    effective_id = row.path + row.id;
                    if (effective_id === '/') {
                        effective_id = '';
                    }
                    first_action_onclick(
                        e,
                        {
                            ids: [effective_id],
                            event_handlers: this.dialogEventHandlers,
                            callback_scope: this
                        }
                    );
                }
                break;
            case 'getThumbnail':
                if (isFCKEditorBrowse) {
                    browseSelect(e);
                } else {
                    this._toggleItemSelection(origin, true);
                }
                break;
            case 'getTitleAndView':
                if (isFCKEditorBrowse) {
                    browseSelect(e);
                } else if (this._parent.data._click_action === 'shadowbox' &&
                        Shadowbox) {
                    YAHOO.util.Event.stopEvent(e);
                    Shadowbox.open(YAHOO.util.Event.getTarget(e));
                } else if (
                    this._parent.data._click_action === 'file_properties'
                ) {
                    YAHOO.util.Event.stopEvent(e);
                    doFileProperties(e);
                }
                break;
            default:
                break;
            }
            td = null;
            break;
        case 'div':
            // Currently, only clicking the blue area gets you here.
            break;
        default:
            this._toggleItemSelection(origin, true);
            break;
        }
        origin = null;
    }

    function getCMFUIDfromPath(path) {
        var item, items = this._parent.data._items, root_url;
        for (item in items) {
            if (items.hasOwnProperty(item)) {
                if (items[item].path + items[item].id === path) {
                    return items[item].cmf_uid;
                }
            }
        }

        root_url = this._parent.data.root_path + this._parent.data.root_id;

        // Handle the view root
        // This requires a special hack if at the site root
        if (path === root_url ||
                (path === "" && root_url === '/')) {
            return this._parent.data.root_cmf_uid;
        }
    }

    /*
        -+++++++++-
        |pasteHere|
        -+++++++++-
        + This inserts the 'Paste Here' action as the default action into
    */

    function pasteHere(e, dialogParams) {
        YAHOO.util.Event.stopEvent(e);
        var qstr = "",
            name = "id:list=",
            thisObj,
            that = this,
            x,
            ID,
            parent_cmf_uid,
            parent_data;
        for (x = 0; x < clipboard.items.length; x += 1) {
            thisObj = this._parent.data.getData(clipboard.items[x]);
            qstr = [qstr, name, thisObj.path, thisObj.id, "&"].join("");
        }
        qstr = [qstr, "action=", clipboard.action].join("");

        // Insure that the parent is redrawn if it did not have subitems
        ID = dialogParams.ids[0];
        parent_cmf_uid = this.getCMFUIDfromPath(ID);
        parent_data = this._parent.data.getData(parent_cmf_uid);

        if (parent_data &&
                (
                    !parent_data.subitems ||
                    !parent_data.subitems.length
                )) {
            this._parent.data._updateItem(
                parent_cmf_uid,
                {last_catalogued : 0}
            );
        }

        YAHOO.util.Connect.asyncRequest(
            'POST',
            [portal_url, ID, '/doPaste'].join(""),
            {
                scope: that,
                success: this._pasteCallback,
                failure: AZCAT.utils.connFail
            },
            qstr
        );

        clipboard.items = '';
        clipboard.action = '';
        this._removePasteAction();
    }

    /*
        -++++++++-
        |cutItems|
        -++++++++-
        + This method will store the selected items into the cut id list
        and enable the paste into here methods.
    */
    function cutItems() {
        clipboard.items = this._getSelectedCMFUids();
        clipboard.action = 'cut';
        this.insertPasteAction();
    }

    /*
        -+++++++++-
        |copyItems|
        -+++++++++-
        + This method will store the selected items into the copy id list
        and enable the paste into here methods.
    */
    function copyItems() {
        clipboard.items = this._getSelectedCMFUids();
        clipboard.action = 'copy';
        this.insertPasteAction();
    }

    function insertPasteAction() {
        var qstr = [
                'cmf_uids=',
                JSON.stringify(clipboard.items),
                '&action=',
                clipboard.action
            ].join(''),
            that = this;
        YAHOO.util.Connect.asyncRequest(
            'POST',
            [portal_url, '/getAllowedPasteFolders'].join(""),
            {
                scope: that,
                success: this._insertCallback,
                failure: AZCAT.utils.connFail
            },
            qstr
        );
    }

    function setColumnsDirty(isDirty) {
        this._columnsDirty = isDirty;
    }

    function destroy() {
        var filling_div = document.getElementById(
                'filling__' + this._parent.data.prefs_id
            );
        YAHOO.util.Event.removeListener(window, "beforeunload", this.destroy);
        this._clearControlButtons();

        this._parent.data.itemAdded.unsubscribe(this._processAddedItem, this);

        if (filling_div) {
            YAHOO.util.Event.purgeElement(filling_div);
            YAHOO.util.Dom.batch(
                YAHOO.util.Dom.getChildren(filling_div),
                recursivePurgeAndRemove
            );
        }

        if (!this._suppress_sidebar && this._parent.sidebar) {
            this._parent.sidebar.destroy();
        }
    }

    return function (parent, suppress_sidebar) {
        // My resources, this instance
        // Private varables, actual

        var filling, that = {
            //Private varables, by convention not actually hidden
            _parent : parent,
            _dirtyData : {},
            _wasRemoved : {},
            _wasInserted : [],
            _viewType : '',
            _isTree : false,
            _isList : false,
            _isGallery : false,
            _isSearch : false,
            _batching : {
                "Container"                : null,
                "TD"                       : null,
                "Min"                      : null,
                "Max"                      : null,
                "Total"                    : null,
                "PreviousSpan"             : null,
                "PreviousA"                : null,
                "NextSpan"                 : null,
                "NextA"                    : null,
                "perPage"                  : null,
                "perPageSelect"            : null,
                "perRow"                   : null,
                "perRowSelect"             : null
            },
            _openTo : {},
            _controlButtons : [],
            _rootActionButtons : [],
            _supress_sidebar : suppress_sidebar,
            _searchedFromViewType : "",
            _columnsDirty : true,
            //Private Methods
            _setViewType : _setViewType,
            _drawTree : _drawTree,
            _createBatchFooter : _createBatchFooter,
            _showPreviousLink : _showPreviousLink,
            _hidePreviousLink : _hidePreviousLink,
            _showNextLink : _showNextLink,
            _hideNextLink : _hideNextLink,
            _updatePerPage : _updatePerPage,
            _updatePerRow : _updatePerRow,
            _disablePerPage : _disablePerPage,
            _enablePerPage : _enablePerPage,
            _updateRow : _updateRow,
            _recursiveOpenStateUpdate : _recursiveOpenStateUpdate,
            _grabLastSubitem : _grabLastSubitem,
            _sortLevel : _sortLevel,
            _updateColumns : _updateColumns,
            _refreshColumnHeaders : _refreshColumnHeaders,
            _getPerPageSelect : _getPerPageSelect,
            _getPerRowSelect : _getPerRowSelect,
            _updateBatchDisplay : _updateBatchDisplay,
            _resetBatchSize : _resetBatchSize,
            _getColumnsLength : _getColumnsLength,
            _createControlButtons : _createControlButtons,
            _clearControlButtons : _clearControlButtons,
            _createActionsSidebar : _createActionsSidebar,
            _getSelectedCMFUids : _getSelectedCMFUids,
            _updateActiveSidebarActions : _updateActiveSidebarActions,
            _setActiveSidebarButtons : _setActiveSidebarButtons,
            _handleSidebarButtonClick : _handleSidebarButtonClick,
            _pasteCallback : _pasteCallback,
            _removePasteAction : _removePasteAction,
            _insertCallback : _insertCallback,
            _toggleItemSelection : _toggleItemSelection,
            _displayClearButton : _displayClearButton,
            _clearFilter : _clearFilter,
            _clearFilterAndRefreshList : _clearFilterAndRefreshList,
            _changeActiveTab : _changeActiveTab,
            _doSearch : _doSearch,
            _toggleSubItems : _toggleSubItems,
            _processAddedItem : _processAddedItem,

            // Public methods
            setViewType : setViewType,
            getViewType : getViewType,
            isTree : isTree,
            isList : isList,
            isGallery : isGallery,
            isSearch : isSearch,
            setIsSearch : setIsSearch,
            updateGallery : updateGallery,
            createTreeOrList : createTreeOrList,
            updateTreeOrList : updateTreeOrList,
            updateDisplay : updateDisplay,
            addDirtyData : addDirtyData,
            addWasRemoved : addWasRemoved,
            addWasInserted : addWasInserted,
            resetBatchStart : resetBatchStart,
            treeViewClick : treeViewClick,
            listViewClick : listViewClick,
            galleryViewClick : galleryViewClick,
            batchPreviousClick : batchPreviousClick,
            batchNextClick : batchNextClick,
            perPageClick : perPageClick,
            perRowClick : perRowClick,
            addColumn : addColumn,
            deleteColumn : deleteColumn,
            moveColumn : moveColumn,
            dialogEventHandlers : dialogEventHandlers,
            displayClick : displayClick,
            getCMFUIDfromPath : getCMFUIDfromPath,
            pasteHere : pasteHere,
            cutItems : cutItems,
            copyItems : copyItems,
            insertPasteAction : insertPasteAction,
            setColumnsDirty : setColumnsDirty,
            destroy : destroy
        };

        that.afterDisplayUpdateEvent = new YAHOO.util.CustomEvent(
            "afterDisplayUpdateEvent",
            that
        );

        if (!suppress_sidebar &&
                document.getElementById('sidebar_actions_container')) {
            filling = document.getElementById(
                'filling__' + parent.data.prefs_id
            );

            parent.registerEls({
                top_align: filling,
                stretched: YAHOO.util.Dom.getAncestorByClassName(
                    filling.parentNode,
                    'yui-content'
                )
            });
        }

        parent.data.itemAdded.subscribe(_processAddedItem, that, true);

        YAHOO.util.Event.on(window, "beforeunload", destroy, that, true);

        return that;
    };
}());

AZCAT.register("data", AZCAT.siteman.data, {version: "2.0.0", build: "???"});
AZCAT.register(
    "dataView",
    AZCAT.siteman.dataView,
    {
        version: "2.0.0",
        build: "???"
    }
);

