anchor.diff:  (in-package :cl-oid-connect)
   ; Should this be here?
   
  -(eval-when (:compile-toplevel :execute)
  +(eval-when (:compile-toplevel :execute :load-toplevel)
     (defun vars-to-symbol-macrolets (vars obj)
  -    (iterate:iterate (iterate:for var in vars)
  -                     (iterate:collect `(,var (gethash ,(alexandria:make-keyword var) ,obj))))))
  +    (iterate:iterate (iterate:for (store key) in (ensure-mapping vars))
  +                     (iterate:collect `(,store (gethash ,(alexandria:make-keyword key) ,obj))))))
   
   (defmacro with-session-values (vars session &body body)
     (alexandria:once-only (session)
       `(symbol-macrolet ,(vars-to-symbol-macrolets vars session)
          ,@body)))
  +
  +; This probably should eventually go?
  +(defmacro with-endpoints (endpoint-schema  &body body)
  +  `(let* ((*endpoint-schema* ,endpoint-schema))
  +     ,@body))
  +
  +(defmacro with-session ((var) &body body)
  +  `(progn
  +     (format t "The session var is: ~a it contains: ~a~%"  ,(symbol-name var) ,var)
  +     (let ((,var (context :session)))
  +       (format t "The session var is: ~a it now contains: ~a~%"  ,(symbol-name var) ,var)
  +       ,@body)))
  +
  +(defmacro def-route ((url args &key (app *oid*) (method :GET)) &body body)
  +  `(setf (ningle:route ,app ,url :method ,method)
  +         #'(lambda ,args
  +             (declare (ignorable ,@args))
  +             ,@body)))
   
   (defparameter *oid* (make-instance 'ningle:<app>))
   (setf drakma:*text-content-types* (cons '("application" . "json") drakma:*text-content-types*))
  
positive.code:     (cl-json:decode-json-from-string
        (drakma:http-request endpoint
                             :parameters `(("alt" . "json")
                                           ("access_token" . ,access-token))
                             ))))
  
  (defun google-login-entry (params)
    (declare (ignore params))
    (with-context-variables (session)
      (let ((state (gen-state 36)))
        (setf (gethash :state session) state)
        (with-endpoints *goog-endpoint-schema*
          (setf (gethash :endpoint-schema session) *goog-endpoint-schema*)
          (multiple-value-bind (content rcode headers) (do-auth-request *goog-endpoint-schema* state)
            (if (< rcode 400)
              `(302 (:location ,(cdr (assoc :location headers))))
              content))))))
  
  (defun facebook-login-entry (params)
    (declare (ignore params))
    (let ((session (ningle:context :session))
          (state (gen-state 36)))
        (setf (gethash :state session) state)
        (with-endpoints *fbook-endpoint-schema*
          (setf (gethash :endpoint-schema session) *fbook-endpoint-schema*)
          (multiple-value-bind (content rcode headers uri) (do-auth-request *fbook-endpoint-schema* state)
            (declare (ignore headers))
            (if (< rcode 400)
              `(302 (:location ,(format nil "~a" uri)))
              content)))))
  
  (defun google-callback (login-callback)
    (lambda (params)
      (let ((received-state (cdr (string-assoc "state" params)))
            (code (cdr (string-assoc "code" params))))
        (check-state received-state
                     (with-context-variables (session)
                       (with-endpoints *goog-endpoint-schema*
                         (let* ((a-t (get-access-token *goog-endpoint-schema* code))
                                (access-token (assoc-cdr :access--token a-t)) ;; Argh
                                (id-token (assoc-cdr :id--token a-t))
                                (decoded (cljwt:decode id-token :fail-if-unsupported nil))
                                (user-info (get-user-info *goog-endpoint-schema* access-token)))
                           (setf (gethash :idtoken session) id-token
                                 (gethash :accesstoken session) access-token
                                 (gethash :userinfo session) user-info
                                 (gethash :app-user session) (funcall login-callback
                                                                      user-info
                                                                      decoded
                                                                      access-token))
                           '(302 (:location "/"))
                           )))
                     '(403 '() "Out, vile imposter!")))))
  
  (defmacro setup-session ((session) &rest rest &key nonsense &allow-other-keys)
    (declare (ignorable nonsense))
    (cons 'progn
          (iterate:iterate (iterate:for key   in rest       by #'cddr )
                           (iterate:for value in (cdr rest) by #'cddr)
                           (iterate:collect `(setf (gethash ,(alexandria:make-keyword (key)) ,session) ,value)))))
  
  (defun facebook-callback (login-callback)
    (lambda (params)
      (let ((received-state (cdr (string-assoc "state" params)))
            (code (cdr (string-assoc "code" params))))
        (with-endpoints *fbook-endpoint-schema*
          (check-state received-state
                       (let* ((a-t (get-access-token *fbook-endpoint-schema* code))
                              (id-token (assoc-cdr :access--token a-t))
                              (user-info (get-user-info *fbook-endpoint-schema* id-token)))
                         (with-session-values (accesstoken userinfo idtoken app-user) (context :session)
                                              (setf accesstoken a-t
                                                    userinfo user-info
                                                    idtoken id-token
                                                    app-user (funcall login-callback user-info id-token a-t)))
  
                           '(302 (:location "/")))
                       '(403 '() "Out, vile imposter!"))))))
  
  (defun userinfo-route (params)
    (declare (ignore params))
  
negative.code: (defparameter *goog-info* (sheeple:clone =service-info=))
  (defparameter *endpoint-schema* nil)
  (defparameter *goog-endpoint-schema* (defobject (=endpoint-schema= *goog-info*)))
  
  (defproto *fbook-endpoint-schema* (=endpoint-schema= *fbook-info*)
            ((auth-endpoint "https://www.facebook.com/dialog/oauth")
  