         guard slot.match else { return nil }
         return node.payloads[slot.index]
     }
+
+    public func indexOf(key: Key) -> Int? {
+        var node = self
+        var index = 0
+        while !node.isLeaf {
+            let slot = node.slotOf(key)
+            index += node.children[0 ..< slot.index].reduce(0, combine: { $0 + $1.count })
+            if slot.match {
+                return index
+            }
+            node = node.children[slot.index]
+        }
+        let slot = node.slotOf(key)
+        guard slot.match else { return nil }
+        return index + slot.index
+    }
 }
 
 //MARK: Insertion
 
 extension BTree {
-    public mutating func insert(key: Key, _ payload: Payload) {
-        guard let (separator, right) = self.insertAndSplit(key, payload) else { return }
+    public mutating func set(key: Key, to payload: Payload) -> Payload? {
+        return self.insert(payload, at: key, replacingExisting: true)
+    }
+    public mutating func insert(payload: Payload, at key: Key) {
+        self.insert(payload, at: key, replacingExisting: false)
+    }
+
+    private mutating func insert(payload: Payload, at key: Key, replacingExisting replace: Bool) -> Payload? {
+        let (old, splinter) = self.insertAndSplit(key, payload, replace: replace)
+        guard let (separator, right) = splinter else { return old }
         let left = self
         keys.removeAll()
         payloads.removeAll()

        children.append(left)
        children.append(right)
        count = left.count + right.count + 1
    }

    private mutating func insertAndSplit(key: Key, _ payload: Payload) -> (separator: (Key, Payload), splinter: BTree<Key, Payload>)? {
        count += 1
        let slot = slotOf(key).index
        if isLeaf {
            keys.insert(key, atIndex: slot)
            payloads.insert(payload, atIndex: slot)
        }
        else {
            guard let (separator, splinter) = children[slot].insertAndSplit(key, payload) else { return nil }
            keys.insert(separator.0, atIndex: slot)
            payloads.insert(separator.1, atIndex: slot)
            children.insert(splinter, atIndex: slot + 1)
        }
        return isTooLarge ? split() : nil
    }

    private mutating func split() -> (separator: (Key, Payload), splinter: BTree<Key, Payload>) {


//MARK: BTree definition

/// An in-memory b-tree data structure, efficiently mapping `Comparable` keys to arbitrary payloads.
/// Iterating over the elements in a b-tree returns them in ascending order of their keys.
public struct BTree<Key: Comparable, Payload> {

    /// A sorted array of keys.
