static void mergeSortNoCopy(final int[] x,final int[] y,final int[] auxX,final int[] auxY,final int toIndex,final int insertionSortIndex){
  if ((toIndex > x.length) || (toIndex > y.length) || (toIndex > auxX.length)|| (toIndex > auxY.length)) {
    throw new ArrayIndexOutOfBoundsException("bad arguments: toIndex=" + toIndex);
  }
  mergeSort(x,y,x,auxX,y,auxY,insertionSortIndex,toIndex);
  if ((insertionSortIndex == 0) || (auxX[insertionSortIndex - 1] <= auxX[insertionSortIndex])) {
    System.arraycopy(auxX,0,x,0,toIndex);
    System.arraycopy(auxY,0,y,0,toIndex);
    return;
  }
  for (int i=0, p=0, q=insertionSortIndex; i < toIndex; i++) {
    if ((q >= toIndex) || ((p < insertionSortIndex) && (auxX[p] <= auxX[q]))) {
      x[i]=auxX[p];
      y[i]=auxY[p];
      p++;
    }
 else {
      x[i]=auxX[q];
      y[i]=auxY[q];
      q++;
    }
  }
}

static void mergeSortNoCopy ( final int [ ] x , final int [ ] y , final int [ ] auxX , final int [ ] auxY , final int toIndex , final int insertionSortIndex ) { if ( ( toIndex > x . length ) || ( toIndex > y . length ) || ( toIndex > auxX . length ) || ( toIndex > auxY . length ) ) { throw new ArrayIndexOutOfBoundsException ( "bad arguments: toIndex=" + toIndex ) ; } mergeSort ( x , y , x , auxX , y , auxY , insertionSortIndex , toIndex ) ; if ( ( insertionSortIndex == 0 ) || ( auxX [ insertionSortIndex - 1 ] <= auxX [ insertionSortIndex ] ) ) { System . arraycopy ( auxX , 0 , x , 0 , toIndex ) ; System . arraycopy ( auxY , 0 , y , 0 , toIndex ) ; return ; } for ( int i = 0 , p = 0 , q = insertionSortIndex ; i < toIndex ; i ++ ) { if ( ( q >= toIndex ) || ( ( p < insertionSortIndex ) && ( auxX [ p ] <= auxX [ q ] ) ) ) { x [ i ] = auxX [ p ] ; y [ i ] = auxY [ p ] ; p ++ ; } else { x [ i ] = auxX [ q ] ; y [ i ] = auxY [ q ] ; q ++ ; } } }
modified merge sort : input arrays are in both auxx / auxy ( sorted : 0 to insertionsortindex ) and x / y ( unsorted : insertionsortindex to toindex ) outputs are stored in x / y arrays
