Given two sorted arrays, add the elements of the second array into the first In Cracking the Coding Interview by Gayle Laakmann McDowell, there's a question that asks you to write code for the following:


  Given two sorted arrays, A and B. Write a method merging the elements
  of B into A in sorted order. Assume A has a large enough buffer at the
  end to hold all of B's elements.


Though the problem isn't very hard, I've been striving to increase the readability of my code in general. As such, I wrote two versions of my solution, and am looking for input on which version is most readable.

Version 1:

// Given two sorted arrays, adds the elements of the second array into 
// the first, while maintaining ordering property.
// XXX: Assumes first array has enough buffer space to hold all elements
public static &lt;Type extends Comparable&lt;Type&gt;&gt; Type[] 
mergeIntoFirstArray(Type[] first_array, Type[] second_array) {

    int first_idx         = numElementsInArray(first_array) - 1; 
    int second_idx        = second_array.length - 1;
    int merge_idx        = numElementsInArray(first_array) + second_array.length - 1;    //

    // merge largest values first, until either array is exhausted
    while (first_idx &gt;= 0 &amp;&amp; second_idx &gt;= 0) {
        Type first_value    =  first_array[first_idx];
        Type second_value    =  second_array[second_idx];

        // add the largest value
        if (first_value.compareTo(second_value) &gt; 0){
            first_array[merge_idx] = first_value ;
            first_idx--;
        } else {
            first_array[merge_idx] = second_value ;
            second_idx--;
        }
        merge_idx-- ;
    }

    // if second_array still has values, merge them in
    while (second_idx &gt;=0) { 
        first_array[merge_idx] = second_array[second_idx] ;
        merge_idx-- ;
        second_idx--;
    }

    return first_array ;
}


Version 2:

public static &lt;Type extends Comparable&lt;Type&gt;&gt; Type[] 
mergeIntoFirstArrayV2(Type[] first_array, Type[] second_array) {
    int f    = numElementsInArray(first_array)-1; 
    int s    = second_array.length - 1;

    // merge in largest values first
    for (int merge_idx = f + s + 1 ; merge_idx &gt;= 0 ; merge_idx--) {
        Type fvalue    =  f &gt;= 0 ? first_array[f]  : null;
        Type svalue    =  s &gt;= 0 ? second_array[s] : null;

        // first value exists, and is greater than second value
        if (fvalue != null &amp;&amp; 
            (svalue == null || fvalue.compareTo(svalue) &gt; 0)) {
            first_array[merge_idx] = svalue ;
            s_idx--;
        }
        else {
            first_array[merge_idx] = svalue ;
            s_idx--;
        }
    }

    return first_array ;
}


Any meaningful input on improving the readability of either method would also be appreciated. For one, I think my variable names might be unclear or too long in some cases. For version 2, I suspect that though the code is more concise, it is harder to understand at a glance.
Both are equivalently readable, I'll nitpick on some details though :)

Both solutions will fail with null elements.

The generic type would be better named T instead of Type, as Type has another definition already.

numElementsInArray() as a function looks a little odd because it is undefined, instead consider passing in the information you need as part of the method definition.

When modifying in place you do not want to return the array because presumably you are trying to skimp on memory allocations and are just going to look for the result in the first array that was passed in.