         }
         return elements
     }
-
+    
     func pathToLeaf(for key: T, mediator: RMediator, currentStatus: PageStatus) throws -> ([(node: TreeInternal<T>, childPage: PageId, childIndex: Int, status: PageStatus)], TreeLeaf<T, U>, PageStatus) {
         switch self {
         case .leafNode(let l):
             return ([], l, currentStatus)
         case .internalNode(let i):
-            for (index, (max, pid)) in i.pairs.enumerated() {
-                if key <= max {
+            let boundaryIndex = i.firstIndex(with: key)
+            if boundaryIndex < i.pairs.count {
+                if boundaryIndex < i.pairs.count {
+                    let (_, pid) = i.pairs[boundaryIndex]
                     let (node, status) : (TreeNode<T, U>, PageStatus) = try mediator.readPage(pid)
                     let (p, leaf, leafstatus) = try node.pathToLeaf(for: key, mediator: mediator, currentStatus: status)
-                    let path = [(node: i, childPage: pid, childIndex: index, status: currentStatus)] + p
+                    let path = [(node: i, childPage: pid, childIndex: boundaryIndex, status: currentStatus)] + p
                     return (path, leaf, leafstatus)
                 }
             }

        return false
    }

    public func get(key: T) -> [U] {
        do {
            let (node, _) : (TreeNode<T, U>, PageStatus) = try mediator.readPage(root)

            successful += 1
        }
    }

    func firstIndex(with key: T) -> Int {
        var low = 0
        var high = pairs.count
        while low < high {
            let midIndex = low + (high - low)/2
            if pairs[midIndex].0 < key {
                low = midIndex + 1
            } else {
                high = midIndex
            }
        }
        return low
    }
    
}

public enum TreeNode<T: BufferSerializable & Comparable, U: BufferSerializable> : PageMarshalled {
