YAHOO = { };

YAHOO.lang = {
    /**
     * Applies all properties in the supplier to the receiver if the
     * receiver does not have these properties yet.  Optionally, one or 
     * more methods/properties can be specified (as additional parameters). 
     * This option will overwrite the property if receiver 
     * has it already.  If true is passed as the third parameter, all 
     * properties will be applied and _will_ overwrite properties in 
     * the receiver.
     *
     * @method augmentObject
     * @static
     * @since 2.3.0
     * @param {Function} r  the object to receive the augmentation
     * @param {Function} s  the object that supplies the properties to augment
     * @param {String*|boolean}  arguments zero or more properties methods 
     *        to augment the receiver with.  If none specified, everything
     *        in the supplier will be used unless it would
     *        overwrite an existing property in the receiver. If true
     *        is specified as the third parameter, all properties will
     *        be applied and will overwrite an existing property in
     *        the receiver
     */
    augmentObject: function(r, s) {
        if (!s||!r) {
            throw new Error("Absorb failed, verify dependencies.");
        }
        var a=arguments, i, p, override=a[2];
        if (override &amp;&amp; override !== true) { // only absorb the specified properties
            for ( i=2; i &lt; a.length; i = i+1) {
                r[a[i]] = s[a[i]];
            }
        } else { // take everything, overwriting only if the third parameter is true
            for (p in s) { 
                if (override || <b class='incorrect'>!r[p]</b>) {
                    r[p] = s[p];
                }
            }
            
            YAHOO.lang._IEEnumFix<b class="incorrect">(r, s)</b>;
        }
    },
    
    _IEEnumFix: function(r, s) {
        if (<b class="incorrect">YAHOO.env.ua.ie</b>) {
            var add=["toString", "valueOf"];
            for (i=0;i &lt; add.length;i=i+1) {
                var fname=add[i],f=s[fname];
                if (YAHOO.lang.isFunction(f) &amp;&amp; f!=Object.prototype[fname]) {
                    r[fname]=f;
                }
            }
        }
    },

    isFunction : function( o ) {
        return typeof o === "function";
    }
};

// I'm not copying over YAHOO's full env and YAHOO_Config packages just for this example.
YAHOO.env = {
	ua : function() {
		var o = { ie:0, opera:0 }, ua=navigator.userAgent, m = ua.match(/Opera[\s\/]([^\s]*)/);
		if (m &amp;&amp; m[1]) o.opera = parseFloat(m[1]); 
		else {
			m = ua.match(/MSIE\s([^;]*)/);
			if (m &amp;&amp; m[1]) o.ie = parseFloat(m[1]);
		}
		return o;
	}()
};

//------------------------------------------------------------------
var r = { 
    _draggable : false
    ,isDraggable : function() { return this._draggable }
    ,valueOf : function() { return 1; }
};
var s = {
    _draggable : true
    ,valueOf : function() { return 2; }
    ,toString : function() { return 's'; }
};

YAHOO.lang.augmentObject(r, s);

return [
    r.isDraggable(),
    r.valueOf(),
    r.toString()
].join(String.nl); // true 1 [object Object].
