diff --git a/tconfpy.py b/tconfpy.py
index 55cb225..8286970 100755
--- a/tconfpy.py
+++ b/tconfpy.py
@@ -6,7 +6,7 @@
 # Program Information
 
 PROGNAME = "tconfpy"
-RCSID = "$Id: tconfpy.py,v 1.186 2005/01/13 10:36:24 tundra Exp $"
+RCSID = "$Id: tconfpy.py,v 1.187 2005/01/13 20:45:50 tundra Exp $"
 VERSION = RCSID.split()[2]
 
 # Copyright Information
@@ -158,52 +158,35 @@
 #----------------------------------------------------------#
 
 
-ALLOWNEWVAR   = True     # Allow new variable creation in cfg file
-TEMPLATES     = {}       # Place to hold variable templates
-TEMPONLY      = False    # Allow only template variable creation
-LITERALVARS   = False
-DEBUG         = False    # Control Debug output
-INLITERAL     = False    # Indicates we are currently in a literal block
-
-DebugMsg      = []       # Place to store and return debug info
-ErrMsgs       = []       # Place to store and return errors
-WarnMsgs      = []       # Place to store and return warnings
-LiteralLines  = []       # Place to store and return unprocessed lines
-
-
-CondStack     = [["", True,]]  # Conditional stack
-TotalLines    = 0        # Total number of lines parsed
-
-
-#####
-# Dummy Object Used To Return Parsing Results
-#####
-
-# This is done so the caller only needs to know the name of
-# each result set, not its position in the list of returned items
-
-
-class RetObj(object):
-
-    def __init__(self):
-        self.SymTable = {}
-        self.Errors   = []
-        self.Warnings = []
-        self.Debug    = []
-        self.Literals = []
-
-# End of 'RetObj'
-
-
 ##########
-# Symbol Table
+# Symbol Table Related Classes
 ##########
 
-# Symbol Table is a dictionary in the form:
+# Symbol Table is an object containing a dictionary in the form:
 #
 #  {varname : descriptor}
 #
-#  where the descriptor is an object with the following attributes
+
+class SymbolTable(object):
+
+    Symbols       = {}
+    DebugMsgs     = []
+    ErrMsgs       = []
+    WarnMsgs      = []
+    LiteralLines  = []
+    ALLOWNEWVAR   = True
+    TEMPLATES     = {}
+    TEMPONLY      = False
+    LITERALVARS   = False
+    INLITERAL     = False
+    DEBUG         = False
+    CondStack     = [["", True],]  # Always has one entry as a sentinel
+    TotalLines    = 0
+
+# End of class 'SymbolTable'
+
+
+# The descriptor is an object with the following attributes
 #
 # Value, Writeable, Type, Default, LegalVals = [list of legal vals], Min, Max]
 
@@ -234,16 +217,16 @@
 # End of class 'VarDescriptor'
 
 
-# Initialize the table using the predefined symbols
 
-SymTable     = {}
+
+SymTable     = SymbolTable()
 
 for var in Predefined.keys():
 
     d = VarDescriptor()
     d.Value = Predefined[var]
     d.Writeable = False
-    SymTable[var] = d
+    SymTable.Symbols[var] = d
     
                 
 ##########
@@ -368,9 +351,9 @@
 
 def DebugMsg(dmsg, args):
 
-    global DebugMsgs
+    global SymTable
     
-    DebugMsgs.append(mkmsg(Messages[dmsg] % args, dmsg))
+    SymTable.DebugMsgs.append(mkmsg(Messages[dmsg] % args, dmsg))
 
 # End of 'DebugMsg()'
 
@@ -381,9 +364,9 @@
 
 def ErrorMsg(error, args):
 
-    global ErrMsgs
+    global SymTable
     
-    ErrMsgs.append(mkmsg(Messages[error] % args + "!", error))
+    SymTable.ErrMsgs.append(mkmsg(Messages[error] % args + "!", error))
 
 # End of 'ErrorMsg()'
 
@@ -394,9 +377,9 @@
 
 def WarningMsg(warning, args):
 
-    global WarnMsgs
+    global SymTable
     
-    WarnMsgs.append(mkmsg(Messages[warning] % args + "!", warning))
+    SymTable.WarnMsgs.append(mkmsg(Messages[warning] % args + "!", warning))
 
 # End of 'WarningMsg()'
 
@@ -421,7 +404,7 @@
 
 def ParseConfig(cfgfile,
                 CallingProgram=PROGINFO,
-                InitialSymTable={},
+                InitialSymTable=SymbolTable(),
                 AllowNewVars=True,
                 Templates={},
                 TemplatesOnly=False,
@@ -429,43 +412,32 @@
                 ReturnPredefs=True,
                 Debug=False):
 
-    global DebugMsgs, ErrMsgs, WarnMsgs, LiteralLines
-    global ALLOWNEWVAR, TEMPLATES, TEMPONLY, LITERALVARS, INLITERAL, DEBUG
-    global CondStack, SymTable, TotalLines
+    global SymTable
     
-    # Initialize the globals
-
-    DebugMsgs     = []
-    ErrMsgs       = []
-    WarnMsgs      = []
-    LiteralLines  = []
-
-    ALLOWNEWVAR   = AllowNewVars
-    TEMPLATES     = Templates
-    TEMPONLY      = TemplatesOnly
-    LITERALVARS   = LiteralVars
-    INLITERAL     = False
-    DEBUG         = Debug
-
-    CondStack     = [["", True],]  # Always has one entry as a sentinel
-    TotalLines    = 0
-
     # Set the name of the calling program for output messages
     
     mkmsg.proginfo = CallingProgram
     
-    
-    # Setup container to return parsing results
+    # Create a new symbol table
 
-    retobj = RetObj()
+    SymTable = SymbolTable()
+
+    # Initialize the globals
+
+    SymTable.ALLOWNEWVAR   = AllowNewVars
+    SymTable.TEMPLATES     = Templates
+    SymTable.TEMPONLY      = TemplatesOnly
+    SymTable.LITERALVARS   = LiteralVars
+    SymTable.INLITERAL     = False
+    SymTable.DEBUG         = Debug
 
 
     # Add any passed symbols to the SymbolTable
 
     deserror = False
-    for sym in InitialSymTable:
+    for sym in InitialSymTable.Symbols:
 
-        des = InitialSymTable[sym]
+        des = InitialSymTable.Symbols[sym]
 
         # Make sure a valid descriptor was passed for each variable
 
@@ -521,41 +493,36 @@
 
         # Only load the symbol table with valid entries
         if desok:
-            SymTable[sym] = des
+            SymTable.Symbols[sym] = des
 
         # Indicate that a problem was encountered
         else:
             deserror = True
 
     # If any of the passed symbols had bogus descriptor contents, we're done
-    if deserror:
 
-        retobj.SymTable = SymTable
-        retobj.Errors   = ErrMsgs
-        retobj.Warnings = WarnMsgs
-        retobj.Debug    = DebugMsgs
-        retobj.Literals = LiteralLines
-        return retobj
+    if deserror:
+        return SymTable
 
 
     # Symbol Table passed to API was OK, so keep going
 
     # Make sure the symbol table has a valid namespace
 
-    if NAMESPACE not in SymTable:
-        SymTable[NAMESPACE] = VarDescriptor()
-        SymTable[NAMESPACE].Value = ""
+    if NAMESPACE not in SymTable.Symbols:
+        SymTable.Symbols[NAMESPACE] = VarDescriptor()
+        SymTable.Symbols[NAMESPACE].Value = ""
 
     # Otherwise, ensure that the initial namespace is properly formed.
     # If not, revert to root namespace.
     
-    elif not ValidateSymbolName(SymTable[NAMESPACE].Value, STARTUP, STARTUP, AllowEmpty=True):
-        SymTable[NAMESPACE].Value = ""
+    elif not ValidateSymbolName(SymTable.Symbols[NAMESPACE].Value, STARTUP, STARTUP, AllowEmpty=True):
+        SymTable.Symbols[NAMESPACE].Value = ""
 
     # Report namespace to debug output
 
-    if DEBUG:
-        DebugMsg("dNAMESPACE", (STARTUP, STARTUP, SymTable[NAMESPACE].Value))
+    if SymTable.DEBUG:
+        DebugMsg("dNAMESPACE", (STARTUP, STARTUP, SymTable.Symbols[NAMESPACE].Value))
 
 
     # Parse the file
@@ -564,35 +531,29 @@
 
     # Make sure we had all condition blocks balanced with matching '.endif'
 
-    finalcond = len(CondStack)
+    finalcond = len(SymTable.CondStack)
     if finalcond != 1:
         ErrorMsg("eENDIFMISS", (cfgfile, ATEOF, finalcond-1))
 
     # Make sure we ended any literal processing properly
-    if INLITERAL:
+    if SymTable.INLITERAL:
         WarningMsg("wENDLITMISS", (cfgfile, ATEOF))
 
     # Return the parsing results
 
-    if DEBUG:
-        DebugMsg("dNUMLINES", (cfgfile, TotalLines))
+    if SymTable.DEBUG:
+        DebugMsg("dNUMLINES", (cfgfile, SymTable.TotalLines))
             
     # Strip out Prefefined Variables if user does not want them
     
     if not ReturnPredefs:
 
-        del SymTable[NAMESPACE]
+        del SymTable.Symbols[NAMESPACE]
         for sym in Predefined:
-            del SymTable[sym]
+            del SymTable.Symbols[sym]
 
 
-    retobj.SymTable = SymTable
-    retobj.Errors   = ErrMsgs
-    retobj.Warnings = WarnMsgs
-    retobj.Debug    = DebugMsgs
-    retobj.Literals = LiteralLines
-
-    return retobj
+    return SymTable
 
 
 # End of 'ParseConfig()'
@@ -655,23 +616,23 @@
             # Prepend the current namespace unless we are in the top-level
             # namespace. 
 
-            elif SymTable[NAMESPACE].Value:
-                sym = "%s%s%s" % (SymTable[NAMESPACE].Value, NSSEP, sym)
+            elif SymTable.Symbols[NAMESPACE].Value:
+                sym = "%s%s%s" % (SymTable.Symbols[NAMESPACE].Value, NSSEP, sym)
 
         # Handle environment variables
         if sym and sym[0] == ENVIRO and sym[1:] in os.environ:
             envvar = os.getenv(sym[1:])
             line = line.replace(var, envvar)
 
-            if DEBUG:
+            if SymTable.DEBUG:
                 DebugMsg("dVARREF", (cfgfile, linenum, var, envvar))
             
         # Handle variables in symbol table
-        elif sym in SymTable:
-            symval = str(SymTable[sym].Value)
+        elif sym in SymTable.Symbols:
+            symval = str(SymTable.Symbols[sym].Value)
             line = line.replace(var, symval)
 
-            if DEBUG:
+            if SymTable.DEBUG:
                 DebugMsg("dVARREF", (cfgfile, linenum, var, symval))
             
 
@@ -701,7 +662,7 @@
 
 def ParseFile(cfgfile, current_cfg, current_linenum):
 
-    global IgnoreCase, MsgList, SymTable, TotalLines
+    global MsgList, SymTable
 
 
     linenum=0
@@ -712,7 +673,7 @@
         # Process and massage the configuration file
         for line in cf.read().splitlines():
             linenum += 1
-            TotalLines += 1
+            SymTable.TotalLines += 1
 
             # Parse this line
             ParseLine(line, cfgfile, linenum)
@@ -733,7 +694,7 @@
 
 def ParseLine(line, cfgfile, linenum):
 
-    global CondStack, MsgList, SymTable, INLITERAL
+    global MsgList, SymTable
 
     orig = line                 # May need copy of original for debug output
 
@@ -754,20 +715,20 @@
     if line.strip() in (LITERAL, ENDLITERAL):
 
         if line.strip() == LITERAL:
-            if INLITERAL:
+            if SymTable.INLITERAL:
                 WarningMsg("wLITEXTRA", (cfgfile, linenum))
             else:
-                INLITERAL = True
+                SymTable.INLITERAL = True
 
         # Process ENDLITERAL statements
         else:
-            if not INLITERAL:
+            if not SymTable.INLITERAL:
                 WarningMsg("wENDLITEXTRA", (cfgfile, linenum))
             else:
-                INLITERAL = False
+                SymTable.INLITERAL = False
 
 
-        if DEBUG:
+        if SymTable.DEBUG:
             DebugMsg("dPARSEDLINE", (cfgfile, linenum, orig, line))
 
         return
@@ -781,16 +742,16 @@
     # block.
     #####
 
-    if INLITERAL:
+    if SymTable.INLITERAL:
 
-        if CondStack[-1][1]:
+        if SymTable.CondStack[-1][1]:
 
-            if LITERALVARS:
+            if SymTable.LITERALVARS:
                 line, ref_ok = DerefVar(line, cfgfile, linenum)
 
-            LiteralLines.append(line)
+            SymTable.LiteralLines.append(line)
 
-            if DEBUG:
+            if SymTable.DEBUG:
                 DebugMsg("dPARSEDLINE", (cfgfile, linenum, orig, line))
 
 
@@ -798,7 +759,7 @@
         # noting in debug output if requested.
         
         else:
-            if DEBUG:
+            if SymTable.DEBUG:
                 DebugMsg("dLINEIGNORE", (cfgfile, linenum, orig, dNOTINCLUDE))
 
         return
@@ -818,7 +779,7 @@
     if not line:
 
         # Note blank lines for debug purposes
-        if DEBUG:
+        if SymTable.DEBUG:
             DebugMsg("dLINEIGNORE", (cfgfile, linenum, orig, dBLANKLINE))
 
         return
@@ -836,14 +797,14 @@
 
         # Get the enclosing block type and state
 
-        btyp, bst = CondStack.pop()
+        btyp, bst = SymTable.CondStack.pop()
 
         # ELSE is only permitted after an immediately preceding IF form
 
 
         if btyp != IF:
             ErrorMsg("eELSENOIF", (cfgfile, linenum))
-            CondStack.append(["", False])   # Error makes all that follows False
+            SymTable.CondStack.append(["", False])   # Error makes all that follows False
 
         # We *are* in an IF block an ELSE is appropriate.
         # To determine whether the ELSE should be taken or not we have
@@ -859,15 +820,15 @@
             # If the containing block is True, the contained IF state is legitimate.
             # The ELSE inverts the IF state in that case.
             
-            if CondStack[-1][1]:
-                CondStack.append([ELSE, not bst])
+            if SymTable.CondStack[-1][1]:
+                SymTable.CondStack.append([ELSE, not bst])
 
             # The containing block is false, so everything within it is also false
 
             else:
-                CondStack.append([ELSE, False])
+                SymTable.CondStack.append([ELSE, False])
                 
-        if DEBUG:
+        if SymTable.DEBUG:
             DebugMsg("dPARSEDLINE", (cfgfile, linenum, orig, line))
 
         return
@@ -880,14 +841,14 @@
     if line == ENDIF:
 
         # Remove one level of conditional nesting
-        CondStack.pop()
+        SymTable.CondStack.pop()
 
         # Error, if there are more .endifs than conditionals
-        if not CondStack:
+        if not SymTable.CondStack:
             ErrorMsg("eENDIFEXTRA", (cfgfile, linenum))
-            CondStack.append(["", False])  # Restore sentinel & inhibit further parsing
+            SymTable.CondStack.append(["", False])  # Restore sentinel & inhibit further parsing
 
-        if DEBUG:
+        if SymTable.DEBUG:
             DebugMsg("dPARSEDLINE", (cfgfile, linenum, orig, line))
 
         return
@@ -915,8 +876,8 @@
 
     if FIRSTTOK == INCLUDE:
 
-        if not CondStack[-1][1]:
-            if DEBUG:
+        if not SymTable.CondStack[-1][1]:
+            if SymTable.DEBUG:
                 DebugMsg("dLINEIGNORE", (cfgfile, linenum, orig, dNOTINCLUDE))
             return
 
@@ -926,7 +887,7 @@
         if ref_ok:
             ParseFile(line, cfgfile, linenum)
 
-        if DEBUG:
+        if SymTable.DEBUG:
             DebugMsg("dPARSEDLINE", (cfgfile, linenum, orig, line))
 
         return
@@ -991,7 +952,7 @@
                         #      4) We're dealing with the NAMESPACE variable
                         #      5) The variable name is not escaped
 
-                        ns = SymTable[NAMESPACE].Value
+                        ns = SymTable.Symbols[NAMESPACE].Value
 
                         if ns and \
                            v[0] != ENVIRO and \
@@ -1007,7 +968,7 @@
                                 v = "%s%s%s" % (ns, NSSEP, v)
 
                         # Produce debug ouput of actual variable name being checked
-                        if DEBUG:
+                        if SymTable.DEBUG:
                             DebugMsg("dVAREXISTS", (cfgfile, linenum, v))
                 
                         # Handle environment variables
@@ -1016,7 +977,7 @@
                                 numexist += 1
 
                         # Handle local local variables
-                        elif v in SymTable:
+                        elif v in SymTable.Symbols:
                             numexist += 1
 
                     # And set the conditional state accordingly
@@ -1093,15 +1054,15 @@
         # Set parser state based on a successful conditional test
         # But it has to be ANDed with the state of the enclosing block
 
-        enclosing = CondStack[-1][1]
-        CondStack.append([IF, condstate and enclosing])
+        enclosing = SymTable.CondStack[-1][1]
+        SymTable.CondStack.append([IF, condstate and enclosing])
 
         # Now reflect this in the parsed line
         line = sTRUE
         if not condstate:
             line = sFALSE
 
-        if DEBUG:
+        if SymTable.DEBUG:
             DebugMsg("dPARSEDLINE", (cfgfile, linenum, orig, line))
 
         return
@@ -1117,8 +1078,8 @@
 
     elif EQUAL in line:
 
-        if not CondStack[-1][1]:
-            if DEBUG:
+        if not SymTable.CondStack[-1][1]:
+            if SymTable.DEBUG:
                 DebugMsg("dLINEIGNORE", (cfgfile, linenum, orig, dNOTINCLUDE))
             return
 
@@ -1127,7 +1088,7 @@
         if line.count(DELIML + DELIMR):
             ErrorMsg("eSYMNONAME", (cfgfile, linenum))
 
-            if DEBUG:
+            if SymTable.DEBUG:
                 DebugMsg("dPARSEDLINE", (cfgfile, linenum, orig, line))
 
             return
@@ -1163,7 +1124,7 @@
             # move this test down into the body of the variable name
             # processing where namespace fiddling takes place.
 
-            elif l in SymTable and not SymTable[l].Writeable:
+            elif l in SymTable.Symbols and not SymTable.Symbols[l].Writeable:
                 ErrorMsg("eVARREADONLY", (cfgfile, linenum, l))
 
             # Load variable into the symbol table
@@ -1188,7 +1149,7 @@
                 # In all other cases prepend current namespace
                 else:
                     varname = l
-                    ns =  SymTable[NAMESPACE].Value
+                    ns =  SymTable.Symbols[NAMESPACE].Value
 
                     # Top level namespace variables don't need
                     # separator.
@@ -1200,10 +1161,10 @@
                 # default to be this first value assigned and
                 # create the new entry
 
-                if l not in SymTable:
+                if l not in SymTable.Symbols:
 
                     # Only do this if new variable creation allowed
-                    if ALLOWNEWVAR:
+                    if SymTable.ALLOWNEWVAR:
 
                         # Rules for new variable creation:
                         #
@@ -1213,16 +1174,16 @@
 
                         # Rule 1
                         
-                        if varname in TEMPLATES:
+                        if varname in SymTable.TEMPLATES:
 
                             # Create the new variable
                             
-                            SymTable[l] = TEMPLATES[varname]
+                            SymTable.Symbols[l] = SymTable.TEMPLATES[varname]
 
                             # Load the proposed value only if valid
 
                             if ValidateValue(l, r, cfgfile, linenum):
-                                SymTable[l].Value = r
+                                SymTable.Symbols[l].Value = r
                                 
                             # If value is invalid, remove this
                             # variable.  We cannot create a new
@@ -1231,11 +1192,11 @@
                             # function.
 
                             else:
-                                del(SymTable[l])
+                                del(SymTable.Symbols[l])
 
                         # Rule 2
                         
-                        elif TEMPONLY:
+                        elif SymTable.TEMPONLY:
                             ErrorMsg("eTEMPONLY", (cfgfile, linenum, varname))
 
                         # Rule 3
@@ -1247,7 +1208,7 @@
                             d = VarDescriptor()
                             d.Default = r
                             d.Value = r
-                            SymTable[l] = d
+                            SymTable.Symbols[l] = d
 
                     # New vars not allowed
                     else:
@@ -1272,16 +1233,16 @@
                         # equivalent logical value for boolean
                         # variables first
 
-                        if SymTable[l].Type == TYPE_BOOL:
+                        if SymTable.Symbols[l].Type == TYPE_BOOL:
                             r = Booleans[r.capitalize()]
 
-                        SymTable[l].Value = r
+                        SymTable.Symbols[l].Value = r
 
                         # Produce debug output when we change namespaces
-                        if DEBUG and l == NAMESPACE:
+                        if SymTable.DEBUG and l == NAMESPACE:
                             DebugMsg("dNAMESPACE",  (cfgfile, linenum, r))
 
-        if DEBUG:
+        if SymTable.DEBUG:
             DebugMsg("dPARSEDLINE", (cfgfile, linenum, orig, line))
 
         return
@@ -1369,7 +1330,7 @@
             update = False   # Validation function issues appropriate errors
 
     
-    des = SymTable[l]
+    des = SymTable.Symbols[l]
     typ = des.Type
     lv  = des.LegalVals
     low = des.Min
@@ -1434,7 +1395,7 @@
                         # This can be kind of complex, so produce
                         # debug output here to help the poor user
 
-                        if DEBUG:
+                        if SymTable.DEBUG:
                             DebugMsg("dREGEXMATCH", (cfgfile, linenum, r, rex, l))
                             
                 except:
@@ -1486,7 +1447,7 @@
 
 
 __all__ = ["ParseConfig",
-           "RetObj",
+           "SymbolTable",
            "TYPE_BOOL",
            "TYPE_COMPLEX",
            "TYPE_FLOAT",