docs: function(elem, types, handler) {
  		// don't do events on text and comment nodes
  		if ( elem.nodeType == 3 || elem.nodeType == 8 )
  			return;
  
  		var events = jQuery.data(elem, "events"), ret, index;
  
  		if ( events ) {
  			// Unbind all events for the element
  			if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") )
  				for ( var type in events )
  					this.remove( elem, type + (types || "") );
  			else {
  				// types is actually an event object here
  				if ( types.type ) {
  					handler = types.handler;
  					types = types.type;
  				}
  
  				// Handle multiple events seperated by a space
  				// jQuery(...).unbind("mouseover mouseout", fn);
  				jQuery.each(types.split(/\s+/), function(index, type){
  					// Namespaced event handlers
  					var namespaces = type.split(".");
  					type = namespaces.shift();
  					var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
  
  					if ( events[type] ) {
  						// remove the given handler for the given type
  						if ( handler )
  							delete events[type][handler.guid];
  
  						// remove all handlers for the given type
  						else
  							for ( var handle in events[type] )
  								// Handle the removal of namespaced events
  								if ( namespace.test(events[type][handle].type) )
  									delete events[type][handle];
  									
  						if ( jQuery.event.specialAll[type] )
  							jQuery.event.specialAll[type].teardown.call(elem, namespaces);
  
  						// remove generic event handler if no more handlers exist
  						for ( ret in events[type] ) break;
  						if ( !ret ) {
  							if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
  								if (elem.removeEventListener)
  									elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
  								else if (elem.detachEvent)
  									elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
  							}
  							ret = null;
  							delete events[type];
  						}
  					}
  				});
  			}
  
  			// Remove the expando if it's no longer used
  			for ( ret in events ) break;
  			if ( !ret ) {
  				var handle = jQuery.data( elem, "handle" );
  				if ( handle ) handle.elem = null;
  				jQuery.removeData( elem, "events" );
  				jQuery.removeData( elem, "handle" );
  			}
  		}
  	}