code: @VisibleForTesting MoveDesc<E> removeAt(int index) {
      checkPositionIndex(index, size);
      modCount++;
      size--;
      if (size == index) {
        queue[size] = null;
        return null;
      }
      E actualLastElement = elementData(size);
      int lastElementAt = heapForIndex(size)
          .getCorrectLastElement(actualLastElement);
      E toTrickle = elementData(size);
      queue[size] = null;
      MoveDesc<E> changes = fillHole(index, toTrickle);
      if (lastElementAt < index) {
        // Last element is moved to before index, swapped with trickled element.
        if (changes == null) {
          // The trickled element is still after index.
          return new MoveDesc<E>(actualLastElement, toTrickle);
        } else {
          // The trickled element is back before index, but the replaced element
          // has now been moved after index.
          return new MoveDesc<E>(actualLastElement, changes.replaced);
        }
      }
      // Trickled element was after index to begin with, no adjustment needed.
      return changes;
    }
docs: Removes the element at position {@code index}.
  
  <p>Normally this method leaves the elements at up to {@code index - 1},
  inclusive, untouched.  Under these circumstances, it returns {@code null}.
  
  <p>Occasionally, in order to maintain the heap invariant, it must swap a
  later element of the list with one before {@code index}. Under these
  circumstances it returns a pair of elements as a {@link MoveDesc}. The
  first one is the element that was previously at the end of the heap and is
  now at some position before {@code index}. The second element is the one
  that was swapped down to replace the element at {@code index}. This fact is
  used by iterator.remove so as to visit elements during a traversal once and
  only once.