private int gallopRight(T key, T[] array, int idx, int length,
            int hint, Comparator<T> comparator) {
        
        int offset = 1;
        int lastOffset = 0;
        if (comparator.compare(key, array[idx + hint]) < 0) {
            /* key < array[hint] -- gallop left, until
             * array[hint - offset] <= key < array[hint - lastOffset]
             */
            int maxOffset = hint + 1;
            while (offset < maxOffset && comparator.compare(key, array[idx + hint - offset]) < 0) {
                lastOffset = offset;
                offset = (offset << 1) + 1;
                /* int overflow. 
                 * Note: not sure if this can happen, but it's included in both
                 * the original and Java7 TimSort implementations.
                 */
                if (offset <= 0) {
                    offset = maxOffset;
                }
            }
            if (offset > maxOffset) {
                offset = maxOffset;
            }

            // Translate back to offsets relative to idx. 
            int k = lastOffset;
            lastOffset = hint - offset;
            offset = hint - k;
        } else {
            /* array[hint] <= key -- gallop right, until
             * array[hint + lastOffset] <= key < array[hint + offset]
             */
            int maxOffset = length - hint;
            while (offset < maxOffset && comparator.compare(key, array[idx + hint + offset]) >= 0) {
                lastOffset = offset;
                offset = (offset << 1) + 1;
                /* int overflow. 
                 * Note : not sure if that can happen but it's here in both 
                 * original and java 7 TimSort implementation
                 */
                if (offset <= 0) {
                    offset = maxOffset;
                }
            }
            if (offset > maxOffset) {
                offset = maxOffset;
            }

            // Translate back to offsets relative to idx. 
            lastOffset += hint;
            offset += hint;
        }        

        /* Now array[lastOffset] <= key < array[offset], so key belongs somewhere to the
         * right of lastOffset but no farther right than offset.  Do a binary
         * search, with invariant array[lastOffset-1] <= key < array[offset].
         */
        lastOffset++;
        while (lastOffset < offset) {
            int m = lastOffset + ((offset - lastOffset) >>> 1);

            if (comparator.compare(key, array[idx + m]) < 0) {
                offset = m;           //key < array[idx + m] 
            } else {
                lastOffset = m + 1;  // array[idx + m] <= key 
            }
        }        
        return offset;
    }
Exactly like gallopLeft(), except that if key already exists in
array[0:n], finds the position immediately to the right of the rightmost
equal value.

The code duplication is massive, but this is enough different given that
we're sticking to "<" comparisons that it's much harder to follow if
written as one routine with yet another "left or right?" flag.

@param key the key to search
@param array is a sorted array with n elements, starting at array[0]. n
must be > 0.
@param idx the index to start
@param length the length of the run
@param hint is an index at which to begin the search, 0 <= hint < n. The
closer hint is to the final result, the faster this runs.
@param comparator the comparator used to order the range, and to search
@return value is the int k in 0..n such that array[k-1] <= key < array[k]
jme3-core/src/main/java/com/jme3/util/ListSort.java