        (map second)
        (filter mount-state?)))
 
-
 ;;TODO ns based for now. need to be _state_ based
 (defn- add-deps [{:keys [ns] :as state} all]
   (let [refers (ns-refers ns)

  (toString [this] 
    (str "'" state "' is not started (to start all the states call mount/start)")))

;;TODO validate stop and the fact that start and stop are fns
(defn- validate [{:keys [start stop]}]
  (when-not start 
    (throw (IllegalArgumentException. "can't start a stateful thing without a start function. (i.e. missing :start fn)")))
  {:start start :stop stop})

(defmacro defstate [state & body]
  (let [[state [c cf d df]] (macro/name-with-attributes state body)
        {:keys [start stop]} (validate {c cf d df})]
    (let [s-meta (-> {:mount-state mount-state
                      :order (make-state-seq state)
                      :start `(fn [] (~@start)) 
                      :started? false}
                     (cond-> df (assoc :stop `(fn [] (~@stop)))))]
      `(defonce ~(with-meta state (merge (meta state) s-meta))
         (NotStartedState. ~(str state))))))

(defn- up [var {:keys [ns name start started?]}]
  (when-not started?
    (info ">> starting.. " name)
    (let [s (try (start) 
                 (catch Throwable t 
                   (throw (RuntimeException. (str "could not start [" name "] due to") t))))]
      (intern ns (symbol name) s)
      (alter-meta! var assoc :started? true))))

(defn- down [var {:keys [ns name stop started?]}]
  (when started?
    (info "<< stopping.. " name)
    (when stop 
      (try
        (stop)
        (catch Throwable t 
          (throw (RuntimeException. (str "could not stop [" name "] due to") t)))))
    (intern ns (symbol name) (NotStartedState. name)) ;; (!) if a state does not have :stop when _should_ this might leak
    (alter-meta! var assoc :started? false)))

;;TODO args might need more thinking
(defn args [] @-args)

          without (remove (set states) app)]
      (apply start without))
    (start)))

(defn suspend [& states]
  (let [states (or (seq states) (find-all-states))]
    (bring states sigstop <)
    :suspended))

(defn resume [& states]
  (let [states (or (seq states) (find-all-states))]
    (bring states sigcont <)
    :resumed))
