 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  Generic Trait  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(def *out-count* (atom 1))
-
+;(def *out-count* (atom 1))
+
+;; Canonical SPs are Atomic and Pair; wrappers use TS of inner SP.
 (defn canonicalize [sp] (ts-sp (sp-ts sp)))
 (defn canonical? [sp] (identical? sp (ts-sp (sp-ts sp))))
 
 (defn notify-output-set! [w s] #_ (println "NO" s w) (w))
 (defn notify-child! [w s c] #_ (println "NC" s c w) (swap! *out-count* inc) (w c))
+
+
+;; Note subsumption following is a bit tricky, since we want access to all children
+;; (including unpublished ones).
+;; TODO: remove all-children if it doesn't help?
+;; What we need is a 3-way dependence:
+;; Child, sub child, sub link.?
+
 
 (traits/deftrait simple-subproblem
   [nm inp-set wrapped-ts eval!-fn ri-fn]
   [                 ts-atom          (atom wrapped-ts)
-   ^ArrayList       output-watchers  (ArrayList.)
-                    out-set-atom     (atom nil)
-   ^ArrayList       child-watchers   (ArrayList.)
-   ^ArrayList       child-list       (ArrayList.)
+   ^PubSubHub       output-ps        (make-pubsubhub)
+   ^PubSubHub       child-ps         (make-pubsubhub)
+   ^PubSubHub       all-child-ps     (make-pubsubhub)
    ^IdentityHashMap subsuming-sp-set (IdentityHashMap.)]
   [summaries/simple-cached-node]
   Subproblem

                       (summaries/or-summary s))))]    
       (summaries/connect! ret ss)
       (connect-and-watch! ss left-sp
         (fn left-output []
           (connect-and-watch-ts! ss @right-sp 
             (fn [] (set-output-set! ret (get-output-set! @right-sp))))
           (schedule-decrease! ss))
         (fn left-child [left-child]
           (add-sp-child! ret (make-pair-subproblem left-child right-name #(refine-input @right-sp %)) true))) 


  (get-output-set      [s]  "Return output or nil")
  (add-output-watcher! [s w] "Add watcher to be notified of self when has output.")
  (set-output-set!     [s o] "Internal. Set output set. ")

  (get-children        [s]  "List current outputs, for debugging only.")
  (add-child-watcher!  [s w] "Add a watcher to be notified of all child sps.")
  (add-sp-child!       [s o up?] "O is a subproblem child, possibly without output yet.
                                  Updates cost if up? and child must be held before publishing.")

  (publish-sp-child!   [s o] "Internal. O is a subproblem with output.  s must have output too.")
  (get-all-children [s] "Internal.  Get children, including unpublished ones.")

  (subsuming-sps       [s] "subproblems with same name, >= inp-set") 
  (add-subsuming-sp!   [s subsuming-sp]) 

  (refine-input        [s refined-input-set] "Return a child sp. Must have output."))

  
(defn get-output-set! [sp] (let [o (get-output-set sp)] (assert o) o))

(defn terminal? [sp]
