             case .Min:
 
                 if items[left] < items[index] {
-                    return Heap(items: self.swapItemsForIndices(left, index), ordering: ordering).downHeap(left)
+                    return Heap(items: items.swapValuesForIndices(left, index), ordering: ordering).downHeap(left)
                 } else {
                     return self
                 }
             case .Max:
                 if items[right] > items[index] {
-                    return Heap(items: self.swapItemsForIndices(right, index), ordering: ordering).downHeap(right)
+                    return Heap(items: items.swapValuesForIndices(right, index), ordering: ordering).downHeap(right)
                 } else {
                     return self
                 }

    
    // Delete the root from the heap, return the new heap
    func extract() -> Heap {
        let newHeap = Heap(items: self.moveLastItemToFront(), ordering: ordering)
        return newHeap.downHeap(0)
    }
}

// Private
extension Heap {
    
    private func upHeap(index: Int) -> Heap {

    }
}

extension Array {
    var lastIndex: Int {
        return self.endIndex - 1
    }
    
    var last: Element {
        return self[self.lastIndex]
    }
    
    private nonmutating func swapValuesForIndices(firstIndex: Int, _ secondIndex: Int) -> [Element] {
        guard firstIndex >= 0 && secondIndex >= 0 else {
            fatalError("Invalid indices")
        }
        var newItems = self
        newItems[firstIndex] = self[secondIndex]
        newItems[secondIndex] = self[firstIndex]
        return newItems
    }
    
    private nonmutating func moveLastElementToFront() -> [Element] {
        guard self.count > 1 else {
            return self
        }
        
        var newElements = Array(self.dropLast())
        newElements[0] = self.last
        return newElements
    }
}

// Min Heap
let emptyMinHeap = Heap<Int>(items: [], ordering: Ordering.Min)
let minHeap = emptyMinHeap.insert(10).insert(8).insert(2).insert(5).insert(7).insert(4)
