lib/Ext/util/Collection.js
function(oldKey, item) {
        var me = this,
            sorted = me.sorted,
            presorted = me.presorted,
            filtered = me.filtered,
            filterable = me.mixins.filterable,
            items = me.items,
            keys = me.keys,
            all = me.all,
            map = me.map,
            returnItem = null,
            oldItemsLn = items.length,
            subjectToOptimize = false,
            oldItem, index, newKey;

        if (arguments.length == 1) {
            item = oldKey;
            oldKey = newKey = me.getKey(item);
            subjectToOptimize = true;
        } else {
            newKey = me.getKey(item);
        }

        oldItem = map[oldKey];
        if (typeof oldKey == 'undefined' || oldKey === null || typeof oldItem == 'undefined') {
            return me.add(newKey, item);
        }

        me.map[newKey] = item;
        if (newKey !== oldKey) {
            delete me.map[oldKey];
        }

        if (sorted && me.getAutoSort()) {
            if (!subjectToOptimize) {
                Ext.Array.remove(items, oldItem);
                Ext.Array.remove(keys, oldKey);
            } else {
                var itemsFrom = items.indexOf(oldItem);
            }
            if (!presorted) {
                Ext.Array.remove(all, oldItem);
                all.push(item);
                me.dirtyIndices = true;
            } else {
                var allTo = this.findInsertionIndex(all, item, undefined, true),
                    allFrom = all.indexOf(item);

                if (allTo !== allFrom) {
                    move(all, allFrom, allTo);
                    me.dirtyIndices = true;
                }
            }

            if (filtered && me.getAutoFilter()) {
                // If the item is now filtered we check if it was not filtered
                // before. If that is the case then we subtract from the length
                if (filterable.isFiltered.call(me, item)) {
                    if (oldItemsLn !== items.length) {
                        me.length--;
                    }

                    if (subjectToOptimize) {
                        Ext.Array.remove(items, oldItem);
                        Ext.Array.remove(keys, oldKey);
                    }

                    return null;
                }
                // If the item was filtered, but now it is not anymore then we
                // add to the length
                else if (oldItemsLn === items.length) {
                    me.length++;
                    returnItem = item;
                }
            }

            if (!subjectToOptimize) {
                index = this.findInsertionIndex(items, item);

                Ext.Array.splice(keys, index, 0, newKey);
                Ext.Array.splice(items, index, 0, item);
            } else {
                index = this.findInsertionIndex(items, item, undefined, true);

                move(keys, itemsFrom, index);
                move(items, itemsFrom, index);
            }
        } else {
            if (filtered) {
                if (me.getAutoFilter() && filterable.isFiltered.call(me, item)) {
                    if (me.indexOf(oldItem) !== -1) {
                        Ext.Array.remove(items, oldItem);
                        Ext.Array.remove(keys, oldKey);
                        me.length--;
                        me.dirtyIndices = true;
                    }
                    return null;
                }
                else if (me.indexOf(oldItem) === -1) {
                    items.push(item);
                    keys.push(newKey);
                    me.indices[newKey] = me.length;
                    me.length++;
                    return item;
                }
            }

            index = me.indexOf(oldItem);

            keys[index] = newKey;
            items[index] = item;

            if (newKey !== oldKey) {
                this.dirtyIndices = true;
            }
        }

        return returnItem;


        function move(array, from, to) {
            if( to === from ) return;

            var target = array[from];
            var increment = to < from ? -1 : 1;

            for(var k = from; k != to; k += increment){
                array[k] = array[k + increment];
            }
            array[to] = target;
        }
    }
function(oldKey, item) {
        var me = this,
            sorted = me.sorted,
            presorted = me.presorted,
            filtered = me.filtered,
            filterable = me.mixins.filterable,
            items = me.items,
            keys = me.keys,
            all = me.all,
            map = me.map,
            returnItem = null,
            oldItemsLn = items.length,
            subjectToOptimize = false,
            oldItem, index, newKey;

        if (arguments.length == 1) {
            item = oldKey;
            oldKey = newKey = me.getKey(item);
            subjectToOptimize = true;
        } else {
            newKey = me.getKey(item);
        }

        oldItem = map[oldKey];
        if (typeof oldKey == 'undefined' || oldKey === null || typeof oldItem == 'undefined') {
            return me.add(newKey, item);
        }

        me.map[newKey] = item;
        if (newKey !== oldKey) {
            delete me.map[oldKey];
        }

        if (sorted && me.getAutoSort()) {
            if (!subjectToOptimize) {
                Ext.Array.remove(items, oldItem);
                Ext.Array.remove(keys, oldKey);
            } else {
                var itemsFrom = items.indexOf(oldItem);
            }
            if (!presorted) {
                Ext.Array.remove(all, oldItem);
                all.push(item);
                me.dirtyIndices = true;
            } else {
                var allTo = this.findInsertionIndex(all, item, undefined, true),
                    allFrom = all.indexOf(item);

                if (allTo !== allFrom) {
                    move(all, allFrom, allTo);
                    me.dirtyIndices = true;
                }
            }

            if (filtered && me.getAutoFilter()) {
                // If the item is now filtered we check if it was not filtered
                // before. If that is the case then we subtract from the length
                if (filterable.isFiltered.call(me, item)) {
                    if (oldItemsLn !== items.length) {
                        me.length--;
                    }

                    if (subjectToOptimize) {
                        Ext.Array.remove(items, oldItem);
                        Ext.Array.remove(keys, oldKey);
                    }

                    return null;
                }
                // If the item was filtered, but now it is not anymore then we
                // add to the length
                else if (oldItemsLn === items.length) {
                    me.length++;
                    returnItem = item;
                }
            }

            if (!subjectToOptimize) {
                index = this.findInsertionIndex(items, item);

                Ext.Array.splice(keys, index, 0, newKey);
                Ext.Array.splice(items, index, 0, item);
            } else {
                index = this.findInsertionIndex(items, item, undefined, true);

                move(keys, itemsFrom, index);
                move(items, itemsFrom, index);
            }
        } else {
            if (filtered) {
                if (me.getAutoFilter() && filterable.isFiltered.call(me, item)) {
                    if (me.indexOf(oldItem) !== -1) {
                        Ext.Array.remove(items, oldItem);
                        Ext.Array.remove(keys, oldKey);
                        me.length--;
                        me.dirtyIndices = true;
                    }
                    return null;
                }
                else if (me.indexOf(oldItem) === -1) {
                    items.push(item);
                    keys.push(newKey);
                    me.indices[newKey] = me.length;
                    me.length++;
                    return item;
                }
            }

            index = me.indexOf(oldItem);

            keys[index] = newKey;
            items[index] = item;

            if (newKey !== oldKey) {
                this.dirtyIndices = true;
            }
        }

        return returnItem;


        function move(array, from, to) {
            if( to === from ) return;

            var target = array[from];
            var increment = to < from ? -1 : 1;

            for(var k = from; k != to; k += increment){
                array[k] = array[k + increment];
            }
            array[to] = target;
        }
    }
function ( oldKey , item ) { var me = this , sorted = me . sorted , presorted = me . presorted , filtered = me . filtered , filterable = me . mixins . filterable , items = me . items , keys = me . keys , all = me . all , map = me . map , returnItem = null , oldItemsLn = items . length , subjectToOptimize = false , oldItem , index , newKey ; if ( arguments . length == 1 ) { item = oldKey ; oldKey = newKey = me . getKey ( item ) ; subjectToOptimize = true ; } else { newKey = me . getKey ( item ) ; } oldItem = map [ oldKey ] ; if ( typeof oldKey == 'undefined' || oldKey === null || typeof oldItem == 'undefined' ) { return me . add ( newKey , item ) ; } me . map [ newKey ] = item ; if ( newKey !== oldKey ) { delete me . map [ oldKey ] ; } if ( sorted && me . getAutoSort ( ) ) { if ( ! subjectToOptimize ) { Ext . Array . remove ( items , oldItem ) ; Ext . Array . remove ( keys , oldKey ) ; } else { var itemsFrom = items . indexOf ( oldItem ) ; } if ( ! presorted ) { Ext . Array . remove ( all , oldItem ) ; all . push ( item ) ; me . dirtyIndices = true ; } else { var allTo = this . findInsertionIndex ( all , item , undefined , true ) , allFrom = all . indexOf ( item ) ; if ( allTo !== allFrom ) { move ( all , allFrom , allTo ) ; me . dirtyIndices = true ; } } if ( filtered && me . getAutoFilter ( ) ) { // If the item is now filtered we check if it was not filtered // before. If that is the case then we subtract from the length if ( filterable . isFiltered . call ( me , item ) ) { if ( oldItemsLn !== items . length ) { me . length -- ; } if ( subjectToOptimize ) { Ext . Array . remove ( items , oldItem ) ; Ext . Array . remove ( keys , oldKey ) ; } return null ; } // If the item was filtered, but now it is not anymore then we // add to the length else if ( oldItemsLn === items . length ) { me . length ++ ; returnItem = item ; } } if ( ! subjectToOptimize ) { index = this . findInsertionIndex ( items , item ) ; Ext . Array . splice ( keys , index , 0 , newKey ) ; Ext . Array . splice ( items , index , 0 , item ) ; } else { index = this . findInsertionIndex ( items , item , undefined , true ) ; move ( keys , itemsFrom , index ) ; move ( items , itemsFrom , index ) ; } } else { if ( filtered ) { if ( me . getAutoFilter ( ) && filterable . isFiltered . call ( me , item ) ) { if ( me . indexOf ( oldItem ) !== - 1 ) { Ext . Array . remove ( items , oldItem ) ; Ext . Array . remove ( keys , oldKey ) ; me . length -- ; me . dirtyIndices = true ; } return null ; } else if ( me . indexOf ( oldItem ) === - 1 ) { items . push ( item ) ; keys . push ( newKey ) ; me . indices [ newKey ] = me . length ; me . length ++ ; return item ; } } index = me . indexOf ( oldItem ) ; keys [ index ] = newKey ; items [ index ] = item ; if ( newKey !== oldKey ) { this . dirtyIndices = true ; } } return returnItem ; function move ( array , from , to ) { if ( to === from ) return ; var target = array [ from ] ; var increment = to < from ? - 1 : 1 ; for ( var k = from ; k != to ; k += increment ) { array [ k ] = array [ k + increment ] ; } array [ to ] = target ; } }
Replaces an item in the collection. Fires the {@link #replace} event when complete.
@param {String} oldKey

The key associated with the item to replace, or the replacement item.

If you supplied a {@link #getKey} implementation for this MixedCollection, or if the key of your stored items is
in a property called **id**, then the MixedCollection will be able to _derive_ the key of the replacement item.
If you want to replace an item with one having the same key value, then just pass the replacement item in this
parameter.
@param {Object} item {Object} item (optional) If the first parameter passed was a key, the item to associate with
that key.
@return {Object} The new item.
Replaces an item in the collection . Fires the { @link #replace } event when complete . @param { String } oldKey