 (defn apply-to-iterator [iterator movements]
   (for [movement movements]
     (case (nth movement 0)
-      :next [(.next iterator) (.key iterator)]
-      :seek [(.seek iterator (nth movement 1)) (.key iterator)])))
+      :next (do
+              (.next iterator)
+              (.key iterator))
+      :seek (do
+              (.seek iterator (nth movement 1))
+              (.key iterator)))))
 
 (defn apply-to-elems [elems movements]
-  (let [elems (atom elems)]
+  (let [cur-elems (atom elems)]
     (for [movement movements]
       (case (nth movement 0)
         :next (do
-                (swap! elems rest)
-                [(not (empty? @elems)) (first (first @elems))])
+                (swap! cur-elems rest)
+                (or (first (first @cur-elems)) (first (last elems))))
         :seek (do
-                (swap! elems (fn [elems] (drop-while #(key-lt (nth % 0) (nth movement 1)) elems)))
-                [(and (not (nil? (first @elems))) (key= (nth movement 1) (first (first @elems)))) (first (first @elems))])))))
+                (reset! cur-elems (drop-while #(key-lt (nth % 0) (nth movement 1)) elems))
+                (or (first (first @cur-elems)) (first (last elems))))))))
 
 (defn run-iterator-prop [min-keys key-len actions movements]
   (let [tree (apply-to-tree (tree min-keys key-len) actions)

          (aset outer-key outer-ix (aget key outer-ix)))
        (.maintain this)))

(deftype Join [current-key iterators ^:mutable end?]
  Object
  (maintain [this]
            ;; if all equal, done
            ;; if all blocked but max, .next on max
            ;; if all blocked, set end? true
            ;; otherwise seek smallest non-blocked to max, recur
            )
  (reset [this]
         (debug)
         (debug :reset)
         (dotimes [i (alength current-key)]
           (aset current-key i least))
         (dotimes [i (alength iterators)]
           (.reset (aget iterators i)))
         (set! end? false)
         (.maintain this))
  (key [this]
       (when (false? end?)
         current-key))
  (next [this]
        ;; .next on smallest non-blocked iter
        ;; maintain
        )
  (seek [this key]
        ;; .seek on all iters
        ;; maintain
        ))

(defn join [iterators num-vars iterator->var->nextable? iterator->var->present?]
  (let [seek-key (least-key num-vars)

;; ITERATORS
;; .key / .val return key and val currently pointed at. key may be aliased
;; On creation/reset, points to first key
;; On next, either point to next key or set .-end? true.
;; On seek, point to first key greater than or equal to seek-key, or otherwise the last key
;; NOTE iterators are not write-safe unless reset after writing

;; TODO think we might need to be able to get last key on end
