private void heapfy(List<T> list, int index, int max) {
        int largestIndex = index;
        T largestValue = list.get(index);

        int leftIndex = index * 2 + 1;
        boolean hasLeft = leftIndex < max;
        if ( hasLeft ) {
            T left = list.get(leftIndex);
            boolean leftIsLarger = left.compareTo(largestValue) > 0;
            if ( leftIsLarger ) {
                largestIndex = leftIndex;
                largestValue = list.get(leftIndex);
            }
        }

        int rightIndex = index * 2 + 2;
        boolean hasRight = rightIndex < max;
        if ( hasRight ) {
            T right = list.get(rightIndex);
            boolean rightIsLarger = right.compareTo(largestValue) > 0;
            if ( rightIsLarger ) {
                largestIndex = rightIndex;
                largestValue = list.get(rightIndex);
            }
        }

        boolean pullUpLargerValue = largestIndex != index;
        if ( pullUpLargerValue ) {
            T indexValue = list.get(index);
            list.set(index, largestValue);
            list.set(largestIndex, indexValue);
            heapfy(list, largestIndex, max);
        }
    }