   (apply str (interpose "\n" (map #(add-dep-string opts %) sources))))
 
 (comment
-  (path-relative-to (io/file "out/goog/base.js") {:url (io/resource "cljs/core.js")})
-  (add-dep-string {} {:url (io/resource "cljs/core.js") :requires ["goog.string"] :provides ["cljs.core"]})
-  (deps-file {} [{:url (io/resource "cljs/core.js") :requires ["goog.string"] :provides ["cljs.core"]}])
+  (path-relative-to (io/file "out/goog/base.js") {:url (io/resource "out/cljs/core.js")})
+  (add-dep-string {} {:url (io/resource "out/cljs/core.js") :requires ["goog.string"] :provides ["cljs.core"]})
+  (deps-file {} [{:url (io/resource "out/cljs/core.js") :requires ["goog.string"] :provides ["cljs.core"]}])
   )
 
 (defn output-one-file [{:keys [output-to]} js]
-  (if output-to (spit output-to js) js))
+  (cond (nil? output-to) js
+        (string? output-to) (spit output-to js)
+        :else (println js)))
 
 (defn output-deps-file [opts sources]
   (output-one-file opts (deps-file opts sources)))

  "Topologically sort a collection of dependencies."
  [coll]
  (let [state (build-index coll)]
    (:order (reduce comp/dependency-order-visit (assoc state :order []) (keys state)))))

(defn dependencies
  "Given a sequence of Closure namespace strings, return the list of

      (if (seq requires)
        (let [node (get index (first requires))]
          (recur (concat (rest requires) (:requires node)) (conj deps node)))
        (cons "goog/base.js" (map :file (dependency-order deps)))))))

(comment
  ;; find dependencies
  (dependencies ["goog.array"])
  )

(def compiled-cljs (atom {}))

(defn get-compiled-cljs
  "If not already compiled, compile the given cljs namespace. Return
  an IJavaScript for this file. Compiled output will be written to the
  working directory."
  [opts ns]
  (let [file (str (string/replace ns "." "/") ".cljs")
        js-file (comp/rename-to-js file)
        out-file (io/file (output-directory opts) js-file)
        javascript (if (and (.exists out-file) (get @compiled-cljs ns))
                     (get @compiled-cljs ns)
                     (-compile (io/resource file)
                               (merge opts {:output-file js-file})))]
    (do (swap! compiled-cljs (fn [old] (assoc old ns javascript)))
        javascript)))

(defn cljs-dependencies
  "Given a list of all required namespaces, return a list of
  IJavaScripts which are the cljs dependencies in dependency
  order. The returned list will not only include the explicitly
  required files but any transative depedencies as well. JavaScript
  files will be compiled to the working directory if they do not
  already exist."
  [opts requires]
  (letfn [(cljs-deps [coll] (filter #(.startsWith % "cljs.") coll))]
    (loop [requires (cljs-deps requires)
           deps {}]
      (if (seq requires)
        (let [next-ns (first requires)
              js (get-compiled-cljs opts next-ns)
              new-requires (remove #(or (contains? deps %)
                                        (contains? (set requires) %))
                                   (cljs-deps (-requires js)))]
          (recur (concat (rest requires) new-requires) (assoc deps next-ns js)))
        (dependency-order (vals deps))))))

(comment
  ;; only get cljs deps
  (cljs-dependencies {} ["goog.string" "cljs.core"])
  ;; get transative deps
  (cljs-dependencies {} ["cljs.string"])
  ;; don't get cljs.core twice
  (cljs-dependencies {} ["cljs.core" "cljs.string"])
  )

(defn add-dependencies
  "Given one or more IJavaScript objects in dependency order, produce
  a new sequence of IJavaScript objects which includes the input list
  plus all dependencies in dependency order."
  [opts & inputs]
  (let [requires (mapcat -requires inputs)
        required-cljs (cljs-dependencies opts requires)
        required (dependencies (concat (mapcat -requires required-cljs) requires))
        index (dependency-index)]
    (concat (map #(javascript-file (io/resource %)
                                   (:provides (get index %))
                                   (:requires (get index %))) required)
            required-cljs
            inputs)))

(comment
  ;; add dependencies to literal js
  (add-dependencies {} "goog.provide('test.app');\ngoog.require('cljs.core');")
  (add-dependencies {} "goog.provide('test.app');\ngoog.require('goog.array');")
  (add-dependencies {} (str "goog.provide('test.app');\n"
                            "goog.require('goog.array');\n"
                            "goog.require('cljs.set');"))
  ;; add dependencies to a JavaScriptFile record
  (add-dependencies {} (javascript-file (to-url "samples/hello/src/hello/core.cljs")
                                     ["hello.core"]
                                     ["goog.array"]))
  )
