(function ($){

    var items = [],

    keys = [],

    maximum = null,

    size = 0;

    function cache (key, value) {

        return (typeof(value) === 'undefined') ? items[key] : push(key, value);

    }

    function empty () {

        return limit(0);

    }

    function exists (key) {

        return (typeof(items[key]) !== 'undefined');

    }

    function limit (number) {

        var removed = 0;

        if (typeof(number) === 'number') {

            number = parseInt(number);

            if (number < 0) number = 0;

            maximum = number;

            while (size > maximum) {

                shift();

                ++removed;

            }

        }

        else maximum = null;

        return removed;

    }

    function pop () {

        return remove(keys.pop());

    }

    function push (key, value) {

        keys.push(key);

        if (typeof(items[key]) === 'undefined') ++size;

        items[key] = value;

        if ((maximum !== null) && (size > maximum)) shift();

        return size;

    }

    function remove (key) {

        var removed;

        if (typeof(items[key]) !== 'undefined') {

            removed = items[key];

            delete items[key];

            --size;

        }

        return removed;

    }

    function shift () {

        return remove(keys.shift());

    }

    function unshift (key, value) {

        keys.unshift(key);

        if (typeof(items[key]) === 'undefined') ++size;

        items[key] = value;

        if ((maximum !== null) && (size > maximum)) pop();

        return size;

    }

    $.cache = $.extend(cache, {
        empty: empty,
        exists: exists,
        limit: limit,
        pop: pop,
        push: push,
        remove: remove,
        shift: shift,
        unshift: unshift
    });

})(jQuery);