function _fnSort(oSettings, col, dir) {
		var
			i, ien, iLen,
			aiOrig = [],
			extSort = DataTable.ext.type.order,
			aoData = oSettings.aoData,
			sortCol,
			displayMaster = oSettings.aiDisplayMaster,
			aSort;

		// Resolve any column types that are unknown due to addition or invalidation
		// @todo Can this be moved into a 'data-ready' handler which is called when
		//   data is going to be used in the table?
		_fnColumnTypes(oSettings);

		// Allow a specific column to be sorted, which will _not_ alter the display
		// master
		if (col !== undefined) {
			var srcCol = oSettings.aoColumns[col];
			aSort = [{
				src: col,
				col: col,
				dir: dir,
				index: 0,
				type: srcCol.sType,
				formatter: extSort[srcCol.sType + "-pre"],
				sorter: extSort[srcCol.sType + "-" + dir]
			}];
			displayMaster = displayMaster.slice();
		}
		else {
			aSort = _fnSortFlatten(oSettings);
		}

		for (i = 0, ien = aSort.length; i < ien; i++) {
			sortCol = aSort[i];

			// Load the data needed for the sort, for each cell
			_fnSortData(oSettings, sortCol.col);
		}

		/* No sorting required if server-side or no sorting array */
		if (_fnDataSource(oSettings) != 'ssp' && aSort.length !== 0) {
			// Reset the initial positions on each pass so we get a stable sort
			for (i = 0, iLen = displayMaster.length; i < iLen; i++) {
				aiOrig[i] = i;
			}

			// If the first sort is desc, then reverse the array to preserve original
			// order, just in reverse
			if (aSort.length && aSort[0].dir === 'desc') {
				aiOrig.reverse();
			}

			/* Do the sort - here we want multi-column sorting based on a given data source (column)
			 * and sorting function (from oSort) in a certain direction. It's reasonably complex to
			 * follow on it's own, but this is what we want (example two column sorting):
			 *  fnLocalSorting = function(a,b){
			 *    var test;
			 *    test = oSort['string-asc']('data11', 'data12');
			 *      if (test !== 0)
			 *        return test;
			 *    test = oSort['numeric-desc']('data21', 'data22');
			 *    if (test !== 0)
			 *      return test;
			 *    return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
			 *  }
			 * Basically we have a test for each sorting column, if the data in that column is equal,
			 * test the next column. If all columns match, then we use a numeric sort on the row
			 * positions in the original data array to provide a stable sort.
			 */
			displayMaster.sort(function (a, b) {
				var
					x, y, k, test, sort,
					len = aSort.length,
					dataA = aoData[a]._aSortData,
					dataB = aoData[b]._aSortData;

				for (k = 0; k < len; k++) {
					sort = aSort[k];

					// Data, which may have already been through a `-pre` function
					x = dataA[sort.col];
					y = dataB[sort.col];

					if (sort.sorter) {
						// If there is a custom sorter (`-asc` or `-desc`) for this
						// data type, use it
						test = sort.sorter(x, y);

						if (test !== 0) {
							return test;
						}
					}
					else {
						// Otherwise, use generic sorting
						test = x < y ? -1 : x > y ? 1 : 0;

						if (test !== 0) {
							return sort.dir === 'asc' ? test : -test;
						}
					}
				}

				x = aiOrig[a];
				y = aiOrig[b];

				return x < y ? -1 : x > y ? 1 : 0;
			});
		}
		else if (aSort.length === 0) {
			// Apply index order
			displayMaster.sort(function (x, y) {
				return x < y ? -1 : x > y ? 1 : 0;
			});
		}

		if (col === undefined) {
			// Tell the draw function that we have sorted the data
			oSettings.bSorted = true;

			_fnCallbackFire(oSettings, null, 'order', [oSettings, aSort]);
		}

		return displayMaster;
	}
Change the order of the table
 @param {object} oSettings dataTables settings object
 @memberof DataTable#oApi