private void maxHeapInsert() {
        int index = elems.size() - 1;
        Node<T> currNode = elems.get(index);

        /* Keep bubbling up until we hit the root or are in the right place. */
        while (index > 1) {
            /* Look up the parent. */
            int parentIndex = index / 2;
            Node<T> parentNode = elems.get(parentIndex);

            /* Tricky edge case!  If this is the very last node and a singleton, we want
             * to compare the low field of the node rather than the high field.
             */
            if (currNode.high == null) { // Singleton
                /* If we're below the upper bound, we're done. */
                if (comparator.compare(currNode.low, parentNode.high) < 0) break;
                
                /* Otherwise, swap with the parent and repeat. */
                T temp = currNode.low;
                currNode.low = parentNode.high;
                parentNode.high = temp;
                
                /* Update the index and position to reflect the change. */
                index = parentIndex;
                currNode = parentNode;
            } else { // Doubleton 
                /* If we're below the lower bound, we're done. */
                if (comparator.compare(currNode.high, parentNode.high) < 0) break;
                
                /* Otherwise, swap with the parent and repeat. */
                T temp = currNode.high;
                currNode.high = parentNode.high;
                parentNode.high = temp;
                
                /* Update the index and position to reflect the change. */
                index = parentIndex;
                currNode = parentNode;
            }
        }
    }