   (sp-ts               [s] (or @ts-atom (reset! ts-atom (make-tree-summarizer s))))
   (evaluate!           [s] (eval!-fn s))
   
-  (get-output-set      [s] @out-set-atom)
-  (add-output-watcher! [s w] (if @out-set-atom (notify-output-set! w s) (.add output-watchers w)))
-  (set-output-set!    [s o]
-    (util/print-debug 2 "SO" s)
-    (assert (nil? @out-set-atom))
-    (reset! out-set-atom o)
-    (doseq [w output-watchers] (notify-output-set! w s)))
+  (get-output-set      [s] (first (publications output-ps)))
+  (add-output-watcher! [s w] (subscribe! output-ps w))
+  (set-output-set!    [s o] (assert (not (get-output-set s))) (publish! output-ps o))
   
-  (get-children        [s] (doall (seq child-list)))
-  (add-child-watcher!  [s w]
-    (.add child-watchers w)                   
-    (when (get-output-set s)) (doseq [c (get-children s)] (notify-child! w s c)))
-  (add-sp-child!*      [s c] 
+  (get-children        [s] (publications child-ps))
+  (add-child-watcher!  [s w] (subscribe! child-ps w))
+  (add-sp-child!       [sp child-sp up?] ;; TODO: subsumption should prevent child from gettong output before parent ??
+   (util/print-debug 2 "AC" sp child-sp)
+   (when (canonical? sp)
+     (schedule-subsumption! (sp-ts sp) (sp-ts child-sp))
+     (publish! all-child-ps child-sp)
+     (when *propagate-subusmption* #_ ::TODO) ;; TODO!!
+     )   
+   (if (and (get-output-set sp) (get-output-set child-sp))
+    (publish-sp-child! sp child-sp)
+    (do (summaries/connect! sp (sp-ts child-sp)) 
+        (add-output-watcher! sp 
+          (fn [_] (add-output-watcher! child-sp
+                   (fn [_] (publish-sp-child! sp child-sp) 
+                           (summaries/disconnect! sp (sp-ts child-sp))
+                           (schedule-decrease! sp)))))
+        (when up? (schedule-increase! sp)))))
+  (publish-sp-child!      [s c] 
     (util/assert-is (and (not (identical? s c)) (get-output-set s) (get-output-set c)))
-    (.add child-list c)
     (when (canonical? s)
       (summaries/connect! (sp-ts s) (sp-ts c))
       (schedule-increase! (sp-ts s)))    
-    (doseq [w (doall (seq child-watchers))] (swap! *out-count* inc) (w c)))
-
+    (publish! child-ps c))
+
+  (get-all-children    [s] (publications all-child-ps))
+
+    
   (subsuming-sps [s] (keys subsuming-sp-set))
   (add-subsuming-sp! [s subsuming-sp]
     (util/assert-is (canonical? s))

             [summaries/or-summarizable
              (simple-subproblem nm inp-set (sp-ts inner-sp) noeval ri-fn)])]
    (connect-and-watch! ret inner-sp
      (fn [] (set-output-set! ret (output-wrap (get-output-set! inner-sp))))
      (fn [inner-child] (child-watch ret inner-child)))
    ret))


   identity
   (fn child-watch [sp child-sp] ;     (println sp child-sp (def *bad* [sp child-sp]))
     (if (=-state-sets (get-output-set! inner-sp) (get-output-set! child-sp))
       (do (schedule-increase! sp) (connect-and-watch! sp child-sp nil #(child-watch sp %))) 
       (add-sp-child! sp (make-output-collecting-subproblem fs inp-key child-sp) :irrelevant))) 
   (fn refine-input [s ni]
     (let [ninp-key (get-input-key fs ni)]
       (if (= inp-key ninp-key)
