MergeSort -- ArrayIndexOutOfBoundsException

PEssoal, estou fazendo um trabalho de análise de algoritmos que eu devo analizar uma maneira de Ordenação, escolhi o mergeSort por achar mais interessante, tudo bem até aí, o problema é que meu programa está se limitando no máximo 64 itens na Array,mas numeros impares e/ou acima de 64 ocorre um ArrayIndexOutOfBoundsException.
Vejam o código:

[code]package analisealgoritmo;

import java.util.Scanner;

public class AnaliseAlgoritmo {

/**
 * Metodo Main, Cria o vetor final onde serão armazenados os dados organizados
 * e recebe uma entrada do usuário que determinará o tamanho do Vetor.
 * 
 */
public static void main(String[] args) {
    int x = 0;
    int[] vetorfinal = new int[x];
    System.out.println("Insira um número");
    try {
        Scanner input = new Scanner(System.in);
        x = input.nextInt();

    } catch (NumberFormatException nb) {
        nb.printStackTrace();
    }
    if (testaQuadrado(x)) {
        vetorfinal = mergeSort(geraVetor(x));
        System.out.println();
        System.out.println();
        System.out.println();
        formataMatriz(vetorfinal, x);
    } else {
        System.out.println("Não é um quadrado perfeito");
    }

}

/**
 * Gera vetor de acordo com o tamanho inserido no main,
 * caso o tamanho seja '0' retorna nulo, caso contrário
 * cria um vetor de números aleatórios
 */
public static int[] geraVetor(int tamanho) {

    if (tamanho == 0) {
        return null;
    }

    int[] vetor = new int[tamanho];
    for (int i = 0; i < tamanho; i++) {
        vetor[i] = (int) (Math.random() * 1000);

        System.out.print(vetor[i] + ". ");

    }
    return vetor;
}

/**
 * O Vetor no final deve ser impresso de forma quadrada perfeita, portanto esse 
 * método se responsabiliza por checar se o numero inserido é um quadrado perfeito.
 */
public static boolean testaQuadrado(double i) {
    if (i == 0) {
        return false;
    }

    Double resultado = Math.sqrt(i);
    if (resultado != null) {
        return resultado.intValue() == resultado.doubleValue();
    } else {
        return false;
    }
}

/**
 * MergeSort recursivo Baseado nos livros Algoritmos 2º ed. da editora Campus e 
 * Sorting and Searching do Knuth 
 * Caso o quadrado seja um numero impar ocorre Erro. (Preciso corrigir esse erro)
 */
public static int[] mergeSort(int[] vetor) {
    if (vetor == null) {
        return null;
    }

    if (vetor.length <= 1) {
        return vetor;
    }
    int meio;

        meio = ((vetor.length) / 2);
   
    int[] direita = new int[meio];
    int[] esquerda = new int[vetor.length - meio];

    System.arraycopy(vetor, 0, esquerda, 0, meio);
    System.arraycopy(vetor, meio, direita, 0, vetor.length - meio);

    direita = mergeSort(direita);
    esquerda = mergeSort(esquerda);

    return merge(esquerda, direita);
}

/**
 * Algoritmo 100% Baseado em Knuth que organiza definitivamente.
 *  
 */
public static int[] merge(int[] esquerda, int[] direita) {

    if (esquerda == null || direita == null) {
        return null;
    }

    int[] result = new int[esquerda.length + direita.length];

    int i = 0, j = 0, k = 0;

    while (i < esquerda.length && j < direita.length) {

        if (esquerda[i] > direita[j]) {
            result[k] = direita[j];
            j++;
        } else {
            result[k] = esquerda[i];
            i++;
        }
        k++;
    }
    while (i < esquerda.length) {
        result[k] = esquerda[i];
        i++;
        k++;
    }

    while (j < direita.length) {
        result[k] = direita[j];
        j++;
        k++;

    }

    return result;
}

/**
 * Aqui ocorre a impressão dos vetores em um quadrado perfeito ordenando
 * crescentemente as colunas.
 *  
 */
public static void formataMatriz(int[] vetorfinal, int tamanho) {

    if (vetorfinal == null || tamanho == 0) {
        System.out.println("Valores nulos encontrados");
    }
    int[] finalvetor = vetorfinal;

    int z = (int) Math.sqrt(tamanho);
    int matriz[][] = new int[z][z];


    for (int i = 0; i < finalvetor.length; i++) {
        matriz[(int) i / z][i % z] = finalvetor[i];
    }

    for (int i = 0; i < z; i++) {
        for (int j = 0; j < z; j++) {
            System.out.print(matriz[j][i] + "  ");
        }
        System.out.println();
    }

}

}
[/code]
Ps. eu sei que não está organizado e orientado a objetos, mas meu professor pediu que fizesse assim.

tks for helping.

coloca ai a pilha de erros pra gente ver

Esse erro é gerado com a inserção dos numeros impares que comentei.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException 547. 111. 805. 295. 271. 706. 506. 654. 9. at java.lang.System.arraycopy(Native Method) at analisealgoritmo.AnaliseAlgoritmo.mergeSort(AnaliseAlgoritmo.java:92) at analisealgoritmo.AnaliseAlgoritmo.main(AnaliseAlgoritmo.java:24) Java Result: 1