docs: function( elem, types, handler, data ) {
  		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
  			return;
  		}
  
  		// For whatever reason, IE has trouble passing the window object
  		// around, causing it to be cloned in the process
  		if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
  			elem = window;
  		}
  
  		// Make sure that the function being executed has a unique ID
  		if ( !handler.guid ) {
  			handler.guid = jQuery.guid++;
  		}
  
  		// if data is passed, bind to handler
  		if ( data !== undefined ) {
  			// Create temporary function pointer to original handler
  			var fn = handler;
  
  			// Create unique handler function, wrapped around original handler
  			handler = jQuery.proxy( fn );
  
  			// Store data in unique handler
  			handler.data = data;
  		}
  
  		// Init the element's event structure
  		var events = jQuery.data( elem, "events" ) || jQuery.data( elem, "events", {} ),
  			handle = jQuery.data( elem, "handle" ), eventHandle;
  
  		if ( !handle ) {
  			eventHandle = function() {
  				// Handle the second event of a trigger and when
  				// an event is called after a page has unloaded
  				return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
  					jQuery.event.handle.apply( eventHandle.elem, arguments ) :
  					undefined;
  			};
  
  			handle = jQuery.data( elem, "handle", eventHandle );
  		}
  
  		// If no handle is found then we must be trying to bind to one of the
  		// banned noData elements
  		if ( !handle ) {
  			return;
  		}
  
  		// Add elem as a property of the handle function
  		// This is to prevent a memory leak with non-native
  		// event in IE.
  		handle.elem = elem;
  
  		// Handle multiple events separated by a space
  		// jQuery(...).bind("mouseover mouseout", fn);
  		types = types.split( /\s+/ );
  
  		var type, i = 0;
  
  		while ( (type = types[ i++ ]) ) {
  			// Namespaced event handlers
  			var namespaces = type.split(".");
  			type = namespaces.shift();
  
  			if ( i > 1 ) {
  				handler = jQuery.proxy( handler );
  
  				if ( data !== undefined ) {
  					handler.data = data;
  				}
  			}
  
  			handler.type = namespaces.slice(0).sort().join(".");
  
  			// Get the current list of functions bound to this event
  			var handlers = events[ type ],
  				special = this.special[ type ] || {};
  
  			// Init the event handler queue
  			if ( !handlers ) {
  				handlers = events[ type ] = {};
  
  				// Check for a special event handler
  				// Only use addEventListener/attachEvent if the special
  				// events handler returns false
  				if ( !special.setup || special.setup.call( elem, data, namespaces, handler) === false ) {
  					// Bind the global event handler to the element
  					if ( elem.addEventListener ) {
  						elem.addEventListener( type, handle, false );
  					} else if ( elem.attachEvent ) {
  						elem.attachEvent( "on" + type, handle );
  					}
  				}
  			}
  
  			if ( special.add ) {
  				var modifiedHandler = special.add.call( elem, handler, data, namespaces, handlers );
  				if ( modifiedHandler && jQuery.isFunction( modifiedHandler ) ) {
  					modifiedHandler.guid = modifiedHandler.guid || handler.guid;
  					modifiedHandler.data = modifiedHandler.data || handler.data;
  					modifiedHandler.type = modifiedHandler.type || handler.type;
  					handler = modifiedHandler;
  				}
  			}
  
  			// Add the function to the element's handler list
  			handlers[ handler.guid ] = handler;
  
  			// Keep track of which events have been used, for global triggering
  			this.global[ type ] = true;
  		}
  
  		// Nullify elem to prevent memory leaks in IE
  		elem = null;
  	}