function isArray (arr) {
    return Object.prototype.toString.call(arr) === '[object Array]';
}

function isObject (obj) {
    return Object.prototype.toString.call(obj) === '[object Object]';
}

function isFunction (fn) {
    return Object.prototype.toString.call(fn) === '[object Function]';
}

function trim (string) {
    return string.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
}

/*
 * Styles
 * - .css()
 * - .hasClass()
 * - .addClass(), .removeClass()
 */

// TODO: make sure setting with numbers works.
// currently faster than jQuery - no metrics yet.
$.fn.css = function (property, value) {

    if (!property) {
        return this;
    }

    var i = 0,
        len;

    if (!value) { // getting CSS or setting with object

        if (isObject(property)) { // set CSS with object

            for (len = this.length; i < len; i++) {
                for (var key in property) {
                    if (property.hasOwnProperty(key)) {
                        this[i].style[key] = property[key];
                    }
                }
            }

            return this;

        } else { // get CSS of first elem in collection with string or array of properties
            var result = {};

            if (typeof property === 'string') {
                return getStyle(this[0], property);
            } else if (isArray(property)) {
                for (len = property.length; i < len; i++) {
                    result[property[i]] = getStyle(this[0], property[i]);
                }
                return result;
            } else {
                return this; // is this fail safe necessary? should we error if improper params are passed?
            }
        }

    } else { // set string CSS property with string/num value or return from function

        if (isFunction(value)) {
            for (len = this.length; i < len; i++) {
                this[i].style[property] = value.call(this[0], i, getStyle(this[i], property)); // fn gets elem as this and params (index, current style) 
            }
        } else {
            for (len = this.length; i < len; i++) {
                this[i].style[property] = value;
            }
        }

        return this;
    }

    // IE8 POLYFILL:
    function getStyle (elem, prop) {
        // while setting CSS can be done with either camel-cased or dash-separated properties
        // getting computed CSS properties is persnickety about formatting

        if (typeof window.getComputedStyle === 'undefined') { // IE8 POLYFILL
            prop = prop === 'float' ? 
                'styleFloat' : 
                prop.replace(/^-ms-/, 'ms-').replace(/-([a-z])/gi, function (all, letter) { // insure that property is camel cased
                    return letter.toUpperCase();
                });
            return elem.currentStyle[prop];
        } else {
            prop = prop.replace(/[A-Z]/g, function (match) { // insure the property is dash-separated
                return '-' + match.toLowerCase();
            });
            return window.getComputedStyle(elem, null).getPropertyValue(prop);
        }
    }
};

$.fn.hasClass = function (className) {
    // ripped nearly word for word from jQuery. Thanks, open source world.
    for (var i = 0, len = this.length; i < len; i++) {
        if (this[i].nodeType === 1 && (' ' + this[i].className + ' ').replace(/[\t\r\n\f]/g, ' ').indexOf(className) >= 0) {
            return true;
        }
    }

    return false;
};

$.fn.addClass = function (value) {

    if (!value) {
        return this;
    }

    var i = 0, 
        len = this.length;

    if (typeof value === 'string') {

        // value.split(' ') is faster & more readable but ' klass', would return [' ', 'klass']
        var classes = (value || '').match(/\S+/g) || []; // gotta use jQuery's regexp.

        for (; i < len; i++) {
            var currentClasses = (' ' + this[i].className + ' ').replace(/[\t\r\n\f]/g, ' '),
                newClasses = '';

            for (var j = 0, classLen = classes.length; j < classLen; j++) {
                if (currentClasses.indexOf(classes[j]) < 0) {
                    newClasses += classes[j] + (j !== classLen-1 ? ' ' : '');
                }
            }

            if (trim(newClasses) !== currentClasses) {
                this[i].className = newClasses;
            }
        }
    } else if (isFunction(value)) {
        for (; i < len; i++) {
            // have to pass node recusively in an array so it registers in the add class loop
            $.fn.addClass.call([this[i]], value.call(this, i, this[i].className));
        }
    }

    return this;
};


@@ -3527,37 +3527,51 @@
 %7B%0A        return
+ $.merge($(),
  this
+)
 ;%0A    %7D%0A%0A    var
@@ -4360,24 +4360,61 @@
 %7D%0A        %7D%0A
+%0A        return $.merge($(), this);%0A%0A
     %7D else i
@@ -4429,32 +4429,59 @@
 ction(value)) %7B%0A
+%0A        var result = %5B%5D;%0A%0A
         for (; i
@@ -4601,16 +4601,28 @@
         
+result.push(
 $.fn.add
@@ -4682,16 +4682,17 @@
 ssName))
+)
 ;%0A      
@@ -4687,39 +4687,37 @@
 e)));%0A        %7D%0A
+%0A
     
-%7D%0A%0A
     return this;
@@ -4711,18 +4711,40 @@
  return 
-this;
+$.merge($(), result);%0A    %7D
 %0A%7D;%0A%0A

fix return for recursing addClass