               ;;  1. remove this event handler
               ;;  2. remove state
               ;;  3. stop the events forwarder
-              :done (do
-                      (re-frame.core/clear-event-handler! id)
-                      {:db (dissoc db db-path)
-                       :event-forwarder {:unregister id}})
+              :done {:db (dissoc db db-path)
+                     :event-forwarder {:unregister id}
+                     :deregister-event-handler id})          ;; XXX write this effects handler
 
-              ;;
               ;; A new event has been forwarded to this handler. What does it mean?
               ;;  1. does this new event mean we need to dispatch another
               ;;  2. remember that this new event has happened
-              (let [[event-id forwarded-event] event-v
-                    _   (assert (= id event-id))
-                    _   (assert (vector? forwarded-event))
-                    forwarded-event-id     (first forwarded-event)
-                    {:keys [seen-events started-tasks]} (get-in db db-path)
+              (let [[_ [forwarded-event-id & args]] event-v
+                    {:keys [seen-events started-tasks]} (get-state db)
                     new-seen-events    (conj seen-events forwarded-event-id)
-                    ready-tasks    (startable-tasks rules new-seen-events started-tasks)
-                    ready-task-ids (->> ready-tasks (map :dispatch) set)
-                    new-started-tasks (set/union started-tasks ready-task-ids)]
-                {:db       (new-state db new-seen-events new-started-tasks)
+                    ready-tasks        (newly-startable-tasks rules new-seen-events started-tasks)
+                    ready-task-ids     (->> ready-tasks (map :dispatch) set)
+                    new-started-tasks  (set/union started-tasks ready-task-ids)]
+                {:db       (set-state db new-seen-events new-started-tasks)
                  :dispatch (concat (map :dispatch ready-tasks))})))))
 
-(defn register-fx!
-  []
-  (re-frame.core/def-fx
-    :aync-flow
-    (fn [{:as flow :keys [id]}]
-      ;; XXX check that flow is valid.
-      (re-frame.core/def-event-fx
-        id                           ;; add debug middleware???  XXXX
-        (make-flow-event-handler flow))
-      (re-frame.core/dispatch [id :steup]))))
+(re-frame.core/def-fx
+  :aync-flow
+  (fn [{:as flow :keys [id]}]
+    (re-frame.core/def-event-fx
+      (or id default-id)                                 ;; add debug middleware???  XXXX
+      (make-flow-event-handler flow))
+    (re-frame.core/dispatch [id :steup])))
 
 

  (:require [re-frame.core]
            [clojure.set :as set]))


(defn startable-tasks
  "Given a set of 'now-seen-events' and a set of already started tasks
  return the list of tasks which should now be started."
  [rules now-seen-events started-tasks]
  (->> (remove (comp started-tasks :id) rules)
       (filterv (fn [task]
                  (condp = (:when task)
                    :seen-all-of  (empty? (set/difference (:events task)  now-seen-events))
                    :seen-any-of  (seq (set/intersection now-seen-events (:events task))))))))


(defn make-flow-event-handler
  [{:keys [id db-path rules first-dispatch]}]
  (let [all-events  (apply set/union (map :events rules))       ;; all of the events refered to in the spec
        new-state (fn [db seen started]
                    (assoc-in db db-path {:seen-events seen :started-tasks started}))


        ;;  rules'  XXX make all :dispatch a list PLUS make :done   [id :done]   then use rules' below
        ;;
        ]

    ;; return an event handler which will manage the flow
    ;; This event handler will receive 3 kinds of events
    ;;   (dispatch [:id :steup])
    ;;   (dispatch [:id :done])
    ;;   (dispatch [:id [:a :forwarded :event :vector])
    ;;

              ;;  1. Initialise the state  (seen-events and started-tasks)
              ;;  2. dispatch the first event, to kick start
              ;;  3. arrange for the events to get forwarded to this handler
              :setup {:db (set-state db #{} #{})
                      :dispatch first-dispatch
                      :event-forwarder {:register id
                                        :events   all-events
