   ;;     (format "There is no arrow in your %s form:" (name fact-or-facts)))))
   )
 
-            
+
+;;; Ta-da!
+
+(defn complete-fact-transformation [metadata forms]
+  (given-possible-fact-nesting
+   (-> forms
+       (expand-fact-body metadata)
+       (convert-expanded-body-to-compendium-form metadata)
+       wrap-with-load-time-code)))
+                                   

    sequential?  (preserve-type form (eagerly (map midjcoexpand form)))
    :else        form))


;;; Macroexpansion-time support functions

(def ^{:dynamic true} *parse-time-fact-level* 0)

(defn- working-on-top-level-fact? []
  (= *parse-time-fact-level* 1))
  
(defmacro given-possible-fact-nesting [& forms]
  `(binding [*parse-time-fact-level* (inc *parse-time-fact-level*)]
     ~@forms))

(defmacro working-on-nested-facts [& forms]
  ;; Make sure we don't treat this as a top-level fact
  `(binding [*parse-time-fact-level* (+ 2 *parse-time-fact-level*)]
     ~@forms))

;; ;; The rather hackish construction here is to keep
;; ;; the expanded fact body out of square brackets because
;; ;; `tabular` expansions use `seq-zip`. 

;; (defn wrap-with-creation-time-fact-recording [function-form]
;;   (if (working-on-top-level-fact?)
;;     `((fn [fact-function#]
;;         (record-fact-existence fact-function#)
;;         fact-function#)
;;       ~function-form)
;;     function-form))


;; (defn convert-to-fact-function [to-be-wrapped this-function-here-symbol metadata]
;;   `(letfn [(base-function# [] ~to-be-wrapped)
;;            (~this-function-here-symbol []
;;              (with-meta base-function# '~metadata))]
;;      (~this-function-here-symbol)))


(defn convert-expanded-body-to-compendium-form
  ([expanded-body metadata]
     (convert-expanded-body-to-compendium-form expanded-body metadata
                                               (gensym 'this-function-here-)))
  
  ([expanded-body metadata this-function-here-symbol]
     (letfn [(put-check-time-fact-recording-in-body [body]
               (if (working-on-top-level-fact?)

                             :description @midje.internal-ideas.fact-context/nested-descriptions
                             :position (midje.internal-ideas.file-position/line-number-known ~lineno)}))))

                                ;;; Fact processing

;; There are three stages to fact processing:
;; * Body processing: the convertion of arrow and provided forms into their
;;   semi-sweet forms, the insertion of background data, line numbering, etc.
;;   
;; * Compendium processing: wrapping the body in a function form that supports
;;   rerunning and history keeping.
;;   
;; * Load-time processing: wrapping the final form in code that does whatever
;;   should be done the first time the fact is loaded. (Such as running it for
;;   the first time.)

;;; Support code 

(def ^{:dynamic true} *parse-time-fact-level* 0)

(defn- working-on-top-level-fact? []
  (= *parse-time-fact-level* 1))
  
(defmacro given-possible-fact-nesting [& forms]
  `(binding [*parse-time-fact-level* (inc *parse-time-fact-level*)]
     ~@forms))

(defmacro working-on-nested-facts [& forms]
  ;; Make sure we don't treat this as a top-level fact
  `(binding [*parse-time-fact-level* (+ 2 *parse-time-fact-level*)]
     ~@forms))

;;; Body Processing

(defn to-semi-sweet
  "Convert sweet keywords into their semi-sweet equivalents.
   1) Arrow sequences become expect forms.
