 (def memory-sessions (ref {}))
 
 (defmethod read-session :memory
-  [id]
+  [repository id]
   (@memory-sessions id))
 
 (defmethod write-session :memory
-  [session]
+  [repository session]
   (dosync
     (alter memory-sessions
       assoc (session :id) session)))
 
 (defmethod destroy-session :memory
-  [session]
+  [repository session]
   (dosync
     (alter memory-sessions
       dissoc (session :id))))


(defn- set-session-cookie
  "Set the session cookie on the response if required."
  [request response session]
  (let [new?   (:new-session? request)
        cookie (session-cookie new? session)
        update (set-cookie :compojure-session cookie, :path "/")]
    (if cookie
      (update-response request response update)
      response)))

(defn- save-handler-session
  "Save the session for a handler if required."
  [request response session]
  (when (and (contains? response :session)
             (nil? (response :session)))
    (destroy-session session))
  (when (or (:session response)
            (contains? *session-repo* :expires)
            (:new-session? request)
            (not-empty (:flash request)))
    (write-session session)))

(defn with-session
  "Wrap a handler in a session of the specified type. Session type defaults to
  :memory if not supplied."
  ([handler]
    (with-session handler :memory))
  ([handler session-repo]
    (fn [request]
      (binding [*session-repo* session-repo]
        (let [request  (-> request assoc-cookies
                                   assoc-request-session
                                   assoc-request-flash)
              response (handler request)
              session  (or (:session response) (:session request))]
          (when response
            (save-handler-session request response session)
            (set-session-cookie   request response session)))))))

;; User functions for modifying the session

(defn set-session
  "Return a response map with the session set."

(defn- assoc-expiry
  "Associate an :expires-at key with the session if the session repository
  contains the :expires key."
  [repository session]
  (if-let [expires (:expires repository)]
    (assoc session :expires-at (timestamp-after expires))
    session))

