TODO rework
[clinton/abcde.git] / abcde
diff --git a/abcde b/abcde
index 9b51ecc..3fc4cc5 100755 (executable)
--- a/abcde
+++ b/abcde
@@ -1,6 +1,6 @@
 #!/bin/sh
 # Copyright (c) 1998-2001 Robert Woodcock <rcw@debian.org>
-# Copyright (c) 2003-2004 Jesus Climent <jesus.climent@hispalinux.es>
+# Copyright (c) 2003-2005 Jesus Climent <jesus.climent@hispalinux.es>
 # This code is hereby licensed for public consumption under either the
 # GNU GPL v2 or greater, or Larry Wall's Artistic license - your choice.
 #
@@ -11,7 +11,7 @@
 # Copyright for this work is to expire January 1, 2010, after which it
 # shall be public domain.
 
-VERSION="2.3.0"
+VERSION="2.3.99"
 
 usage ()
 {
@@ -20,17 +20,21 @@ echo "Usage: abcde [options] [tracks]"
 echo "Options:"
 echo "-1     Encode the whole CD in a single file"
 echo "-a <action1[,action2]...>"
-echo "       Actions to perform (cddb,read,normalize,encode,tag,move,playlist,clean)"
+echo "       Actions to perform (cddb,read,normalize,encode,tag,move,replaygain,playlist,clean)"
 #echo "-A     Experimental actions (retag, transcode)"
-echo "-b     Batch mode: enable album normalization and nogap encoding"
+echo "-b     Enable batch normalization"
+#echo "-B     Disable batch replaygain (do file by file)"
 echo "-c <file>"
 echo "       Specify a configuration file (overrides system and user config files)"
 echo "-C <discid#>"
 echo "       Specify discid to resume from (only needed if you no longer have the cd)"
 echo "-d <device>"
-echo "       Specify CDROM device to grab"
+echo "       Specify CDROM device to grab (flac uses a single-track flac file)"
 echo "-D     Debugging mode (equivalent to sh -x abcde)"
 echo "-e     Erase encoded track information from status file"
+#echo "-E     Set the encoding information for the tags"
+echo "-f     Force operations that otherwise are considered harmful. Read \"man abcde\""
+echo "-g     Use \"lame --nogap\" for MP3 encoding. Disables low disk and pipes flags"
 echo "-h     This help information"
 #echo "-i    Tag files while encoding, when possible (local only) -NWY-"
 echo "-j <#> Number of encoder processes to run at once (localhost)"
@@ -42,29 +46,51 @@ echo "-N     Noninteractive. Never prompt for anything"
 echo "-m     Modify playlist to include CRLF endings, to comply with some players"
 echo "-M     Create a CUE file"
 echo "-o <type1[,type2]...>"
-echo "       Output file type(s) (vorbis,mp3,flac,spx,mpc). Defaults to vorbis"
+echo "       Output file type(s) (vorbis,mp3,flac,spx,mpc,wav). Defaults to vorbis"
 echo "-p     Pad track numbers with 0's (if less than 10 tracks)"
 echo "-P     Use UNIX pipes to read+encode without wav files"
 echo "-r <host1[,host2]...>"
 echo "       Also encode on these remote hosts"
-echo "-R     Add replaygain values to the tag info (only for vorbis,flac)"
+#echo "-R     Add replaygain values to the tag info (only for vorbis,flac,mp3)"
+echo "-s <field>"
+echo "       Show dielfs from the CDDB info (year,genre)"
 echo "-S <#> Set the CD speed"
-#echo "-t    File types to preprocess (wav)"
-#echo "-T    Set postprocessing options"
 echo "-t <#> Start the track numbering at a given number"
 echo "-T <#> Same as -t but modifies tag numbering"
+echo "-u     Use UNICODE tags and comments"
 echo "-v     Show version number and exit"
 echo "-V     Be a bit more verbose about what is happening behind the scenes"
 echo "-x     Eject CD after all tracks are read"
 echo "-w <comment>"
 echo "       Add a comment to the CD tracks"
 echo "-W <#> Contatenate CDs: -T #01 -w \"CD #\"" 
+echo "-z     Use debug CDROMREADERSYNTAX option (needs cdparanoia)"
 echo ""
 echo "Tracks is a space-delimited list of tracks to grab."
-echo "Ranges specified with hyphens are allowed."
+echo "Ranges specified with hyphens are allowed (i.e., 1-5)."
+echo ""
 #echo "Double hyphens are used to concatenate tracks"
 }
 
+addstatus ()
+{
+       echo "$@" >> "$ABCDETEMPDIR/status"
+}
+
+# log [level] [message]
+# 
+# log outputs the right message in a common format
+log ()
+{
+       BLURB="$1"
+       shift
+       case $BLURB in
+               error)   echo "[ERR] abcde: $@" >&2 ;;
+               warning) echo "[WAR] $@" >&2 ;;
+               info)    echo "[INF] $@" ;;
+       esac
+}
+
 # Funtions to replace the need of seq, which is too distribution dependant.
 f_seq_row ()
 {
@@ -79,12 +105,17 @@ f_seq_row ()
 f_seq_line ()
 {
        i=$1
-       while [ $i -ne `expr $2 + 1` ]
-       do
-               printf $i" "
-               i=`expr $i + 1`
-       done
-       echo
+       if echo i | grep -q "[[:digit:]]" ; then
+               while [ $i -ne `expr $2 + 1` ]
+               do
+                       printf $i" "
+                       i=`expr $i + 1`
+               done
+               echo
+       else
+               log error "syntax error while processing track numbers"
+               exit 1
+       fi
 }
 
 # Functions to replace the need of awk {print $1} and {print $NF}
@@ -135,6 +166,29 @@ checkstatus ()
        fi
 }
 
+# chechwarnings [blurb]
+# Returns "0" if the blurb was found (meaning there was an warning),
+# returns 1 if it wasn't (yes this is a little backwards).
+# Does not print the blurb on stdout.
+# Otherwise, returns "".
+checkwarnings ()
+{
+       if [ -e "$ABCDETEMPDIR/warnings" ]; then :; else
+               return 1
+       fi
+       # Take the last line in the status file if there's multiple matches
+       PATTERN="^$1(:.*)?$"
+       BLURB="$(egrep $PATTERN "$ABCDETEMPDIR/warnings" | tail -n 1)"
+
+       if [ -z "$BLURB" ]; then
+               # negative, we did not have a negative...
+               return 1
+       else
+               # affirmative, we had a negative...
+               return 0
+       fi
+}
+
 # checkerrors [blurb]
 # Returns "0" if the blurb was found (meaning there was an error),
 # returns 1 if it wasn't (yes this is a little backwards).
@@ -158,6 +212,31 @@ checkerrors ()
        fi
 }
 
+# page [file]
+# Finds the right pager in the system to display a file
+page ()
+{
+       PAGEFILE="$1"
+       # Use the debian sensible-pager wrapper to pick the pager
+       # user has requested via their $PAGER environment variable
+       if [ -x "/usr/bin/sensible-pager" ]; then
+               /usr/bin/sensible-pager "$PAGEFILE"
+       elif [ -x "$PAGER" ]; then
+               # That failed, try to load the preferred editor, starting
+               # with their PAGER variable
+               $PAGER "$PAGEFILE"
+               # If that fails, check for less
+       elif [ -x /usr/bin/less ]; then
+               /usr/bin/less -f "$PAGEFILE"
+               # more should be on all UNIX systems
+       elif [ -x /bin/more ]; then
+               /bin/more "$PAGEFILE"
+       else
+               # No bananas, just cat the thing
+               cat "$PAGEFILE" >&2
+       fi
+}
+
 # run_command [blurb] [command...]
 # Runs a command, silently if necessary, and updates the status file
 run_command ()
@@ -180,7 +259,7 @@ run_command ()
                fi
        fi
        case "$1" in
-       normalize)
+       normalize|normalize-audio)
                if [ "$RETURN" = "2" ]; then
                        # File was already normalized.
                        RETURN=0
@@ -252,6 +331,88 @@ relpath ()
        echo $TO
 }
 
+# do_getcddbinfo
+# Finds an specific field from cddbinfo
+# 
+#      TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2 -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')
+#      TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | head -n 1 | cut -f2 -d= | tr -d \[:cntrl:\])
+#      TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
+
+do_getcddbinfo()
+{
+       case $1 in
+       TRACKNAME1)
+               TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | head -n 1 | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
+               ;;
+       TRACKNAME)
+               TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
+               ;;
+       esac
+}
+
+# do_gettracknum
+# Get the track number we are going to use for different actions
+do_gettracknum()
+{
+       if [ -n "$STARTTRACKNUMBER" ] ; then
+               # Get the trackpadding from the current track
+               CURRENTTRACKPADDING=$(echo -n $UTRACKNUM | wc -c)
+               TRACKNUM=$( printf %0.${CURRENTTRACKPADDING}d $(expr ${UTRACKNUM} + ${STARTTRACKNUMBER} - $FIRSTTRACK ))
+       else
+               TRACKNUM=${UTRACKNUM}
+       fi
+}
+
+do_replaygain()
+{
+       if checkstatus replaygain; then :; else
+               run_command "" echo "Adding replygain information..."
+               for OUTPUT in $( echo $OUTPUTTYPE | tr , \ )
+               do
+                       case $OUTPUT in
+                               vorbis|ogg)
+                                       OUTPUT=$OGGOUTPUTCONTAINER
+                                       ;;
+                               flac)
+                                       OUTPUT=$FLACOUTPUTCONTAINER
+                                       ;;
+                       esac
+                       OUTPUTFILES=""
+                       for UTRACKNUM in $TRACKQUEUE
+                       do
+                               CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
+                               do_getcddbinfo TRACKNAME
+                               splitvarious
+                               TRACKFILE="$(mungefilename "$TRACKNAME")"
+                               ARTISTFILE="$(mungefilename "$TRACKARTIST")"
+                               ALBUMFILE="$(mungefilename "$DALBUM")"
+                               do_gettracknum
+                               if [ "$VARIOUSARTISTS" = "y" ]; then
+                                       OUTPUTFILE="$(eval echo $VAOUTPUTFORMAT)"
+                               else
+                                       OUTPUTFILE="$(eval echo $OUTPUTFORMAT)"
+                               fi
+                               OUTPUTFILES="$OUTPUTDIR/$OUTPUTFILE.$OUTPUT $OUTPUTFILES"
+                       done
+                       case "$OUTPUT" in
+                               flac)
+                                       run_command replaygain-flac $METAFLAC --add-replay-gain "$OUTPUTFILES"
+                                       ;;
+                               vorbis|ogg)
+                                       run_command replaygain-vorbis $VORBISGAIN --album "$OUTPUTFILES"
+                                       ;;
+                               mp3)
+                                       run_command replaygain-mp3 $MP3GAIN -a "$OUTPUTFILES"
+                                       ;;
+                               *);;
+                       esac
+               done
+               if checkerrors "replaygain-.{3,6}"; then :; else
+                       run_command replaygain true
+               fi
+       fi
+}
+
 # This code splits the a Various Artist track name from one of the following
 # forms:
 #
@@ -269,37 +430,37 @@ splitvarious ()
        if [ "$VARIOUSARTISTS" = "y" ] && [ ! "$ONETRACK" = "y" ]; then
                case "$VARIOUSARTISTSTYLE" in
                forward)
-                       DTITLEARTIST=$(echo "$TRACKNAME" | sed 's- / -~-g')
-                       TRACKARTIST=$(echo "$DTITLEARTIST" | cut -f1 -d~)
-                       TRACKNAME=$(echo "$DTITLEARTIST" | cut -f2 -d~)
+                       DTITLEARTIST="$(echo "$TRACKNAME" | sed 's- / -~-g')"
+                       TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
+                       TRACKNAME="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
                        ;;
                forward-dash)
-                       DTITLEARTIST=$(echo "$TRACKNAME" | sed 's, - ,~,g')
-                       TRACKARTIST=$(echo "$DTITLEARTIST" | cut -f1 -d~)
-                       TRACKNAME=$(echo "$DTITLEARTIST" | cut -f2 -d~)
+                       DTITLEARTIST="$(echo "$TRACKNAME" | sed 's, - ,~,g')"
+                       TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
+                       TRACKNAME="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
                        ;;
                reverse)
-                       DTITLEARTIST=$(echo "$TRACKNAME" | sed 's- / -~-g')
-                       TRACKARTIST=$(echo "$DTITLEARTIST" | cut -f2 -d~)
-                       TRACKNAME=$(echo "$DTITLEARTIST" | cut -f1 -d~)
+                       DTITLEARTIST="$(echo "$TRACKNAME" | sed 's- / -~-g')"
+                       TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
+                       TRACKNAME="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
                        ;;
                reverse-dash)
-                       DTITLEARTIST=$(echo "$TRACKNAME" | sed 's, - ,~,g')
-                       TRACKARTIST=$(echo "$DTITLEARTIST" | cut -f2 -d~)
-                       TRACKNAME=$(echo "$DTITLEARTIST" | cut -f1 -d~)
+                       DTITLEARTIST="$(echo "$TRACKNAME" | sed 's, - ,~,g')"
+                       TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
+                       TRACKNAME="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
                        ;;
                colon)
-                       DTITLEARTIST=$(echo "$TRACKNAME" | sed 's-: -~-g')
-                       TRACKARTIST=$(echo "$DTITLEARTIST" | cut -f1 -d~)
-                       TRACKNAME=$(echo "$DTITLEARTIST" | cut -f2 -d~)
+                       DTITLEARTIST="$(echo "$TRACKNAME" | sed 's-: -~-g')"
+                       TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
+                       TRACKNAME="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
                        ;;
                trailing-paren)
-                       DTITLEARTIST=$(echo "$TRACKNAME" | sed 's,^\(.*\) (\(.*\)),\1~\2,')
-                       TRACKARTIST=$(echo "$DTITLEARTIST" | cut -f2 -d~)
-                       TRACKNAME=$(echo "$DTITLEARTIST" | cut -f1 -d~)
+                       DTITLEARTIST="$(echo "$TRACKNAME" | sed 's,^\(.*\) (\(.*\)),\1~\2,')"
+                       TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
+                       TRACKNAME="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
                        ;;
                esac
-       elif [ "$ONETRACK" = "y" ]; then
+       elif [ "$VARIOUSARTISTS" = "y" ] && [ "$ONETRACK" = "y" ]; then
                TRACKARTIST="Various"
        else
                TRACKARTIST="$DARTIST"
@@ -372,7 +533,7 @@ local id=""
                "gangsta")               id=59 ;;
                "top 40")                id=60 ;;
                "christian rap")         id=61 ;;
-               "pop/funk")              id=62 ;;
+               "pop/funk"|"pop / funk") id=62 ;;
                "jungle")                id=63 ;;
                "native american")       id=64 ;;
                "cabaret")               id=65 ;;
@@ -458,6 +619,7 @@ local id=""
                "anime")                 id=145 ;;
                "jpop")                  id=146 ;;
                "synthpop")              id=147 ;;
+               "rock/pop"|"rock / pop") id=148 ;;
                *)                       return 1 ;;
        esac
 echo ${id}
@@ -472,129 +634,158 @@ return 0
 do_tag ()
 {
        COMMENTOUTPUT="$(eval echo ${COMMENT})"
+       CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
        run_command '' echo "Tagging track $1 of $TRACKS: $TRACKNAME..."
        # If we want to start the tracks with a given number, we need to modify the
        # TRACKNUM value before evaluation
-       if [ -n "$STARTTRACKNUMBER" -a -n "$STARTTRACKNUMBERTAG" ] ; then
-               # Get the trackpadding from the current track
-               CURRENTTRACKPADDING=$(echo -n $UTRACKNUM | wc -c)
-               TRACKNUM=$( printf %0.${CURRENTTRACKPADDING}d $(expr ${UTRACKNUM} + ${STARTTRACKNUMBER} - $FIRSTTRACK ))
+       if [ -n "$STARTTRACKNUMBERTAG" ] ; then
+               do_gettracknum
        fi
        for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
        do
-       case "$OUTPUT" in
-       mp3)
-               # id3v2 v0.1.9 claims to have solved the -c bug, so we merge both id3 and id3v2
-               GENREID=$(do_getgenreid "${CDGENRE}")
-
-               # FIXME # track numbers in mp3 come with 1/10, so we cannot happily substitute them with $TRACKNUM
-               run_command tagtrack-$1 $TAGGER $TAGGEROPTS -c "$COMMENTOUTPUT" \
-                       -A "$DALBUM" -a "$TRACKARTIST" -t "$TRACKNAME" -y "$CDYEAR" \
-                       -g "$GENREID" -T "${TRACKNUM:-$1/$TRACKS}" \
-                       "$ABCDETEMPDIR/track$1.$OUTPUT"
-               ;;
-       vorbis|ogg)
-               case "$OGGENCODERSYNTAX" in
-                       vorbize|oggenc)
-                               # vorbiscomment can't do in-place modification, mv the file first
-                               if [ -f "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" -a ! -f "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" ]; then
-                                       mv "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER"
-                               fi
-                               (
-                               # These are from http://www.xiph.org/ogg/vorbis/doc/v-comment.html
-                               echo ARTIST="$TRACKARTIST"
-                               echo ALBUM="$DALBUM"
-                               echo TITLE="$TRACKNAME"
-                               if [ -n "$CDYEAR" ]; then
-                                       echo DATE="$CDYEAR"
-                               fi
-                               if [ -n "$CDGENRE" ]; then
-                                       echo GENRE="$CDGENRE"
-                               fi      
-                               echo TRACKNUMBER=${TRACKNUM:-$1}
-                               echo CDDB=$CDDBDISCID
-                               if [ "$(eval echo ${COMMENT})" != "" ]; then
-                                       case "$COMMENTOUTPUT" in
-                                               *=*) echo "$COMMENTOUTPUT";;
-                                               *)   echo COMMENT="$COMMENTOUTPUT";;
-                                       esac    
-                               fi
-                               ) | run_command tagtrack-$1 $VORBISCOMMENT $VORBISCOMMENTOPTS -w \
-                                       "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER"
-                               # Doublecheck that the commented file was created successfully before wiping the original
-                               if [ -f "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" ]; then
-                                       rm -f "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER"
-                               else
-                                       mv "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER"
-                               fi
-                               ;;
+               case "$OUTPUT" in
+               mp3)
+                       # id3v2 v0.1.9 claims to have solved the -c bug, so we merge both id3 and id3v2
+                       GENREID=$(do_getgenreid "${CDGENRE}")
+       
+                       case "$ID3SYNTAX" in
+                               id3);;
+                               eyed3)
+                                       # FIXME # track numbers in mp3 come with 1/10, so we cannot happily substitute them with $TRACKNUM
+                                       run_command tagtrack-$OUTPUT-$1 $TAGGER $TAGGEROPTS --commen=::"$COMMENTOUTPUT" \
+                                               -A "$DALBUM" -a "$TRACKARTIST" -t "$TRACKNAME" -Y "$CDYEAR" \
+                                               -G "$GENREID" -n "${TRACKNUM:-$1}" "${TRACKNUM:+-N $TRACKS}" \
+                                               "${ENCODING:+--set-encoding=$ENCODING}"
+                                               "$ABCDETEMPDIR/track$1.$OUTPUT"
+                                       ;;
+                               *)
+                                       # FIXME # track numbers in mp3 come with 1/10, so we cannot happily substitute them with $TRACKNUM
+                                       run_command tagtrack-$OUTPUT-$1 $TAGGER $TAGGEROPTS -c "$COMMENTOUTPUT" \
+                                               -A "$DALBUM" -a "$TRACKARTIST" -t "$TRACKNAME" -y "$CDYEAR" \
+                                               -g "$GENREID" -T "${TRACKNUM:-$1/$TRACKS}" \
+                                               "$ABCDETEMPDIR/track$1.$OUTPUT"
+                                       ;;
+                       esac
+                       ;;
+               vorbis|ogg)
+                       case "$OGGENCODERSYNTAX" in
+                               vorbize|oggenc)
+                                       # vorbiscomment can't do in-place modification, mv the file first
+                                       if [ -f "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" -a ! -f "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" ]; then
+                                               mv "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER"
+                                       fi
+                                       (
+                                       # These are from http://www.xiph.org/ogg/vorbis/doc/v-comment.html
+                                       echo ARTIST="$TRACKARTIST"
+                                       echo ALBUM="$DALBUM"
+                                       echo TITLE="$TRACKNAME"
+                                       if [ -n "$CDYEAR" ]; then
+                                               echo DATE="$CDYEAR"
+                                       fi
+                                       if [ -n "$CDGENRE" ]; then
+                                               echo GENRE="$CDGENRE"
+                                       fi      
+                                       echo TRACKNUMBER=${TRACKNUM:-$1}
+                                       echo CDDB=$CDDBDISCID
+                                       if [ "$(eval echo ${COMMENT})" != "" ]; then
+                                               case "$COMMENTOUTPUT" in
+                                                       *=*) echo "$COMMENTOUTPUT";;
+                                                       *)   echo COMMENT="$COMMENTOUTPUT";;
+                                               esac    
+                                       fi
+                                       ) | run_command tagtrack-$OUTPUT-$1 $VORBISCOMMENT $VORBISCOMMENTOPTS -w \
+                                               "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER"
+                                       # Doublecheck that the commented file was created successfully before wiping the original
+                                       if [ -f "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" ]; then
+                                               rm -f "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER"
+                                       else
+                                               mv "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER"
+                                       fi
+                                       ;;
+                       esac
+                       ;;
+               flac)
+                       (
+                       echo ARTIST="$TRACKARTIST"
+                       echo ALBUM="$DALBUM"
+                       echo TITLE="$TRACKNAME"
+                       if [ -n "$CDYEAR" ]; then
+                               echo DATE="$CDYEAR"
+                       fi
+                       if [ -n "$CDGENRE" ]; then
+                               echo GENRE="$CDGENRE"
+                       fi      
+                       echo TRACKNUMBER="${TRACKNUM:-$1}"
+                       echo CDDB="$CDDBDISCID"
+                       if [ "$(eval echo ${COMMENT})" != "" ]; then
+                               case "$COMMENTOUTPUT" in
+                                       *=*) echo "$COMMENTOUTPUT";;
+                                       *)   echo COMMENT="$COMMENTOUTPUT";;
+                               esac    
+                       fi
+                       ) | run_command tagtrack-$OUTPUT-$1 $METAFLAC $METAFLACOPTS --import-tags-from=- "$ABCDETEMPDIR/track$1.$FLACOUTPUTCONTAINER"
+                       ;;
+               spx)
+                       run_command tagtrack-$OUTPUT-$1 true
+                       ;;
+               mpc)
+                       run_command tagtrack-$OUTPUT-$1 true
+                       ;;
+               wav)
+                       run_command tagtrack-$OUTPUT-$1 true
+                       ;;
                esac
-               ;;
-       flac)
-               (
-               echo ARTIST="$TRACKARTIST"
-               echo ALBUM="$DALBUM"
-               echo TITLE="$TRACKNAME"
-               if [ -n "$CDYEAR" ]; then
-                       echo DATE="$CDYEAR"
-               fi
-               if [ -n "$CDGENRE" ]; then
-                       echo GENRE="$CDGENRE"
-               fi      
-               echo TRACKNUMBER=${TRACKNUM:-$1}
-               echo CDDB=$CDDBDISCID
-               if [ "$(eval echo ${COMMENT})" != "" ]; then
-                       case "$COMMENTOUTPUT" in
-                               *=*) echo "$COMMENTOUTPUT";;
-                               *)   echo COMMENT="$COMMENTOUTPUT";;
-                       esac    
-               fi
-               ) | run_command tagtrack-$1 $METAFLAC $METAFLACOPTS --import-tags-from=- "$ABCDETEMPDIR/track$1.$FLACOUTPUTCONTAINER"
-               ;;
-       spx)
-               run_command tagtrack-$1 true
-               ;;
-       mpc)
-               run_command tagtrack-$1 true
-               ;;
-       esac
        done
+       if checkerrors "tagtrack-(.{3,6})-$1"; then :; else
+               run_command tagtrack-$1 true
+       fi
+
 }
 
-# do_batch_encode
+# do_nogap_encode
 # variables used:
 # OUTPUTTYPE, {FOO}ENCODERSYNTAX, ENCNICE, ENCODER, ENCODEROPTS
-do_batch_encode ()
+do_nogap_encode ()
 {
        # The commands here don't go through run_command because they're never supposed to be silenced
-       echo "Batch encoding tracks: $TRACKQUEUE"
-       OUTPUT=$(echo $OUTPUTTYPE | grep "mp3" )
-       case "$OUTPUT" in
-       mp3)
-               case "$MP3ENCODERSYNTAX" in
-               lame)
-                       (
-                       cd "$ABCDETEMPDIR"
-                       TRACKFILES=
-                       for UTRACKNUM in $TRACKQUEUE
-                       do
-                               TRACKFILES="$TRACKFILES track$UTRACKNUM.wav"
-                       done
-                       nice $ENCNICE $MP3ENCODER $MP3ENCODEROPTS --nogap $TRACKFILES
-                       RETURN=$?
-                       if [ "$RETURN" != "0" ]; then
-                               echo "batch-encode: $ENCODER returned code $RETURN" >> errors
-                       else
+       echo "Encoding gapless MP3 tracks: $TRACKQUEUE"
+       for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
+       do
+               case "$OUTPUT" in
+               mp3)
+                       case "$MP3ENCODERSYNTAX" in
+                       lame)
+                               (
+                               cd "$ABCDETEMPDIR"
+                               TRACKFILES=
                                for UTRACKNUM in $TRACKQUEUE
                                do
-                                       echo encodetrack-$UTRACKNUM >> status
+                                       TRACKFILES="$TRACKFILES track$UTRACKNUM.wav"
                                done
-                       fi
-                       )
+                               nice $ENCNICE $MP3ENCODER $MP3ENCODEROPTS --nogap $TRACKFILES
+                               RETURN=$?
+                               if [ "$RETURN" != "0" ]; then
+                                       echo "nogap-encode: $ENCODER returned code $RETURN" >> errors
+                               else
+                                       for UTRACKNUM in $TRACKQUEUE
+                                       do
+                                               run_command encodetrack-$OUTPUT-$UTRACKNUM true
+                                               #run_command encodetrack-$UTRACKNUM true
+                                       done
+                               fi
+                               )
+                               ;;
+                       esac
                        ;;
                esac
-               ;;
-       esac
+       done            
+       if checkerrors "nogap-encode"; then :; else
+               if [ ! "$KEEPWAVS" = "y" ] ; then
+                       if [ ! "$KEEPWAVS" = "move" ] ; then
+                               rm -f "$IN"
+                       fi
+               fi
+       fi
        # Other encoders fall through to normal encoding as the tracks
        # have not been entered in the status file.
 }
@@ -623,13 +814,14 @@ do_encode ()
                                TEMPARG="PIPE_$MPPENCODER"
                                ;;
                esac
-               IN=${!TEMPARG}
+               IN="$( eval echo "\$$TEMPARG" )"
        else
                IN="$ABCDETEMPDIR/track$1.wav"
                case "$OUTPUT" in
                        mp3)
                                case "$MP3ENCODERSYNTAX" in
                                        # FIXME # check if mp3enc needs -if for pipes
+                                       # FIXME # I have not been able to find a working mp3enc binary
                                        mp3enc)
                                                FILEARG="-if $IN"
                                                ;;
@@ -647,6 +839,9 @@ do_encode ()
        if [ -s "$IN" -o X"$USEPIPES" = "Xy" ] ; then
                for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
                do
+                       if [ "$NOGAP" = "y" ] && checkstatus encodetrack-$OUTPUT-$1 ; then 
+                               continue
+                       fi
                        case "$OUTPUT" in
                                vorbis|ogg)
                                        OUT="$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER"
@@ -660,6 +855,8 @@ do_encode ()
                        esac
                        if [ X"$USEPIPES" = "Xy" ]; then
                                RUN_COMMAND=""
+                               # We need a way to store the creation of the files when using PIPES
+                               RUN_COMMAND_PIPES="run_command encodetrack-$OUTPUT-$1 true"
                        else
                                run_command '' echo "Encoding track $1 of $TRACKS: $TRACKNAME..."
                                RUN_COMMAND="run_command encodetrack-$OUTPUT-$1"
@@ -696,16 +893,15 @@ do_encode ()
                                ;;
                        flac)
                                case "$2" in
-                               %local*%)
+                               %local*%)
                                        case "$FLACENCODERSYNTAX" in
-                                       flac) $RUN_COMMAND nice $ENCNICE $FLACENCODER  $FLACENCODEROPTS -o "$OUT" "$IN" ;; 
+                                       flac) $RUN_COMMAND nice $ENCNICE $FLACENCODER $FLACENCODEROPTS -o "$OUT" "$IN" ;; 
                                        esac
-                                       ;;
-       
-                               *)
-                                       echo -n "DISTMP3:"
-                                       echo "$DISTMP3 $DISTMP3OPTS $2 $IN $OUT >/dev/null 2>&1"
-                                       $RUN_COMMAND nice $DISTMP3NICE $DISTMP3 $DISTMP3OPTS "$2" "$IN" "$OUT" > /dev/null 2>&1
+                                               ;;
+                                       *)
+                                               vecho -n "DISTMP3:"
+                                               vecho "$DISTMP3 $DISTMP3OPTS $2 $IN $OUT >/dev/null 2>&1"
+                                               $RUN_COMMAND nice $DISTMP3NICE $DISTMP3 $DISTMP3OPTS "$2" "$IN" "$OUT" > /dev/null 2>&1
                                        ;;
                                esac
                                ;;
@@ -733,22 +929,24 @@ do_encode ()
                                ## FIXME ## to the encoder ends up empty.
                                $RUN_COMMAND nice $ENCNICE $MPPENCODER $MPPENCODEROPTS --artist "$TRACKARTIST" --album "$DALBUM" --title "$TRACKNAME" --track "$1" --genre "$CDGENRE" --year "$CDYEAR" --comment "$COMMENT" "$IN" "$OUT"
                                ;;
+                       wav)
+                               # In case of wav output we need nothing. Just keep the wavs.
+                               ;;
                        esac
+                       $RUN_COMMAND_PIPES
                done
                # Only remove .wav if the encoding succeeded
-               if checkerrors "encodetrack-(.{3,4})-$1"; then 
-                       run_command encodetrack-$1 false
-               else
+               if checkerrors "encodetrack-(.{3,6})-$1"; then :; else
                        run_command encodetrack-$1 true
                        if [ ! "$KEEPWAVS" = "y" ] ; then
-                               rm -f "$IN"
+                               if [ ! "$KEEPWAVS" = "move" ] ; then
+                                       rm -f "$IN"
+                               fi
                        fi
                fi
        else
-               if [ "$(checkstatus encode-output)" = "loud" ]; then
-                       echo "HEH! The file we were about to encode disappeared:"
-                       echo ">> $IN"
-               fi
+               run_command "" echo "HEH! The file we were about to encode disappeared:"
+               run_command "" echo ">> $IN"
                run_command encodetrack-$1 false
        fi
 }
@@ -856,7 +1054,7 @@ do_batch_gain ()
        do
                MP3FILES="$TRACKFILES track$UTRACKNUM.mp3"
        done
-       # XXX: Hard-coded batch option!
+       # FIXME # Hard-coded batch option!
        $NORMALIZER -b $NORMALIZEROPTS $TRACKFILES
        RETURN=$?
        if [ "$RETURN" != "0" ]; then
@@ -926,14 +1124,6 @@ do_move ()
 {
        for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
        do
-               case $OUTPUT in
-                       vorbis|ogg)
-                               OUTPUT=$OGGOUTPUTCONTAINER
-                               ;;
-                       flac)
-                               OUTPUT=$FLACOUTPUTCONTAINER
-                               ;;
-               esac
                # Create ALBUMFILE, ARTISTFILE, TRACKFILE
                # Munge filenames as follows:
                # ' ' -> '_'
@@ -941,49 +1131,85 @@ do_move ()
                # ''' -> ''
                # '?' -> ''
                # Eat control characters
-               ALBUMFILE=$(mungefilename "$DALBUM")
-               ARTISTFILE=$(mungefilename "$TRACKARTIST")
-               TRACKFILE=$(mungefilename "$TRACKNAME")
-               GENRE=$(mungegenre "$GENRE")
-               YEAR=$(echo $CDYEAR)
+               ALBUMFILE="$(mungefilename "$DALBUM")"
+               ARTISTFILE="$(mungefilename "$TRACKARTIST")"
+               TRACKFILE="$(mungefilename "$TRACKNAME")"
+               GENRE="$(mungegenre "$GENRE")"
+               YEAR="$(echo $CDYEAR)"
                # If we want to start the tracks with a given number, we need to modify the
                # TRACKNUM value before evaluation
-               if [ -n "$STARTTRACKNUMBER" ] ; then
-                       # Get the trackpadding from the current track
-                       CURRENTTRACKPADDING=$(echo -n $UTRACKNUM | wc -c)
-                       TRACKNUM=$( printf %0.${CURRENTTRACKPADDING}d $(expr ${UTRACKNUM} + ${STARTTRACKNUMBER} - $FIRSTTRACK ))
-               else
-                       TRACKNUM=${UTRACKNUM}
-               fi
+               do_gettracknum
                # Supported variables for OUTPUTFORMAT are GENRE, ALBUMFILE, ARTISTFILE,
                # TRACKFILE, and TRACKNUM.
                if [ "$VARIOUSARTISTS" = "y" ]; then
-                       OUTPUTFILE=$(eval echo $VAOUTPUTFORMAT)
-                       else
-                       OUTPUTFILE=$(eval echo $OUTPUTFORMAT)
-               fi
-               # Check that the directory for OUTPUTFILE exists, if it doesn't, create it
-               OUTPUTFILEDIR=$(dirname "$OUTPUTDIR/$OUTPUTFILE")
-               # mkdir -p shouldn't return an error if the directory already exists
-               mkdir -p "$OUTPUTFILEDIR"
-               vecho "Moving $ABCDETEMPDIR/track$1.$OUTPUT to $OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
-               run_command movetrack-$1 mv "$ABCDETEMPDIR/track$1.$OUTPUT" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
-               # Lets move the cue file
-               if CUEFILE=$(checkstatus cuefile) >/dev/null ; then 
-                       if [ -r "$ABCDETEMPDIR/$CUEFILE" ]; then
-                               if checkstatus movecue-$OUTPUT; then :; else
-                                       vecho "Copying cue file to its destination directory..."
-                                       if checkstatus onetrack >/dev/null ; then
-                                               case $OUTPUT in
-                                                       mp3)
-                                                               run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.cue"
-                                                               ;;
-                                                       *)
-                                                               run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT.cue"
-                                                               ;;
-                                               esac
+                       OUTPUTFILE="$(eval echo "$VAOUTPUTFORMAT")"
+               else
+                       OUTPUTFILE="$(eval echo "$OUTPUTFORMAT")"
+               fi
+               if checkerrors "tagtrack-$OUTPUT-$1"; then :; else
+                       # Once we know the specific output was successful, we can change the OUTPUT to the value containing the container
+                       case $OUTPUT in
+                               vorbis|ogg)
+                                       OUTPUT=$OGGOUTPUTCONTAINER
+                                       ;;
+                               flac)
+                                       OUTPUT=$FLACOUTPUTCONTAINER
+                                       ;;
+                       esac
+                       # Check that the directory for OUTPUTFILE exists, if it doesn't, create it
+                       OUTPUTFILEDIR="$(dirname "$OUTPUTDIR/$OUTPUTFILE")"
+                       case $OUTPUT in
+                               wav)
+                                       if [ "$DOCLEAN" != "y" ] && [ "$FORCE" != "y" ]; then
+                                               # FIXME # introduce warnings?
+                                               :
                                        else
-                                               run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTFILEDIR/$CUEFILE"
+                                               # mkdir -p shouldn't return an error if the directory already exists
+                                               mkdir -p "$OUTPUTFILEDIR"
+                                               run_command movetrack-$1 mv "$ABCDETEMPDIR/track$1.$OUTPUT" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
+                                               if checkstatus movetrack-output-$OUTPUT; then :; else
+                                                       run_command movetrack-output-$OUTPUT true
+                                               fi
+                                       fi
+                                       ;;
+                               *)
+                                       # mkdir -p shouldn't return an error if the directory already exists
+                                       mkdir -p "$OUTPUTFILEDIR"
+                                       run_command movetrack-$1 mv "$ABCDETEMPDIR/track$1.$OUTPUT" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
+                                       if checkstatus movetrack-output-$OUTPUT; then :; else
+                                               run_command movetrack-output-$OUTPUT true
+                                       fi
+                                       ;;
+                       esac
+                       # Lets move the cue file
+                       if CUEFILE=$(checkstatus cuefile) >/dev/null ; then 
+                               if [ -r "$ABCDETEMPDIR/$CUEFILE" ]; then
+                                       if checkstatus movecue-$OUTPUT; then :; else
+                                               # Silence the Copying output since it overlaps with encoding processes...
+                                               #run_command '' vecho "Copying cue file to its destination directory..."
+                                               if checkstatus onetrack >/dev/null ; then
+                                                       case $OUTPUT in
+                                                               wav)
+                                                                       if [ "$DOCLEAN" != "y" ] && [ "$FORCE" != "y" ]; then
+                                                                               # We dont have the dir, since it was not created before.
+                                                                               :
+                                                                       else
+                                                                               run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.cue"
+                                                                       fi
+                                                                       ;;
+                                                               # NOTE: Creating a cue file with the 3-char-extension files is to comply with
+                                                               # http://brianvictor.tripod.com/mp3cue.htm#details
+                                                               [a-z0-9][a-z0-9][a-z0-9])
+                                                                       run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.cue"
+                                                                       ;;
+                                                               *)
+                                                                       run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT.cue"
+                                                                       ;;
+                                                       esac
+                                               else
+                                                       run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTFILEDIR/$CUEFILE"
+                                               fi
+                                               echo movecue-$OUTPUT >> "$ABCDETEMPDIR/status"
                                        fi
                                fi
                        fi
@@ -1000,11 +1226,19 @@ do_playlist ()
 {
        for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
        do
+               case $OUTPUT in
+                       vorbis|ogg)
+                               OUTPUT=$OGGOUTPUTCONTAINER
+                               ;;
+                       flac)
+                               OUTPUT=$FLACOUTPUTCONTAINER
+                               ;;
+               esac
                # Create a playlist file for the playlist data to go into.
                # We used to wipe it out if it existed. Now we request permision if interactive.
                for LASTTRACK in $TRACKQUEUE; do :; done
-               ALBUMFILE=$(mungefilename "$DALBUM")
-               ARTISTFILE=$(mungefilename "$DARTIST")
+               ALBUMFILE="$(mungefilename "$DALBUM")"
+               ARTISTFILE="$(mungefilename "$DARTIST")"
                GENRE=$(mungegenre "$GENRE")
                YEAR=${CDYEAR:-$CDYEAR}
                if [ "$VARIOUSARTISTS" = "y" ] ; then
@@ -1040,19 +1274,15 @@ do_playlist ()
                        do
                                # Shares some code with do_move since the filenames have to match
                                CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
-                               TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2 -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')
+                               #TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2 -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')
+                               do_getcddbinfo TRACKNAME
                                splitvarious
-                               TRACKFILE=$(mungefilename "$TRACKNAME")
-                               ARTISTFILE=$(mungefilename "$TRACKARTIST")
+                               TRACKFILE="$(mungefilename "$TRACKNAME")"
+                               ARTISTFILE="$(mungefilename "$TRACKARTIST")"
+                               ALBUMFILE="$(mungefilename "$DALBUM")"
                                # If we want to start the tracks with a given number, we need to modify the
                                # TRACKNUM value before evaluation
-                               if [ -n "$STARTTRACKNUMBER" ] ; then
-                                       # Get the trackpadding from the current track
-                                       CURRENTTRACKPADDING=$(echo -n $UTRACKNUM | wc -c)
-                                       TRACKNUM=$( printf %0.${CURRENTTRACKPADDING}d $(expr ${UTRACKNUM} + ${STARTTRACKNUMBER} - $FIRSTTRACK ))
-                               else
-                                       TRACKNUM=${UTRACKNUM}
-                               fi
+                               do_gettracknum
                                if [ "$VARIOUSARTISTS" = "y" ]; then
                                        OUTPUTFILE=$(eval echo $VAOUTPUTFORMAT)
                                else
@@ -1099,11 +1329,21 @@ do_discid ()
                if [ "$OSFLAVOUR" = "OSX" ]; then
                        disktool -u ${CDROM#/dev/}
                fi
-               TRACKINFO=$($CDDISCID $CDROM)
+               if [ "$CDROMREADERSYNTAX" = "flac" ] ; then
+                       TRACKINFO=$($METAFLAC $METAFLACOPTS --export-cuesheet-to=- $CDROM | $CUE2DISCID)
+               else
+                       TRACKINFO=$($CDDISCID $CDROM)
+               fi
                # Make sure there's a CD in there by checking cd-discid's return code
-               if [ "$?" = "1" ]; then
-                       echo "abcde error: CD could not be read. Perhaps there's no CD in the drive?" >&2
-                       exit 1
+               if [ ! "$?" = "0" ]; then
+                       if [ "$CDROMREADERSYNTAX" = "flac" ] ; then
+                               log error "cuesheet information from the flac file could not be read."
+                               log error "Perhaps the flac file does not contain a cuesheet?."
+                               exit 1
+                       else
+                               log error "CD could not be read. Perhaps there's no CD in the drive?"
+                               exit 1
+                       fi
                fi
                # In OSX, remount the disc again
                if [ "$OSFLAVOUR" = "OSX" ]; then
@@ -1133,17 +1373,15 @@ do_discid ()
                                cdparanoia|debug)
                                        if [ "$WEHAVEACD" = "y" ]; then
                                                vecho "Querying the CD for audio tracks..."
-                                               CDPARANOIAOUTPUT="$( $CDROMREADER -d $CDROM -Q --verbose 2>&1 )"
+                                               CDPARANOIAOUTPUT="$( $CDROMREADER -$CDPARANOIACDROMBUS $CDROM -Q --verbose 2>&1 )"
                                                RET=$?
                                                if [ ! "$RET" = "0" ];then
-                                                       echo "Warning: Something went wrong while querying the CD... Maybe a DATA CD?"
+                                                       log warning "something went wrong while querying the CD... Maybe a DATA CD?"
                                                fi
-                                               TRACKS="$( echo "$CDPARANOIAOUTPUT" | egrep '^[[:space:]]+[[:digit:]]' | tail -n 1 | get_first | tr -d "." | tr '\n' ' ' )"
+                                               TRACKS="$(echo "$CDPARANOIAOUTPUT" | egrep '^[[:space:]]+[[:digit:]]' | tail -n 1 | get_first | tr -d "." | tr '\n' ' ')"
                                                CDPARANOIAAUDIOTRACKS="$TRACKS"
                                        else
-                                               if [ -f "$ABCDETEMPDIR/status" ] && checkstatus cdparanoia-audio-tracks ; then
-                                                       TRACKS=$( cat "$ABCDETEMPDIR/cdparanoia-audio-tracks" )
-                                               else
+                                               if [ -f "$ABCDETEMPDIR/status" ] && TRACKS=$(checkstatus cdparanoia-audio-tracks); then :; else
                                                        TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
                                                fi
                                        fi
@@ -1154,7 +1392,7 @@ do_discid ()
                        TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
                fi
                if echo "$TRACKS" | grep "[[:digit:]]" > /dev/null 2>&1 ;then :;else
-                       echo "The disc does not contain any tracks. Giving up..."
+                       log info "The disc does not contain any tracks. Giving up..."
                        exit 0
                fi
                echo -n "Grabbing entire CD - tracks: "
@@ -1166,7 +1404,7 @@ do_discid ()
                while [ "$X" -ne "$TRACKS" ]
                do
                        X=$(printf "%0.${TRACKNUMPADDING}d" $(expr $X + 1))
-                       TRACKQUEUE=$(echo "$TRACKQUEUE" $X)
+                       TRACKQUEUE=$(echo $TRACKQUEUE $X)
                done
                echo $TRACKQUEUE
        else
@@ -1263,16 +1501,19 @@ do_discid ()
                if checkstatus cuefile > /dev/null 2>&1 ; then :; else
                        CUEFILE=cue-$(echo "$TRACKINFO" | cut -f1 -d' ').txt
                        vecho "Creating cue file..."
-                       $MKCUE $MKCUEOPTS > "$ABCDETEMPDIR/$CUEFILE"
-                       echo cuefile=$CUEFILE >> "$ABCDETEMPDIR/status"
+                       if $CUEREADER $CUEREADEROPTS > "$ABCDETEMPDIR/$CUEFILE"; then
+                               echo cuefile=$CUEFILE >> "$ABCDETEMPDIR/status"
+                       else
+                               log warning "reading the CUE sheet with mkcue is still considered experimental"
+                               log warning "and there was a problem with the CD reading. abcde will continue,"
+                               log warning "but consider reporting the problem to the abcde author"
+                       fi
                fi
        fi
        # If we got the CDPARANOIA status and it is not recorded, save it now
        if [ -n "$CDPARANOIAAUDIOTRACKS" ]; then
-               if checkstatus cdparanoia-audio-tracks; then :; else
-                       if echo "$CDPARANOIAAUDIOTRACKS" >> "$ABCDETEMPDIR/cdparanoia-audio-tracks"; then
-                               echo "cdparanoia-audio-tracks" >> "$ABCDETEMPDIR/status"
-                       fi
+               if checkstatus cdparanoia-audio-tracks > /dev/null 2>&1; then :; else
+                       echo cdparanoia-audio-tracks=$CDPARANOIAAUDIOTRACKS >> "$ABCDETEMPDIR/status"
                fi
        fi
        
@@ -1284,7 +1525,6 @@ do_discid ()
 # Create a proper CUE file based on the CUE file we created before.
 do_cleancue()
 {
-       # FIXME # we can get the name of the cuefile from the status file
        if CUEFILE_IN="$ABCDETEMPDIR"/$(checkstatus cuefile); then
                CUEFILE_OUT=$CUEFILE_IN.out
                ### FIXME ### checkstatus cddb
@@ -1322,6 +1562,18 @@ do_cddbparse ()
                vecho "ONETRACK mode selected: displaying only the title of the CD..."
        fi
        echo "---- $(grep DTITLE "${CDDBPARSEFILE}" | cut '-d=' -f2- | tr -d \\r\\n ) ----"
+       if [ X"$SHOWCDDBYEAR" = "Xy" ]; then
+               PARSEDYEAR=$(grep DYEAR "${CDDBPARSEFILE}" | cut '-d=' -f2-)
+               if [ ! X"$PARSEDYEAR" = "X" ]; then
+                       echo "Year: $PARSEDYEAR"
+               fi
+       fi
+       if [ X"$SHOWCDDBGENRE" = "Xy" ]; then
+               PARSEDGENRE=$(grep DGENRE "${CDDBPARSEFILE}" | cut '-d=' -f2-)
+               if [ ! X"$PARSEDGENRE" = "X" ]; then
+                       echo "Genre: $PARSEDGENRE"
+               fi
+       fi
        if [ ! "$ONETRACK" = "y" ]; then
                for TRACK in $(f_seq_row 1 $TRACKS)
                do
@@ -1358,7 +1610,8 @@ do_localcddb ()
                        fi
                        if [ "$USELOCALRESP" = "y" ]; then
                                #echo "Using local copy of CDDB data"
-                               cp "${CDDBLOCALFILE}" "$ABCDETEMPDIR/cddbread.1"
+                               echo "# DO NOT ERASE THIS LINE! Added by abcde to imitate cddb output" > "$ABCDETEMPDIR/cddbread.1"
+                               cat "${CDDBLOCALFILE}" >> "$ABCDETEMPDIR/cddbread.1"
                                echo 999 > "$ABCDETEMPDIR/cddbquery" # Assuming 999 isn't used by CDDB
                                echo cddb-readcomplete >> "$ABCDETEMPDIR/status"
                                do_cddbparse "${CDDBLOCALFILE}" > "$ABCDETEMPDIR/cddbchoices"
@@ -1575,40 +1828,52 @@ do_cddbedit ()
                                else
                                        # The user has a choice to make, display the info in a pager if necessary
                                        if [ $(cat "$ABCDETEMPDIR/cddbchoices" | wc -l) -ge 24 ]; then
-                                               # Use the debian sensible-pager wrapper to pick the pager
-                                               # user has requested via their $PAGER environment variable
-                                               if [ -x "/usr/bin/sensible-pager" ]; then
-                                                       /usr/bin/sensible-pager "$ABCDETEMPDIR/cddbchoices"
-                                               elif [ -x "$PAGER" ]; then
-                                                       # That failed, try to load the preferred editor, starting
-                                                       # with their PAGER variable
-                                                       $PAGER "$ABCDETEMPDIR/cddbchoices"
-                                                       # If that fails, check for less
-                                               elif [ -x /usr/bin/less ]; then
-                                                       /usr/bin/less -f "$ABCDETEMPDIR/cddbchoices"
-                                                       # more should be on all UNIX systems
-                                               elif [ -x /bin/more ]; then
-                                                       /bin/more "$ABCDETEMPDIR/cddbchoices"
-                                               else
-                                                       # No bananas, just cat the thing
-                                                       cat "$ABCDETEMPDIR/cddbchoices" >&2
-                                               fi
+                                               page "$ABCDETEMPDIR/cddbchoices"
                                        else
                                                # It's all going to fit in one page, cat it
                                                cat "$ABCDETEMPDIR/cddbchoices" >&2
                                        fi
                                        
+                                       CDDBCHOICENUM=""
+                                       # Setting the choice to an impossible integer to avoid errors in the numeric comparisons
+                                       CDCHOICENUM=-1
                                        # I'll take CDDB read #3 for $400, Alex
-                                       echo -n "Which entry would you like abcde to use (0 for none)? [0-$CDDBCHOICES]: " >&2
-                                       read CDDBCHOICE
-                                       [ X"$CDDBCHOICE" = "X" ] && CDDBCHOICE=1
-                                       # Make sure we get a valid choice
-                                       CDCHOICENUM=$(echo $CDDBCHOICE | xargs printf %d 2>/dev/null)
-                                       while [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; do
-                                               echo "Invalid selection. Please choose a number between 1 and $CDDBCHOICES." >&2
-                                               echo -n "Selection [0-$CDDBCHOICES]: " >&2
+                                       while [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; do
+                                               echo -n "Which entry would you like abcde to use (0 for none)? [0-$CDDBCHOICES]: " >&2
                                                read CDDBCHOICE
-                                               CDCHOICENUM=$(echo $CDDBCHOICE | xargs printf %d 2>/dev/null)
+                                               [ X"$CDDBCHOICE" = "X" ] && CDDBCHOICE=1
+                                               if echo $CDDBCHOICE | egrep -q "[[:digit:]]+,[[:digit:]]+" ; then
+                                                       if [ ! X"$DIFF" = "X" ]; then
+                                                               PARSECHOICE1=$(echo $CDDBCHOICE | cut -d"," -f1)
+                                                               PARSECHOICE2=$(echo $CDDBCHOICE | cut -d"," -f2)
+                                                               if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $CDDBCHOICES ] || \
+                                                                  [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $CDDBCHOICES ] || \
+                                                                  [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then 
+                                                                       echo "Invalid diff range. Please select two coma-separated numbers between 1 and $CDDBCHOICES" >&2
+                                                               else
+
+                                                                       # We parse the 2 choices to diff, store them in temporary files and diff them.
+                                                                       for PARSECHOICE in $(echo $CDDBCHOICE | tr , \ ); do
+                                                                               do_cddbparse "$ABCDETEMPDIR/cddbread.$PARSECHOICE" > "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE"
+                                                                       done
+                                                                       echo "Showing diff between choices $PARSECHOICE1 and $PARSECHOICE2..." > "$ABCDETEMPDIR/cddbread.diff"
+                                                                       $DIFF $DIFFOPTS "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE1" "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE2" >> "$ABCDETEMPDIR/cddbread.diff"
+                                                                       if [ $(cat "$ABCDETEMPDIR/cddbread.diff" | wc -l) -ge 24 ]; then
+                                                                               page "$ABCDETEMPDIR/cddbread.diff"
+                                                                       else
+                                                                               cat "$ABCDETEMPDIR/cddbread.diff" >&2
+                                                                       fi
+                                                               fi
+                                                       else
+                                                               echo "The diff program was not found in your path. Please choose a number between 0 and $CDDBCHOICES." >&2
+                                                       fi
+                                               else
+                                                       if [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; then
+                                                               # Make sure we get a valid choice
+                                                               CDCHOICENUM=$(echo $CDDBCHOICE | xargs printf %d 2>/dev/null)
+                                                               echo "Invalid selection. Please choose a number between 0 and $CDDBCHOICES." >&2
+                                                       fi
+                                               fi
                                        done
                                        if [ "$CDCHOICENUM" = "0" ]; then
                                                vecho "Creating empty CDDB template..."
@@ -1704,8 +1969,12 @@ do_cddbedit ()
                # If that fails, check for a vi
                elif which vi >/dev/null 2>&1; then
                        vi "$CDDBDATA"
+               elif [ -x /usr/bin/vim ]; then
+                       /usr/bin/vim "$CDDBDATA"
                elif [ -x /usr/bin/vi ]; then
                        /usr/bin/vi "$CDDBDATA"
+               elif [ -x /bin/vi ]; then
+                       /bin/vi "$CDDBDATA"
                # nano should be on all (modern, i.e., sarge) debian systems
                elif which nano >/dev/null 2>&1 ; then
                        nano "$CDDBDATA"
@@ -1718,7 +1987,7 @@ do_cddbedit ()
                        /usr/bin/mg "$CDDBDATA"
                # bomb out
                else
-                       echo "No editor available. Check your EDITOR environment variable." >&2
+                       log warning "no editor available. Check your EDITOR environment variable."
                fi
                # delete editor backup file if it exists
                if [ -w "$CDDBDATA~" ]; then
@@ -1811,7 +2080,7 @@ do_cddbedit ()
        echo "variousartiststyle=$VARIOUSARTISTSTYLE" >> "$ABCDETEMPDIR/status"
 
        if [ "$EDITCDDB" = "y" ] && [ "$UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE" = "y" ]; then
-               if [ $CDDBDATAMD5SUM != "" ]  && [ $CDDBDATAMD5SUM != $($MD5SUM "$CDDBDATA" | cut -d " " -f 1) ]; then
+               if [ "$CDDBDATAMD5SUM" != "" ]  && [ "$CDDBDATAMD5SUM" != "$($MD5SUM "$CDDBDATA" | cut -d " " -f 1)" ]; then
                        # This works but does not have the necessary error checking
                        # yet. If you are familiar with the CDDB spec
                        # (see http://www.freedb.org/src/latest/DBFORMAT) 
@@ -1865,9 +2134,11 @@ do_cdread ()
                LASTTRACK=$3
                UTRACKNUM=$FIRSTTRACK
                case "$CDROMREADERSYNTAX" in
+                       ### FIXME ### How are we calculating the tracks in flac mode?
+                       flac) READTRACKNUMS="$FIRSTTRACK.1-$(($LASTTRACK + 1)).0" ;;
                        cdparanoia) READTRACKNUMS="$FIRSTTRACK-$LASTTRACK" ;;
                        cdda2wav) READTRACKNUMS="$FIRSTTRACK+$LASTRACK" ;;
-                       *) echo "abcde error: $CDROMREADERSYNTAX does not support ONETRACK mode"
+                       *) log error "$CDROMREADERSYNTAX does not support ONETRACK mode"
                           exit 1 ;;
                esac
        else
@@ -1875,14 +2146,17 @@ do_cdread ()
        fi
        CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
        if [ "$USEPIPES" = "y" ]; then
-               TEMPARG="PIPE_$CDROMREADERSYNTAX"
-               FILEARG="${!TEMPARG}"
+               TEMPARG="PIPERIPPER_$CDROMREADERSYNTAX"
+               FILEARG="$( eval echo "\$$TEMPARG" )"
                REDIR=""
                PIPE_MESSAGE="and encoding "
        else
                WAVDATA="$ABCDETEMPDIR/track$UTRACKNUM.wav"
                case "$CDROMREADERSYNTAX" in
-               ## FIXME ## Find the case for dagrab, to avoid exceptions
+               ## FIXME ## Find the cases for dagrab and flac, to avoid exceptions
+                       flac)
+                               FILEARG="--output-name=$WAVDATA"
+                               ;;
                        dagrab)
                                FILEARG="-f $WAVDATA"
                                ;;
@@ -1896,15 +2170,20 @@ do_cdread ()
                echo "Grabbing ${PIPE_MESSAGE}tracks $UTRACKNUM - $LASTTRACK as one track ..." >&2
        else
                if [ -r "$CDDBDATA" ]; then
-                       TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | head -n 1 | cut -f2 -d= | tr -d \[:cntrl:\])
+                       #TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | head -n 1 | cut -f2 -d= | tr -d \[:cntrl:\])
+                       do_getcddbinfo TRACKNAME
                        echo "Grabbing ${PIPE_MESSAGE}track $UTRACKNUM: $TRACKNAME..." >&2
                else
                        echo "Grabbing ${PIPE_MESSAGE}track $UTRACKNUM..." >&2
                fi
        fi
        case "$CDROMREADERSYNTAX" in
+               ### FIXME ### use an exception for flac, since it uses -o
+               ### FIXME ### Shall we just use -o $FILEARG ??
+               flac)
+                       nice $READNICE $FLAC -d --cue=${READTRACKNUMS:-$UTRACKNUM.1-$(($UTRACKNUM + 1)).0} "$FILEARG" "$CDROM" ;;
                cdparanoia) 
-                       nice $READNICE $CDROMREADER -d $CDROM ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR ;;
+                       nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS $CDROM ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR ;;
                cdda2wav)
                        if [ "$OSFLAVOUR" = "OSX" ] ; then
                                # Hei, we have to unmount the device before running anything like cdda2wav in OSX
@@ -1937,7 +2216,7 @@ do_cdread ()
                        else
                                false
                        fi ;;
-               debug) nice $READNICE $CDROMREADER -d $CDROM -w $UTRACKNUM-[:1] "$FILEARG" $REDIR
+               debug) nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS $CDROM -w $UTRACKNUM-[:1] "$FILEARG" $REDIR
                        ;;
        esac
        RETURN=$?
@@ -1984,7 +2263,25 @@ do_cdspeed ()
 vecho ()
 {
 if [ x"$EXTRAVERBOSE" != "x" ]; then
-       echo $@
+       case $1 in
+               warning) log warning "$@" ;;
+               *) echo "$@" ;;
+       esac
+fi
+}
+
+# decho [message]
+#
+# decho outputs a debug message if DEBUG is selected
+decho ()
+{
+if [ x"$DEBUG" != "x" ]; then
+       if echo $1 | grep -q "^\[" ; then
+               DEBUGECHO=$(echo "$@" | tr -d '[]')
+               echo "[DEBUG] $DEBUGECHO: `eval echo \\$${DEBUGECHO}`"
+       else
+               echo "[DEBUG] $1"
+       fi
 fi
 }
 
@@ -2009,6 +2306,13 @@ pre_read ()
 :
 }
 
+# post_read
+# Empty post_read function, to be defined in the configuration file.
+post_read ()
+{
+:
+}
+
 ###############################################################################
 # End of functions
 #
@@ -2020,6 +2324,13 @@ CDDBURL="http://freedb.freedb.org/~cddb/cddb.cgi"
 CDDBSUBMIT=freedb-submit@freedb.org
 CDDBPROTO=5
 HELLOINFO="$(whoami)@$(hostname)"
+CDDBCOPYLOCAL="n"
+CDDBLOCALDIR="$HOME/.cddb"
+CDDBUSELOCAL="n"
+
+# List of fields we parse and show during the CDDB parsing...
+SHOWCDDBFIELDS="year,genre"
+
 INTERACTIVE=y
 CDROMREADERSYNTAX=cdparanoia
 ENCODERSYNTAX=default
@@ -2030,6 +2341,7 @@ FLACENCODERSYNTAX=default
 SPEEXENCODERSYNTAX=default
 MPPENCODERSYNTAX=default
 NORMALIZERSYNTAX=default
+CUEREADERSYNTAX=default
 
 OUTPUTFORMAT='${ARTISTFILE}-${ALBUMFILE}/${TRACKNUM}.${TRACKFILE}'
 # Use the following VAOUTPUTFORMAT to revert to 2.0.x VA format:
@@ -2051,17 +2363,20 @@ VARIOUSARTISTS=n
 VARIOUSARTISTSTYLE=forward
 KEEPWAVS=n
 PADTRACKS=n
-CDDBCOPYLOCAL="n"
-CDDBLOCALDIR="$HOME/.cddb"
-CDDBUSELOCAL="n"
+NOGAP=n
+BATCHNORM=n
 
 # If using scsi devices, cdda2wav needs a CDROMID, instead of a device node
 # i.e. CDROMID="1,0,0"
 CDROMID=""
+# If we are using the IDE bus, we need CDPARANOIACDROMBUS defined as "d"
+# If we are using the ide-scsi emulation layer, we need to define a "g"
+CDPARANOIACDROMBUS="d"
 
 # program paths - defaults to checking your $PATH
 # mp3
 LAME=lame
+TOOLAME=toolame
 GOGO=gogo
 BLADEENC=bladeenc
 L3ENC=l3enc
@@ -2079,6 +2394,7 @@ MPPENC=mppenc
 
 ID3=id3
 ID3V2=id3v2
+EYED3=eyeD3
 CDPARANOIA=cdparanoia
 CDDA2WAV=cdda2wav
 DAGRAB=dagrab
@@ -2093,11 +2409,16 @@ METAFLAC=metaflac
 NORMALIZE=normalize-audio
 CDSPEED=eject
 VORBISGAIN=vorbisgain
+MP3GAIN=mp3gain
 MKCUE=mkcue
+MKTOC=cdrdao
+DIFF=diff
+CUE2DISCID=cue2discid
 
 # Options for programs called from abcde
 # mp3
 LAMEOPTS=
+TOOLAMEOPTS=
 GOGOOPTS=
 BLADEENCOPTS=
 L3ENCOPTS=
@@ -2107,7 +2428,7 @@ MP3ENCOPTS=
 VORBIZEOPTS=
 OGGENCOPTS=
 # flac
-FLACOPTS=
+FLACOPTS="-f"
 # speex
 SPEEXENCOPTS=
 # mpc
@@ -2126,8 +2447,10 @@ NORMALIZEOPTS=
 CDSPEEDOPTS="-x"
 CDSPEEDVALUE=
 MKCUEOPTS=
+MKTOCOPTS=""
 VORBISCOMMENTOPTS="-R"
 METAFLACOPTS="--no-utf8-convert"
+DIFFOPTS=
 
 # Default to one process if -j isn't specified
 MAXPROCS=1
@@ -2143,6 +2466,7 @@ DEFAULT_OUTPUT_BINARIES=vorbis:oggenc,flac:flac,mp3:lame,mp3:bladeenc,spx:speex
 # Let's use these checkings to determine the OS flavour, which will be used later
 if [ X$(uname) = "XFreeBSD" ] ; then
        HTTPGET=fetch
+       MD5SUM=md5
        NEEDCDROMID=y
        OSFLAVOUR=FBSD
 elif [ X$(uname) = "XDarwin" ] ; then
@@ -2154,6 +2478,9 @@ elif [ X$(uname) = "XDarwin" ] ; then
 elif [ X$(uname) = "XOpenBSD" ] ; then
        HTTPGET=wget
        MD5SUM=md5
+elif [ X$(uname) = "XNetBSD" ] ; then
+       HTTPGET=ftp
+       MD5SUM=md5
 else
        HTTPGET=wget
 fi
@@ -2189,7 +2516,8 @@ if [ "$HTTPGETOPTS" = "" ] ; then
                wget) HTTPGETOPTS="-q -O -";;
                curl) HTTPGETOPTS="-f -s";;
                fetch)HTTPGETOPTS="-q -o -";;
-               *) echo "abcde warning: HTTPGET in non-standard and HTTPGETOPTS are not defined." >&2 ;;
+               ftp)  HTTPGETOPTS="-q -o -";;
+               *) log warning "HTTPGET in non-standard and HTTPGETOPTS are not defined." ;;
        esac
 fi
 
@@ -2211,21 +2539,24 @@ if [ "$CDROM" = "" ] ; then
 fi
 
 # Parse command line options
-#while getopts 1a:bc:C:d:Dhj:klLnNo:pr:S:t:T:vVx opt ; do
-while getopts 1a:A:bc:C:d:Dehj:klLmMnNo:pPr:Rs:S:t:T:vVxw:W: opt ; do
+#while getopts 1a:A:bc:C:d:Dehj:klLmMnNo:pPr:Rs:S:t:T:vVxw:W: opt ; do
+while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:uvVxw:W:z opt ; do
        case "$opt" in
                1) ONETRACK=y ;;
                a) ACTIONS="$OPTARG" ;;
-               A) EXPACTIONS="$OPTARG";;
-               b) BATCH=y ;;
-               c) if [ -e "$OPTARG" ] ; then . "$OPTARG" ; else echo "abcde error: config file \"$OPTARG\" cannot be found." >&2 ; exit 1 ; fi ;;
+               A) EXPACTIONS="$OPTARG" ;;
+               b) BATCHNORM=y ;;
+               B) NOBATCHREPLAYGAIN=y ;;
+               c) if [ -e "$OPTARG" ] ; then . "$OPTARG" ; else log error "config file \"$OPTARG\" cannot be found." ; exit 1 ; fi ;;
                C) DISCID="${OPTARG#abcde.}" ;;
                d) CDROM="$OPTARG" ;;
                D) set -x ;;
                e) ERASEENCODEDSTATUS=y ;;
                h) usage; exit ;;
                e) ERASEENCODEDSTATUS=y ;;
-#              f) FORCECDDBUSELOCAL=y ;;
+               E) ENCODING="$OPTARG" ;;
+               f) FORCE=y ;;
+               g) NOGAP=y ;;
                i) INLINETAG=y ;;
                j) MAXPROCS="$OPTARG" ;;
                k) KEEPWAVS=y ;;
@@ -2239,14 +2570,12 @@ while getopts 1a:A:bc:C:d:Dehj:klLmMnNo:pPr:Rs:S:t:T:vVxw:W: opt ; do
                p) PADTRACKS=y ;;
                P) USEPIPES=y ;;
                r) REMOTEHOSTS="$OPTARG" ;;
-               R) REPLAYGAIN=y ;;
-               s) STARTTRACKNUMBER="$OPTARG" ;;
+               R) DOREPLAYGAIN=y ;;
+               s) SHOWCDDBFIELDS="$OPTARG" ;;
                S) CDSPEEDVALUE="$OPTARG" ;;
-#              t) PREPROCESSFORMATS="$OPTARG"
-#                 PREPROCESS=y ;;
-#              T) POSTPROCESSFORMATS="$OPTARG" ;;
                t) STARTTRACKNUMBER="$OPTARG" ;;
                T) STARTTRACKNUMBER="$OPTARG" ; STARTTRACKNUMBERTAG="y" ;;
+               u) CDDBPROTO=6 ;;
                v) 
                   echo "This is abcde v$VERSION."
                   echo "Usage: abcde [options] [tracks]"
@@ -2259,33 +2588,52 @@ while getopts 1a:A:bc:C:d:Dehj:klLmMnNo:pPr:Rs:S:t:T:vVxw:W: opt ; do
                W) if echo $OPTARG | grep -q "[[:digit:]]" ; then 
                     STARTTRACKNUMBER="${OPTARG}01" ; STARTTRACKNUMBERTAG="y" ; COMMENT="CD${OPTARG}"
                   else
-                    echo "abcde error: argument of -W must be integer"
+                    log error "argument of -W must be integer"
                         exit 1
                   fi
                   ;;
+               z) DEBUG=y ; CDROMREADERSYNTAX=debug ; EJECTCD="n" ;;
                ?) usage; exit ;;
        esac
 done
 
 shift $(($OPTIND - 1))
 
+# If the user specified a flac file, then switch to special flac mode
+if echo $CDROM | grep -i -q '.flac$'; then
+       vecho "abcde: switching to flac CDROMREADERSYNTAX..."
+       CDROMREADERSYNTAX=flac
+       if [ "$EJECTCD" = "y" ];then
+               vecho "abcde: CDROM flac mode, deactivating EJECTCD..."
+               EJECTCD=n
+       fi
+fi
+
+# If the user provided a DISCID, disable eject
+if [ -n "$DISCID" ]; then EJECTCD=n ; fi
+
 # Decide if we can continue.
 if [ "$ONETRACK" = "y" ]; then 
        # FIXME # remove check as soon as we find out about the other readers
        case "$CDROMREADERSYNTAX" in
+               flac) ;;
                cdparanoia) ;;
                cdda2wav) ;;
-               *) echo "abcde error: $CDROMREADERSYNTAX does not support ONETRACK mode"
+               *) log error "$CDROMREADERSYNTAX does not support ONETRACK mode"
                   exit 1 ;;
        esac
-       if [ "$BATCH" = "y" ]; then
-               echo "abcde error: BATCH mode is not compatible with ONETRACK mode"
-               BATCH=n
+       if [ "$BATCHNORM" = "y" ]; then
+               log warning "BATCHNORM mode is not compatible with ONETRACK mode. Disabling..."
+               BATCHNORM=n
+       fi
+       if [ "$NOGAP" = "y" ]; then
+               log warning "NOGAP mode is not compatible with ONETRACK mode. Disabling..."
+               NOGAP=n
        fi
        # It does not matter how many tracks we want. In ONETRACK mode we grab them all
        # FIXME # allow ranges of tracks to be selected for onetrack ripping
        if [ $# -gt 0 ]; then
-               vecho "abcde warning: ONETRACK mode selected, grabbing all tracks..."
+               log warning "ONETRACK mode selected, grabbing all tracks..."
        fi
 else
        while [ $# -gt 0 ]; do
@@ -2315,6 +2663,7 @@ DOENCODE=n
 DOPOSTPROCESS=n
 DOTAG=n
 DOMOVE=n
+DOREPLAYGAIN=n
 DOPLAYLIST=n
 DOCLEAN=n
 
@@ -2329,48 +2678,44 @@ do
 #              postprocess) DOPREPROCESS=y; DOENCODE=y; DOREAD=y;;
                tag) DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
                move) DOMOVE=y; DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
+               replaygain) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOREPLAYGAIN=y;;
                playlist) DOCDDB=y; DOPLAYLIST=y;;
                clean) DOCLEAN=y;;
        esac
 done
 
-# Sanity checks:
-
-# Check the encoding format, if nothing has been configured in the system, from the ones available in the system
-if [ X"$OUTPUTTYPE" = "X" ]; then
-       for DEFAULT_OUTPUT in $( echo "$DEFAULT_OUTPUT_BINARIES" | tr , \ ); do
-               DEFAULT_OUTPUT_FORMAT="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 1)"
-               DEFAULT_OUTPUT_BINARY="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 2)"
-               if which $DEFAULT_OUTPUT_BINARY > /dev/null 2>&1 ; then
-                       OUTPUTTYPE=$DEFAULT_OUTPUT_FORMAT
-                       vecho "No default output type defined. Autoselecting $OUTPUTTYPE..." >&2
-                       break
-               fi
-       done
-       if [ X"$OUTPUTTYPE" = "X" ]; then
-               echo "abcde error: no encoder found in the PATH" >&2
-               echo "hits: are all dependencies installed? has the \$PATH been modified?" >&2
-               exit 1
-       fi
+if [ "$DONORMALIZE" = "y" ] && [ "$DOREPLAYGAIN" = "y" ]; then
+       # FIXME # should we abort on error or just inform the user?
+       log warning "selected both normalize and replaygain actions"
 fi
 
+for SHOWCDDBFIELD in $(echo $SHOWCDDBFIELDS | tr , \ ); do
+       case $SHOWCDDBFIELD in
+               y*|Y*) SHOWCDDBYEAR="y";;
+               g*|G*) SHOWCDDBGENRE="y";;
+               *) ;;
+       esac
+done
+
+# Sanity checks:
+
 # At this point a CDROM has to be defined, so we check it exists.
 if [ X"$CDROM" != "X" ] ; then 
        if [ "$CDROMREADERSYNTAX" = "cdda2wav" ] && [ "$NEEDCDROMID" = "y" ] ; then
                if [ "$OSFLAVOUR" = "FBSD" ]; then
                        if ! echo "$CDROMID" | grep "^[0-9],[0-9],[0-9]$" >/dev/null 2>&1 ; then
-                               echo "abcde error: CDROMID not in the right format for $CDROMREADERSYNTAX"
-                               echo "Use \"cdrecord -scanbus\" to obtain a adecuate ID an set CDROMID accordingly"
+                               log error "CDROMID not in the right format for $CDROMREADERSYNTAX"
+                               log error "Use \"cdrecord -scanbus\" to obtain a adecuate ID an set CDROMID accordingly"
                                exit 1
                        fi
                fi
        elif [ ! -e "$CDROM" -a X"$DOREAD" = "Xy" ]; then
-               echo "abcde error: CDROM device cannot be found." >&2
+               log error "CDROM device cannot be found."
                exit 1
        fi
 # avoid processing if we are not going to hit the CDROM.
 elif [ X"$DOREAD" = "Xy" ]; then
-       echo "abcde error: CDROM has not been defined or cannot be found" >&2
+       log error "CDROM has not been defined or cannot be found"
        exit 1
 fi
 
@@ -2382,20 +2727,68 @@ fi
 # - anything else?
 if [ X"$USEPIPES" = "Xy" ]; then
        if [ $(echo "$OUTPUTTYPE" | tr , \  | wc -w ) -gt 1 ]; then
-               echo "abcde error: Unix pipes not compatible with multiple outputs" >&2
+               log error "Unix pipes not compatible with multiple outputs"
                exit 1
        fi
        if [ X"$DONORMALIZE" = "Xy" ]; then
-               echo "abcde error: Unix pipes not compatible with normalizer"
+               log error "Unix pipes not compatible with normalizer"
                # FIXME # Do we need to exit or shall we just disable the mode?
                exit 1
        fi
+       if [ X"$BATCHNORM" = "Xy" ]; then
+               log error "Unix pipes not compatible with BATCHNORM encoding"
+               exit 1
+       fi
+       if [ X"$NOGAP" = "Xy" ]; then
+               log error "Unix pipes not compatible with NOGAP encoding"
+               exit 1
+       fi
        if [ X"$DOENCODE" = "Xn" ]; then
-               vecho "Disabling Unix pipes since we are not encoding!"
+               vecho warning "Disabling Unix pipes since we are not encoding!"
                USEPIPES=n
        fi
        if [ X"$LOWDISK" = "Xy" ]; then
-               vecho "abcde error: Unix pipes not compatible with lowdisk algorithm"
+               log error "Unix pipes not compatible with lowdisk algorithm"
+               exit 1
+       fi
+fi
+
+# LOWDISK pre-tests, before we get into more problematic stuff
+# Not compatible with anything that needs all the files in the hard disc:
+# - BATCHNORM
+# - NOGAP lame mode
+if [ X"$LOWDISK" = "Xy" ]; then
+       if [ X"$BATCHNORM" = "Xy" ]; then
+               log error "Unix pipes not compatible with BATCHNORM encoding"
+               exit 1
+       fi
+       if [ X"$NOGAP" = "Xy" ]; then
+               log error "Unix pipes not compatible with NOGAP encoding"
+               exit 1
+       fi
+fi
+
+# BATCHNORM pre-tests, before we get into serious problems
+# Not compatible with 
+if [ "$BATCHNORM" = "y" ] && [ "$DONORMALIZE" = "n" ]; then
+       vecho warning "Disabling BATCHNORM since we are not normalizing!"
+       BATCHNORM=n
+fi
+
+# Check the encoding format from the ones available in the system, if nothing has been configured in the system.
+if [ X"$OUTPUTTYPE" = "X" ]; then
+       for DEFAULT_OUTPUT in $( echo "$DEFAULT_OUTPUT_BINARIES" | tr , \ ); do
+               DEFAULT_OUTPUT_FORMAT="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 1)"
+               DEFAULT_OUTPUT_BINARY="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 2)"
+               if [ -x $(which $DEFAULT_OUTPUT_BINARY) ] ; then
+                       OUTPUTTYPE=$DEFAULT_OUTPUT_FORMAT
+                       vecho "No default output type defined. Autoselecting $OUTPUTTYPE..." >&2
+                       break
+               fi
+       done
+       if [ X"$OUTPUTTYPE" = "X" ]; then
+               log error "no encoder found in the PATH"
+               log error "hints: are all dependencies installed? has the \$PATH been modified?"
                exit 1
        fi
 fi
@@ -2418,6 +2811,10 @@ case "$CDROMREADERSYNTAX" in
                CDROMREADER="$CDDAFS"
                CDROMREADEROPTS="$CDDAFSOPTS"
                ;;
+       flac)
+               CDROMREADER="$FLAC"
+               CDROMREADEROPTS="$FLACOPTS"
+               ;;
 esac
 
 # There's only one normalize...
@@ -2430,7 +2827,7 @@ esac
 
 # Allow -o OUTPUT(1):OPTIONS(1),...,OUTPUT(N):OPTIONS(N) mode of operation
 if echo "$OUTPUTTYPE" | grep ":" > /dev/null 2>&1 ; then
-       for OUTPUT in $(echo $OUTPUTTYPE | tr , \ ); do
+       for OUTPUT in "$(echo "$OUTPUTTYPE" | tr , \ )"; do
                case "$OUTPUT" in
                        vorbis:*|ogg:*) OGGENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
                        mp3:*)  MP3ENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
@@ -2439,7 +2836,7 @@ if echo "$OUTPUTTYPE" | grep ":" > /dev/null 2>&1 ; then
                        mpc:*)  MPPENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
                esac
        done
-       for OUTPUT in $(echo $OUTPUTTYPE | tr , \ ); do
+       for OUTPUT in "$(echo "$OUTPUTTYPE" | tr , \ )"; do
                TEMPOUTPUT=$( echo "$OUTPUT" | cut -d: -f1 )
                TEMPOUTPUTTYPE="${TEMPOUTPUTTYPE:+$TEMPOUTPUTTYPE,}$TEMPOUTPUT"
        done
@@ -2455,16 +2852,18 @@ do
                vorbis|ogg)
                        [ "$OGGENCODERSYNTAX" = "default" ] && OGGENCODERSYNTAX=oggenc
                        [ "$DOTAG" = "y" ] && NEEDCOMMENTER=y
-                       [ "$REPLAYGAIN" = "y" ] && NEEDVORBISGAIN=y
+                       [ "$DOREPLAYGAIN" = "y" ] && NEEDVORBISGAIN=y
                        OGGOUTPUTCONTAINER=ogg
                        ;;
                mp3)
                        [ "$MP3ENCODERSYNTAX" = "default" ] && MP3ENCODERSYNTAX=lame
                        [ "$DOTAG" = "y" ] && NEEDTAGGER=y
+                       [ "$DOREPLAYGAIN" = "y" ] && NEEDMP3GAIN=y
                        ;;
                flac)
                        [ "$FLACENCODERSYNTAX" = "default" ] && FLACENCODERSYNTAX=flac
                        [ "$DOTAG" = "y" ] && NEEDMETAFLAC=y
+                       [ "$DOREPLAYGAIN" = "y" ] && NEEDMETAFLAC=y
                        ;;
                spx)
                        [ "$SPEEXENCODERSYNTAX" = "default" ] && SPEEXENCODERSYNTAX=speexenc
@@ -2472,7 +2871,13 @@ do
                mpc)
                        [ "$MPPENCODERSYNTAX" = "default" ] && MPPENCODERSYNTAX=mppenc
                        ;;
-               *)      echo "abcde error: Invalid OUTPUTTYPE defined" >&2
+               wav)
+                       if [ "$KEEPWAVS" = "y" ]; then
+                               vecho "Unsetting the KEEPWAVS option, since the resulting wav files were requested..."
+                       fi
+                       KEEPWAVS=move
+                       ;;
+               *)      log error "Invalid OUTPUTTYPE defined"
                        exit 1
                        ;;
        esac
@@ -2484,6 +2889,10 @@ case "$MP3ENCODERSYNTAX" in
                MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$LAMEOPTS}"
                MP3ENCODER="$LAME"
                ;;
+       toolame)
+               MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$TOOLAMEOPTS}"
+               MP3ENCODER="$TOOLAME"
+               ;;
        gogo)
                MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$GOGOOPTS}"
                MP3ENCODER="$GOGO"
@@ -2521,8 +2930,8 @@ case "$FLACENCODERSYNTAX" in
                FLACENCODER="$FLAC"     
                # FLAC streams can be encapsulated on a Ogg transport layer
                if echo "$FLACENCODEROPTS" | egrep -q -- "(^| )--ogg($| )" ;then
-                       echo "abcde error: FLAC on an Ogg container is not yet supported" >&2
-                       echo "             due to problem with adding comments to such files" >&2
+                       log error "FLAC on an Ogg container is not yet supported"
+                       log error "due to problem with adding comments to such files"
                        exit 1
                        FLACOUTPUTCONTAINER=ogg
                else
@@ -2553,14 +2962,28 @@ else
        TAGGEROPTS="$ID3V2OPTS"
 fi
 
+# Specific for NOGAP is the use of lame. Another encoder fails...
+if [ "$NOGAP" = "y" ] && [ ! "$MP3ENCODER" = "lame" ]; then
+       log warning "the NOGAP option is specific of lame. Deactivating..."
+       NOGAP=n
+fi
+
+# Options for mkcue
+case "$CUEREADERSYNTAX" in
+       default|mkcue)
+               CUEREADEROPTS="${CDROM}"
+               CUEREADER="$MKCUE"
+               ;;
+esac
+
 # Check if both OGGEOUTPUTCONTAINER and FLACOUTPUTCONTAINER are the same, and differentiante them
 if [ X"$OGGOUTPUTCONTAINER" = "Xogg" ] && [ X"$FLACOUTPUTCONTAINER" = "Xogg" ]; then
-       echo "abcde error: FLAC on an Ogg container is not yet supported" >&2
-       echo "             due to problem with adding comments to such files" >&2
+       log error "FLAC on an Ogg container is not yet supported"
+       log error "due to problem with adding comments to such files"
        exit 1
        OGGOUTPUTCONTAINER=ogg.ogg
        FLACOUTPUTCONTAINER=flac.ogg
-       vecho "abcde warning: modified file endings due to conflicting transport layers in Ogg/Vorbis and Ogg/FLAC"
+       vecho warning "modified file endings due to conflicting transport layers in Ogg/Vorbis and Ogg/FLAC"
 fi
 
 # Clean up nice options (either use '-n NICELEVEL or -NICELEVEL')
@@ -2588,31 +3011,38 @@ fi
 if [ ! "$CDDBAVAIL" = "n" ] && [ "$DOCDDB" = "y" ]; then
        NEEDHTTPGET=y
 fi
-if [ "$CUEFILE" = "y" ]; then
-       NEEDMKCUE=y
+if [ "$MAKECUEFILE" = "y" ]; then
+       NEEDCUEREADER=y
 fi
 
 if [ X"$CDSPEEDVALUE" != "X" ]; then
        case "$CDROMREADERSYNTAX" in
                cdparanoia|debug) CDROMREADEROPTS="$CDPARANOIAOPTS -S $CDSPEEDVALUE" ;;
+               ### FIXME ### translate "cue2discid" from python to bash
+               flac) NEEDMETAFLAC=y ; NEEDCUE2DISCID=y ;;
                *) NEEDCDSPEED=y ;;
        esac
 fi
 
+###USEPIPESSUPPORT###
+
 # Rippers with USEPIPE support
 # FIXME # Include here all the rippers we can figure out support pipes
-PIPE_cdparanoia="-"
+PIPERIPPER_cdparanoia="-"
+PIPERIPPER_debug="-"
+PIPERIPPER_flac="-c "
 
 # Encoders with USEPIPE support
 # FIXME # Include here all the encoders we can figure out support pipes
 PIPE_lame="-"
 PIPE_bladeenc="-"
 PIPE_oggenc="-"
+PIPE_flac="-"
 
 # Figure out if we can use pipes with the ripper/encoder combination
 # exit otherwise
 if [ "$USEPIPES" = "y" ]; then
-       PIPERIPPERSVARCHECK="PIPE_${CDROMREADER}"
+       PIPERIPPERSVARCHECK="PIPERIPPER_${CDROMREADERSYNTAX}"
        case "$OUTPUT" in
                mp3)
                        PIPEENCODERSVARCHECK="PIPE_$MP3ENCODERSYNTAX" ;;
@@ -2625,16 +3055,20 @@ if [ "$USEPIPES" = "y" ]; then
                mpc)
                        PIPEENCODERSVARCHECK="PIPE_$MPPENCODER" ;;
        esac
-       if [ ! -n "${!PIPERIPPERSVARCHECK}" ] ; then
-               echo "abcde error: no support for pipes with given ripper" >&2
-               echo "read the USEPIPES file from the source tarball to help" >&2
-               echo "on a Debian system, read /usr/share/doc/abcde/USEPIPES.gz" >&2
+       decho "PIPERIPPERSVARCHECK: $( eval echo "\$$PIPERIPPERSVARCHECK" )"
+       if [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "$" ] || \
+          [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "" ] ; then
+               log error "no support for pipes with given ripper"
+               log error "read the USEPIPES file from the source tarball to get help."
+               log error "On a Debian system, it is under /usr/share/doc/abcde/USEPIPES.gz"
                exit 1;
        fi
-       if [ ! -n "${!PIPEENCODERSVARCHECK}" ] ; then
-               echo "abcde error: no support for pipes with given encoder" >&2
-               echo "read the USEPIPES file from the source tarball to help" >&2
-               echo "on a Debian system, read /usr/share/doc/abcde/USEPIPES.gz" >&2
+       decho "PIPEENCODERSVARCHECK: $( eval echo "\$$PIPEENCODERSVARCHECK" )"
+       if [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "$" ] || \
+          [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "" ] ; then
+               log error "no support for pipes with given encoder"
+               log error "read the USEPIPES file from the source tarball to help"
+               log error "on a Debian system, read /usr/share/doc/abcde/USEPIPES.gz"
                exit 1;
        fi
 fi
@@ -2646,15 +3080,16 @@ for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
        ${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \
        ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \
        ${NEEDDISKTOOL+disktool} ${NEEDCDSPEED+$CDSPEED} \
-       ${NEEDVORBISGAIN+$VORBISGAIN} ${NEEDMKCUE+$MKCUE}
+       ${NEEDVORBISGAIN+$VORBISGAIN} ${NEEDMP3GAIN+$MP3GAIN} \
+       ${NEEDCUEREADER+$CUEREADER} ${NEEDCUE2DISCID+$CUE2DISCID}
 do
        # Cut off the command-line options we just added in
        X=$(echo $X | cut -d' ' -f2)
        if [ "$(which $X)" = "" ]; then
-               echo "abcde error: $X is not in your path." >&2
+               log error "$X is not in your path." >&2
                exit 1
        elif [ ! -x $(which $X) ]; then
-               echo "abcde error: $X is not executable." >&2
+               log error "$X is not executable." >&2
                exit 1
        fi
 done
@@ -2663,9 +3098,15 @@ CDROMREADER="$CDROMREADER $CDROMREADEROPTS"
 CDDBTOOL="$CDDBTOOL $CDDBTOOLOPTS"
 HTTPGET="$HTTPGET $HTTPGETOPTS"
 
+# And last but not least, check if we can diff between files
+if [ -x $(which $DIFF) ]; then :; else
+       vecho warning "Disabling diff since we cannot find it in the \$PATH..."
+       DIFF=""
+fi
+
 # Here it used to say:
 # One thousand lines in, we can start doing stuff with things
-# Well, right now we are at line 2157 ;)
+# Well, right now we are at line 2736 ;)
 
 # Export needed things so they can be read in this subshell
 export CDDBTOOL ABCDETEMPDIR TRACKQUEUE LOWDISK EJECTCD EJECT EJECTOPTS
@@ -2697,14 +3138,15 @@ if [ "$DOCDDB" = "y" ]; then
        fi
        do_cddbedit
 
-       eval $($CDDBTOOL parse "$CDDBDATA")
+       eval "$($CDDBTOOL parse "$CDDBDATA")"
 fi
 
 # Before reading tracks, we set the speed of the device
 
 if [ X"$CDSPEEDVALUE" != "X" ]; then
        case "$CDROMREADERSYNTAX" in
-               cdparanoia|debug) : ;;
+               cdparanoia|debug) ;;
+               flac) ;;
                *) do_cdspeed ;;
        esac
 fi
@@ -2739,7 +3181,11 @@ fi
 if [ "$ONETRACK" = "y" ]; then 
        TRACKS="$FIRSTTRACK"
        if checkstatus readtrack-$FIRSTTRACK; then :; else
-               do_cdread onetrack $FIRSTTRACK $LASTTRACK
+               if [ "$USEPIPES" = "y" ]; then
+                       do_cdread onetrack $FIRSTTRACK $LASTTRACK | do_encode $FIRSTTRACK %local0% > /dev/null 2>&1
+               else
+                       do_cdread onetrack $FIRSTTRACK $LASTTRACK
+               fi
        fi
 else
        for UTRACKNUM in $TRACKQUEUE
@@ -2762,9 +3208,14 @@ else
                                fi
                        fi
                fi
-               if [ "$BATCH" = "y" ]; then
+               if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ]; then
                    :
                else
+                       # If we are not reading, set the encode output to loud already, so
+                       # that we can see the output of the first track.
+                       if [ "$MAXPROCS" = "1" ] && [ ! "$DOREAD" = "y" ]; then
+                               echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
+                       fi
                        echo NEXTTRACK # Get the encoder machine churning again
                        if [ "$DOREAD" = "y" ]; then
                                if [ "$LOWDISK" = "y" ] && [ "$DOENCODE" = "y" ]; then
@@ -2788,10 +3239,13 @@ if [ "$MAXPROCS" = "1" ]; then
 fi
 
 # All tracks read, start encoding.
-if [ "$BATCH" = "y" ] || [ "$ONETRACK" = "y" ]; then
+if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ] || [ "$ONETRACK" = "y" ]; then
        echo NEXTTRACK
 fi
 
+# Execute the user-defined post_read funtion before ejecting CD
+post_read
+
 # We are now finished with the cdrom - it can be safely ejected. Note that
 # abcde will not have completed yet.
 if [ "$EJECTCD" = "y" ] && [ -x $(which $EJECT) ]; then
@@ -2842,19 +3296,28 @@ fi
 #
 #) | (
 
-# In batch mode, we want all tracks to be read first.
-if [ "$BATCH" = "y" ]; then
+# In BATCHNORM and/or NOGAP modes, we want all tracks to be read first.
+#BACK
+if [ "$BATCHNORM" = "y" ] || [ "$NOGAP" = "y" ]; then
        read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
        if [ "$GOAHEAD" = "NO" ]; then break; fi
        for LASTTRACK in $TRACKQUEUE; do :; done
        if checkstatus readtrack-$LASTTRACK; then
-               if [ "$DONORMALIZE" = "y" ]; then
+               if [ "$DONORMALIZE" = "y" ] && [ "$BATCHNORM" = "y" ]; then
                        if checkstatus normalizetrack-$LASTTRACK; then :; else do_batch_normalize; fi
-                       if checkerrors batch-normalize; then exit; fi
+                       if checkerrors batch-normalize; then exit 1; fi
                fi
-               if [ "$DOENCODE" = "y" ]; then
-                       if checkstatus encodetrack-$LASTTRACK; then :; else do_batch_encode; fi
-                       if checkerrors batch-encode; then exit; fi
+               if [ "$DOENCODE" = "y" ] && [ "$NOGAP" = "y" ]; then
+                       if [ "$DONORMALIZE" = "y" ]; then
+                               for UTRACKNUM in $TRACKQUEUE
+                               do
+                                       if checkstatus readtrack-$UTRACKNUM; then
+                                               if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
+                                       fi
+                               done
+                       fi
+                       if checkstatus encodetrack-$LASTTRACK; then :; else do_nogap_encode; fi
+                       if checkerrors nogap-encode; then exit 1; fi
                fi
        fi
 fi
@@ -2931,7 +3394,8 @@ do
 #                      TRACKNUM=$(printf %0.${TRACKNUMPADDING}d $(expr ${UTRACKNUM} + 0))
                        TRACKNUM=$UTRACKNUM
                        CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
-                       TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
+                       #TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
+                       do_getcddbinfo TRACKNAME
                        splitvarious
                fi
        fi
@@ -3002,9 +3466,17 @@ if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
 fi
 # If the above didn't catch the stragglers, this will
 wait
+if [ "$DOREPLAYGAIN" = "y" ]; then
+       do_replaygain
+fi
+
+# FIXME #
+# Check if all the encoded formats have been actually moved to the final destination
+# ...
+
 # Check to see if run_command logged any errors
 if [ -f "$ABCDETEMPDIR/errors" ]; then
-       echo "The following commands failed to run:"
+       log error "The following commands failed to run:"
        cat "$ABCDETEMPDIR/errors"
        # Don't clean up
        DOCLEAN=n
@@ -3013,6 +3485,18 @@ if [ "$KEEPWAVS" = "y" ];then
        # Don't clean up
        DOCLEAN=n
 fi
+# Check if we have moved all the formats we had previously encoded, if we are not using the FORCE.
+if [ "$DOCLEAN" = "y" ] && [ ! "$FORCE" = "y" ]; then
+       ENCODED_FORMATS=$(egrep "^encodetrack-(.{3,6})-(.{1,2})$" "$ABCDETEMPDIR/status" | cut -d"-" -f2 | sort -u | tr '\n' '|')
+       MOVED_FORMATS=$(egrep "^movetrack-output-(.{3,6})$" "$ABCDETEMPDIR/status" | cut -d"-" -f3 | sort -u | tr '\n' '|')
+       decho [ENCODED_FORMATS]
+       decho [MOVED_FORMATS]
+       if [ "$ENCODED_FORMATS" != "$MOVED_FORMATS" ]; then
+               log warning "Not all encoded formats have been requested to be moved."
+               log warning "Use \"-a clean -f -C $DISCID\" to force the removal of the remaining data."
+               DOCLEAN=n
+       fi
+fi
 if [ "$DOCLEAN" = "y" ]; then
        # Wipe all the evidence
        # Gimme gimme gimme some more time!