       (.push results (.key iterator))
       (.next iterator))
     results))
+
+(deftype Join [^:mutable key-ix iterators key-ix->iterators key-ix->intersection key-ix->iterator->present? ^:mutable end?]
+  Object
+  (key [this]
+       (when (false? end?)
+         (.key (aget key-ix->intersection key-ix))))
+  (maintain [this]
+            (set! end? (.-end? (aget key-ix->intersection key-ix))))
+  (next [this]
+        (when (false? end)
+          (.next (aget key-ix->intersection key-ix))
+          (.maintain this)))
+  (seek [this key]
+        (when (false? end)
+          (.seek (aget key-ix->intersection key-ix) key)
+          (.maintain this)))
+  (down [this]
+        (assert (< key-ix (- (alength key-ix->iterators) 1)))
+        (set! key-ix (+ key-ix 1))
+        (let [iterator->present? (aget key-ix->iterator->present? key-ix)]
+          (dotimes [i (alength iterator->present?)]
+            (if (aget iterator->present? i)
+              (.down (aget iterators i))
+              (.mark (aget iterators i))))
+          (.maintain this)))
+  (up [this]
+      (assert (> key-ix 0))
+      (set! key-ix (- key-ix 1))
+      (let [iterator->present? (aget key-ix->iterator->present? key-ix)]
+        (dotimes [i (alength iterator->present?)]
+          (if (aget iterator->present? i)
+            (.up (aget iterators i))
+            (.reset (aget iterators i))))
+        (.maintain this))))
 
 ;; TESTS
 

      (set! moving-key-ix pinned-key-ix)
      (set! pinned-key-ix (- pinned-key-ix 1))
      (set! pinned-key (aget seek-key pinned-key-ix))
      (aset seek-key moving-key-ix least)))

(defn trieterator [tree]
  (let [it (iterator tree)]

                        (do
                          (set! node (aget (.-children node) ix))
                          (set! ix 0)
                          (recur)))))))))))
  (mark [this]
        (apush marked-nodes node)
        (apush marked-ixes ix))
  (reset [this]
         (assert (> (alength marked-nodes) 0))
         (assert (> (alength marked-ixes) 0))
         (set! node (.pop nodes))
         (set! ix (.pop marked-ixes))))

(defn iterator [tree]
  (loop [node (.-root tree)]
    (if (nil? (.-children node))
      (if (> (alength (.-keys node)) 0)
        (Iterator. (.-max-keys tree) node 0 #js [] #js [] false)
        (Iterator. (.-max-keys tree) node 0 #js [] #js [] true))
      (recur (aget (.-children node) 0)))))

(deftype Trieterator [iterator seek-key ^:mutable pinned-key ^:mutable pinned-key-ix ^:mutable moving-key-ix ^:mutable end?]
