 (defn- sp-ts   [s] (tree-summarizer (stub s)))
 
 (defmethod print-method angelic.search.implicit.dash_astar.Subproblem [sp o]
-  (print-method (format "#<SP$%8h %s>" (System/identityHashCode (stub sp)) (sp-name sp)) o))
-
-(defn- add-sp-child! [sp child-sp]
+ (print-method (format "#<SP$%8h %s>" (System/identityHashCode (stub sp)) (sp-name sp)) o))
+
+(defn direct-sp? [sp] (= (ts-stub (sp-ts sp)) (stub sp)))
+
+(defn- add-sp-child!* [sp child-sp]
   (assert (not (terminal? sp)))
   (summaries/summary-changed-local! sp)
   (add-output! sp child-sp))
+
+(defn- add-sp-child! [sp child-sp]
+  (when (direct-sp? sp) #_ ::TODO)
+  (add-sp-child!* sp child-sp))
+
+(defn- add-sp-child-stub! [sp child-stub]
+  (when (direct-sp? sp) #_ ::TODO)  
+  (connect-and-watch-stub! sp child-stub #(add-sp-child!* sp %)))
+
+(defn- add-sp-child-stub-up! [sp child-stub]
+  (when (direct-sp? sp) #_ ::TODO)  
+  (connect-and-watch-stub-up! sp child-stub #(add-sp-child!* sp %)))
+
 
 (traits/deftrait simple-subproblem [stb out-set term? ri-fn] [] [watched-node]
   Subproblem (stub            [s] stb)


(declare make-pair-stub1 make-pair-stub2)

;; Note: disconnect is needed since blocked trumps live.
;; TODO: get rid of disconnect -- just need to kill at the right time ?
;; Note: this is the only place logic depends on summary.  Potential for problems?
(defn- make-pair-subproblem [stb left-sp right-sp]
  (let [expand-right? (and (summary/solved? (summaries/summary left-sp)) (empty? (get-outputs left-sp)))
        kids (if expand-right? [(sp-ts left-sp) right-sp] [left-sp (sp-ts right-sp)])
        ss   (summaries/make-sum-summarizer kids)
        ret (make-simple-subproblem
             stb (output-set right-sp) false             
             (if (or expand-right? (not *collect-equal-outputs*)) summaries/or-summary
                 (let [left-done? (atom false)] ;; Manually take into account left-solved, when no output message.
                   (fn [s] 
                     (when (and (not @left-done?) (summary/solved? (summaries/summary left-sp))
                                (empty? (get-outputs left-sp)))
;                       (print ".")
                       (reset! left-done? true)
                       (summaries/disconnect! s ss )
                        ;; Make sure we don't double count, because child will use tree-summarizer of left.
                       (add-watcher! left-sp (fn [o] (def *bad* [stb left-sp right-sp])
                                               (throw (RuntimeException. "Solved and children."))))
                       (add-sp-child! s (get-stub-output! (make-pair-stub2 left-sp (stub right-sp)))))       
                     (summaries/or-summary s))))             
             (fn [s ri] (make-pair-stub1 (stub-name stb) (refine-input left-sp ri) #(refine-input right-sp %))))]
    (summaries/connect! ret ss)
    (let [[watch stub-f] (if expand-right?
                           [right-sp #(make-pair-stub2 left-sp (stub %))]
                           [left-sp #(make-pair-stub2 % (refine-input right-sp (output-set %)))])]
      (add-watcher! watch
         (fn [o]
           (summaries/summary-changed-local! ss)
           (connect-and-watch-stub-up! ret (stub-f o) #(add-sp-child! ret %)))))
    ret))




;;   X --> Y ==> for all child keys k, child(X, k) --> child(Y, k)

;; --> TODO: every SP should watch all subsuming SPs for children with matching
;;     names, add these as subsumption parents.
;; (Except any direct parents)
;; --> TODO: this should happen as soon as stub is created, not have to wait for SP.
;; This means that TS needs to know about stubs-in-training.

;; TODO: wrapping names don't match pair-stub1.  Get rid of norm-name hack?



(set! *warn-on-reflection* true)

