       :else
         state)))
 
-(defn reload-all [state]
+(defn reload
+  "Executes remove/reload operations on a dependency tracker until
+  either an error is encountered or there are no more pending
+  operations."
+  [state]
   (loop [state (dissoc state :error)]
     (let [{:keys [unload load error]} state]
       (if (and (or (seq load) (seq unload))

             (concat (sort (dep/topo-comparator new-deps) changed)
                     load)))))

(defn reload-one [state]
  (let [{:keys [unload load]} state]
    (cond
      (seq unload)

      (remove-deps new-decls)
      (add-deps new-decls)))

(defn- affected-namespaces [deps new-names]
  (apply set/union
         (set new-names)
         (map #(dep/transitive-dependents deps %) new-names)))

(defn tracker
  "Returns a new namespace dependency tracker."
  []
  {:deps (dep/graph)
   :unload ()
   :load ()
   :namespaces {}})

(defn add-files
  "Reads ns declarations from files; returns an updated dependency
  tracker indicating which namespaces need to be reloaded after files
  were added."
  [state files]
  (let [{:keys [load unload deps namespaces]} state
        new-pairs (keep (fn [file]
                          (when-let [decl (tns/read-file-ns-decl file)]
                            [file decl]))
                        files)
        new-decls (map second new-pairs)
        new-deps (update-deps deps new-decls)
        changed (affected-namespaces deps (map second new-decls))]
    (assoc state
      :namespaces (into namespaces new-pairs)
      :deps new-deps
      :unload (distinct
               (concat (reverse (sort (dep/topo-comparator deps) changed))
