         ;; this handles dynamicval as well
         o))
 
-
-(defn all-static? [params]
-  (every? (complement dynamic-param?) params))
-
-(declare resolve-magic-code)
-
-(defn resolve-dynamic-fn-arg [o]
+(defn static-combine
+  ([o] (static-combine o true))
+  ([o nav-pos?]
+   (cond (sequential? o)
+         (do
+           (if-not nav-pos?
+             ;; should never happen...
+             (throw-illegal "Cannot statically combine sequential when not in nav pos"))
+           (continuous-subseqs-transform*
+             rich-nav?
+             (doall (map static-combine (flatten o)))
+             (fn [s] [(comp-paths* s)])))
+
+         (instance? DynamicFunction o)
+         (->DynamicFunction
+          (static-combine (:op o) false)
+          (doall (map #(static-combine % false) (:params o))))
+
+         (instance? DynamicPath o)
+         (->DynamicPath (static-combine (:path o)))
+
+         (instance? DynamicVal o)
+         o
+
+         :else
+         (if nav-pos?
+          (coerce-nav o)
+          o))))
+
+
+(declare resolve-nav-code)
+
+(defn resolve-arg-code [o]
   (cond (instance? DynamicFunction o)
-        (let [op (resolve-dynamic-fn-arg (:op o))
-              params (map resolve-dynamic-fn-arg (:params o))]
-          (if (all-static? (conj params op))
-            (apply op params)
-            (->DynamicFunction op params)))
+        (let [op (resolve-arg-code (:op o))
+              params (map resolve-arg-code (:params o))]
+          (maybe-direct-nav
+            `(~(original-obj op) ~@params)
+            (direct-nav? (:op o))))
 
         (instance? DynamicVal o)
-        o
+        (:code o)
 
         (instance? DynamicPath o)
-        (let [res (resolve-magic-code o)]
-          (if (rich-nav? res)
-            res
-            (->DynamicVal res)))
+        (resolve-nav-code o)
 
         :else
         o))
 
-(defn resolve-dynamic-fn-arg-code [o]
-  (cond (instance? DynamicFunction o)
-        (let [op (resolve-dynamic-fn-arg-code (:op o))
-              params (map resolve-dynamic-fn-arg-code (:params o))]
-          `(~(original-obj op) ~@params))
-
-        (instance? DynamicVal o)
-        (:code o)
-
-        :else
-        (original-obj o)))
-
-
-(defn resolve-magic-code [o]
+
+(defn resolve-nav-code [o]
   (cond
     (instance? DynamicPath o)
     (let [path (:path o)]
       (if (sequential? path)
-        (if (empty? path)
-          STAY*
-          (let [resolved (vec (map resolve-magic-code (flatten path)))
-                combined (continuous-subseqs-transform*
-                          rich-nav?
-                          resolved
-                          (fn [s] [(comp-paths* s)]))]
-            (if (= 1 (count combined))
-              (first combined)
-              `(comp-navs ~@combined))))
-        (resolve-magic-code path)))
+        (let [resolved (vec (map resolve-nav-code path))]
+          (cond (empty? resolved) STAY*
+                (= 1 (count resolved)) (first resolved)
+                :else `(comp-navs ~@resolved)))
+        (resolve-nav-code path)))
 
     (instance? DynamicVal o)
     (let [code (:code o)]


(def ^:dynamic *DEBUG-INLINE-CACHING* false)

(defn magic-precompilation [path ns-str used-locals-list]
;  (println "before magic-precompilation*:" path)
  (let [used-locals-set (set used-locals-list)
        magic-path (magic-precompilation* path)
;        _ (println "magic-precompilation*" path)
        ns (find-ns (symbol ns-str))
        final-code (resolve-magic-code (->DynamicPath magic-path))
        ;; this handles the case where a dynamicnav ignores a dynamic arg and produces
        ;; something static instead
        static? (empty? (used-locals used-locals-set final-code))
        maker (binding [*ns* ns]
                (eval+
;                 (spy
                  `(fn [~@(if static? [] used-locals-list)]
                     ~final-code)))]
    (when *DEBUG-INLINE-CACHING*
      (println "Inline caching debug information")
      (println "--------------------------------")
      (println "Input path:" path "\n")
      (println "Processed path:" magic-path "\n")
      (println "Produced code:" final-code))
    (if static?
      (->CachedPathInfo false (maker))
      (->CachedPathInfo true maker))))


  ;; TODO: could have a global flag about whether or not to compile and cache static
  ;; portions, or whether to compile everything together on each invocation (so that
  ;; it can be redefined in repl


(defn compiled-setval* [path val structure]

        (instance? FnInvocation o)
        (let [op (magic-precompilation* (:op o))
              params (doall (map magic-precompilation* (:params o)))]
          (if (or (-> op meta :dynamicnav)
                  (all-static? (conj params op)))
            (apply op params)
            (->DynamicFunction op params)))

