Merge sort implementation with various improvements
Mandatory stability note: the sequence

    if(array[left_index] &lt; array[right_index]){
        temp_holder[temp_index++] = array[left_index++];
    } else {
        temp_holder[temp_index++] = array[right_index++];
    }


causes loss of stability (equal elements are merged in the wrong order).
The code still does unnecessary copying (from tmp back to array). It is unnecessary because it can be avoided. Allocate a temporary array once, then

    merge_sort subrange 0 of arr into corresponding subrange of tmp
    merge_sort subrange 1 of arr into corresponding subrange of tmp
    merge subranges from tmp to arr

The insertion sort implementation is suboptimal. Testing two conditions in

    while(before &gt;= left &amp;&amp; array[before] &gt; temp)


can be avoided. Take a look at the Alex Stepanov's technique (he is talking about quicksort, but the first 4 methods, which you are are only interested in, are equally applicable to your case).
The algorithms of this kind generally look better at the semi-open ranges. Try to rewrite the code with the assumption that highBound does not belong to the range.