anchor.diff:  - The names (for use as final args)
   - The lookup assertions"
     (loop for (name type) in args
  -     when (aif (type-exp name type) (list name it)) collect it into convs
  -     collect name into as 
  -     when (lookup-assn name type) collect it into assrs
  -     finally (return (values convs as assrs))))
  +     for table? = (eq type :table)
  +     for t-exp = (type-expression name type)
  +     for assn = (lookup-assertion name type)
  +     collect name into arguments 
  +     if table? collect (list name t-exp) into table-lookups and collect assn into table-assertions
  +     when (and (not table?) t-exp) collect (list name t-exp) into type-expressions
  +     when (and (not table?) assn) collect it into assertions
  +     finally (return (values arguments table-lookups table-assertions type-expressions assertions))))
   
   (defmacro define-handler ((name) (&rest args) &body body)
     "Defines handlers with an eye for self-documentation, DRY and portability"
     (let* ((uri (concatenate 'string "/" (string-downcase (symbol-name name)))) 
   	 (opts `(,name :uri ,uri)))
  -    (multiple-value-bind (type-conversion final-args lookup-assertions) (type-pieces args)
  +    (multiple-value-bind (final-args table-lookups table-assertions type-conversions lookup-assertions) (type-pieces args)
         `(progn
  -	 (setf (gethash ,uri *handlers*) (list ,@(mapcar (lambda (s) (string-downcase (symbol-name s))) final-args)))
  +	 (setf (gethash ,uri *handlers*) '(,@args))
   	 ,(if (not args)
   	      `(define-easy-handler ,opts nil (encode-json-to-string (progn ,@body)))
  -	      `(define-easy-handler ,opts ,final-args
  -		 (assert (and ,@final-args))
  -		 (let* ,type-conversion
  -		   ,@lookup-assertions
  -		   (encode-json-to-string ,@body))))))))
  +	      (if (and (eq (caar body) 'with-lock-held) table-lookups)
  +		  `(define-easy-handler ,opts ,final-args
  +		     (assert (and ,@final-args))
  +		     (let* ,table-lookups
  +		       ,@table-assertions
  +		       (with-lock-held ,(cadar body)
  +			 (let* ,type-conversions
  +			   ,@lookup-assertions
  +			   (encode-json-to-string (progn ,@(cddar body)))))))
  +		  `(define-easy-handler ,opts ,final-args
  +		     (assert (and ,@final-args))
  +		     (let* ,(append table-lookups type-conversions)
  +		       ,@(append table-assertions lookup-assertions)
  +		       (encode-json-to-string ,@body)))))))))
   
   (defmacro define-sse-handler ((name) (&rest args) &body body)
     `(define-handler (,name) (,@args)
  
positive.code: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;;;;;;;;; All for the custom define-handler
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  (defun type-exp (arg type)
    "Given a symbol name and a type, returns the expression to read that type from a string"
    (match type
      (:string 
  
negative.code:     ((or :keyword :facing)
       `(intern (string-upcase ,arg) :keyword))
      (:table 
       (lookup-expression arg '(private-tables *server*) '(public-tables *server*)))
      ((list :list _)
       `(loop for elem in (decode-json-from-string ,arg)
  	 collect (gethash elem (things table))))
      ((or :stack :flippable :placeable
  	 (list :card :from-table))
       (lookup-expression arg '(things table)))
      ((list :card :from-hand)
       (lookup-expression arg '(hand *player*)))
      (_ (error "Invalid type label: '~a'" type))))
  
  (defun lookup-expression (arg &rest places)
    (with-gensyms (sym)
      `(let ((,sym (intern (string-upcase ,arg) :keyword)))
         (or ,@(loop for p in places
  		collect `(gethash ,sym ,p))))))
  
  (defun lookup-assertion (arg type)
    (match type
      (:table `(assert (typep ,arg 'table)))
      (:stack `(assert (typep ,arg 'stack)))
  