 ;; -----------------------------------------------------------------------------
 ;; Analyze
 
+(declare compile*)
+
 (def *loaded* (atom #{}))
 
 (defn require
-  ([name cb]
+  ([bound-vars name opts cb]
    (when-not (contains? @*loaded* name)
      (*load-fn* name
        (fn [source]
-         (*eval-fn* source)
-         (cb true)))))
-  ([name reload cb]
+         (compile* bound-vars source opts (fn [ret] (cb true)))))))
+  ([bound-vars name reload opts cb]
    (when (= :reload reload)
      (swap! *loaded* disj name))
    (when (= :reload-all reload)

   (when-not (contains? @*loaded* name)
     (*load-fn* name
       (fn [source]
         (*eval-fn* source)
         (cb true))))))

(declare ns-side-effects)

(defn analyze* [env bound-vars source opts cb]
  (let [rdr  (rt/string-push-back-reader source)
        eof  (js-obj)
        aenv (ana/empty-env)]
    (binding [ana/*cljs-ns*    (:*cljs-ns* bound-vars)
              *ns*             (:*ns* bound-vars)
              r/*data-readers* (:*data-readers* bound-vars)
              env/*compiler*   env]
      (loop []
        (let [form (r/read {:eof eof} rdr)]
          (if-not (identical? eof form)
            (let [aenv (assoc aenv :ns (ana/get-namespace ana/*cljs-ns*))
                  ast  (ana/analyze aenv form)]
              (if (= (:op ast) :ns)
                (ns-side-effects env ast opts bound-vars
                  (fn [_] (cb)))
                (recur)))
            (cb)))))))


  "Given a lib, a namespace, deps, its dependencies, env, an analysis environment
   and opts, compiler options - analyze all of the dependencies. Required to
   correctly analyze usage of other namespaces."
  ([bound-vars ana-env lib deps cb] (analyze-deps bound-vars lib deps nil cb))
  ([bound-vars ana-env lib deps opts cb]
   (let [compiler @(:*compiler* bound-vars)]
     (binding [ana/*cljs-dep-set* (vary-meta (conj (:*cljs-dep-set* bound-vars) lib)
                                    update-in [:dep-path] conj lib)]
