anchor.diff:      (format stream "title = <~a>, artist = <~a>, album = <~a>, year = <~a>, comment = <~a>, track = <~d>, genre = ~d (~a)"
               title artist album year comment track genre (mp3-tag:get-id3v1-genre genre))))
   
  -(defmethod initialize-instance ((me v21-tag-header) &key instream)
  +(defmethod initialize-instance :after ((me v21-tag-header) &key instream)
     "Read in a V2.1 tag.  Caller will have stream-seek'ed file to correct location and ensured that TAG was present"
     (log5:with-context "v21-frame-initializer"
       (log-id3-frame "reading v2.1 tag")
  
positive.code: 
              ;; Must make extended header here since it is subject to unsynchronization.
              (when (header-extended-p flags)
                (setf ext-header (make-instance 'id3-extended-header :instream mem-stream)))
  
              ;; Start reading frames from memory stream
              (multiple-value-bind (_ok _frames) (read-loop version mem-stream)
  
negative.code:       (log-id3-frame "v21 tag: ~a" (vpprint me nil)))))
  
  (defclass id3-ext-header ()
    ((size         :accessor size         :initarg :size         :initform 0)
     (flags        :accessor flags        :initarg :flags        :initform 0)
     (padding      :accessor padding      :initarg :padding      :initform 0)
     (crc          :accessor crc          :initarg :crc          :initform nil)
     (is-update    :accessor is-update    :initarg :is-update    :initform nil)
     (restrictions :accessor restrictions :initarg :restrictions :initform 0))
    (:documentation "Class representing a V2.3/4 extended header"))
  
  (defmethod initialize-instance :after ((me id3-ext-header) &key instream version)
    "Read in the extended header.  Caller will have stream-seek'ed to correct location in file.
  Note: extended headers are subject to unsynchronization, so make sure that INSTREAM has been made sync-safe.
  NB: 2.3 and 2.4 extended flags are different..."
    (with-slots (size flags padding crc is-update restrictions) me
      (setf size (stream-read-u32 instream))
      (setf flags (stream-read-u16 instream)) ; reading in flags fields, must discern below 2.3/2.4
      (log-id3-frame "making id3-ext-header: version = ~d, size = ~d, flags = ~x"
                     version size flags)
      (ecase version
        (3
         (setf padding (stream-read-u32 instream))
         (when (logand flags #x8000)
           (if (not (= size 10))
               (warn-user "CRC bit set in extended header, but not enough bytes to read")
               (setf crc (stream-read-u32 instream)))))
        (4
         (when (not (= (logand #xff00 flags) 1))
           (warn-user "v2.4 extended flags length is not 1"))
         (setf flags (logand flags #xff)) ; lop off type byte (the flags length)
         (let ((len 0))
           (when (logand #x3000 flags)
             (setf len (stream-read-u8 instream))
             (when (not (zerop len)) (warn-user "v2.4 extended header is-tag length is ~d" len))
             (setf is-update t))
           (when (logand #x2000 flags)
             (setf len (stream-read-u8 instream))
             (when (not (= 5 len)) (warn-user "v2.4 extended header crc length is ~d" len))
             (setf crc (stream-read-u32 instream :bits-per-byte 7)))
           (when (logand #x1000 flags)
             (setf len (stream-read-u8 instream))
             (when (not (= 5 1)) (warn-user "v2.4 extended header restrictions length is ~d" len))
             (setf restrictions (stream-read-u8 instream))))))))
  
  (defun ext-header-restrictions-grok (r)
    "Return a string that shows what restrictions are in an ext-header"
    (if (zerop r)
        "No restrictions"
        (with-output-to-string (s)
          (format s "Tag size restictions: ~a/"
                  (ecase (ash (logand #xc0 r) -6)
                    (0 "No more than 128 frames and 1 MB total tag size")
                    (1 "No more than 64 frames and 128 KB total tag size")
                    (2 "No more than 32 frames and 40 KB total tag size")
                    (3 "No more than 32 frames and 4 KB total tag size")))
          (format s "Tag encoding restictions: ~a/"
                  (ecase (ash (logand #x20 r) -5)
                    (0 "No restrictions")
                    (1 "Strings are only encoded with ISO-8859-1 [ISO-8859-1] or UTF-8 [UTF-8]")))
          (format s "Tag field size restictions: ~a/"
                  (ecase (ash (logand #x18 r) -3)
                    (0 "No restrictions")
                    (1 "No string is longer than 1024 characters")
                    (2 "No string is longer than 128 characters")
                    (3 "No string is longer than 30 characters")))
          (format s "Tag image encoding restrictions: ~a/"
                  (ecase (ash (logand #x04 r) -2)
                    (0 "No restrictions")
                    (1 "Images are encoded only with PNG [PNG] or JPEG [JFIF]")))
          (format s "Tag image size restrictions: ~a"
                  (ecase (logand #x04 r)
                    (0 "No restrictions")
                    (1 "All images are 256x256 pixels or smaller.")
                    (2 "All images are 64x64 pixels or smaller.")
                    (3 "All images are exactly 64x64 pixels, unless required otherwise."))))))
  
  (defmethod vpprint ((me id3-ext-header) stream)
    (with-slots (size flags padding crc is-update restrictions) me
      (format stream "extended header: size: ~d, flags: ~x, padding ~:d, crc = ~x is-update ~a, restrictions = ~x/~a~%"
              size flags padding crc is-update restrictions (ext-header-restrictions-grok restrictions))))
  
  ;;; NB: v2.2 only really defines bit-7. It does document bit-6 as being the compression flag, but then states
  ;;; that if it is set, the software should "ignore the entire tag if this (bit-6) is set"
  