jQuery.fn.chain = function(){
	var args = jQuery.makeArray(arguments), name = args.shift();
	var self = jQuery(this), depth = 0, cur = this._orig || this;

	self._chain = [];
	self._orig = this;

	args.push(function(){
		for ( var i = 0; i < self._chain.length; i++ )
			cur = jQuery.fn[ self._chain[i][0] ].apply( cur, self._chain[i][1] );
	});

	for ( var method in self )
		if ( typeof self[ method ] === "function" && method !== "chain" ) (function(method){
			var push = /pushStack/.test( self[ method ] + "" );

			self[ method ] = function(){
				if ( method === "end" && depth-- === 0 ) {
					if ( self._orig._chain ) {
						self._orig._chain.push([ name, args ]);
						return self._orig;
					} else {
						return jQuery.fn[ name ].apply( self._orig, args );
					}
				}

				self._chain.push([ method, arguments ]);

				if ( push )
					depth++;

				return this;
			};
		})(method);

	return self;
};
