private VListLocation<T> locateElement(int index) {
    /* Bounds-check. */
    if (index >= size() || index < 0)
      throw new IndexOutOfBoundsException("Position " + index + "; size "
          + size());

    /* Because the list is stored with new elements in front and old
     * elements in back, we'll invert the index so that 0 refers to the
     * final element of the array and size() - 1 refers to the first
     * element.
     */
    index = size() - 1 - index;

    /* Scan across the cells, looking for the first one that can hold our
     * entry. We do this by continuously skipping cells until we find one
     * that can be sure to hold this element.
     * 
     * Note that each cell has mElems.length elements, of which mFreeSpace
     * is used. This means that the total number of used elements in each
     * cell is mElems.length - mFreeSpace.
     */
    VListCell<T> curr = mHead;
    while (index >= curr.mElems.length - curr.mFreeSpace) {
      /* Skip past all these elements. */
      index -= curr.mElems.length - curr.mFreeSpace;
      curr = curr.mNext;
    }

    /* We're now in the correct location for what we need to do. The element
     * we want can be found by indexing the proper amount beyond the free
     * space.
     */
    return new VListLocation<T>(curr, index + curr.mFreeSpace);
  }