   [[name args & body :as f] props computed]
   (let [scope (fn-scope f)]
     (if (not= scope :static)
-      (let [this-index      (.indexOf args 'this)
+      (let [prop-names      (map :name props)
+            computed-names  (map :name computed)
+            this-index      (.indexOf args 'this)
             props-index     (.indexOf args 'props)
             actual-props    (if (>= props-index 0)
                               (args props-index)

                                nil))
            actual-computed `(~'om/get-computed ~actual-props)]
        `(~name ~args
          (~'let [{:keys [~@props]} ~actual-props
                  {:keys [~@computed]} ~actual-computed]
           ~@body)))
      f)))


  ([pred pad coll] (sequence (pad-by pred pad) coll)))

(defn parse-props-spec
  "Parse a props spec like [user [name email {friends User}]] into
   a flat collection with the following structure:

   [{:name user/name :join nil}
    {:name user/email :join nil}
    {:name user/friends :join User}].

   From this it is trivial to a) generate keys for destructuring
   view props and b) generate an Om Next query."
  [spec]
  (letfn [(prop-type [p]
            (cond
              (or (symbol? p) (map? p)) :prop
              (vector? p)               :children
              :else                     :unknown))
          (prop-name [p]
            (cond
              (symbol? p) (name p)
              (map? p)    (name (ffirst p))
              :else       nil))
          (parse-prop [parent p]
            (cond
              (symbol? p) {:name (symbol (prop-name parent)
                                         (prop-name p))
                           :join nil}
              (map? p)    {:name (symbol (prop-name parent)
                                         (prop-name p))
                           :join (second (first p))}
              :else       nil))
          (parse-step [result [p children]]
            {:pre [(= (prop-type p) :prop)
                   (or (nil? children)
                       (= (prop-type children) :children))]}
            (concat result
                    (cond
                      (nil? children)    [(parse-prop nil p)]
                      (vector? children) (mapv #(parse-prop p %)
                                               children))))]
    (->> (pad-by #(= (prop-type %1) (prop-type %2)) nil spec)
         (partition-all 2 2)
         (reduce parse-step []))))

(def fn-specs
  "Function specifications for all functions that are not Object
