/**
   * Puts a key/value pair into the array, optimizing for the case where the key is greater than all
   * existing keys in the array.
   */
  public void append(int key, E value) {
    if (mSize != 0 && key <= mKeys[mSize - 1]) {
      put(key, value);
      return;
    }

    if (mGarbage && mSize >= mKeys.length) {
      gc();
    }

    int pos = mSize;
    if (pos >= mKeys.length) {
      int n = ArrayUtils.idealIntArraySize(pos + 1);

      int[] nkeys = new int[n];
      Object[] nvalues = new Object[n];

      // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
      System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
      System.arraycopy(mValues, 0, nvalues, 0, mValues.length);

      mKeys = nkeys;
      mValues = nvalues;
    }

    mKeys[pos] = key;
    mValues[pos] = value;
    mSize = pos + 1;
  }
  /**
   * Creates a new SparseArray containing no mappings that will not require any additional memory
   * allocation to store the specified number of mappings.
   */
  public SparseArray(int initialCapacity) {
    initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);

    mKeys = new int[initialCapacity];
    mValues = new Object[initialCapacity];
    mSize = 0;
  }
  /**
   * Adds a mapping from the specified key to the specified value, replacing the previous mapping
   * from the specified key if there was one.
   */
  public void put(int key, E value) {
    int i = binarySearch(mKeys, 0, mSize, key);

    if (i >= 0) {
      mValues[i] = value;
    } else {
      i = ~i;

      if (i < mSize && mValues[i] == DELETED) {
        mKeys[i] = key;
        mValues[i] = value;
        return;
      }

      if (mGarbage && mSize >= mKeys.length) {
        gc();

        // Search again because indices may have changed.
        i = ~binarySearch(mKeys, 0, mSize, key);
      }

      if (mSize >= mKeys.length) {
        int n = ArrayUtils.idealIntArraySize(mSize + 1);

        int[] nkeys = new int[n];
        Object[] nvalues = new Object[n];

        // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
        System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
        System.arraycopy(mValues, 0, nvalues, 0, mValues.length);

        mKeys = nkeys;
        mValues = nvalues;
      }

      if (mSize - i != 0) {
        // Log.e("SparseArray", "move " + (mSize - i));
        System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
        System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
      }

      mKeys[i] = key;
      mValues[i] = value;
      mSize++;
    }
  }