              (concat (sort (dep/topo-comparator new-deps) changed)
                      load)))))
 
-(defn reload-one [state]
+(defn remove-files
+  "Returns an updated dependency tracker indicating which namespaces
+  need to be reloaded after files were removed."
+  [state files]
+  (let [{:keys [load unload deps namespaces]} state
+        removed (keep (comp second namespaces) files)
+        new-deps (reduce dep/remove-key deps removed)
+        changed (affected-namespaces deps removed)]
+    (assoc state
+      :namespaces (apply dissoc namespaces files)
+      :deps new-deps
+      :unload (distinct
+               (concat (reverse (sort (dep/topo-comparator deps) changed))
+                       unload))
+      :load (distinct
+             (filter (complement (set removed))
+                     (concat (sort (dep/topo-comparator new-deps) changed)
+                             load))))))
+
+(defn reload-one
+  "Executes one unload/reload operation; returns updated dependency
+  tracker indicating errors and which namespaces remain to be
+  removed/reloaded."
+  [state]
   (let [{:keys [unload load]} state]
     (cond
       (seq unload)

      :else
        state)))

(defn reload-all [state]
  (loop [state (dissoc state :error)]
    (let [{:keys [unload load error]} state]
      (if (and (or (seq load) (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))
