     (do (warn "dropping message due to high transition-count")
         [])))
 
-(defn make-router [ruleset components & {:keys [unit dispatch?]
-                                         :or {dispatch? true}}]
-  {:unit unit
-   :components components
-   :ruleset ruleset
-   :dispatch? dispatch?})
-
-#_(defrecord MessageRouter [ruleset]
-
-  p/Router
-
-  (advance [this msg]
-    (advance ruleset msg)))
-
-#_(defn message-router [ruleset]
-  (->MessageRouter ruleset))
+(defn- get-component-unit [{:keys [ruleset] :as router} component]
+  (-> (:units ruleset)
+      owc/map-invert-coll
+      (get component)))
+
+(defn- get-tunnel [{:keys [unit] :as router} component]
+  (and unit
+       (let [cunit (get-component-unit router component)]
+         (and (not= unit cunit)
+              cunit))))
+
+(defn dispatch [{:keys [components] :as router} msg]
+  (when-let [component (peek (::component msg))]
+    (let [tunnel (get-tunnel router component)
+          msg (if tunnel
+                (update msg ::component pop)
+                msg)
+          dest (or tunnel component)
+          destcomp (or (get components dest)
+                       (get components :DEFAULT))]
+      (cond (fn? destcomp)                   (destcomp msg)
+            (satisfies? ap/Channel destcomp) (a/put! destcomp msg)
+            (satisfies? p/Tunnel destcomp)   (p/send destcomp msg)
+            true (throw (ex-info "don't know how to dispatch"
+                                 {:router router
+                                  :msg msg
+                                  :tunnel tunnel
+                                  :component component
+                                  :dest dest
+                                  :destcomp destcomp}))))))
+
+(defn route [{:keys [dispatch?] :as router} msg]
+  (let [resmsgs (advance router msg)]
+    (if dispatch?
+      (map (partial dispatch router) resmsgs)
+      resmsgs)))
 
 (defn message [route map & {:keys [max-transitions]
                             :or {max-transitions 100}}]

         ::transition-count 0
         ::max-transitions max-transitions))

(defn dispatch [{:keys [components] :as router} msg]
  (when-let [component (peek (::component msg))]
    (let [tunnel (get-tunnel router component)
          dest (or tunnel component)
          destcomp (get components dest)]
      (cond (fn? destcomp)                   (destcomp msg)
            (satisfies? ap/Channel destcomp) (a/put! destcomp msg)
            (satisfies? p/Tunnel destcomp)   (p/send destcomp msg)
            true (throw (ex-info "cannot dispatch" {:router router
                                                    :msg msg
                                                    :tunnel tunnel
                                                    :component component
                                                    :dest dest}))))))

#_(defn- process [this req]
  (advance req (:ruleset this)))

                  (transform %))
            transitions)
       (apply concat)))

(defn- handle-events [eventhandlers msg]
  (reduce (fn [s [key eventhandler]]
