      (if (< (cutoff node) next-best)
          (PartialResult (stitch-results new-results state reward-to-state) (cutoff node))   
        (let [[entry neg-reward] (queues/g-pq-remove-min-with-cost! (:queue node))
-             b-s (:state entry), b-rts (:reward-to-state entry), b-ra (:remaining-actions entry), b-sa (:sanode entry)
-             rec-next-best (max next-best (cutoff node))]
+             b-s (:state entry), b-rts (:reward-to-state entry), 
+             b-ra (:remaining-actions entry), b-sa (:sanode entry)
+             rec-next-best (- (max next-best (cutoff node)) b-rts)]
            (if (empty? b-ra)
-               (let [eff (vary-meta (env/extract-effects b-s (:context node)) assoc :opt (:opt (meta b-s)))]
+               (let [eff (extract-effect b-s (:context node) (:opt (meta b-s)))]
                  (swap! (:result-map-atom node) assoc-safe >= eff b-rts)
                  (recur (assoc-safe new-results >= eff b-rts)))
-             (let [rec (expand-sa-node b-sa cache (- rec-next-best b-rts) b-s b-rts (- 0 neg-reward b-rts))]
+             (let [rec (expand-sa-node b-sa cache rec-next-best b-s b-rts (- 0 neg-reward b-rts))]
                (when (> (:cutoff rec) Double/NEGATIVE_INFINITY) 
                  (queues/g-pq-replace! (:queue node) entry (- 0 b-rts (:cutoff rec))))
                (doseq [[ss sr] (:result-map rec)]
-                 (queues/g-pq-add! (:queue node)
-                   (make-sanode-entry ss (when (next b-ra) (get-sa-node cache ss (second b-ra))) sr (next b-ra))
-                   (- sr)))
+                 (queues/g-pq-add! (:queue node) (get-sanode-entry cache ss sr (next b-ra)) (- sr)))
                (recur new-results)))))))
 
 

        root  (get-sa-node cache init (hierarchy/TopLevelAction e [(hierarchy/initial-plan henv)]))]
    (loop [cutoff 0 last-cutoff 0]
      (let [result (expand-sa-node root cache cutoff init 0.0 last-cutoff)]
;        (println "TOP" (:cutoff result) cutoff last-cutoff result)
        (cond (not (empty? (:result-map result)))
                (let [[k v] (util/first-maximal-element val (:result-map result))]
;                  (println k)
                  [(:opt (meta k)) v])
              (> (:cutoff result) Double/NEGATIVE_INFINITY)
                (recur (:cutoff result) cutoff))))))

;; This version may be inefficient in graphy domains, but should still be complete+optimal
;; (as long as rewards for primitives are strictly negative)


;; A PartialResult stores a map from states to rewards, where a state is present
;; iff it has reward > cutoff. 
(deftype PartialResult [result-map cutoff])



(deftype SANode [context action result-map-atom queue])

(defn cutoff [node]
  (- (nth (queues/g-pq-peek-min (:queue node)) 1)))


;; Represents an action sequence from a state, with sanode representing the first action
; in remaining-actions. (or nil, if remaining-actions is empty.)
(deftype SANodeEntry [state sanode reward-to-state remaining-actions hash-code] :as this
  Object
  (equals [y] (or (identical? this y) 
                  (and (= state (:state y)) (= remaining-actions (:remaining-actions y)))))
  (hashCode [] hash-code))

(defn make-sanode-entry [state sanode reward-to-state remaining-actions]
  (SANodeEntry state sanode reward-to-state remaining-actions
               (unchecked-add (int (hash state)) 
                              (unchecked-multiply (int 13) (int (hash remaining-actions))))))



(defn make-queue [initial-elements]
  (let [q (queues/make-graph-search-pq)]
