 
            (== old-var new-var)
            ;; ACROSS: assumes prefixes all equal, keys not all equal, iterators sorted by ascending key, nothing at end
-           (let [iterators (aget var->iterators new-var)
-                 num-iterators (alength iterators)
-                 previous (mod (- current 1) num-iterators)
-                 max-key (.key-at (aget iterators previous) new-var)
-                 iterator (aget iterators current)
+           (let [var-iterators (aget var->iterators new-var)
+                 num-var-iterators (alength var-iterators)
+                 previous (mod (- current 1) num-var-iterators)
+                 max-key (.key-at (aget var-iterators previous) new-var)
+                 iterator (aget var-iterators current)
                  min-key (.key-at iterator new-var)
                  old-key (.inner-key iterator)]
              (debug :search max-key current seek-key)

                     (do
                       (aset seek-key new-var max-key)
                       (recur new-var (+ new-var 1) 0))
                     (recur new-var new-var (mod (+ current 1) num-iterators)))))))

           (< new-var old-var)
           ;; UP: assumes prefixes and keys all equal, nothing at end
           (if (== old-var 0)
             (set! end? true)
             (let [new-var (- old-var 1)
                   iterators (aget var->iterators new-var)
                   iterator (aget iterators (- (alength iterators) 1))]
               (debug :up old-var seek-key)
               (when (< old-var (alength var->iterators))
                 (aset seek-key old-var least))

  (end? [this]
        (.-end? iterator)))

(deftype Join [seek-key iterators var->iterators var->iterator->reset? ^:mutable end?]
  Object
  (reset [this]
         (debug)
