anchor.diff:    (and (listp obj)
          (every #'rpc-call-p obj)))
   
  -(deftype rpc-request () '(and list (satisfies rpc-request-p)))
  -
  -(define-condition invalid-call-object ()
  -  ((obj :initarg :obj)))
  +(deftype rpc-request () '(satisfies rpc-request-p))
   
   (defun marshall-request (obj)
     (check-type obj rpc-request)
  -  (when (not (every #'valid-call-p obj))
  -    (error 'invalid-call-obj :obj (find-if-not #'valid-call-p obj)))
     (json:with-array ()
       (loop for call in obj do
            (json:as-array-member ()
              (marshall-call call)))))
   
  -(defun json-is-request (json-obj)
  -  "Return T if a REQUEST object could be unmarshalled from JSON-OBJ."
  -  (and (listp json-obj)
  -       (every #'json-is-call json-obj)))
  -
  -(defun intermediate-to-request (obj)
  -  "Convert an intermediate-format object to a request object."
  -  (mapcar #'intermediate-to-call obj))
  -
  -(defun unmarshall-request (json-string)
  +(defun unmarhsall-request (json-string)
     "Unmarshall a REQUEST object from the decoded JSON object JSON-OBJ."
  -  (let ((json-obj (json:decode-json-from-string  json-string)))
  -    (when (not (json-is-request json-obj))
  -      (format *debug-io* "Invalid rpc-request json object ~S~%" json-obj)
  +  (let ((json-obj (json:decode-json-from-string json-string)))
  +    (unless (listp json-obj)
         (error 'invalid-json-obj :type 'rpc-request :json json-obj))
  -    (intermediate-to-request json-obj)))
  +    (mapcar #'build-call json-obj)))
  +
   
   ;;; Response, a list of RESULTs
   (defun rpc-response-p (obj)
  
positive.code: (in-package #:cl-mtgnet)
  
  ;;; TODO: have marshall/unmarshall only deal with string<->struct
  ;;; conversions (don't expose or accept intermediate json-obj)
  (defmacro encode-fields ((obj) &rest fields)
    "JSON-encode the FIELDS slots of OBJ. Expects to be run inside a JSON:WITH-OBJECT block."
    `(progn
       ,@(loop for f in fields collect
              (if (listp f)
                  `(json:as-object-member ((quote ,(first f)))
                     (funcall ,(second f) (slot-value ,obj (quote ,(first f)))))
                  `(json:encode-object-member (quote ,f)
                                              (slot-value ,obj (quote ,f)))))))
  
  (defun json-key (symb)
    "Return the symbol produced by JSON encoding and decoding SYMB."
  
negative.code:          collect `(assoc (json-key (quote ,f))
                           ,alist))))
  
  (defun get-field (key alist &rest args)
    "Return either the value of the field named KEY from the decoded
  json object ALIST, or NIL. Additional arguments will be passed to
  ASSOC."
    (let* ((key (json-key key))
           (cell (apply #'assoc (cons key (cons alist args)))))
      (and cell (cdr cell))))
  
  ;;; Error conditions
  (define-condition invalid-json-obj ()
    ((type :initarg :type)
     (json :initarg :json)))
  
  (define-condition invalid-call-object ()
    ((obj :initarg :obj)))
  
  (define-condition invalid-result-obj ()
    ((obj :initarg :obj)))
  
  ;;; Call object, one per method call
  ;; TODO: Find a more stringent definition for arglist ('(list string)?)
  (deftype arglist () `list)
  
  (defstruct rpc-call
    "A single method invocation."
    (service "" :type string :read-only t)
    (method "" :type string :read-only t)
    (args '() :type arglist :read-only t)
    (id nil :read-only t))
  
  (defun valid-call-p (obj)
    "Returns T if the object is a valid CALL object."
  