diff --git a/tren.py b/tren.py
index f1b1756..795d4b4 100755
--- a/tren.py
+++ b/tren.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2
 # tren.py
 # Copyright (c) 2010-2020 TundraWare Inc.
 # For Updates See:  http://www.tundraware.com/Software/tren
@@ -9,7 +9,7 @@
 BASENAME = PROGNAME.split(".py")[0]
 PROGENV  = BASENAME.upper()
 INCLENV  = PROGENV + "INCL"
-RCSID = "$Id: tren.py,v 1.242 2011/08/01 18:07:17 tundra Exp $"
+RCSID = "$Id: tren.py,v 1.243 2020/11/07 18:07:17 tundra Exp $"
 VERSION = RCSID.split()[2]
 
 # Copyright Information
@@ -439,7 +439,7 @@
            'u' : str.upper
           }
 
-CASEOPS = list(CASETBL.keys())
+CASEOPS = CASETBL.keys()
 CASEOPS.sort()
 
 
@@ -690,8 +690,7 @@
             try:
                 pathname, basename = os.path.split(fullname)
                 stats    = os.stat(fullname)
-            except (IOError, OSError) as xxx_todo_changeme2:
-                (errno, errstr) = xxx_todo_changeme2.args
+            except (IOError, OSError), (errno, errstr):
                 ErrorMsg(eFILEOPEN % (fullname, errstr))
 
             # Some operating systems (Windows) terminate the path with
@@ -747,7 +746,7 @@
 
             statflag, storage, order = seqtype
 
-            vieworder = list(storage.keys())
+            vieworder = storage.keys()
             vieworder.sort()
 
             # Sort alphabetically when multiple filenames
@@ -1277,8 +1276,7 @@
 
                     try:
                         os.rename(fullold, fullnew)
-                    except OSError as xxx_todo_changeme:
-                        (errno, errstr) = xxx_todo_changeme.args
+                    except OSError, (errno, errstr):
                         ErrorMsg(eRENAMEFAIL % (fullold, fullnew, errstr))
 
         self.indentlevel -= 1
@@ -1503,7 +1501,7 @@
                 token = r[2][1:]
 
                 found = False
-                for seqtoken in list(self.SortViews.keys()) + [ORDERBYADATE, ORDERBYCDATE, ORDERBYMDATE]:
+                for seqtoken in self.SortViews.keys() + [ORDERBYADATE, ORDERBYCDATE, ORDERBYMDATE]:
 
                     if token.split(ALPHADELIM)[0] == (seqtoken):
 
@@ -1831,7 +1829,7 @@
     DebugMsg(dCURSTATE)
     DebugMsg(SEPARATOR)
 
-    opts = list(ProgramOptions.keys())
+    opts = ProgramOptions.keys()
     opts.sort()
     for o in opts:
         DebugMsg(ColumnPad([o, ProgramOptions[o]]))
@@ -2069,8 +2067,7 @@
 
                         OPTIONS = OPTIONS[:i] + n + OPTIONS[i+1:]
 
-                    except IOError as xxx_todo_changeme1:
-                        (errno, errstr) = xxx_todo_changeme1.args
+                    except IOError, (errno, errstr):
                         ErrorMsg(eFILEOPEN % (inclfile, errstr))
 
             i += 1
@@ -2169,8 +2166,7 @@
 
 try:
     opts, args = getopt.getopt(OPTIONS, OPTIONSLIST)
-except getopt.GetoptError as xxx_todo_changeme3:
-    (errmsg, badarg) = xxx_todo_changeme3.args
+except getopt.GetoptError, (errmsg, badarg):
     ErrorMsg(eBADARG % errmsg)
 
 # Create and populate an object with rename targets.  This must be
diff --git a/tren2.py b/tren2.py
deleted file mode 100755
index fb871e4..0000000
--- a/tren2.py
+++ /dev/null
@@ -1,2391 +0,0 @@
-#!/usr/bin/env python
-# tren.py
-# Copyright (c) 2010-2011 TundraWare Inc.
-# For Updates See:  http://www.tundraware.com/Software/tren
-
-# Program Information
-
-PROGNAME = "tren.py"
-BASENAME = PROGNAME.split(".py")[0]
-PROGENV  = BASENAME.upper()
-INCLENV  = PROGENV + "INCL"
-RCSID = "$Id: tren.py,v 1.242 2011/08/01 18:07:17 tundra Exp $"
-VERSION = RCSID.split()[2]
-
-# Copyright Information
-
-CPRT         = "(c)"
-DATE         = "2010-2011"
-OWNER        = "TundraWare Inc."
-RIGHTS       = "All Rights Reserved."
-COPYRIGHT    = "Copyright %s %s, %s  %s" % (CPRT, DATE, OWNER, RIGHTS)
-
-PROGVER      = PROGNAME + " " + VERSION + (" - %s" % COPYRIGHT)
-HOMEPAGE     = "http://www.tundraware.com/Software/%s\n" % BASENAME
-
-
-
-#----------------------------------------------------------#
-#            Variables User Might Change                   #
-#----------------------------------------------------------#
-
-
-
-#------------------- Nothing Below Here Should Need Changing ------------------#
-
-
-#----------------------------------------------------------#
-#                       Imports                            #
-#----------------------------------------------------------#
-
-import copy
-import getopt
-import glob
-import os
-import random
-import re
-import shlex
-from   stat import *
-import sys
-import time
-
-#####
-# Imports conditional on OS
-#####
-
-# Set OS type - this allows us to trigger OS-specific code
-# where needed.
-
-OSNAME     = os.name
-POSIX      = False
-WINDOWS    = False
-
-if OSNAME == 'nt':
-    WINDOWS = True
-
-elif OSNAME == 'posix':
-    POSIX = True
-
-# Set up Windows-specific stuff
-    
-if WINDOWS:
-
-    # Try to load win32all stuff if it's available
-
-    try:
-        from win32api import GetFileAttributes, GetComputerName
-        import win32con
-        from win32file import GetDriveType
-        from win32wnet import WNetGetUniversalName
-        from win32security import *
-        WIN32HOST = GetComputerName()
-        WIN32ALL = True
-
-    except:
-        WIN32ALL = False
-
-# Set up Unix-specific stuff
-
-elif POSIX:
-
-    # Get Unix password and group features
-
-    import grp
-    import pwd
-
-
-# Uh oh, this is not an OS we know about
-
-else:
-    sys.stderr.write("Unsupported Operating System!  Aborting ...\n")
-    sys.exit(1)
-    
-
-#----------------------------------------------------------#
-#                 Aliases & Redefinitions                  #
-#----------------------------------------------------------#
-
-
-
-#----------------------------------------------------------#
-#                Constants & Literals                      #
-#----------------------------------------------------------#
-
-
-#####
-# General Program Constants
-#####
-
-MAXINCLUDES  =  1000        # Maximum number of includes allowed - used to catch circular references
-MAXNAMELEN   =  255         # Maximum file or directory name length
-MINNAMELEN   =  1           # Minimum file or directory name length
-
-#####
-# Message Formatting Constants
-#####
-
-# Make sure these make sense: ProgramOptions[MAXLINELEN] > PADWIDTH + WRAPINDENT
-# because of the way line conditioning/wrap works.
-
-PADCHAR      =  " "         # Padding character
-PADWIDTH     =  30          # Column width
-LSTPAD       =  13          # Padding to use when dumping lists
-WRAPINDENT   =   8          # Extra indent on wrapped lines
-MINLEN       =  PADWIDTH + WRAPINDENT + 1  # Minimum line length
-
-
-#####
-# Command Line Option Strings
-#####
-
-# List all legal command line options that will be processed by getopt() later.
-# We exclude -I here because it is parsed manually before the getopt() call.
-
-OPTIONSLIST  =  "A:abCcde:fhi:P:qR:r:S:T:tvw:Xx" # All legal command line options in getopt() format
-
-
-#####
-# Literals
-#####
-
-ARROW        =  "--->"          # Used for formatting renaming messages
-ASKDOREST    =  "!"             # Do rest of renaming without asking
-ASKNO        =  "N"             # Do not rename current file
-ASKQUIT      =  "q"             # Quit renaming all further files
-ASKYES       =  "y"             # Rename current file
-COMMENT      =  "#"             # Comment character in include files
-DEFINST      =  0               # Default replacement instance
-DEFLEN       =  80              # Default output line length
-DEFSEP       =  "="             # Default rename command separator: old=new
-DEFSUFFIX    =  ".backup"       # String used to rename existing targets
-DEFESC       =  "\\"            # Escape character
-INCL         =  "I"             # Include file command line option
-INDENT       =  "    "          # Indent string for nested messages
-NULLESC      =  "Escape string"                   # Cannot be null
-NULLRENSEP   =  "Old/New separator string"        # Cannot be null
-NULLSUFFIX   =  "Forced renaming suffix string"   # Cannot be null
-OPTINTRO     =  "-"             # Option introducer
-PATHDELUNIX  =  ":"             # Separates include path elements on Unix systems
-PATHDELWIN   =  ";"             # Separates include path elements on Windows systems
-PATHSEP      =  os.path.sep     # File path separator character
-RANGESEP     =  ":"             # Separator for instance ranges
-SINGLEINST   =  "SINGLEINST"    # Indicates a single, not range, in a slice
-WINDOWSGROUP =  "WindowsGroup"  # Returned on Windows w/o win32all
-WINDOWSUSER  =  "WindowsUser"   # Reutrned on Windows w/o win32all
-WINGROUPNOT  =  "GroupNotAvailable"    # Returned when win32all can't get a group name
-WINUSERNOT   =  "UserNotAvailable"     # Returned when win32all can't get a user name
-
-#####
-# Replacement Token Literals
-#####
-
-# Sequence Alphabets
-
-BINARY     =  "Binary"
-DECIMAL    =  "Decimal"
-OCTAL      =  "Octal"
-HEXLOWER   =  "HexLower"
-HEXUPPER   =  "HexUpper"
-LOWER      =  "Lower"
-LOWERUPPER =  "LowerUpper"
-UPPER      =  "Upper"
-UPPERLOWER =  "UpperLower"
-
-# General Literals
-
-ALPHADELIM =  ":"             # Delimits alphabet name in a Sequence renaming token
-TOKDELIM   =  "/"             # Delimiter for all renaming tokens
-
-# Shared File Attribute And Sequence Renaming Tokens
-
-TOKFILADATE  =  "ADATE"
-TOKFILATIME  =  "ATIME"
-TOKFILCMD    =  "CMDLINE"
-TOKFILCDATE  =  "CDATE"
-TOKFILCTIME  =  "CTIME"
-TOKFILDEV    =  "DEV"
-TOKFILFNAME  =  "FNAME"
-TOKFILGID    =  "GID"
-TOKFILGROUP  =  "GROUP"
-TOKFILINODE  =  "INODE"
-TOKFILMODE   =  "MODE"
-TOKFILMDATE  =  "MDATE"
-TOKFILMTIME  =  "MTIME"
-TOKFILNLINK  =  "NLINK"
-TOKFILSIZE   =  "SIZE"
-TOKFILUID    =  "UID"
-TOKFILUSER   =  "USER"
-
-# File Time Renaming Tokens
-
-TOKADAY    =  "ADAY"          # mm replacement token
-TOKAHOUR   =  "AHOUR"         # hh replacement token
-TOKAMIN    =  "AMIN"          # mm replacement token
-TOKAMON    =  "AMON"          # MM replacement token
-TOKAMONTH  =  "AMONTH"        # Mmm replacement token
-TOKASEC    =  "ASEC"          # ss replacement token
-TOKAWDAY   =  "AWDAY"         # Ddd replacement token
-TOKAYEAR   =  "AYEAR"         # yyyy replacement token
-
-TOKCDAY    =  "CDAY"          # mm replacement token
-TOKCHOUR   =  "CHOUR"         # hh replacement token
-TOKCMIN    =  "CMIN"          # mm replacement token
-TOKCMON    =  "CMON"          # MM replacement token
-TOKCMONTH  =  "CMONTH"        # Mmm replacement token
-TOKCSEC    =  "CSEC"          # ss replacement token
-TOKCWDAY   =  "CWDAY"         # Ddd replacement token
-TOKCYEAR   =  "CYEAR"         # yyyy replacement token
-
-TOKMDAY    =  "MDAY"          # mm replacement token
-TOKMHOUR   =  "MHOUR"         # hh replacement token
-TOKMMIN    =  "MMIN"          # mm replacement token
-TOKMMON    =  "MMON"          # MM replacement token
-TOKMMONTH  =  "MMONTH"        # Mmm replacement token
-TOKMSEC    =  "MSEC"          # ss replacement token
-TOKMWDAY   =  "MWDAY"         # Ddd replacement token
-TOKMYEAR   =  "MYEAR"         # yyyy replacement token
-
-# System Renaming Tokens
-
-TOKCMDEXEC =  "`"             # Delimiter for command execution renaming tokens
-TOKENV     =  "$"             # Introducer for environment variable replacement tokens
-TOKRAND    =  "RAND"          # Random replacement token
-TOKNAMESOFAR = "NAMESOFAR"    # New name so far
-
-# Sequence Renaming Tokens
-
-TOKASCEND  =  "+"             # Ascending order flag
-TOKDESCEND =  "-"             # Descending order flag
-
-
-#####
-# Internal program state literals
-#####
-
-ASK            =  "ASK"
-BACKUPS        =  "BACKUPS"
-DEBUG          =  "DEBUG"
-CASECONV       =  "CASECONV"
-CASESENSITIVE  =  "CASESENSITIVE"
-ESCAPE         =  "ESCAPE"
-EXISTSUFFIX    =  "EXISTSUFFIX"
-FORCERENAME    =  "FORCERENAME"
-INSTANCESTART  =  "INSTANCESTART"
-INSTANCEEND    =  "INSTANCEEND"
-MAXLINELEN     =  "MAXLINELEN"
-QUIET          =  "QUIET"
-REGEX          =  "REGEX"
-RENSEP         =  "RENSEP"
-TARGETSTART    =  "TARGETSTART"
-TARGETEND      =  "TARGETEND"
-TESTMODE       =  "TESTMODE"
-
-
-#####
-# Renaming Literals
-#####
-
-# Rename target keys
-
-BASE           =  "BASENAME"
-PATHNAME       =  "PATHNAME"          
-STATS          =  "STATS"
-
-# These literals serve two purposes:
-#
-#  1) They are used as the type indicator in a Sequence Renaming Token
-#  2) They are keys to the SortViews and DateViews dictionaries that stores the prestorted views
-
-ORDERBYADATE   =  TOKFILADATE
-ORDERBYATIME   =  TOKFILATIME
-ORDERBYCMDLINE =  TOKFILCMD
-ORDERBYCDATE   =  TOKFILCDATE
-ORDERBYCTIME   =  TOKFILCTIME
-ORDERBYDEV     =  TOKFILDEV
-ORDERBYFNAME   =  TOKFILFNAME
-ORDERBYGID     =  TOKFILGID
-ORDERBYGROUP   =  TOKFILGROUP
-ORDERBYINODE   =  TOKFILINODE
-ORDERBYMODE    =  TOKFILMODE
-ORDERBYMDATE   =  TOKFILMDATE
-ORDERBYMTIME   =  TOKFILMTIME
-ORDERBYNLINK   =  TOKFILNLINK
-ORDERBYSIZE    =  TOKFILSIZE
-ORDERBYUID     =  TOKFILUID
-ORDERBYUSER    =  TOKFILUSER
-
-# Rename string keys
-
-NEW            = "NEW"
-OLD            = "OLD"
-
-
-#----------------------------------------------------------#
-#              Prompts, & Application Strings              #
-#----------------------------------------------------------#
-
-
-#####
-# Debug Messages
-#####
-
-DEBUGFLAG          =   "-d"
-dALPHABETS         =   "Alphabets"
-dCMDLINE           =   "Command Line"
-dCURSTATE          =   "Current State Of Program Options"
-dDATEVIEW          =   "Date View:"
-dDEBUG             =   "DEBUG"
-dDUMPOBJ           =   "Dumping Object %s"
-dINCLFILES         =   "Included Files:"
-dPROGENV           =   "$" + PROGENV
-dRENREQ            =   "Renaming Request:"
-dRENSEQ            =   "Renaming Sequence: %s"
-dRENTARGET         =   "Rename Target:"
-dRESOLVEDOPTS      =   "Resolved Command Line"
-dSEPCHAR           =   "-"     # Used for debug separator lines
-dSORTVIEW          =   "Sort View:"
-
-
-#####
-# Error Messages
-#####
-
-eALPHABETEXIST     =  "Sequence renaming token '%s' specifies a non-existent alphabet!"
-eALPHABETMISSING   =  "Sequence renaming token '%s' has a missing or incorrect alphabet specification!"
-eALPHACMDBAD       =  "Alphabet specificaton '%s' malformed! Try \"Name:Alphabet\""
-eALPHACMDLEN       =  "Alphabet '%s' too short!  Must contain at least 2 symbols."
-eARGLENGTH         =  "%s must contain exactly %s character(s)!"
-eBADARG            =  "Invalid command line: %s!"
-eBADCASECONV       =  "Invalid case conversion argument: %s! Must be one of: %s"
-eBADINCL           =  "option -%s requires argument" % INCL
-eBADLEN            =  "Bad line length '%s'!"
-eBADNEWOLD         =  "Bad -r argument '%s'!  Requires exactly one new, old string separator (Default: " + DEFSEP + ")"
-eBADREGEX          =  "Invalid Regular Expression: %s"
-eBADSLICE          =  "%s invalid slice format! Must be integer values in the form: n, :n, n:, start:end, or :"
-eERROR             =  "ERROR"
-eEXECFAIL          =  "Renaming token: '%s', command '%s' Failed To Execute!"
-eFILEOPEN          =  "Cannot open file '%s': %s!"
-eLINELEN           =  "Specified line length too short!  Must be at least %s" % MINLEN
-eNAMELONG          =  "Renaming '%s' to new name '%s' too long! (Maximum length is %s.)"
-eNAMESHORT         =  "Renaming '%s' to new name '%s' too short! (Minimum length is %s.)"
-eNOROOTRENAME      =  "Cannot rename root of file tree!"
-eNULLARG           =  "%s cannot be empty!"
-eRENAMEFAIL        =  "Attempt to rename '%s' to '%s' failed : %s!"
-eTOKBADSEQ         =  "Unknown sequence renaming token, '%s'!"
-eTOKDELIM          =  "Renaming token '%s' missing delimiter!"
-eTOKRANDIG         =  "Renaming token: '%s' has invalid random precision!  Must be integer > 0."
-eTOKUNKNOWN        =  "Unknown renaming token, '%s'!"
-eTOOMANYINC        =  "Too many includes! (Max is %d) Possible circular reference?" % MAXINCLUDES
-
-
-#####
-# Informational Messages
-#####
-
-iFORCEDNOBKU  =  "Forced renaming WITHOUT backups in effect!!! %s is overwriting %s."
-iRENFORCED    =  "Target '%s' exists.  Creating backup."
-iRENSKIPPED   =  "Target '%s' exists. Renaming '%s' skipped."
-iRENAMING     =  "Renaming '%s' " + ARROW + " '%s'"
-iSEQTOOLONG   =  "Sequence number %s, longer than format string %s, Rolling over!"
-
-
-#####
-# Usage Prompts
-#####
-
-uTable = [PROGVER,
-          HOMEPAGE,
-          "usage:  " + PROGNAME + " [-abCcdfhqtvwXx] [-e type] [-I file] [-i instance] [-P escape] [ -R separator] [-r old=new] [-S suffix] [-T target] [-w width] ... file|dir file|dir ...",
-          "   where,",
-          "         -A alphabet   Install \"alphabet\" for use by sequence renaming tokens",
-          "         -a            Ask interactively before renaming (Default: Off)",
-          "         -b            Turn off backups during forced renaming (Default: Do Backups)",
-          "         -C            Do case-sensitive renaming (Default)",
-          "         -c            Collapse case when doing string substitution (Default: False)",
-          "         -d            Dump debugging information (Default: False)",
-          "         -e type       Force case conversion (Default: None)",
-          "         -f            Force renaming even if target file or directory name already exists (Default: False)",
-          "         -h            Print help information (Default: False)",
-          "         -I file       Include command line arguments from file",
-          "         -i num|range  Specify which instance(s) to replace (Default: %s)" % DEFINST,
-          "         -P char       Use 'char' as the escape sequence (Default: %s)" % DEFESC,
-          "         -q            Quiet mode, do not show progress (Default: False)",
-          "         -R char       Separator character for -r rename arguments (Default: %s)" % DEFSEP,
-          "         -r old=new    Replace old with new in file or directory names",
-          "         -S suffix     Suffix to use when renaming existing filenames (Default: %s)" % DEFSUFFIX,
-          "         -t            Test mode, don't rename, just show what the program *would* do (Default: False)",
-          "         -T num|range  Specify which characters in file name are targeted for renaming (Default: Whole Name)",
-          "         -v            Print detailed program version information and continue (Default: False)",
-          "         -w length     Line length of diagnostic and error output (Default: %s)" % DEFLEN,
-          "         -X            Treat the renaming strings literally (Default)",
-          "         -x            Treat the old replacement string as a Python regular expression (Default: False)",
-         ]
-
-
-#----------------------------------------------------------#
-#                   Lookup Tables                          #
-#----------------------------------------------------------#
-
-
-# Case Conversion
-
-
-# Notice use of *unbound* string function methods from the class definition
-
-CASETBL = {'c' : str.capitalize,
-           'l' : str.lower,
-           's' : str.swapcase,
-           't' : str.title,
-           'u' : str.upper
-          }
-
-CASEOPS = CASETBL.keys()
-CASEOPS.sort()
-
-
-# Day And Month Conversion Tables
-
-
-DAYS   = {0:"Mon", 1:"Tue", 2:"Wed", 3:"Thu", 4:"Fri", 5:"Sat", 6:"Sun"}
-          
-MONTHS = {1:"Jan", 2:"Feb", 3:"Mar", 4:"Apr", 5:"May", 6:"Jun",
-          7:"Jul", 8:"Aug", 9:"Sep", 10:"Oct", 11:"Nov", 12:"Dec"}
-
-# File Time Renaming Token Lookup Table
-
-FILETIMETOKS = { TOKADAY   : ("%02d", "ST_ATIME", "tm_mday"),
-                 TOKAHOUR  : ("%02d", "ST_ATIME", "tm_hour"),
-                 TOKAMIN   : ("%02d", "ST_ATIME", "tm_min"),
-                 TOKAMON   : ("%02d", "ST_ATIME", "tm_mon"),
-                 TOKAMONTH : ("",     "ST_ATIME", "tm_mon"),
-                 TOKASEC   : ("%02d", "ST_ATIME", "tm_sec"),
-                 TOKAWDAY  : ("",     "ST_ATIME", "tm_wday"),
-                 TOKAYEAR  : ("%04d", "ST_ATIME", "tm_year"),
-                 TOKCDAY   : ("%02d", "ST_CTIME", "tm_mday"),
-                 TOKCHOUR  : ("%02d", "ST_CTIME", "tm_hour"),
-                 TOKCMIN   : ("%02d", "ST_CTIME", "tm_min"),
-                 TOKCMON   : ("%02d", "ST_CTIME", "tm_mon"),
-                 TOKCMONTH : ("",     "ST_CTIME", "tm_mon"),
-                 TOKCSEC   : ("%02d", "ST_CTIME", "tm_sec"),
-                 TOKCWDAY  : ("",     "ST_CTIME", "tm_wday"),
-                 TOKCYEAR  : ("%04d", "ST_CTIME", "tm_year"),
-                 TOKMDAY   : ("%02d", "ST_MTIME", "tm_mday"),
-                 TOKMHOUR  : ("%02d", "ST_MTIME", "tm_hour"),
-                 TOKMMIN   : ("%02d", "ST_MTIME", "tm_min"),
-                 TOKMMON   : ("%02d", "ST_MTIME", "tm_mon"),
-                 TOKMMONTH : ("",     "ST_MTIME", "tm_mon"),
-                 TOKMSEC   : ("%02d", "ST_MTIME", "tm_sec"),
-                 TOKMWDAY  : ("",     "ST_MTIME", "tm_wday"),
-                 TOKMYEAR  : ("%04d", "ST_MTIME", "tm_year")
-               }
-
-# Alphabets - The user can add to these on the command line
-
-ALPHABETS  =  {
-
-               BINARY      : ["0", "1"],
-    
-               DECIMAL     : ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
-
-               HEXLOWER    : ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"],
-
-               HEXUPPER    : ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"],
-
-               LOWER       : ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",
-                              "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" ],
-
-               LOWERUPPER  : ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",
-                              "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F",
-                              "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
-                              "W", "X", "Y", "Z"],
-
-               OCTAL       : ["0", "1", "2", "3", "4", "5", "6", "7"],
-
-               UPPER       : ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P",
-                              "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ],
-
-               UPPERLOWER  : ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P",
-                              "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f",
-                              "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
-                              "w", "x", "y", "z"]
-              }
-
-
-
-
-#----------------------------------------------------------#
-#          Global Variables & Data Structures              #
-#----------------------------------------------------------#
-
-# List of all the included files
-
-IncludedFiles     = []
-
-
-# Program toggle and option defaults
-
-ProgramOptions    = {
-                     ASK           : False,       # Interactively ask user before renaming each file
-                     BACKUPS       : True,        # Do backups during forced renaming
-                     DEBUG         : False,       # Debugging off
-                     CASECONV      : None,        # Forced case conversions
-                     CASESENSITIVE : True,        # Search is case-sensitive
-                     ESCAPE        : DEFESC,      # Escape string
-                     EXISTSUFFIX   : DEFSUFFIX,   # What to tack on when renaming existing targets
-                     FORCERENAME   : False,       # Do not rename if target already exists
-                     INSTANCESTART : DEFINST,     # Replace first, leftmost instance by default
-                     INSTANCEEND   : SINGLEINST,
-                     MAXLINELEN    : DEFLEN,      # Width of output messages
-                     QUIET         : False,       # Display progress
-                     REGEX         : False,       # Do not treat old string as a regex
-                     RENSEP        : DEFSEP,      # Old, New string separator for -r
-                     TARGETSTART   : False,       # Entire file name is renaming target by default
-                     TARGETEND     : False, 
-                     TESTMODE      : False        # Test mode off
-                    }
-
-
-# Used to track the sequence of name transformations as each renaming
-# request is applied.  The -1th entry is thus also the "name so far"
-# used for the /NAMESOFAR/ renaming token.
-
-RenSequence       = []
-
-#--------------------------- Code Begins Here ---------------------------------#
-
-
-#----------------------------------------------------------#
-#             Object Base Class Definitions                #
-#----------------------------------------------------------#
-
-
-#####
-# Container For Holding Rename Targets And Renaming Requests
-#####
-
-class RenameTargets:
-
-    """ 
-        This class is used to keep track of all the files and/or
-        directories we're renaming.  After the class is constructed
-        and the command line fully parsed, this will contain:
-
-        self.RenNames    = { fullname : {BASE : basename, PATHNAME : pathtofile, STATS : stats}
-                             ... (repeated for each rename target)
-                           }
-
-        self.SortViews   = {
-                             ORDERBYATIME         : [fullnames in atimes order],
-                             ORDERBYCMDLINE       : [fullnames in command line order],
-                             ORDERBYCTIME         : [fullnames in ctimes order],
-                             ORDERBYDEV           : [fullnames in devs order],
-                             ORDERBYFNAME         : [fullnames in alphabetic order],
-                             ORDERBYGID           : [fullnames in gids order],
-                             ORDERBYGROUP         ; [fullnames in group name order],
-                             ORDERBYINODE         : [fullnames in inode order],
-                             ORDERBYMODE          : [fullnames in mode order],
-                             ORDERBYMTIME         : [fullnames in mtimes order],
-                             ORDERBYNLINK         : [fullnames in nlinks order],
-                             ORDERBYSIZE          : [fullnames in size order],
-                             ORDERBYUID           : [fullnames in uids order],
-                             ORDERBYUSER          : [fullnames in user name order]
-                            }
-
-        self.DateViews   =  {
-                             ORDERBYADATE-date... : [fullnames in  order by atime within same 'date'] ... (repeated for each date),
-                             ORDERBYCDATE-date... : [fullnames in  order by ctime within same 'date'] ... (repeated for each date),
-                             ORDERBYMDATE-date... : [fullnames in  order by mtime within same 'date'] ... (repeated for each date)
-                            }
-        
-        self.RenRequests =  [
-                             {
-                               ASK           : interactive ask flag
-                               BACKUPS       : do backups during forced renaming flag,
-                               OLD           : old rename string,
-                               NEW           : new rename string,
-                               DEBUG         : debug flag,
-                               CASECONV      : type of case conversion,
-                               CASESENSITIVE : case sensitivity flag,
-                               FORCERENAME   : force renaming flag,
-                               INSTANCESTART : Replace first, leftmost instance by default,
-                               INSTANCEEND   : ,
-                               MAXLINELEN    : max output line length,
-                               QUIET         : quiet output flag,
-                               REGEX         : regular expression enable flag,
-                               RENSEP        : old/new rename separator string,
-                               TARGETSTART   : Entire file name target for renaming by default,
-                               TARGETEND     : ,
-                               TESTMODE      : testmode flag
-                             } ... (repeated for each rename request)
-                            ]
-
-    """
-
-    #####
-    # Constructor
-    #####
-
-    def __init__(self, targs):
-
-        # Keep track of all the new filenames we write (or would have)
-        # so test mode can correctly report just what the the progam
-        # *would* do.  Without this, backup generation is not properly
-        # reported in test mode.
-
-        self.RenamedFiles = []
-        self.NewFiles     = []
-
-        # Dictionary of all rename targets and their stat info
-
-        self.RenNames   =   {}
-
-        # Dictionary of all possible sort views
-        # We can load the first two right away since they're based
-        # only on the target names provided on the command line
-
-        i=0
-        while i < len(targs):
-            targs[i] = os.path.abspath(targs[i])
-            i += 1
-
-        alpha = targs[:]
-        alpha.sort()
-        self.SortViews  =   {ORDERBYCMDLINE : targs, ORDERBYFNAME : alpha}
-        del alpha
-
-        # Dictionary to hold all possible date views - files sorted
-        # by time *within* a common date.
-
-        self.DateViews = {}
-
-        # Dictionary of all the renaming requests - will be filled in
-        # by -r command line parsing.
-
-        self.RenRequests = []
-
-
-        # This data structure is used to build various sort views
-        # A null first field means the view requires special handling,
-        # otherwise it's just a stat structure lookup.
-
-        SeqTypes = [
-                     [ST_ATIME,  {},  ORDERBYATIME],
-                     [ST_CTIME,  {},  ORDERBYCTIME],
-                     [ST_DEV,    {},  ORDERBYDEV],
-                     [ST_GID,    {},  ORDERBYGID],
-                     ["",        {},  ORDERBYGROUP],
-                     [ST_INO,    {},  ORDERBYINODE],
-                     [ST_MODE,   {},  ORDERBYMODE],
-                     [ST_MTIME,  {},  ORDERBYMTIME],
-                     [ST_NLINK,  {},  ORDERBYNLINK],
-                     [ST_SIZE,   {},  ORDERBYSIZE],
-                     [ST_UID,    {},  ORDERBYUID],
-                     ["",        {},  ORDERBYUSER],                     
-                   ]
-
-        # Populate the data structures with each targets' stat information
-
-        for fullname in targs:
-
-            try:
-                pathname, basename = os.path.split(fullname)
-                stats    = os.stat(fullname)
-            except (IOError, OSError), (errno, errstr):
-                ErrorMsg(eFILEOPEN % (fullname, errstr))
-
-            # Some operating systems (Windows) terminate the path with
-            # a separator, some (Posix) do not.
-
-            if pathname[-1] != os.sep:
-                pathname += os.sep
-            
-            # Store fullname, basename, and stat info for this file
-            
-            if basename:
-                self.RenNames[fullname] = {BASE : basename, PATHNAME : pathname, STATS : stats}
-
-            # Catch the case where they're trying to rename the root of the directory tree
-
-            else:
-                ErrorMsg(eNOROOTRENAME)
-
-            # Incrementally build lists of keys that will later be
-            # used to create sequence renaming tokens
-
-            for seqtype in SeqTypes:
-
-                statflag, storage, order = seqtype
-
-                # Handle os.stat() values
-
-                if statflag:
-                    sortkey = stats[statflag]
-
-                # Handle group name values
-
-                elif order == ORDERBYGROUP:
-                    sortkey = self.__GetFileGroupname(fullname)
-
-                # Handle user name values
-
-                elif order == ORDERBYUSER:
-                    sortkey = self.__GetFileUsername(fullname)
-
-                # Save into storage
-                    
-                if sortkey in storage:
-                    storage[sortkey].append(fullname)
-                else:
-                    storage[sortkey] = [fullname]
-
-
-        # Create the various sorted views we may need for sequence
-        # renaming tokens
-
-        for seqtype in SeqTypes:
-
-            statflag, storage, order = seqtype
-
-            vieworder = storage.keys()
-            vieworder.sort()            
-
-            # Sort alphabetically when multiple filenames
-            # map to the same key, creating overall
-            # ordering as we go.
-
-            t = []
-            for i in vieworder:
-                storage[i].sort()
-                for j in storage[i]:
-                    t.append(j)
-
-            # Now store for future reference
-
-            self.SortViews[order] = t
-
-        # Release the working data structures
-
-        del SeqTypes
-
-        # Now build the special cases of ordering by time within date
-        # for each of the timestamp types.
-
-        for dateorder, timeorder, year, mon, day in ((ORDERBYADATE, ORDERBYATIME,
-                                                      FILETIMETOKS[TOKAYEAR],
-                                                      FILETIMETOKS[TOKAMON],
-                                                      FILETIMETOKS[TOKADAY]),
-                                               
-                                                     (ORDERBYCDATE, ORDERBYCTIME,
-                                                      FILETIMETOKS[TOKCYEAR],
-                                                      FILETIMETOKS[TOKCMON],
-                                                      FILETIMETOKS[TOKCDAY]),
-
-                                                     (ORDERBYMDATE, ORDERBYMTIME,
-                                                      FILETIMETOKS[TOKMYEAR],
-                                                      FILETIMETOKS[TOKMMON],
-                                                      FILETIMETOKS[TOKMDAY])):
-                                               
-
-            lastdate = ""
-            for fullname in self.SortViews[timeorder]:
-
-                targettime = eval("time.localtime(self.RenNames[fullname][STATS][%s])" % year[1])
-
-                newdate = year[0] % eval("targettime.%s" % year[2]) + \
-                          mon[0]  % eval("targettime.%s" % mon[2]) + \
-                          day[0]  % eval("targettime.%s" % day[2])
-
-                key = dateorder+newdate
-
-                # New file date encountered
-
-                if newdate != lastdate:
-
-                    self.DateViews[key] = [fullname]
-                    lastdate = newdate
-                    
-                # Add file to existing list of others sharing that date
-
-                else:
-                    self.DateViews[key].append(fullname)
-
-    # End of '__init__()'
-
-
-    #####
-    # Debug Dump 
-    #####
-
-    def DumpObj(self):
-
-        SEPARATOR = dSEPCHAR * ProgramOptions[MAXLINELEN]
-        DebugMsg("\n")
-        DebugMsg(SEPARATOR)
-        DebugMsg(dDUMPOBJ % str(self))
-        DebugMsg(SEPARATOR)
-
-
-        # Dump the RenNames and SortView dictionaries
-
-        for i, msg in ((self.RenNames, dRENTARGET), (self.SortViews, dSORTVIEW), (self.DateViews, dDATEVIEW)):
-
-            for j in i:
-                DumpList(msg, j, i[j])
-
-        for rr in self.RenRequests:
-            DumpList(dRENREQ, "", rr)
-
-        DebugMsg(SEPARATOR + "\n\n")
-
-    # End of 'DumpObj()'
-
-
-    #####
-    # Determine File's Group Name
-    #####
-
-    def __GetFileGroupname(self, fullname):
-        
-        if POSIX:
-            return grp.getgrgid(self.RenNames[fullname][STATS][ST_GID])[0]
-
-        else:
-            retval = WINDOWSGROUP
-
-            if WIN32ALL:
-
-                try:
-                    # Get the internal Win32 security group information for this file.
-
-                    hg     = GetFileSecurity(fullname, GROUP_SECURITY_INFORMATION)
-                    sidg   = hg.GetSecurityDescriptorGroup()
-
-                    # We have to know who is hosting the filesystem for this file
-
-                    drive = fullname[0:3]
-                    if GetDriveType(drive) == win32con.DRIVE_REMOTE:
-                        fnhost = WNetGetUniversalName(drive, 1).split('\\')[2]
-
-                    else:
-                        fnhost = WIN32HOST
-
-                    # Now we can translate the sids into names
-
-                    retval  = LookupAccountSid(fnhost, sidg)[0]
-
-                # On any error, just act like win32all isn't there
-                    
-                except:
-                    retval = WINGROUPNOT
-
-            return retval
-
-    # End of 'GetFileGroupname()'
-
-
-    #####
-    # Determine File's User Name
-    #####
-
-    def __GetFileUsername(self, fullname):
-
-        if POSIX:
-            return pwd.getpwuid(self.RenNames[fullname][STATS][ST_UID])[0]
-
-        else:
-            retval = WINDOWSUSER
- 
-            if WIN32ALL:
-
-                try:
-
-                    # Get the internal Win32 security information for this file.
-
-                    ho     = GetFileSecurity(fullname, OWNER_SECURITY_INFORMATION)
-                    sido   = ho.GetSecurityDescriptorOwner()
-
-                    # We have to know who is hosting the filesystem for this file
-
-                    drive = fullname[0:3]
-                    if GetDriveType(drive) == win32con.DRIVE_REMOTE:
-                        fnhost = WNetGetUniversalName(drive, 1).split('\\')[2]
-
-                    else:
-                        fnhost = WIN32HOST
-
-                    # Now we can translate the sids into names
-
-                    retval  = LookupAccountSid(fnhost, sido)[0]
-
-                # On any error, just act like win32all isn't there
-                    
-                except:
-                    retval = WINUSERNOT
-
-            return retval
-
-    # End of 'GetFileUsername()'
-
-
-    #####
-    # Go Do The Requested Renaming
-    #####
-
-    def ProcessRenameRequests(self):
-
-        global RenSequence
-        self.indentlevel = -1
-
-        # Create a list of all renaming to be done.
-        # This includes the renaming of any existing targets.
-
-        for target in self.SortViews[ORDERBYCMDLINE]:
-
-            oldname, pathname = self.RenNames[target][BASE], self.RenNames[target][PATHNAME]
-            newname = oldname
-
-            # Keep track of incremental renaming for use by debug
-            RenSequence = [oldname]
-            
-            for renrequest in self.RenRequests:
-                
-                # Select portion of name targeted for renaming
-
-                lname = ""
-                rname = ""
-                tstart = renrequest[TARGETSTART]
-                tend   = renrequest[TARGETEND]
-
-                # Condition values so that range slicing works properly below.
-                # This couldn't be done at the time the target range was
-                # saved intially, because the length of the name being processed
-                # isn't known until here.
-                
-                if tstart == None:
-                    tstart = 0
-
-                if tend == None:
-                    tend = len(newname)
-                    
-                if tstart or tend:
-
-                    bound = len(newname)
-                        
-                    # Normalize negative refs so we can use consistent
-                    # logic below
-
-                    if tstart < 0:
-                        tstart = bound + tstart
-
-                    if (tend != SINGLEINST and tend < 0):
-                        tend = bound + tend
-
-                    # Condition and bounds check the target range as needed
-
-                    # Handle single position references
-                    if (tend == SINGLEINST):
-
-                        # Select the desired position.  Notice that
-                        # out-of-bounds references are ignored and the
-                        # name is left untouched.  This is so the user
-                        # can specify renaming operations on file
-                        # names of varying lengths and have them apply
-                        # only to those files long enough to
-                        # accommodate the request without blowing up
-                        # on the ones that are not long enough.
-
-                        if 0 <= tstart < bound:
-                            lname, newname, rname = newname[:tstart], newname[tstart], newname[tstart+1:]
-
-                        # Reference is out of bounds - leave name untouched
-
-                        else:
-                            lname, newname, rname = newname, "", ""
-
-                    # Handle slice range requests
-
-                    else:
-
-                        # Out-Of-Bounds or invalid slice ranges will
-                        # cause renaming request to be ignored as above
-
-                        if newname[tstart:tend]:
-                            lname, newname, rname = newname[:tstart], newname[tstart:tend], newname[tend:]
-
-                        else:
-                            lname, newname, rname = newname, "", ""                            
-                    
-
-                # Handle conventional string replacement renaming requests
-                # An empty newname here means that the -T argument processing
-                # selected a new string and/or was out of bounds -> we ignore the request.
-
-                if newname and (renrequest[OLD] or renrequest[NEW]):
-
-                    # Resolve any embedded renaming tokens
-
-                    old = self.__ResolveRenameTokens(target, renrequest[OLD])
-                    new = self.__ResolveRenameTokens(target, renrequest[NEW])
-
-                    oldstrings = []
-
-                    # Build a list of indexes to every occurence of the old string,
-                    # taking case sensitivity into account
-
-                    # Handle the case when old = "".  This means to
-                    # *replace the entire* old name with new.  More
-                    # specifically, replace the entire old name *as
-                    # modified so far by preceding rename commands*.
-
-                    if not old:
-                        old = newname
-
-                    # Find every instance of the 'old' string in the
-                    # current filename.  'Find' in this case can be either
-                    # a regular expression pattern match or a literal
-                    # string match.  
-                    #
-                    # Either way, each 'hit' is recorded as a tuple:
-                    #
-                    #    (index to beginning of hit, beginning of next non-hit text)
-                    #
-                    # This is so subsequent replacement logic knows:
-                    #
-                    #    1) Where the replacement begins
-                    #    2) Where the replacement ends
-                    #
-                    # These two values are used during actual string
-                    # replacement to properly replace the 'new' string
-                    # into the requested locations.
-
-
-                    # Handle regular expression pattern matching
-
-                    if renrequest[REGEX]:
-
-                        try:
-                            # Do the match either case-insentitive or not
-
-                            if renrequest[CASESENSITIVE]:
-                                rematches = re.finditer(old, newname)
-
-                            else:
-                                rematches = re.finditer(old, newname, re.I)
-
-                            # And save off the results
-
-                            for match in rematches:
-                                oldstrings.append(match.span())
-
-                        except:
-                            ErrorMsg(eBADREGEX % old)
-
-                    # Handle literal string replacement
-
-                    else:
-
-                        searchtarget = newname
-                        
-                        # Collapse case if requested
-                        
-                        if not renrequest[CASESENSITIVE]:
-
-                            searchtarget = searchtarget.lower()
-                            old  = old.lower()
-
-                        oldlen = len(old)
-                        i = searchtarget.find(old)
-                        while i >= 0:
-
-                            nextloc = i + oldlen
-                            oldstrings.append((i, nextloc))
-                            i = searchtarget.find(old, nextloc)
-
-                    # If we found any matching strings, replace them
-
-                    if oldstrings:
-
-                        # But only process the instances the user asked for
-
-                        todo = []
-
-                        # Handle single instance requests doing bounds checking as we go
-
-                        start = renrequest[INSTANCESTART]
-                        end   = renrequest[INSTANCEEND]
-
-                        if (end == SINGLEINST):
-
-                            # Compute bounds for positive and negative indicies.
-                            # This is necessary because positive indicies are 0-based,
-                            # but negative indicies start at -1.
-
-                            bound = len(oldstrings)
-
-                            if start < 0:
-                                bound += 1
-
-                            # Now go get that entry
-
-                            if abs(start) < bound:
-                                todo.append(oldstrings[start])
-
-                        # Handle instance range requests
-
-                        else:
-                            todo = oldstrings[start:end]
-
-
-                        # Replace selected substring(s).  Substitute from
-                        # R->L in original string so as not to mess up the
-                        # replacement indicies.
-
-                        todo.reverse()
-                        for i in todo:
-                            newname = newname[:i[0]] + new + newname[i[1]:]
-
-
-                # Handle case conversion renaming requests
-                    
-                elif renrequest[CASECONV]:
-                    newname = CASETBL[renrequest[CASECONV]](newname)
-
-                # Any subsequent replacements operate on the modified name
-                # which is reconstructed by combining what we've renamed
-                # with anything that was excluded from the rename operation.
-
-                newname = lname + newname + rname
-
-                # Keep track of incremental renaming for use by debug
-                RenSequence.append(newname)
-                                
-            # Show the incremental renaming steps if debug is on
-
-            if ProgramOptions[DEBUG]:
-                DebugMsg(dRENSEQ % ARROW.join(RenSequence))
-
-            # Nothing to do, if old- and new names are the same
-
-            if newname != oldname:
-                self.__RenameIt(pathname, oldname, newname)
-            
-    # End of 'ProcessRenameRequests()'
-
-
-    #####
-    # Actually Rename A File
-    #####
-
-    def __RenameIt(self, pathname, oldname, newname):
-
-        self.indentlevel += 1
-        indent = self.indentlevel * INDENT
-        newlen = len(newname)
-        
-        # First make sure the new name meets length constraints
-
-        if newlen < MINNAMELEN:
-            ErrorMsg(indent + eNAMESHORT% (oldname, newname, MINNAMELEN))
-            return
-
-        if newlen > MAXNAMELEN:
-            ErrorMsg(indent + eNAMELONG % (oldname, newname, MAXNAMELEN))
-            return
-
-        # Get names into absolute path form
-
-        fullold = pathname + oldname
-        fullnew = pathname + newname
-
-        # See if our proposed renaming is about to stomp on an
-        # existing file, and create a backup if forced renaming
-        # requested.  We do such backups with a recursive call to
-        # ourselves so that filename length limits are observed and
-        # backups-of-backups are preserved.
-
-        doit = True
-        newexists = os.path.exists(fullnew)
-
-        if (not ProgramOptions[TESTMODE] and newexists) or \
-           (ProgramOptions[TESTMODE] and fullnew not in self.RenamedFiles and (newexists or fullnew in self.NewFiles)):
-
-            if ProgramOptions[FORCERENAME]:
-
-                # Create the backup unless we've been told not to
-
-                if ProgramOptions[BACKUPS]:
-
-                    bkuname = newname + ProgramOptions[EXISTSUFFIX]
-                    InfoMsg(indent + iRENFORCED % fullnew)
-                    self.__RenameIt(pathname, newname, bkuname)
-
-                else:
-                    InfoMsg(iFORCEDNOBKU % (fullold, fullnew))
-                
-            else:
-                InfoMsg(indent + iRENSKIPPED % (fullnew, fullold))
-                doit = False
-
-        if doit:
-
-            if ProgramOptions[ASK]:
-
-                answer = ""
-                while answer.lower() not in [ASKNO.lower(), ASKYES.lower(), ASKDOREST.lower(), ASKQUIT.lower()]:
-
-                    PrintStdout("Rename %s to %s? [%s]: " % (fullold, fullnew, ASKNO+ASKYES+ASKDOREST+ASKQUIT), TRAILING="")
-
-                    answer = sys.stdin.readline().lower().strip()
-
-                    # A blank line means take the default - do nothing.
-
-                    if not answer:
-                        answer = ASKNO.lower()
-                        
-                if answer == ASKNO.lower():
-                    doit = False
-
-                if answer == ASKYES.lower():
-                    doit = True
-
-                if answer == ASKDOREST.lower():
-                    doit = True
-                    ProgramOptions[ASK] = False
-
-                if answer == ASKQUIT.lower():
-                    sys.exit(1)
-
-            if doit:
-                
-                # In test mode, track file names that would be produced.
-                
-                if ProgramOptions[TESTMODE]:
-
-                    self.NewFiles.append(fullnew)
-                    self.RenamedFiles.append(fullold)
-                    
-                    if fullold in self.NewFiles:
-                        self.NewFiles.remove(fullold)
-                    
-                    if fullnew in self.RenamedFiles:
-                        self.RenamedFiles.remove(fullnew)
-
-                InfoMsg(indent + iRENAMING % (fullold, fullnew))
-
-                if not ProgramOptions[TESTMODE]:
-
-                    try:
-                        os.rename(fullold, fullnew)
-                    except OSError, (errno, errstr):
-                        ErrorMsg(eRENAMEFAIL % (fullold, fullnew, errstr))
-
-        self.indentlevel -= 1
-
-    # End of '__RenameIt()'
-
-    
-    #####
-    # Resolve Rename Tokens
-    #####
-
-    """ This replaces all renaming token references in 'renstring'
-        with the appropriate content and returns the resolved string.
-        'target' is the name of the current file being renamed.  We
-        need that as well because some renaming tokens refer to file
-        stat attributes or even the file name itself.
-    """
-
-    def __ResolveRenameTokens(self, target, renstring):
-
-        # Find all token delimiters but ignore any that might appear
-        # inside a command execution replacement token string.
-
-        rentokens = []
-        odd = True
-        incmdexec = False
-
-        i=0
-        while i < len(renstring):
-
-            if renstring[i] == TOKCMDEXEC:
-                incmdexec = not incmdexec
-
-            elif renstring[i] == TOKDELIM:
-
-                if incmdexec:
-                    pass
-
-                elif odd:
-
-                    rentokens.append([i])
-                    odd = not odd
-
-                else:
-
-                    rentokens[-1].append(i)
-                    odd = not odd
-
-
-            i += 1
-
-        # There must be an even number of token delimiters
-        # or the renaming token is malformed
-
-        if rentokens and  len(rentokens[-1]) != 2:
-            ErrorMsg(eTOKDELIM % renstring)
-
-        # Now add the renaming token contents.  This will be used to
-        # figure out what the replacement text should be.
-
-        i = 0
-        while i < len(rentokens):
-
-            rentokens[i].append(renstring[rentokens[i][0]+1 : rentokens[i][1]])
-            i += 1
-
-        # Process each token.  Work left to right so as not to mess up
-        # the previously stored indexes.
-
-        rentokens.reverse()
-
-        for r in rentokens:
-
-            fullrentoken = "%s%s%s" % (TOKDELIM, r[2], TOKDELIM)  # Need this for error messages.
-        
-            ###
-            # File Attribute Renaming Tokens
-            ###
-
-            if r[2] == TOKFILDEV:
-                r[2] = str(self.RenNames[target][STATS][ST_DEV])
-                
-            elif r[2] == TOKFILFNAME:
-                r[2] = os.path.basename(target)
-
-            elif r[2] == TOKFILGID:
-                r[2] = str(self.RenNames[target][STATS][ST_GID])
-
-            elif r[2] == TOKFILGROUP:
-                r[2] = self.__GetFileGroupname(target)
-
-            elif r[2] == TOKFILINODE:
-                r[2] = str(self.RenNames[target][STATS][ST_INO])
-
-            elif r[2] == TOKFILMODE:
-                r[2] = str(self.RenNames[target][STATS][ST_MODE])
-
-            elif r[2] == TOKFILNLINK:
-                r[2] = str(self.RenNames[target][STATS][ST_NLINK])
-
-            elif r[2] == TOKFILSIZE:
-                r[2] = str(self.RenNames[target][STATS][ST_SIZE])
-
-            elif r[2] == TOKFILUID:
-                r[2] = str(self.RenNames[target][STATS][ST_UID])
-
-            elif r[2] == TOKFILUSER:
-                r[2] = self.__GetFileUsername(target)
-                
-
-            ###
-            # File Time Renaming Tokens
-            ###
-
-            elif r[2] in FILETIMETOKS:
-
-                parms = FILETIMETOKS[r[2]]
-                val   = eval("time.localtime(self.RenNames[target][STATS][%s]).%s" % (parms[1], parms[2]))
-
-                # The first value of FILETIMETOKS table entry
-                # indicates the formatting string to use (if the entry
-                # is non null), or that we're doing a lookup for the
-                # name of a month (if the entry is null)
-
-                if parms[0]:
-                    r[2] = parms[0] % val
-
-                elif parms[2] == "tm_mon":
-                    r[2] = MONTHS[val]
-
-                elif parms[2] == "tm_wday":
-                    r[2] = DAYS[val]
-                
-            ###
-            # System Renaming Tokens
-            ###
-            
-            # Environment Variable replacement token
-            
-            elif r[2].startswith(TOKENV):
-
-                r[2] = os.getenv(r[2][1:])
- 
-                # Handle case for nonexistent environment variable
-                
-                if not r[2]:
-                    r[2] = ""
-               
-            
-            # Command Run replacement token
-
-            elif r[2].startswith(TOKCMDEXEC) and r[2].endswith(TOKCMDEXEC):
-
-                command = r[2][1:-1]
-
-                # Handle Windows variants - they act differently
-
-                if not POSIX:
-                    pipe = os.popen(command, 'r')
-
-                # Handle Unix variants
-
-                else: 
-                    pipe = os.popen('{ ' + command + '; } 2>&1', 'r')
-
-                output = pipe.read()
-                status = pipe.close()
-
-                if status == None:
-                    status = 0
-
-                # Nonzero status means error attempting to execute the command
-                    
-                if status:
-                    ErrorMsg(eEXECFAIL % (fullrentoken, command))
-
-                # Otherwise swap the command with its results, stripping newlines
-                    
-                else:
-                    r[2] = output.replace("\n", "")
-
-
-            # Random Number Replacement token
-                    
-            elif r[2].startswith(TOKRAND):
-
-                random.seed()
-
-                # Figure out how many digits of randomness the user want
-
-                try:
-                    precision = r[2].split(TOKRAND)[1]
-                    precision = int(precision)
-
-                except:
-                    ErrorMsg(eTOKRANDIG % fullrentoken)
-
-                if precision < 1:
-                    ErrorMsg(eTOKRANDIG % fullrentoken)
-                    
-                fmt =  '"%0' + str(precision) + 'd" % random.randint(0, pow(10, precision)-1)'
-                r[2] = eval(fmt)
-
-            # Name So Far Replacement Token
-
-            elif r[2] == (TOKNAMESOFAR):
-                r[2] = RenSequence[-1]
-
-            ###
-            # Sequence Renaming Tokens
-            ###
-                    
-            elif r[2] and (r[2][0] == TOKASCEND or r[2][0] == TOKDESCEND):
-
-                # Parse the Sequence Renaming Token into the token itself
-                # and its corresponding formatting field.
-
-                # Note that the a legal Sequence Renaming Token will either
-                # be one of the keys of the SortViews dictionary or one
-                # of the "ORDERBYnDATE" orderings.
-
-                token = r[2][1:]
-
-                found = False
-                for seqtoken in self.SortViews.keys() + [ORDERBYADATE, ORDERBYCDATE, ORDERBYMDATE]:
-
-                    if token.split(ALPHADELIM)[0] == (seqtoken):
-
-                        token, field = token[:len(seqtoken)], token[len(seqtoken):]
-                        found = True
-                        break
-
-                if not found:
-                    ErrorMsg(eTOKBADSEQ % fullrentoken)
-
-                # Now derive the name of the alphabet to use
-
-                if not field.startswith(ALPHADELIM):
-                    ErrorMsg(eALPHABETMISSING % fullrentoken)
-
-                field = field[1:]
-
-                alphabet, alphadelim, field = field.partition(ALPHADELIM)
-
-                if not alphadelim:
-                    ErrorMsg(eALPHABETMISSING % fullrentoken)
-
-                # Empty alphabet string means default to decimal counting
-                    
-                if not alphabet:
-                    alphabet = DECIMAL
-                    
-                if alphabet not in ALPHABETS:
-                    ErrorMsg(eALPHABETEXIST % fullrentoken)
-
-
-                # Retrieve the ordered list of the requested type,
-                # adjust for descending order, and plug in the
-                # sequence number for the current renaming target
-                # (which is just the index of that filename in the
-                # list).
-
-                # One of the standard sorted views requested
-                    
-                if token in self.SortViews:
-                    orderedlist = self.SortViews[token][:]
-
-                # One of the views sorted within dates requested
-
-                else:
-
-
-                    if token == ORDERBYADATE:
-                        year, mon, day = FILETIMETOKS[TOKAYEAR], FILETIMETOKS[TOKAMON], FILETIMETOKS[TOKADAY]
-
-                    elif token == ORDERBYCDATE:
-                        year, mon, day = FILETIMETOKS[TOKCYEAR], FILETIMETOKS[TOKCMON], FILETIMETOKS[TOKCDAY]
-
-                    elif token == ORDERBYMDATE:
-                        year, mon, day = FILETIMETOKS[TOKMYEAR], FILETIMETOKS[TOKMMON], FILETIMETOKS[TOKMDAY]
-
-                    targettime = eval("time.localtime(self.RenNames[target][STATS][%s])" % year[1])
-
-                    key = token + \
-                          year[0] % eval("targettime.%s" % year[2]) + \
-                          mon[0]  % eval("targettime.%s" % mon[2]) + \
-                          day[0]  % eval("targettime.%s" % day[2])
-
-                    orderedlist = self.DateViews[key][:]
-
-                if r[2][0] == TOKDESCEND:
-                    orderedlist.reverse()
-
-                r[2] = ComputeSeqString(field, orderedlist.index(target), ALPHABETS[alphabet])
-
-            ###
-            # Unrecognized Renaming Token
-            ###
-                    
-            else:
-                ErrorMsg(eTOKUNKNOWN % fullrentoken)
-                    
-            ###
-            # Successful Lookup, Do the actual replacement
-            ###
-
-            renstring = renstring[:r[0]] + r[2] + renstring[r[1]+1:]
-            
-        return renstring
-
-    # End of '__ResolveRenameTokens()'
-
-
-# End of class 'RenameTargets'
-    
-
-#----------------------------------------------------------#
-#             Supporting Function Definitions              #
-#----------------------------------------------------------#
-
-
-#####
-# Check For Correct Slice Syntax
-#####
-
-def CheckSlice(val):
-
-    try:
-
-        # Process ranges
-
-        if val.count(RANGESEP):
-
-            lhs, rhs = val.split(RANGESEP)
-
-            if not lhs:
-                lhs = None
-
-            else:
-                lhs = int(lhs)
-
-            if not rhs:
-                rhs = None
-
-            else:
-                rhs = int(rhs)
-
-        # Process single indexes
-
-        else:
-
-            lhs = int(val)
-            rhs = SINGLEINST
-
-    # Something about the argument was bogus
-
-    except:
-        ErrorMsg(eBADSLICE % val)
-
-    return (lhs, rhs)
-
-# End Of 'CheckSlice()'
-
-
-#####
-# Turn A List Into Columns With Space Padding
-#####
-
-def ColumnPad(list, PAD=PADCHAR, WIDTH=PADWIDTH):
-
-    retval = ""
-    for l in list:
-        l = str(l)
-        retval += l + ((WIDTH - len(l)) * PAD)
-
-    return retval
-
-# End of 'ColumnPad()'
-
-
-def ComputeSeqString(fmt, incr, alphabet):
-
-    """ 
-        fmt      = A literal "format field" string
-        incr     = A integer to be "added" to the field
-        alphabet = The alphabet of characters to use, in ascending order
-
-        Add 'incr' to 'fmt' in base(len(alphabet)).  Characters in
-        'fmt' that are not in 'alphabet' are ignored in this addition.
-
-        The final result is limited to be no longer than 'fmt'.  Any
-        result longer than fmt has MSD dropped, thereby effectively
-        rolling over the count.  If 'fmt' is null on entry, the final
-        result length is unlimited.
-    """
-       
-    base     = len(alphabet)
-
-    # Do position-wise "addition" via symbol substitution moving from
-    # right-to-left adjusting for the fact that not all symbols in the
-    # format string will be in the alphabet.
-    
-
-    # First convert the increment into a string in the base of the
-    # alphabet
-
-    idigits = []
-    while incr >  base-1:
-
-        incr, digit = incr/base, incr % base
-        idigits.append(alphabet[digit])
-
-    idigits.append(alphabet[incr])
-    idigits.reverse()
-    incr = "".join(idigits)
-
-    # Now do right-to-left digit addition with the format
-    # field.
-
-    # Do position-wise "addition" via symbol substitution moving from
-    # right-to-left.  Take into account that the format pattern string
-    # may be a different length than the increment string and that not
-    # all characters in the format pattern are guaranteed to exist in
-    # the alphabet.
-
-    newval   = ""
-    carry    = None
-    fmtlen   = len(fmt)
-    incrlen  = len(incr)
-    calcsize = max(fmtlen, incrlen)
-
-    i = -1
-    done = False
-    while abs(i) <= calcsize and not done:
-
-        sum = 0
-
-        if carry:
-            sum += carry
-
-        if fmt and (abs(i) <= fmtlen) and fmt[i] in alphabet:
-            sum +=  alphabet.index(fmt[i])
-
-        if abs(i) <= incrlen:
-            sum += alphabet.index(incr[i])
-
-        # Do arithmetic modulo alphabet length
-            
-        carry, digit = sum/base, sum % base
-
-        if not carry:
-            carry = None
-
-            # We're completely done if we're out of digits in incr and
-            # there's no carry to propagate.  This prevents us from
-            # tacking on leading 0th characters which could overwrite
-            # out-of-alphabet characters in the format field.
-
-            if abs(i-1) > incrlen:
-                done =True
-
-        newval = alphabet[digit] + newval
-
-        i -= 1
-
-    if carry:
-        newval = alphabet[carry] + newval
-
-    # Constrain the results to the length of the original format
-    # string, rolling over and warning the user as necessary.  The one
-    # exception to this is when a null format string is passed.  This
-    # is understood to mean that sequences of any length are
-    # permitted.
-
-    # Result length constrained by format string
-
-    if fmtlen:
-        
-        if len(newval) > fmtlen:
-            InfoMsg(iSEQTOOLONG % (newval,fmt))
-            newval = newval[-fmtlen:]
-
-        return  fmt[:-len(newval)] + newval
-
-    # Any length result permitted
-
-    else:
-        return newval
-
-# End of 'ComputeSeqString()'
-
-
-#####
-# Condition Line Length With Fancy Wrap And Formatting
-#####
-
-def ConditionLine(msg, 
-                  PAD=PADCHAR, \
-                  WIDTH=PADWIDTH, \
-                  wrapindent=WRAPINDENT ):
-
-    retval = []
-    retval.append(msg[:ProgramOptions[MAXLINELEN]])
-    msg = msg[ProgramOptions[MAXLINELEN]:]
-
-    while msg:
-        msg = PAD * (WIDTH + wrapindent) + msg
-        retval.append(msg[:ProgramOptions[MAXLINELEN]])
-        msg = msg[ProgramOptions[MAXLINELEN]:]
-
-    return retval
-
-# End of 'ConditionLine()'
-
-
-#####
-# Print A Debug Message
-#####
-
-def DebugMsg(msg):
- 
-   l = ConditionLine(msg)
-   for msg in l:
-        PrintStderr(PROGNAME + " " + dDEBUG + ": " + msg)
-
-# End of 'DebugMsg()'
-
-
-#####
-# Debug Dump Of A List
-#####
-
-def DumpList(msg, listname, content):
-
-    DebugMsg(msg)
-    itemarrow = ColumnPad([listname, " "], WIDTH=LSTPAD)
-    DebugMsg(ColumnPad([" ", " %s %s" % (itemarrow, content)]))
-
-# End of 'DumpList()'
-
-
-#####
-# Dump The State Of The Program
-#####
-
-def DumpState():
-
-    SEPARATOR = dSEPCHAR * ProgramOptions[MAXLINELEN]
-    DebugMsg(SEPARATOR)
-    DebugMsg(dCURSTATE)
-    DebugMsg(SEPARATOR)
-
-    opts = ProgramOptions.keys()
-    opts.sort()
-    for o in opts:
-        DebugMsg(ColumnPad([o, ProgramOptions[o]]))
-
-    DumpList(dALPHABETS, "", ALPHABETS)
-
-    DebugMsg(SEPARATOR)
-
-
-# End of 'DumpState()'
-
-
-#####
-# Print An Error Message And Exit
-#####
-
-def ErrorMsg(emsg):
-
-    l = ConditionLine(emsg)
-
-    for emsg in l:
-        PrintStderr(PROGNAME + " " + eERROR + ": " + emsg)
-
-    sys.exit(1)
-
-# End of 'ErrorMsg()'
-
-
-#####
-# Split -r Argument Into Separate Old And New Strings
-#####
-
-def GetOldNew(arg):
-
-
-    escaping = False
-    numseps  = 0 
-    sepindex = 0
-    oldnewsep = ProgramOptions[RENSEP]
-
-    i = 0
-    while i < len(arg):
-
-        # Scan string ignoring escaped separators
-
-        if arg[i:].startswith(oldnewsep):
-
-            if (i > 0 and (arg[i-1] != ProgramOptions[ESCAPE])) or i == 0:
-                sepindex = i
-                numseps += 1
-            
-            i += len(oldnewsep)
-
-        else:
-            i += 1
-
-
-    if numseps != 1:
-        ErrorMsg(eBADNEWOLD % arg)
-
-    else:
-        old, new = arg[:sepindex], arg[sepindex + len(oldnewsep):]
-        old = old.replace(ProgramOptions[ESCAPE] + oldnewsep, oldnewsep)
-        new = new.replace(ProgramOptions[ESCAPE] + oldnewsep, oldnewsep)
-        return [old, new]
-
-# End of 'GetOldNew()'
-
-
-#####
-# Print An Informational Message
-#####
-
-def InfoMsg(imsg):
-
-    l = ConditionLine(imsg)
-
-    msgtype = ""
-    if ProgramOptions[TESTMODE]:
-        msgtype = TESTMODE
-
-    if not ProgramOptions[QUIET]:
-        for msg in l:
-            PrintStdout(PROGNAME + " " + msgtype + ": " + msg)
-
-# End of 'InfoMsg()'
-
-
-#####
-# Print To stderr
-#####
-
-def PrintStderr(msg, TRAILING="\n"):
-    sys.stderr.write(msg + TRAILING)
-
-# End of 'PrintStderr()'
-
-
-#####
-# Print To stdout
-#####
-
-def PrintStdout(msg, TRAILING="\n"):
-    sys.stdout.write(msg + TRAILING)
-
-# End of 'PrintStdout()'
-
-
-#####
-# Process Include Files On The Command Line
-#####
-
-def ProcessIncludes(OPTIONS):
-
-    """ Resolve include file references allowing for nested includes.
-        This has to be done here separate from the command line
-        options so that normal getopt() processing below will "see"
-        the included statements.
-
-        This is a bit tricky because we have to handle every possible
-        legal command line syntax for option specification:
-
-          -I filename
-          -Ifilename
-          -....I filename
-          -....Ifilename
-    """
-
-    # Build a list of all the options that take arguments.  This is
-    # needed to determine whether the include symbol is an include
-    # option or part of an argument to a preceding option.
-
-    OPTIONSWITHARGS = ""
-    for i in re.finditer(":", OPTIONSLIST):
-        OPTIONSWITHARGS += OPTIONSLIST[i.start() - 1]
-
-    NUMINCLUDES = 0
-    FoundNewInclude = True
-
-    while FoundNewInclude:
-
-        FoundNewInclude = False
-        i = 0
-        while i < len(OPTIONS):
-
-            # Detect all possible command line include constructs,
-            # isolating the requested filename and replaciing its
-            # contents at that position in the command line.
-
-            field = OPTIONS[i]
-            position = field.find(INCL)
-            
-            if field.startswith(OPTINTRO) and (position > -1):
-
-                
-                lhs = field[:position]
-                rhs = field[position+1:]
-
-                # Make sure the include symbol isn't part of some
-                # previous option argument
-
-                previousopt = False
-                for c in OPTIONSWITHARGS:
-
-                    if c in lhs:
-
-                        previousopt = True
-                        break
-                    
-                # If the include symbol appears in the context of a
-                # previous option, skip this field, otherwise process
-                # it as an include.
-
-
-                if not previousopt:
-                    
-                    FoundNewInclude = True
-                    if lhs == OPTINTRO:
-                        lhs = ""
-
-                    if rhs == "":
-
-                        if i < len(OPTIONS)-1:
-
-                            inclfile = OPTIONS[i+1]
-                            OPTIONS = OPTIONS[:i+1] + OPTIONS[i+2:]
-
-                        # We have an include without a filename at the end
-                        # of the command line which is bogus.
-                        else:
-                            ErrorMsg(eBADARG % eBADINCL)
-
-                    else:
-                        inclfile = rhs
-
-                    # Before actually doing the include, make sure we've
-                    # not exceeded the limit.  This is here mostly to make
-                    # sure we stop recursive/circular includes.
-
-                    NUMINCLUDES += 1
-                    if NUMINCLUDES > MAXINCLUDES:
-                        ErrorMsg(eTOOMANYINC)
-
-                    # Read the included file, stripping out comments
-
-                    # Use include path if one was provided
-
-                    inclpath = os.getenv(INCLENV)
-                    if inclpath:
-
-                        found = searchpath(inclfile, inclpath, PATHDEL)
-                        if found:
-                            inclfile = found[0]
-
-                    try:
-                        n = []
-                        f = open(inclfile)
-                        for line in f.readlines():
-                            line = line.split(COMMENT)[0]
-                            n += shlex.split(line)
-                        f.close()
-
-                        # Keep track of the filenames being included for debug output
-
-                        IncludedFiles.append(os.path.abspath(inclfile))
-
-                        # Insert content of included file at current
-                        # command line position
-
-                        # A non-null left hand side means that there were
-                        # options before the include we need to preserve
-
-                        if lhs:
-                            n = [lhs] + n
-
-                        OPTIONS = OPTIONS[:i] + n + OPTIONS[i+1:]
-
-                    except IOError, (errno, errstr):
-                        ErrorMsg(eFILEOPEN % (inclfile, errstr))
-        
-            i += 1
-
-    return OPTIONS
-
-# End of 'ProcessIncludes()'
-
-
-#####
-# Search Path Looking For Include File
-#####
-
-def searchpath(filename, pathlist, pathdelim):
-
-    # What we'll return if we find nothing
-    
-    retval = []
-
-    # Find all instances of filename in specified paths
-
-    paths = pathlist.split(pathdelim)
-
-    for path in paths:
-
-        if path and path[-1] != PATHSEP:
-            path += PATHSEP
-
-        path += filename
-
-        if os.path.exists(path):
-            retval.append(os.path.realpath(path))
-
-    return retval
-
-# End of 'searchpath()'
-
-
-#####
-# Print Usage Information
-#####
-
-def Usage():
-    for line in uTable:
-        PrintStdout(line)
-
-# End of 'Usage()'
-
-
-#----------------------------------------------------------#
-#                    Program Entry Point                   #
-#----------------------------------------------------------#
-
-# Set up proper include path delimiter
-    
-
-if WINDOWS:
-    PATHDEL = PATHDELWIN
-
-else:
-    PATHDEL = PATHDELUNIX
-
-
-#####
-# Command Line Preprocessing
-# 
-# Some things have to be done *before* the command line
-# options can actually be processed.  This includes:
-#
-#  1) Prepending any options specified in the environment variable.
-#
-#  2) Resolving any include file references
-#
-#  3) Building the data structures that depend on the file/dir names
-#     specified for renaming.  We have to do this first, because
-#     -r renaming operations specified on the command line will
-#     need this information if they make use of renaming tokens.
-#
-#####
-
-# Process any options set in the environment first, and then those
-# given on the command line
-
-
-OPTIONS = sys.argv[1:]
-
-envopt = os.getenv(PROGENV)
-if envopt:
-    OPTIONS = shlex.split(envopt) + OPTIONS
-
-# Deal with include files
-
-OPTIONS = ProcessIncludes(OPTIONS)
-
-# And parse the command line
-
-try:
-    opts, args = getopt.getopt(OPTIONS, OPTIONSLIST)
-except getopt.GetoptError, (errmsg, badarg):
-    ErrorMsg(eBADARG % errmsg)
-
-# Create and populate an object with rename targets.  This must be
-# done here because this object also stores the -r renaming requests
-# we may find in the options processing below.  Also, this object must
-# be fully populated before any actual renaming can take place since
-# many of the renaming tokens derive information about the file being
-# renamed.
-
-
-# Do wildcard expansion on the rename targets because they may
-# have come from an include file (where they are not expanded)
-# or from a Windows shell that doesn't know how to handle globbing
-# properly.
-
-# If the glob expands to nothing, then supply the original string.
-# That way an error will be thrown if either an explicitly named file
-# does not exist, or if a wildcard expands to nothing.
-
-expandedlist = []
-for arg in args:
-
-    wc = glob.glob(arg)
-    if wc:
-        expandedlist += wc
-    else:
-        expandedlist.append(arg)
-
-targs = RenameTargets(expandedlist)
-
-# Now process the options
-
-for opt, val in opts:
-
-    # Install new alphabet
-
-    if opt == "-A":
-
-        alphaname, delim, alpha = val.partition(ALPHADELIM)
-
-        if not delim:
-            ErrorMsg(eALPHACMDBAD % val)
-
-        if not alphaname:
-            ErrorMsg(eALPHACMDBAD % val)
-
-        if len(alpha) < 2:
-            ErrorMsg(eALPHACMDLEN % val)
-
-        a = []
-        for c in alpha:
-            a.append(c)
-
-        ALPHABETS[alphaname] = a
-
-    if opt == "-a":
-        ProgramOptions[ASK] = True
-
-    # Turn off backups during forced renaming
-
-    if opt == "-b":
-        ProgramOptions[BACKUPS] = False
-
-    # Select case-sensitivity for replacements (or not)
-    
-    if opt == "-C":
-        ProgramOptions[CASESENSITIVE] = True
-
-    if opt == "-c":
-        ProgramOptions[CASESENSITIVE] = False
-
-    # Turn on debugging
-
-    if opt == "-d":
-        ProgramOptions[DEBUG] = True
-        DumpState()
-
-    # Force case conversion
-        
-    if opt == "-e":
-
-        # Make sure we support the requested case conversion
-        if val in CASEOPS:
-
-            ProgramOptions[CASECONV] = val
-
-            # Construct a renaming request
-            
-            req = {}
-            req[OLD], req[NEW] = None, None
-            for opt in ProgramOptions:
-                req[opt] = ProgramOptions[opt]
-
-            targs.RenRequests.append(req)
-
-        # Error out if we don't recognize it
-        else:
-            ErrorMsg(eBADCASECONV % (val, ", ".join(CASEOPS)))
-        
-
-    # Force renaming of existing targets
-
-    if opt == "-f":
-        ProgramOptions[FORCERENAME] = True
-
-    # Output usage information
-
-    if opt == "-h":
-        Usage()
-        sys.exit(0)
-
-    # Specify which instances to replace
-
-    if opt == "-i":
-
-        ProgramOptions[INSTANCESTART], ProgramOptions[INSTANCEEND] = CheckSlice(val)
-
-    # Set the escape character
-
-    if opt == "-P":
-        if len(val) == 1:
-            ProgramOptions[ESCAPE] = val
-        else:
-            ErrorMsg(eARGLENGTH % (NULLESC, 1))
-
-    # Set quiet mode
-            
-    if opt == "-q":
-        ProgramOptions[QUIET] = True
-
-    # Set the separator character for replacement specifications
-
-    if opt == '-R':
-        if len(val) == 1:
-            ProgramOptions[RENSEP] = val
-        else:
-            ErrorMsg(eARGLENGTH % (NULLRENSEP, 1))
-
-    # Specify a replacement command
-
-    if opt == "-r":
-        req = {}
-        req[OLD], req[NEW] = GetOldNew(val)
-        ProgramOptions[CASECONV] = None
-        for opt in ProgramOptions:
-            req[opt] = ProgramOptions[opt]
-        targs.RenRequests.append(req)
-
-    # Specify a renaming suffix
-
-    if opt == "-S":
-        if val:
-            ProgramOptions[EXISTSUFFIX] = val
-        else:
-            ErrorMsg(eNULLARG % NULLSUFFIX)
-
-    # Set substring targeted for renaming
-
-    if opt == "-T":
-        ProgramOptions[TARGETSTART], ProgramOptions[TARGETEND] = CheckSlice(val)
-
-    # Request test mode
-
-    if opt == "-t":
-        ProgramOptions[TESTMODE] = True
-
-
-    # Output program version info
-
-    if opt == "-v":
-        PrintStdout(RCSID)
-
-    # Set output width
-
-    if opt == "-w":
-        try:
-            l = int(val)
-        except:
-            ErrorMsg(eBADLEN % val)
-        if l < MINLEN:
-            ErrorMsg(eLINELEN)
-        ProgramOptions[MAXLINELEN] = l
-
-    # Select whether 'old' replacement string is a regex or not
-
-    if opt == "-X":
-        ProgramOptions[REGEX] = False
-
-    if opt == "-x":
-        ProgramOptions[REGEX] = True
-
-
-# At this point, the command line has been fully processed and the
-# container fully populated.  Provide debug info about both if
-# requested.
-
-if ProgramOptions[DEBUG]:
-
-    # Dump what we know about the command line
-
-    DumpList(dCMDLINE, "", sys.argv)
-    DumpList(dPROGENV, "", envopt)
-    DumpList(dRESOLVEDOPTS, "", OPTIONS)
-
-    # Dump what we know about included files
-
-    DumpList(dINCLFILES, "", IncludedFiles)
-
-    # Dump what we know about the container
-
-    targs.DumpObj()
-
-
-# Perform reqested renamings
-
-targs.ProcessRenameRequests()
-
-
-# Release the target container if we created one
-
-del targs
-