docs: function xhr(mockHandler, requestSettings, origSettings, origHandler) {
  		// Extend with our default mockjax settings
  		mockHandler = $.extend(true, {}, $.mockjaxSettings, mockHandler);
  
  		if (typeof mockHandler.headers === 'undefined') {
  			mockHandler.headers = {};
  		}
  		if (typeof requestSettings.headers === 'undefined') {
  			requestSettings.headers = {};
  		}
  		if ( mockHandler.contentType ) {
  			mockHandler.headers['content-type'] = mockHandler.contentType;
  		}
  
  		return {
  			status: mockHandler.status,
  			statusText: mockHandler.statusText,
  			readyState: 1,
  			open: function() { },
  			send: function() {
  				origHandler.fired = true;
  				_xhrSend.call(this, mockHandler, requestSettings, origSettings);
  			},
  			abort: function() {
  				clearTimeout(this.responseTimer);
  			},
  			setRequestHeader: function(header, value) {
  				requestSettings.headers[header] = value;
  			},
  			getResponseHeader: function(header) {
  				// 'Last-modified', 'Etag', 'content-type' are all checked by jQuery
  				if ( mockHandler.headers && mockHandler.headers[header] ) {
  					// Return arbitrary headers
  					return mockHandler.headers[header];
  				} else if ( header.toLowerCase() == 'last-modified' ) {
  					return mockHandler.lastModified || (new Date()).toString();
  				} else if ( header.toLowerCase() == 'etag' ) {
  					return mockHandler.etag || '';
  				} else if ( header.toLowerCase() == 'content-type' ) {
  					return mockHandler.contentType || 'text/plain';
  				}
  			},
  			getAllResponseHeaders: function() {
  				var headers = '';
  				// since jQuery 1.9 responseText type has to match contentType
  				if (mockHandler.contentType) {
  					mockHandler.headers['Content-Type'] = mockHandler.contentType;
  				}
  				$.each(mockHandler.headers, function(k, v) {
  					headers += k + ': ' + v + "\n";
  				});
  				return headers;
  			}
  		};
  	}