      responded?])
 
 (defn- initial-exchange-state
-  [conn]
+  [conn downstream]
   (ExchangeState.
    conn
+   nil
+   downstream
    handle-request
    handle-response
    true

(ns picard.http.server
  (:use picard.http.core))

(declare
 handle-request

        :head?      head?
        :next-up-fn next-up-fn)
     (fn [current-state]
       (maybe-finalize-exchange current-state)
       ((.upstream current-state) :request request)
       (maybe-close-connection current-state)))))

(defn- mk-downstream-fn
  [state]
  (fn [evt val]
    (if (#{:response :body} evt)
      (let [current-state @state]
        ((.next-dn-fn current-state) state evt val current-state))
      (next-dn evt val))))

(defn- exchange
  [app dn conn]
  (let [state   (atom (initial-exchange-state conn dn))
        next-up (app (mk-downstream-fn state))]
    ;; Track the upstream
    (swap! state #(assoc % :upstream next-up))

    ;; The exchange event handler only processes events
    ;; related to the current HTTP exchange and will pass
    ;; on all other events.
    (fn [evt val]
      (if (#{:request :body} evt)
        (let [current-state @state]
          ((.next-up-fn current-state) state evt val current-state))
        (next-up evt val)))))

(defn- throw-http-pipelining-exception
  []
