### Question:
IndirectSort { public static int[] mergesort(int start, int length, IntBinaryOperator comparator) { final int[] src = createOrderArray(start, length); if (length > 1) { final int[] dst = (int[]) src.clone(); topDownMergeSort(src, dst, 0, length, comparator); return dst; } return src; } private  IndirectSort(); static int[] mergesort(int start, int length, IntBinaryOperator comparator); static int[] mergesort(
      T[] input, int start, int length, Comparator<? super T> comparator);  }### Answer:
@Test public void testEmptyAndSingle() { int[] mSortOrder = IndirectSort.mergesort(0, 0, Integer::compare); Assert.assertEquals(mSortOrder.length, 0); for (int i = 0; i < 1000; i++) { mSortOrder = IndirectSort.mergesort(0, i, Integer::compare); Assert.assertEquals(mSortOrder.length, i); } }
@Test public void testOrderedMergeSort() { int[] order = IndirectSort.mergesort(0, DATA_LENGTH, Integer::compare); assertOrder(order, DATA_LENGTH, Integer::compare); }
@Test public void testAscInt() { final int maxSize = 500; final int rounds = 1000; final int vocabulary = 10; final Random rnd = new Random(0x11223344); for (int round = 0; round < rounds; round++) { final int[] input = generateRandom(maxSize, vocabulary, rnd); final int start = rnd.nextInt(input.length - 1); final int length = (input.length - start); IntBinaryOperator intBinaryOperator = (a, b) -> Integer.compare(input[a], input[b]); int[] order = IndirectSort.mergesort(start, length, intBinaryOperator); assertOrder(order, length, intBinaryOperator); } }
@Test public void testAscDouble() { final int maxSize = 1000; final int rounds = 1000; final Random rnd = new Random(0x11223344); for (int round = 0; round < rounds; round++) { final double[] input = generateRandom(maxSize, rnd); final IntBinaryOperator comparator = (a, b) -> Double.compare(input[a], input[b]); final int start = rnd.nextInt(input.length - 1); final int length = (input.length - start); int[] order = IndirectSort.mergesort(start, length, comparator); assertOrder(order, length, comparator); } }
@Test public void testMergeSortIsStable() { final XorShift128P rnd = new XorShift128P(0xdeadbeefL); final int[] data = new int[10000]; for (int i = 0; i < data.length; i++) { data[i] = rnd.nextInt(0x100); } int[] order = IndirectSort.mergesort( 0, data.length, (indexA, indexB) -> (data[indexA] & 0xf0) - (data[indexB] & 0xf0)); for (int i = 1; i < order.length; i++) { if ((data[order[i - 1]] & 0xf0) == (data[order[i]] & 0xf0)) { assertTrue(order[i - 1] < order[i]); } } }