anchor.diff:  
   (defclass mp4-atom ()
     ((atom-file-position :accessor atom-file-position :initarg :atom-file-position)
  -   (atom-size :accessor atom-size :initarg :atom-size)
  -   (atom-type :accessor atom-type :initarg :atom-type)
  -   (atom-children :accessor atom-children :initform (make-mp4-atom-collection)))
  +   (atom-size          :accessor atom-size          :initarg :atom-size)
  +   (atom-type          :accessor atom-type          :initarg :atom-type)
  +   (atom-children      :accessor atom-children      :initform nil))
     (:documentation "The minimal mp4-atom.  Note: not all atoms have children, but we put them here anyway to make things 'simple'"))
   
  -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; A collection of atoms (siblings) ;;;;;;;;;;;;;;;;;;;;
  -(defclass atom-collection ()
  -  ((atoms :accessor atoms :initform nil))
  -  (:documentation "A collection of sibling atoms"))
  -
  -(defun make-mp4-atom-collection () (make-instance 'atom-collection))
  -
  -(defmethod add ((me atom-collection) new-atom)
  -  "Adds new atom to the *end* (need to keep them in order we found them in the file) of this collection"
  -  (log5:with-context "add-atom-collection"
  -	(with-slots (atoms) me
  -	  ;(log-mp4-atom "adding ~a to atom collection: ~a" new-atom atoms)
  -	  (setf atoms (append atoms (list new-atom)))
  -	  ;(log-mp4-atom "collection now: ~a" atoms)
  -	  )))
  -
  -(defmethod size ((me atom-collection))
  -  "Returns the number of atoms in this collection"
  -  (length (slot-value me 'atoms)))
  -
  -(defmethod map-mp4-atom ((me atom-collection) &key (func nil) (depth nil))
  -  "Given a collection of atoms, call map-mp4-atom for each one"
  -  (log5:with-context "map-mp4-atom(collection)"
  -	(log-mp4-atom "map-mp4-atom: mapping collection: ~a" (slot-value me 'atoms))
  -	(dolist (a (slot-value me 'atoms))
  -	  (map-mp4-atom a :func func :depth depth))))
  +(defmethod addc ((me mp4-atom) value)
  +  "Want to add children atoms to end of ATOM-CHILDREN to preserve in-file order."
  +  (with-slots (atom-children) me
  +	(if (null atom-children)
  +		(setf atom-children (list value))
  +		(nconc atom-children (list value)))))
   
   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Concreate atoms ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   (defclass atom-skip (mp4-atom) ())
  
positive.code: 	(labels ((_indented-atom (atom depth)
  			   (format t "~vt~a~%"  (if (null depth) 0 depth) (vpprint atom nil))))
  	  (with-slots (atom-type atom-children) me
  		(log-mp4-atom "map-mp4-atom: begining traversal with ~a, I have ~d children" (as-string atom-type) (size atom-children))
  		(when (null func)
  		  (setf func #'_indented-atom))
  		(funcall func me depth)
  		(map-mp4-atom atom-children :func func :depth (if (null depth) nil (+ 1 depth)))))))
  
  (defmethod traverse ((me mp4-atom) path)
    "Used in finding nested atoms.
  Given an atom and a path, if atom-type matches first element of path, then we've found our match."
    (log5:with-context "traverse-atom"
  	(log-mp4-atom "traverse (mp4-atom): entered with ~a ~a" (as-string (atom-type me)) path)
  	(cond ((null path)
  		   (error "Path exhausted in travese atom")	; don't think this can happen?
  		   nil)
  		  ((= (atom-type me) (first path))
  		   (log-mp4-atom "traverse (mp4-atom): current path matches thus far ~a ~a" (atom-type me) path)
  		   (cond
  			 ((= 1 (length path))
  			  (log-mp4-atom "traverse (mp4-atom): length of path is 1, so found!")
  			  (return-from traverse me)))))
  
  	(log-mp4-atom "traverse (mp4-atom): current path doesn't match ~a ~a" (atom-type me) path)
  	nil))
  
  (defmethod traverse ((me atom-collection) path)
    "Used in finding nested atoms. Seach the collection and if we find a match with first of path,
  call traverse atom (unless length of path == 1, in which case, we've found our match)"
    (log5:with-context "traverse-atom-collection"
  	(log-mp4-atom "traverse (atom-collection): entering with ~a ~a" me path)
  	(dolist (sibling (atoms me))	; cleaner than using map-mp4-atom, but still a kludge
  	  (with-slots (atom-type atom-children) sibling
  		(log-mp4-atom "traverse (atom-collection): looking at ~x::~x" atom-type (first path))
  		(when (= atom-type (first path))
  		  (cond
  			((= 1 (length path))
  			 (log-mp4-atom "traverse (atom-collection): found ~a" sibling)
  			 (return-from traverse sibling))
  			(t
  			 (log-mp4-atom "traverse (atom-collection): path matches, calling traverse atom with ~a, ~a" atom-children (rest path))
  			 (let ((found (traverse atom-children (rest path))))
  			   (if found (return-from traverse found))))))))
  	(log-mp4-atom "traverse (atom-collection): looked at all, found nothing")
  	nil))
  
  (defmethod tag-get-value (atoms node)
    "Helper function to extract text from atom's data atom"
    (let ((atom (traverse atoms
  						(list +mp4-atom-moov+ +mp4-atom-udta+ +mp4-atom-meta+ +mp4-atom-ilst+ node +itunes-ilst-data+))))
  	(if atom
  
negative.code: 						  (declare (ignore depth))
  						  (when (= (atom-type atom) search-name)
  							(push atom found))))
  	(nreverse found)))
  
  (defun get-audio-properties-atoms (mp4-file)
    "First, find all TRAKs under moov. For the one that contains a HDLR atom with DATA of 'soun',
  return trak.mdia.mdhd and trak.mdia.minf.stbl.stsd"
    (dolist (track (find-all (traverse (mp4-atoms mp4-file) (list +mp4-atom-moov+)) "trak"))
  	(let ((hdlr (traverse track (list +mp4-atom-mdia+ +audioprop-hdlr+))))
  	  (when (and (not (null hdlr))
  				 (not (null (mtype hdlr)))
  				 (string= "soun" (as-string (mtype hdlr))))
  		;; we've found the correct track, extract atoms
  		(return-from get-audio-properties-atoms (values (traverse track (list +mp4-atom-mdia+ +audioprop-mdhd+))
  														(traverse track (list +mp4-atom-mdia+ +mp4-atom-minf+ +mp4-atom-stbl+ +audioprop-mp4a+))
  														(traverse track (list +mp4-atom-mdia+ +mp4-atom-minf+ +mp4-atom-stbl+ +audioprop-mp4a+ +audioprop-esds+)))))))
    nil)
  
  ;;; song length is seconds is (float duration) / (float scale)
  (defun get-audio-properties (mp4-file)
    (let ((time))
  	(multiple-value-bind (mdhd mp4a esds) (get-audio-properties-atoms mp4-file)
  	  (progn
  		(format t "mdhd: ~a~%" (vpprint mdhd nil))
  		(format t "mp4a: ~a~%" (vpprint mp4a nil))
  		(format t "esds: ~a~%" (vpprint esds nil))
  		(when mdhd
  		  (setf time (/ (float (duration mdhd)) (float (scale mdhd))))
  		  (format t "~a seconds~%" time))
  		(when mp4a
  		  (inspect mp4a)
  		  (format t "channels: ~d~%" (num-chans mp4a))
  		  (format t "bite/sample: ~:d~%" (samp-size mp4a))
  		  (let* ((upper (ash (samp-rate mp4a) -16))
  				 (lower (logand (samp-rate mp4a) #xffff))
  				 (rate (+ (float upper) (/ (float lower) 1000))))
  		  (format t "sample rate: ~:d~%" rate)))
  		(when esds
  		  (format t "XXX~%"))))))
  