   (summaries/connect! p c false)
   (add-watcher! c f))
 
+(defn- get-stub-output  [s] (first (get-outputs s)))
+(defn- get-stub-output! [s] (util/safe-singleton (get-outputs s)))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;      Tree Summarizers      ;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Every child of TS is also a subsumption parent.
+;; Then, TS has:
+;; Children:
+;;  Ordinary: stub, SP, TS of outputs
+;;  Subsuming: Subsuming TS's
+;; Parents:
+;;  Ordinary: whoever
+;;  Subsuming: stub, SP, TS of outputs,
+;; Note alternative: separate TS and ST - -but cycle is needed for memory, no matter what?.
+
+;; TODO: fix cycles by making subsumption updates only happen when strictly < reward.
+;; TODO: what updates are needed here?
+(defn- make-tree-summarizer [stub]
+  (let [bound-atom (atom 0)
+        ret (traits/reify-traits [summaries/simple-cached-node]
+              summaries/Summarizable
+              (summarize [s]
+                (let [s (summaries/or-summary s @bound-atom)]
+                  (reset! bound-atom (summary/max-reward s))
+                  s)))        
+        sp-watch! (fn [sp]
+                   (summaries/connect! sp ret true)
+                   (connect-and-watch! ret sp
+                     (fn [child-sp]
+                       (let [child-ts (tree-summarizer (stub child-sp))]
+                         (summaries/connect! ts child-ts false)
+                         (summaries/connect! child-ts ts true)
+                         (summaries/summary-changed! ts)))))]
+    (if-let [sp (get-stub-output stub)]
+      (sp-watch! sp)
+      (do (summaries/connect! stub ts true)
+          (connect-and-watch! ts stub sp-watch!)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;     StubFactories     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; TODO: is there a distinction between SF and subsumption meeting place?
+;; Latter can use, e.g., normalized sequences?
+;; As-is, is there any need for SF at all ? 
+
+(defprotocol StubFactory
+  (sf-name [sf])
+  (get-stub [sf inp-set subsuming-sp]))
+
+(defn make-simple-stub-factory [nm make-stub]
+  (let [] ;    h (HashMap.)
+    (reify StubFactory
+      (sf-name [sf] nm)
+      (get-stub [sf inp-set subsuming-sp]
+        (let [stub (make-stub sf inp-set subsuming-sp)]
+          (when subsuming-sp (add-subsuming-sp! stub subsuming-sp))
+          stub)))))
+  
+ ;;        (util/cache-with h inp-set (make-stub inp-set)))
+ 
+(defmulti make-stub-factory (fn [nm] (first nm)))
+
+(def *sf-cache* nil)
+
+(defn get-stub-factory [nm]
+  (util/cache-with ^HashMap *sf-cache* nm (make-stub-factory nm)))
+
+(defn get-stub-by-name [nm is] (get-stub (get-stub-factory nm) is nil))
+
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;     Stubs     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+;; Stub must implement Summarizable, optionally implements Evaluable
+
 (defprotocol Stub
-  (stub-name   [s])
-  (input-set   [s]))
-
-(traits/deftrait simple-stub [name inp] [] [watched-node]
-  Stub (input-set [s] inp)
-       (stub-name [s] name))
+  (stub-factory    [s])
+  (input-set       [s])
+  (tree-summarizer [s] "Summarizer that includes outputs/children."))
+
+(defprotocol Evaluable (evaluate! [s]))
+
+(defn stub-name [s] (sf-name (stub-factory s)))
+
+(traits/deftrait simple-stub [sf inp] [ts-atom (atom nil)] [watched-node]
+  Stub
+  (stub-factory    [s] sf)
+  (input-set       [s] inp)
+  (tree-summarizer [s] (or @ts-atom (reset! ts-atom (make-tree-summarizer s)))))
 
 (defmethod print-method angelic.search.implicit.dash_astar.Stub [s o]
   (print-method (format "#<ST$%8h %s>" (System/identityHashCode s) (stub-name s)) o))
 
-;; Stub must implement Summarizable, optionally implements Evaluable
-
-(defprotocol Evaluable (evaluate! [s]))
-(defn- can-evaluate? [s] (instance? angelic.search.implicit.dash_astar.Evaluable s))
+(defn- add-subsuming-sp! [stub subsuming-sp]
+  (summaries/connect! (tree-summarizer stub) (tree-summarizer (stub subsuming-sp)) true))
 
 (defn- set-stub-output! [stub sp]
   (assert (empty? (get-outputs stub)))

(defn- connect-and-watch-stub-up! [p c f]
  (when (connect-and-watch-stub! p c f) (summaries/summary-changed! p)))

(defn- make-wrapping-stub [[name in-set] inner-stub sp-fn]
  (let [ret (traits/reify-traits [summaries/or-summarizable (simple-stub name in-set)])]
    (connect-and-watch-stub! ret inner-stub #(set-stub-output! ret (sp-fn ret %)))
    ret))


                        ;; Make sure we don't double count, because child will use tree-summarizer of left.
                       (add-watcher! left-sp (fn [o] (def *sum* [s left-sp o])
                                               (throw (RuntimeException. "Solved and children."))))
                       (connect-and-watch-stub! s (make-pair-stub2 sf left-sp (stub right-sp))
                          (fn [os] (connect-and-watch! s os #(add-sp-child! s %))))) ;; no update needed 
                     (summaries/or-summary s b))))             
             (fn [s ri] (make-pair-stub1 s (refine-input left-sp ri)
                          (sp-name right-sp) #(refine-input right-sp %))))]
    (summaries/connect! ret ss false)
    (let [[watch stub-f] (if expand-right?
                           [right-sp #(make-pair-stub2 nil left-sp (stub %))]
                           [left-sp #(make-pair-stub2 nil % (refine-input right-sp (output-set %)))])]
