From what I can tell, the problem is in your merge method, here:
if (i == lIndex) { // If the left array is sorted ...
i
is not necessarily equal to lIndex
when the left array is sorted. As a result, the final part of the merge is not always executed. The duplicate elements you're seeing are left over from the original array A
in the positions that weren't overwritten because of this.
The correct condition is:
if (lIndex == left.length) { // If the left array is sorted ...