         ;(println "path is" path)
         (let [insert-index (first path)
               insert-node (fnext path)
+              ;;TODO this apply should be direct dispatch b/c this is slow
               insert-result (apply insert insert-node insert-index new-elts)]
           ;(println "insert result was" insert-result)
           (if (= 2 (count path)) ; we've only got the root node

    (let [new-children (assoc children index new-child)]
      [(->IndexNode keys new-children)]))
  (insert [node index new-child1 median new-child2]
    (let [new-children (vec (concat (take index children)
                                    [new-child1 new-child2]
                                    (drop (inc index) children)))
          ;;TODO find a better datastructure than vector
          ;;use the vector with lg time split/merge
          new-keys (vec (concat (take index keys)
                                [median]
                                (drop index keys)))]
      (if (>= (count new-children) (* 2 b))
        (let [split-med (nth new-keys (dec b))
              left-index (->IndexNode (vec (take (dec b) new-keys))
                                      (vec (take b new-children)))
              right-index (->IndexNode (vec (drop b new-keys))
                                       (vec (drop b new-children)))
              median (nth new-keys (dec b))]
          [left-index median right-index])
        [(->IndexNode new-keys
                      new-children)])))
  INodeLookup
  (lookup [root key]
    (scan-children-array keys key)))

      ;; Special case for insert into empty tree, since we can't compute paths yet
      (->RootNode [] [(->DataNode [new-key])]))))

(defn delete-key
  [tree key]
  (let [path (lookup-path tree key)])
  )

(defn empty-b-tree
  []
  (->RootNode [] [(->DataNode [])]))
