diff --git a/tconfpy.3 b/tconfpy.3
index b672736..b282fcd 100644
--- a/tconfpy.3
+++ b/tconfpy.3
@@ -157,19 +157,26 @@
 
 .nf
     
-.B ParseConfig(cfgfile, InitialSymTbl={}, Debug=False, LiteralVars=False)
+.B ParseConfig(cfgfile, InitialSymTbl={}, AllowNewVars=True, Debug=False, LiteralVars=False)
 
 where:
 
 .B cfgfile
     The the name of a file containing configuration information
+
 .B InitialSymTbl
     A pre-populated symbol table.  Defaults to an empty symbol table.  As
     described below, this must contain valid \'VarDescriptor\' entries
     for each symbol in the table.
+
+.B AllowNewVars
+    Allow the user to create new variables in the configuration
+    file.  Defaults to True.
+
 .B Debug
     Defaults to False.  If set to True, \*(TC will provide detailed
     debugging information about each line processed when it returns.
+
 .B LiteralVars
     Defaults to False.  If set to True this option Enables variable 
     substitutions within \'.literal\' blocks of a configuration file.
@@ -251,6 +258,120 @@
 
 .SS Passing An Initial Symbol Table
 
+The simplest way to parse a configuration file is just to call
+the parser with the name of that file:
+
+
+.nf
+retval = ParseConfig("myconfigfile")
+.fi
+
+Assuming your configuration file is valid, \'ParseConfig()\' will
+return a symbol table populated with all the variables defined in the
+file and their associated values. This symbol table will have
+.B only
+the symbols defined in that file (plus a few built-in and pre-defined
+symbols needed internally by \*(TC).
+
+However, the API provides a way for you to pass a "primed" symbol
+table to the parser that contains pre-defined symbols/values of
+your own choosing.  Why on earth would you want to do this?  There
+are a number of reasons:
+
+.nf
+1) You may wish to write a configuration file which somehow depends
+   on a pre-defined variable which only the calling program can know:
+
+     .if [APPVERSION] == 1.0
+          # Set configuration for older application releases
+     .else
+          # Set configuration for newer releases
+     .endif
+
+   In this example, only the calling application can know its own
+   version, so it sets the variable APPVERSION in a symbol table
+   which is passed to \'ParseConfig()\'.
+
+2) You may wish to "protect" certain variable names be creating
+   them ahead of time and marking them as "Read Only".  This is
+   useful when you want a variable to be available for use
+   within a configuration file, but you do not want users to
+   be able to change its value.  In this case, the variable can
+   be referenced in a string substitution or conditional test,
+   but cannot be changed.
+
+3) You may want to place limits on what values can be assigned to
+   a particular variable.  By default, all variables newly defined
+   within a configuration file are defined to be strings of any
+   length, with no restrictions on their content.  By pre-defining a
+   variable, you can specify its type (integer, string, boolean, or
+   complex), a list of possible legal values, a range of legal values,
+   min/max string length, or a set of regular expressions for string
+   variables - one of which must match. In other words, you can have
+   \*(TC "validate" what values the user assigns to particular
+   variables.  This substantially simplifies your application because
+   no invalid variable value will ever be returned from the parser.
+
+.fi
+
+
+
+
+When you pass an initial symbol table to the parser, \*(TC does
+some basic validation that the table contents properly conform
+to the \'VarDescriptor\' format and generates error messages if
+it finds problems.   However, the program does
+.B not
+check your specifications to see if they make sense.  For instance
+if you define an integer with a minimum value of 100 and a maximum
+value of 50, \*(TC cheerfully accepts these limits even they they
+are impossible.  You'll just be unable to do anything with that
+variable - any attempt to change its value will cause an error
+to be recorded.  Similarly, if you put a value in \'LegalVals\' that
+is outside the range of \'Min\' to \'Max\', \*(TC will accept
+it quietly.
+
+.SS The \'AllowNewVars\' Option
+
+By default, \*(TC lets the user define any new variables they
+wish in a configuration file, merely by placing a line in the
+file in this form:
+
+.nf
+   Varname = Value
+.fi
+
+However, you can disable this capability by calling the parser like
+this:
+
+.nf
+   retval = ParseConfig("myconfigfile", AllowNewVars=False)
+.fi
+
+This means that the configuration file can "reference"
+any pre-defined variables, and even change their values
+(if they are not Read-Only), but it cannot create
+.B new
+variables.  This is primarily intended for use when you
+pass an initial symbol table to the parser and you do not want
+any other variables defined by the user.  Why?  To prevent them
+from making spelling errors.  For example, you can define the
+variable name "MyEmail" and they will get an error if they
+accidentally try to do something like "myemail = x@y.com".
+
+
+.SS How \*(TC Processes Errors
+
+As a general matter, when \*(TC encounters an error in the
+configuration file currently being parsed, it does two things.  First,
+it adds a descriptive error message into the list of errors returned
+to the calling program (see the next section).  Secondly, in many
+cases, noteably during conditional processing, it sets the parser
+state so the block in which the error occurred is logically False.
+This does not happen in every case, however.  If you are having
+problems with errors, enable the Debugging features of the package and
+look at the debug output.  It provides detailed information about what
+caused the error and why.
 
 
 .SS \*(TC Return Values