anchor.diff:             (loop for i from 0 below length
                 do (write-value type out (char value i)))))
   
  -(define-binary-type general-terminate-string (termintor type)
  +(define-binary-type general-terminate-string (terminator type)
     (:reader (in)
              (with-output-to-string (str)
                (loop for char = (code-char (read-byte in))
  -                until (char= char termintor)
  +                until (char= char terminator)
                   do (write-char char str))))
     (:writer (out val)
              (with-input-from-string (str val)
                (loop for char = (read-char str)
  -                until (char= char termintor)
  +                until (char= char terminator)
                   do (write-byte (char-code char) out)
  -                finally (write-byte (char-code termintor) out)))))
  +                finally (write-byte (char-code terminator) out)))))
   
   (define-binary-type iso-8859-1 ()
     (:reader (in)
  
positive.code:    (extra-flags (optional :type 'u2 :if (extended-p flags)))
     (padding-size (optional :type 'u4 :if (extended-p flags)))
     (crc (optional :type 'u4 :if (crc-p flags extra-flags)))
     (frames id3-frames :size size :frame-type 'id3-v2.3-tag)))
  
  (defun extended-p (flag)
    (logbitp 6 flag))
  
  (defun crc-p (flags extra)
    (and (extended-p flags) (logbitp 15 extra)))
  
negative.code:    (size u3))
    (:dispatch (find-frame-class id)))
  
  (define-tagged-binary-class id3-v2.2-frame ()
    ((id (frame-id :length 3))
     (size u3))
    (:dispatch (find-frame-class id)))
  
  (define-tagged-binary-class id3-v2.3-frame ()
    ((id (frame-id :length 4))
     (size u4)
     (flags u2)
     (decompressed-size (optional :type 'u4 :if (frame-compressed-p flags)))
     (encryption-scheme (optional :type 'u1 :if (frame-encrypted-p flags)))
     (grouping-identity (optional :type 'u1 :if (frame-grouped-p flags))))
    (:dispatch (find-frame-class id)))
  
  (defun frame-compressed-p (flags)
    (logbitp 7 flags))
  
  (defun frame-encrypted-p (flags)
    (logbitp 6 flags))
  
  (defun frame-grouped-p (flags)
    (logbitp 5 flags))
  
  (defmethod frame-header-size ((frame id3-v2.2-frame)) 6)
  (defmethod frame-header-size ((frame id3-v2.3-frame)) 10)
  
  (define-binary-class generic-frame-v2.2 (id3-v2.2-frame generic-frame) ())
  (define-binary-class generic-frame-v2.3 (id3-v2.3-frame generic-frame) ())
  
  (define-binary-class generic-frame (frame)
    ((data (raw-bytes :size (data-bytes (current-binary-object))))))
  
  (defgeneric data-bytes (frame))
  
  (defmethod data-bytes ((frame id3-v2.2-frame))
    (size frame))
  
  (defmethod data-bytes ((frame id3-v2.3-frame))
    (let ((flags (flags frame)))
      (- (size frame)
         (if (frame-compressed-p flags) 4 0)
         (if (frame-encrypted-p flags) 1 0)
         (if (frame-grouped-p flags) 1 0))))
  
  (define-binary-type raw-bytes (size)
    (:reader (in)
             (let ((buf (make-array size :element-type '(unsigned-byte 8))))
               (read-sequence buf in)
               buf))
    (:writer (out val)
             (write-sequence val out)))
  
  (defun find-frame-class (id)
    (cond
      ((and (char= (char id 0) #\T)
            (not (member id '("TXX" "TXXX") :test #'string=)))
       (ecase (length id)
         (3 'text-info-frame-v2.2)
         (4 'text-info-frame-v2.3)))
      ((string= id "COM") 'comment-frame-v2.2)
      ((string= id "COMM") 'comment-frame-v2.3)
      (t (ecase (length id)
           (3 'generic-frame-v2.2)
           (4 'generic-frame-v2.3)))))
  
  (define-binary-type id3-frames (size frame-type)
    (:reader (in)
             (loop with to-read = size
                while (plusp to-read)
                for frame = (read-frame frame-type in)
                while frame
                do (decf to-read (+ (frame-header-size frame)
                                    (size frame)))
                collect frame
                finally (loop repeat (- size to-read)
                           do (read-byte in))))
    (:writer (out val)
             (loop with to-write = size
                for frame in val
                do (write-value 'frame out frame)
                  (decf to-write (+ (frame-header-size frame)
                                    (size frame)))
                  finally (loop repeat to-write
                             do (write-byte 0 out)))))
  
  