src/it/unimi/dsi/fastutil/Arrays.java
public static void mergeSort(final int from, final int to, final IntComparator c, final Swapper swapper) {
		/*
		 * We retain the same method signature as quickSort. Given only a comparator and swapper we
		 * do not know how to copy and move elements from/to temporary arrays. Hence, in contrast to
		 * the JDK mergesorts this is an "in-place" mergesort, i.e. does not allocate any temporary
		 * arrays. A non-inplace mergesort would perhaps be faster in most cases, but would require
		 * non-intuitive delegate objects...
		 */
		final int length = to - from;

		// Insertion sort on smallest arrays
		if (length < MERGESORT_NO_REC) {
			for (int i = from; i < to; i++) {
				for (int j = i; j > from && (c.compare(j - 1, j) > 0); j--) {
					swapper.swap(j, j - 1);
				}
			}
			return;
		}

		// Recursively sort halves
		int mid = (from + to) >>> 1;
		mergeSort(from, mid, c, swapper);
		mergeSort(mid, to, c, swapper);

		// If list is already sorted, nothing left to do. This is an
		// optimization that results in faster sorts for nearly ordered lists.
		if (c.compare(mid - 1, mid) <= 0) return;

		// Merge sorted halves
		inPlaceMerge(from, mid, to, c, swapper);
	}
public static void mergeSort(final int from, final int to, final IntComparator c, final Swapper swapper) {
		/*
		 * We retain the same method signature as quickSort. Given only a comparator and swapper we
		 * do not know how to copy and move elements from/to temporary arrays. Hence, in contrast to
		 * the JDK mergesorts this is an "in-place" mergesort, i.e. does not allocate any temporary
		 * arrays. A non-inplace mergesort would perhaps be faster in most cases, but would require
		 * non-intuitive delegate objects...
		 */
		final int length = to - from;

		// Insertion sort on smallest arrays
		if (length < MERGESORT_NO_REC) {
			for (int i = from; i < to; i++) {
				for (int j = i; j > from && (c.compare(j - 1, j) > 0); j--) {
					swapper.swap(j, j - 1);
				}
			}
			return;
		}

		// Recursively sort halves
		int mid = (from + to) >>> 1;
		mergeSort(from, mid, c, swapper);
		mergeSort(mid, to, c, swapper);

		// If list is already sorted, nothing left to do. This is an
		// optimization that results in faster sorts for nearly ordered lists.
		if (c.compare(mid - 1, mid) <= 0) return;

		// Merge sorted halves
		inPlaceMerge(from, mid, to, c, swapper);
	}
Sorts the specified range of elements using the specified swapper and according to the order induced by the specified
comparator using mergesort.

<p>This sort is guaranteed to be <i>stable</i>: equal elements will not be reordered as a result
of the sort. The sorting algorithm is an in-place mergesort that is significantly slower than a
standard mergesort, as its running time is <i>O</i>(<var>n</var>&nbsp;(log&nbsp;<var>n</var>)<sup>2</sup>), but it does not allocate additional memory; as a result, it can be
used as a generic sorting algorithm.

@param from the index of the first element (inclusive) to be sorted.
@param to the index of the last element (exclusive) to be sorted.
@param c the comparator to determine the order of the generic data (arguments are positions).
@param swapper an object that knows how to swap the elements at any two positions.