@Test(timeout = TIMEOUT)
  public void testMergeSort() {
    DValue[] arrZero = new DValue[0];
    Sorting.mergeSort(arrZero, new BasicComparator());
    assertEquals(0, arrZero.length);
    DValue[] arrOne = new DValue[1];
    arrOne[0] = new DValue(4, 0);
    Sorting.mergeSort(arrOne, new BasicComparator());
    assertEquals(1, arrOne.length);
    assertEquals(4, arrOne[0].val.intValue());

    Random rand = new Random();
    HashMap<Integer, Integer> values = new HashMap<Integer, Integer>();
    for (int i = 0; i < 50; i++) {
      int arrlen = rand.nextInt(1000) + 2;
      DValue[] arrMany = new DValue[arrlen];
      DValue[] arrManySorted = new DValue[arrlen];
      for (int j = 0; j < arrlen; j++) {
        arrMany[j] = new DValue(rand.nextInt(200) - 90, 0);
        if (values.containsKey(arrMany[j].val)) {
          arrMany[j].count = values.get(arrMany[j].val) + 1;
          values.put(arrMany[j].val, arrMany[j].count);
        } else {
          values.put(arrMany[j].val, 0);
        }
      }
      System.arraycopy(arrMany, 0, arrManySorted, 0, arrlen);
      Arrays.sort(arrManySorted);
      Sorting.mergeSort(arrMany, new BasicComparator());
      assertArrayEquals(arrManySorted, arrMany);
      for (int j = 0; j < arrMany.length - 1; j++) {
        if (arrMany[j].val.equals(arrMany[j + 1].val)) {
          assertTrue(arrMany[j].count < arrMany[j + 1].count);
        }
      }
    }
  }