        first
        (dispatch))
 
+
+  (dispatch {:unit :server
+             :components {:a #(println "a" %)
+                          :b #(println "b" %)
+                          :c #(println "c" %)
+                          :d #(println "d" %)
+                          :e #(println "e" %)
+                          :f #(println "f" %)
+                          :browser #(println "browser" %)
+                          :server #(println "server" %)}
+             :ruleset {:units {:browser #{:a :b :c}
+                               :server #{:d :e :f}}}}
+            {::component (list :c)
+             :foo :bar})
+
   )

    (do (warn "dropping message due to high transition-count")
        [])))

(defn make-router [ruleset & {:keys [unit dispatch?]
                              :or {dispatch? true}}]
  {:unit unit
   :ruleset ruleset
   :dispatch? dispatch?})


         ::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)))
