   ([state source name cb]
    (analyze state source name nil cb))
   ([state source name opts cb]
+   {:pre [(atom? state) (string? source)
+          (valid-name? name) (valid-opts? opts) (fn? cb)]}
    (analyze*
      {:*compiler*     state
       :*data-readers* tags/*cljs-data-readers*

  ([state source name cb]
   (compile state source name nil cb))
  ([state source name opts cb]
    (compile*
      {:*compiler*     state
       :*data-readers* tags/*cljs-data-readers*
       :*analyze-deps* (or (:analyze-deps opts) true)
       :*load-macros*  (or (:load-macros opts) true)
       :*load-fn*      (or (:load-fn opts) *load-fn*)
       :*eval-fn*      (or (:eval-fn opts) *eval-fn*)
       :*sm-data*      (when (:source-map opts) (sm-data))}
      source name opts cb)))

;; -----------------------------------------------------------------------------
;; Evaluate String

  "Given a namespace as a symbol return the relative path sans extension"
  [ns-sym]
  (string/replace (ana/munge-path ns-sym) \. \/))

(defn atom? [x]
  (instance? Atom x))

(defn valid-name? [x]
  (or (nil? x) (symbol? x) (string? x)))

(defn valid-opts? [x]
  (or (nil? x) (map? x)))

(defonce
  ^{:doc "Each runtime environment provides a different way to load a library.
