function _fnBuildAjax(oSettings, data, fn) {
		var ajaxData;
		var ajax = oSettings.ajax;
		var instance = oSettings.oInstance;
		var callback = function (json) {
			var status = oSettings.jqXHR
				? oSettings.jqXHR.status
				: null;

			if (json === null || (typeof status === 'number' && status == 204)) {
				json = {};
				_fnAjaxDataSrc(oSettings, json, []);
			}

			var error = json.error || json.sError;
			if (error) {
				_fnLog(oSettings, 0, error);
			}

			oSettings.json = json;

			_fnCallbackFire(oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR], true);
			fn(json);
		};

		if ($.isPlainObject(ajax) && ajax.data) {
			ajaxData = ajax.data;

			var newData = typeof ajaxData === 'function' ?
				ajaxData(data, oSettings) :  // fn can manipulate data or return
				ajaxData;                      // an object object or array to merge

			// If the function returned something, use that alone
			data = typeof ajaxData === 'function' && newData ?
				newData :
				$.extend(true, data, newData);

			// Remove the data property as we've resolved it already and don't want
			// jQuery to do it again (it is restored at the end of the function)
			delete ajax.data;
		}

		var baseAjax = {
			"url": typeof ajax === 'string' ?
				ajax :
				'',
			"data": data,
			"success": callback,
			"dataType": "json",
			"cache": false,
			"type": oSettings.sServerMethod,
			"error": function (xhr, error) {
				var ret = _fnCallbackFire(oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR], true);

				if (ret.indexOf(true) === -1) {
					if (error == "parsererror") {
						_fnLog(oSettings, 0, 'Invalid JSON response', 1);
					}
					else if (xhr.readyState === 4) {
						_fnLog(oSettings, 0, 'Ajax error', 7);
					}
				}

				_fnProcessingDisplay(oSettings, false);
			}
		};

		// If `ajax` option is an object, extend and override our default base
		if ($.isPlainObject(ajax)) {
			$.extend(baseAjax, ajax)
		}

		// Store the data submitted for the API
		oSettings.oAjaxData = data;

		// Allow plug-ins and external processes to modify the data
		_fnCallbackFire(oSettings, null, 'preXhr', [oSettings, data, baseAjax], true);

		if (typeof ajax === 'function') {
			// Is a function - let the caller define what needs to be done
			oSettings.jqXHR = ajax.call(instance, data, callback, oSettings);
		}
		else if (ajax.url === '') {
			callback({});
		}
		else {
			// Object to extend the base settings
			oSettings.jqXHR = $.ajax(baseAjax);

			// Restore for next time around
			if (ajaxData) {
				ajax.data = ajaxData;
			}
		}
	}
Create an Ajax call based on the table's settings, taking into account that
parameters can have multiple forms, and backwards compatibility.

@param {object} oSettings dataTables settings object
@param {array} data Data to send to the server, required by
    DataTables - may be augmented by developer callbacks
@param {function} fn Callback function to run when data is obtained