diff --git a/synthesis/cfgparse2.py b/synthesis/cfgparse2.py
deleted file mode 100644
index c66e581b551b84abcc4406d31b29e651705da21a..0000000000000000000000000000000000000000
--- a/synthesis/cfgparse2.py
+++ /dev/null
@@ -1,1762 +0,0 @@
-"""cfgparse - a powerful, extensible, and easy-to-use configuration parser.
-
-By Dan Gass <dan.gass@gmail.com>
-
-If you have problems with this module, please file bugs through the Source
-Forge project page:
-  http://sourceforge.net/projects/cfgparse
-"""
-
-# @future use option note when get error
-# @future print file/section/linenumber information when checks fail
-# @future - check type='choice' and choices=[] one must have the other
-# @future -- do we have a command line --cfgcheck option that expands all configuration and checks all possible keys?
-
-__version__ = "1.3"
-
-__all__ = []
-
-__copyright__ = """
-Copyright (c) 2004 by Daniel M. Gass.   All rights reserved.
-Copyright (c) 2001-2004 Gregory P. Ward.  All rights reserved.
-Copyright (c) 2002-2004 Python Software Foundation.  All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-  * Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
-  * Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-
-  * Neither the name of the author nor the names of its
-    contributors may be used to endorse or promote products derived from
-    this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""
-
-import ConfigParser as _ConfigParser
-import cStringIO
-import os
-import re
-import sys
-import textwrap
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-# U T I L I T Y
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-# <borrowed file="Lib/optparse.py" version="python2.4" modified="yes">
-try:
-    from gettext import gettext as _
-except ImportError:
-    _ = lambda arg: arg
-
-class HelpFormatter:
-    """
-    Abstract base class for formatting option help.  ConfigParser
-    instances should use one of the HelpFormatter subclasses for
-    formatting help; by default IndentedHelpFormatter is used.
-
-    Instance attributes:
-      parser : OptionParser
-        the controlling OptionParser instance
-      indent_increment : int
-        the number of columns to indent per nesting level
-      max_help_position : int
-        the maximum starting column for option help text
-      help_position : int
-        the calculated starting column for option help text;
-        initially the same as the maximum
-      width : int
-        total number of columns for output (pass None to constructor for
-        this value to be taken from the $COLUMNS environment variable)
-      level : int
-        current indentation level
-      current_indent : int
-        current indentation level (in columns)
-      help_width : int
-        number of columns available for option help text (calculated)
-      default_tag : str
-        text to replace with each option's default value, "%default"
-        by default.  Set to false value to disable default value expansion.
-      option_strings : { Option : str }
-        maps Option instances to the snippet of help text explaining
-        the syntax of that option, e.g. "option=VALUE"
-    """
-
-    NO_DEFAULT_VALUE = "none"
-
-    def __init__(self,
-                 indent_increment,
-                 max_help_position,
-                 width,
-                 short_first):
-        self.parser = None
-        self.indent_increment = indent_increment
-        self.help_position = self.max_help_position = max_help_position
-        if width is None:
-            try:
-                width = int(os.environ['COLUMNS'])
-            except (KeyError, ValueError):
-                width = 80
-            width -= 2
-        self.width = width
-        self.current_indent = 0
-        self.level = 0
-        self.help_width = None          # computed later
-        self.short_first = short_first
-        self.default_tag = "%default"
-        self.option_strings = {}
-        self._short_opt_fmt = "%s %s"
-        self._long_opt_fmt = "%s=%s"
-
-    def set_parser(self, parser):
-        self.parser = parser
-
-    def indent(self):
-        self.current_indent += self.indent_increment
-        self.level += 1
-
-    def dedent(self):
-        self.current_indent -= self.indent_increment
-        assert self.current_indent >= 0, "Indent decreased below 0."
-        self.level -= 1
-
-    def format_usage(self, usage):
-        raise NotImplementedError, "subclasses must implement"
-
-    def format_heading(self, heading):
-        raise NotImplementedError, "subclasses must implement"
-
-    def format_description(self, description):
-        if not description:
-            return ""
-        desc_width = self.width - self.current_indent
-        indent = " "*self.current_indent
-        return textwrap.fill(description,
-                             desc_width,
-                             initial_indent=indent,
-                             subsequent_indent=indent) + "\n"
-
-    def expand_default(self, option):
-        if self.parser is None or not self.default_tag:
-            return option.help
-
-        try:
-            default_value = option.default
-        except AttributeError:
-            default_value = None
-
-        if default_value is NO_DEFAULT or default_value is None:
-            default_value = self.NO_DEFAULT_VALUE
-
-        return option.help.replace(self.default_tag, str(default_value))
-
-    def format_option(self, option):
-        # The help for each option consists of two parts:
-        #   * the opt strings and metavars
-        #     eg. ("option=VALUE")
-        #   * the user-supplied help string
-        #     eg. ("turn on expert mode", "read data from FILENAME")
-        #
-        # If possible, we write both of these on the same line:
-        #   option=VALUE  explanation of some option
-        #
-        # But if the opt string list is too long, we put the help
-        # string on a second line, indented to the same column it would
-        # start in if it fit on the first line.
-        #   thisoption=WAY_TO_LONG
-        #           explanation of the long option
-        result = []
-        opts = self.option_strings[option]
-        opt_width = self.help_position - self.current_indent - 2
-        if len(opts) > opt_width:
-            opts = "%*s%s\n" % (self.current_indent, "", opts)
-            indent_first = self.help_position
-        else:                       # start help on same line as opts
-            opts = "%*s%-*s  " % (self.current_indent, "", opt_width, opts)
-            indent_first = 0
-        result.append(opts)
-        if option.help:
-            help_text = self.expand_default(option)
-            help_lines = textwrap.wrap(help_text, self.help_width)
-            result.append("%*s%s\n" % (indent_first, "", help_lines[0]))
-            result.extend(["%*s%s\n" % (self.help_position, "", line)
-                           for line in help_lines[1:]])
-        elif opts[-1] != "\n":
-            result.append("\n")
-        return "".join(result)
-
-    def store_option_strings(self, parser):
-        self.indent()
-        max_len = 0
-        for opt in parser.option_list:
-            strings = self.format_option_strings(opt)
-            self.option_strings[opt] = strings
-            max_len = max(max_len, len(strings) + self.current_indent)
-        self.indent()
-        for group in parser.option_groups:
-            for opt in group.option_list:
-                strings = self.format_option_strings(opt)
-                self.option_strings[opt] = strings
-                max_len = max(max_len, len(strings) + self.current_indent)
-        self.dedent()
-        self.dedent()
-        self.help_position = min(max_len + 2, self.max_help_position)
-        self.help_width = self.width - self.help_position
-
-    def format_option_strings(self, option):
-        """Return a comma-separated list of option strings & metavariables."""
-        metavar = option.metavar or option.dest.upper()
-        return '%s=%s' % (option.name,metavar)
-
-class IndentedHelpFormatter (HelpFormatter):
-    """Format help with indented section bodies.
-    """
-    # NOTE optparse
-    def __init__(self,
-                 indent_increment=2,
-                 max_help_position=24,
-                 width=None,
-                 short_first=1):
-        HelpFormatter.__init__(
-            self, indent_increment, max_help_position, width, short_first)
-
-    def format_usage(self, usage):
-        return _("usage: %s\n") % usage
-
-    def format_heading(self, heading):
-        return "%*s%s:\n" % (self.current_indent, "", heading)
-
-class TitledHelpFormatter (HelpFormatter):
-    """Format help with underlined section headers.
-    """
-    # NOTE optparse
-    def __init__(self,
-                 indent_increment=0,
-                 max_help_position=24,
-                 width=None,
-                 short_first=0):
-        HelpFormatter.__init__ (
-            self, indent_increment, max_help_position, width, short_first)
-
-    def format_usage(self, usage):
-        return "%s  %s\n" % (self.format_heading(_("Usage")), usage)
-
-    def format_heading(self, heading):
-        return "%s\n%s\n" % (heading, "=-"[self.level] * len(heading))
-
-SUPPRESS_HELP = "SUPPRESS"+"HELP"
-NO_DEFAULT = ("NO", "DEFAULT")
-
-def _repr(self):
-    return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self)
-# </borrowed>
-
-NOTHING_FOUND = ("NOTHING","FOUND")
-
-def split_keys(keys):
-    """Returns list of keys resulting from keys argument.
-
-        --- NO KEYS ---
-        >>> split_keys( None )
-        []
-        >>> split_keys( [] )
-        []
-
-        --- STRINGS ---
-        >>> split_keys( "key1" )
-        ['key1']
-        >>> split_keys( "key1,key2" )
-        ['key1', 'key2']
-        >>> split_keys( "key1.key2" )
-        ['key1', 'key2']
-        >>> split_keys( "key1.key2,key3" )
-        ['key1', 'key2', 'key3']
-
-        --- LISTS ---
-        >>> split_keys( ['key1'] )          # single item
-        ['key1']
-        >>> split_keys( ['key1','key2'] )   # multiple items
-        ['key1', 'key2']
-
-        --- QUOTING ---
-        These tests check that quotes can be used to protect '.' and ','.
-        >>> split_keys( "'some.key1','some,key2'" )    # single ticks work 
-        ['some.key1', 'some,key2']
-        >>> split_keys( '"some,key1","some.key2"' )    # double ticks work
-        ['some,key1', 'some.key2']
-        >>> split_keys( '"some,key1",some.key2' )      # must quote everything
-        Traceback (most recent call last):
-        ConfigParserError: Keys not quoted properly.  Quotes must surround all keys.
-        >>> split_keys( "some,key1,'some.key2'" )      # must quote everything
-        Traceback (most recent call last):
-        ConfigParserError: Keys not quoted properly.  Quotes must surround all keys.
-        >>> split_keys( "key1,'some.key2'.key3" )      # must quote everything
-        Traceback (most recent call last):
-        ConfigParserError: Keys not quoted properly.  Quotes must surround all keys.
-        >>> split_keys('DEFAULT')
-        []
-        >>> split_keys(['DEFAULT'])
-        []
-        """
-    if (keys is None) or (keys == 'DEFAULT') or (keys == ['DEFAULT']):
-        return []
-    try:
-        keys = keys.replace('"',"'")
-        if "'" in keys:
-            keys = keys.strip("'").split("','")
-            for key in keys:
-                if "'" in key:
-                    IMPROPER_QUOTES = "Keys not quoted properly.  Quotes must surround all keys."
-                    raise ConfigParserUserError(IMPROPER_QUOTES)
-        else:
-            keys = keys.replace('.',',').split(',')
-    except AttributeError:
-        pass
-    return keys
-
-def join_keys(keys,sep=','):
-    """
-    >>> join_keys(['key1'])
-    'key1'
-    >>> join_keys(['key1','key2'])
-    'key1,key2'
-    >>> join_keys(['key1','key2'],'.')
-    'key1.key2'
-    >>> join_keys(['key.1','key2'],'.')
-    "'key.1','key2'"
-    >>> join_keys(['key,1','key2'],'.')
-    "'key,1','key2'"
-    >>> join_keys([])
-    'DEFAULT'
-    """
-    if not keys:
-        return 'DEFAULT'
-    mash = ''.join(keys)
-    if '.' in mash or ',' in mash:
-        quote = "'"
-        sep = quote + ',' + quote
-        return quote + sep.join(keys) + quote
-    return sep.join(keys)
-
-def split_paths(paths):
-    """Returns list of paths resulting from paths argument.
-
-        --- NO KEYS ---
-        >>> split_paths( None )
-        []
-        >>> split_paths( [] )
-        []
-
-        --- STRINGS ---
-        >>> split_paths( "path1" )
-        ['path1']
-        >>> split_paths( os.path.pathsep.join(["path1","path2"]) )
-        ['path1', 'path2']
-        >>> split_paths( "path.1,path.2" )
-        ['path.1', 'path.2']
-
-        --- LISTS ---
-        >>> split_paths( ['path1'] )          # single item
-        ['path1']
-        >>> split_paths( ['path1','path2'] )   # multiple items
-        ['path1', 'path2']
-        """
-    if paths is None:
-        return []
-    try:
-        return paths.replace(',',os.path.pathsep).split(os.path.pathsep)
-    except AttributeError:
-        return paths
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-#  E X C E P T I O N S
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-class ConfigParserError(Exception):
-    """Exception associated with the cfgparse module"""
-    pass
-    
-class ConfigParserAppError(Exception):
-    """Exception due to application programming error"""
-    pass
-    
-class ConfigParserUserError(Exception):
-    """Exception due to user error"""
-    pass
-    
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-#  K E Y S
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-class Keys(object):
-    """Prioritizes and stores default configuration keys.
-    
-    This class is used to store default configuration keys for an instance
-    of the Config class.  The different sources of keys are supported (stored)
-    by the following methods of this class:
-
-    add_cfg_keys -- configuration file specified default keys
-    add_cmd_keys -- command line option keys
-    add_env_keys -- environment variable keys
-    
-    The 'get' method returns a combined list of keys in the following order:
-        application keys (passed when calling 'get' method)
-        command line keys
-        environment variable keys
-        configuration file keys
-        a 'DEFAULT' key (always present)
-
-    Setup: modify os module to fake out environment variable gets
-    >>> _getenv = os.getenv
-    >>> def getenv(variable,default):
-    ...     if variable == 'VAR12':
-    ...         return 'env1,env2'
-    ...     elif variable == 'VAR3':
-    ...         return 'env3'
-    ...     elif variable == 'VAR4':
-    ...         return 'env4'
-    ...     else:
-    ...         return default
-    >>> os.getenv = getenv
-
-    Case 1: normal string lists of keys
-    >>> k = Keys()
-    >>> k.add_env_keys('VAR12,VAR3') # this has effect
-    >>> k.add_env_keys('VAR_NONE')   # no effect
-    >>> k.add_cfg_keys('cfg1,cfg2')
-    >>> k.add_cmd_keys('cmd1.cmd2')
-    >>> k.add_env_keys('VAR12')      # no effect (already read)
-    >>> k.get('app1,app2')
-    ['app1', 'app2', 'cmd1', 'cmd2', 'env1', 'env2', 'env3', 'cfg1', 'cfg2', 'DEFAULT']
-
-    Case 2: extend lists using other key input flavors just to make sure each
-            method uses split_keys()
-    >>> k.add_env_keys(['VAR4'])     # this has effect
-    >>> k.add_cfg_keys(['cfg3'])
-    >>> k.add_cmd_keys(['cmd3'])
-    >>> k.get(['app'])
-    ['app', 'cmd1', 'cmd2', 'cmd3', 'env1', 'env2', 'env3', 'env4', 'cfg1', 'cfg2', 'cfg3', 'DEFAULT']
-
-    Teardown: restore os module
-    >>> os.getenv = _getenv
-    """
-    
-    def __init__(self):
-        """Initialize Keys Instance"""
-        self.cmd_keys = []
-        self.env_keys = []
-        self.cfg_keys = []
-        self.env_vars = []
-
-    def __repr__(self):
-        """Return string representation of object"""
-        return ','.join(self.get([]))
-
-    def add_cmd_keys(self,keys):
-        """Store keys from command line interface
-
-        keys -- list of keys (typically from the command line) to store.  May
-            be a list of keys or a string with keys separated by commas.
-            Use any value which evaluates False when no keys.
-        """
-        self.cmd_keys.extend(split_keys(keys))
-
-    def add_env_keys(self,variables):
-        """Store keys from invoking shell's environment variable
-
-        variable -- (string) environment variable name from which to obtain
-            keys to store
-        """
-        variables = split_keys(variables)
-        for variable in variables:
-            # only add keys from shell environment variable if we haven't already
-            if variable not in self.env_vars:
-                # save key variable name so we can't add same keys twice
-                self.env_vars.append(variable)
-                # if shell environment variable has a option save it
-                keys = os.getenv(variable,None)
-                if keys is not None:
-                    self.env_keys.extend(split_keys(keys))
-
-    def add_cfg_keys(self,keys):
-        """Store keys from user's configuration file.
-
-        keys -- list of keys (from user's configuration file) to store.  May
-            be a list of keys or a string with keys separated by comma.
-            Use any value which evaluates False when no keys.
-        """
-        self.cfg_keys.extend(split_keys(keys))
-
-    def get(self,keys=None):
-        """Return prioritized list of stored configuration keys
-
-        keys -- list of differentiator keys.  May be a list of keys or a string
-            with keys separated by commas.  Use any valid which evaluates
-            False when no keys.
-        """
-        keys = split_keys(keys)
-        return (keys + self.cmd_keys + self.env_keys + self.cfg_keys +
-                ['DEFAULT'])
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-#  O P T I O N   V A L U E
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-class Value(object):
-    """Used to store option settings in the blended option dictionary.
-    Needed to be able to tie the option setting back to the configuration
-    file for better error reporting and for round trip get/set/write
-    capability."""
-    def __init__(self,value,parent,section_keys):
-        """Initializes instance."""
-        self.value = value
-        self.parent = parent
-        self.section_keys = section_keys
-
-    def set(self,value):
-        """Sets option setting to 'value' argument passed in.  
-        
-        By default configuration file parsers to do not support round trip.
-        If they do they should subclass Value() and override this method
-        """
-        self.value = value
-
-    def get_roots(self):
-        return ["File: %s" % self.parent.get_filename(),
-                "Section: [%s]" % join_keys(self.section_keys,'.')]
-        
-    def __str__(self):
-        """Returns string representation of the setting."""
-        return str(self.value)
-
-    __repr__ = _repr
-
-    def get(self):
-        """Returns the option setting."""
-        return self.value
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-#  O P T I O N
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-class Option(object):
-    """Options added to configuration parser are an instance of this class."""
-
-    def __init__(self,**kwargs):
-        """Instance initializer.
-        Arguments:
-        kwargs -- dictionary with keys parser,name,type,default,help,check,keys,
-                  choices (see add_option of OptionContainer)
-        """
-        self.__dict__.update(kwargs)
-        if self.dest is None:
-            self.dest = self.name
-        if self.type not in self.conversions:
-            TYPE_DOES_NOT_EXIST = "type '%s' is not valid" % self.type
-            raise ConfigParserAppError(TYPE_DOES_NOT_EXIST)
-        # help cross reference for options partnered with OptionParser
-        self._help_xref = ""
-        self.note = None
-
-    def __str__(self):
-        """Returns string representation of the option."""
-        return self.name
-
-    __repr__ = _repr
-
-    def add_note(self,note):
-        """Adds 'note' argument text to configuration parser help text and 
-        to error messages associated with this option."""
-        self.parser.add_note(note)
-        self.note = note
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Get
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def _get(self,keys):
-        # Read any pending configuration files at the top level in order to
-        # pick up user's default keys in those files.
-        self.parser.parse_pending_cfg([])
-
-        keys = split_keys(keys) + self.keys
-        keys = self.parser.keys.get(keys)
-
-        # Get the option's dictionary from the configuration parser so that
-        # any pending configuration files that are needed are read.
-        option = self.parser.get_option_dict(self.name,keys)
-
-        # When keys are given as an argument, we don't have the constraints
-        # of an exact match like a section.  Instead we use the default
-        # key list (highest priority key first) to walk the option
-        # dictionary.  At each level of the dictionary we look for the
-        # highest priority key and if it exists we move down a level
-        # otherwise the remaining keys are checked in order of priority.
-
-        def walk_option(option):
-            if option.__class__ is dict:
-                for key in keys:
-                    if key in option:
-                        v = walk_option(option[key])
-                        if v.__class__ is not dict:
-                            return v
-            if isinstance(option,Value):
-                return option
-            else:
-                return NOTHING_FOUND
-
-        return walk_option(option)
-    
-    def get(self,keys=[],errors=None):
-        """Returns option value associated with 'keys' argument or options
-        option value using 'keys' argument (in combination with other keys).
-
-        keys -- name of keys to obtain option value from
-
-        Note:
-           If option is partnered with an optparse option and that option
-           is present, the optparse option will take priority and be returned.
-        """
-
-        warnings = []
-        option = NOTHING_FOUND
-
-        def convert(value,option_help):
-            # Do conversion to the type application specified
-            value,warning = self.conversions[self.type](self,value)
-            # Do final check using application check function if supplied
-            if not warning and self.check is not None:
-                value,warning = self.check(value)
-            if warning:
-                try:
-                    warnings.extend(option_help.get_roots())
-                except AttributeError:
-                    warnings.append(option_help)
-                warnings.append(warning)
-            return value
-
-        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-        # Priority 1: Get option from optparse partner (command line)
-        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-        if self.dest in self.parser.optpar_option_partners:
-            option = getattr(self.parser.optparser_options,self.dest,None)
-            if option is None:
-                option = NOTHING_FOUND
-            else:
-                option = convert(option,'command line option')
-
-        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-        # Priority 2: Get a default option
-        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-        if option is NOTHING_FOUND and not warnings:
-
-            option = self._get(keys)
-        
-            if option is not NOTHING_FOUND:
-                value = option.get()
-                option = convert(value,option)
-
-        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-        # Priority 3: Use default specified when adding the option
-        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-        if option is NOTHING_FOUND and not warnings:
-            if self.default is not NO_DEFAULT:
-                option = self.default
-            else:
-                warnings.append('No valid default found.')
-                keys = split_keys(keys) + self.keys
-                keys = self.parser.keys.get(keys)
-                warnings.append('keys=%s' % ','.join(keys))
-                    
-        if warnings:
-            lines = ['Option: %s' % self.name] + warnings
-            lines = '\n'.join(lines) + '\n'
-            if errors is not None:
-                errors.append(lines)
-            else:
-                # not coming back
-                self.parser.write_errors([lines])
-        
-        return option
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Conversions
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def convert_choice(self,value):
-        if value in self.choices:
-            return value,None
-        else:
-            choices = str(self.choices).strip('[]()')
-            warning = "Invalid choice '%s', must be one of: %s" % (value,choices) 
-            return None,warning
-
-    def convert_complex(self,value):
-        try:
-            return complex(value),None
-        except ValueError:
-            return None,"Cannot convert '%s' to a complex number" % (value)
-
-    def convert_float(self,value):
-        try:
-            return float(value),None
-        except ValueError:
-            return None,"Cannot convert '%s' to a float" % (value)
-
-    def convert_int(self,value):
-        try:
-            return int(value),None
-        except ValueError:
-            return None,"Cannot convert '%s' to an integer" % (value)
-
-    def convert_long(self,value):
-        try:
-            return long(value),None
-        except ValueError:
-            return None,"Cannot convert '%s' to a long" % (value)
-
-    def convert_string(self,value):
-        try:
-            return str(value),None
-        except ValueError:
-            return None,"Cannot convert '%s' to a string" % (value)
-
-    def convert_nothing(self,value):
-        return value,None
-
-    conversions = {
-        'choice'  : convert_choice,
-        'complex' : convert_complex,
-        'float'   : convert_float,
-        'int'     : convert_int,
-        'long'    : convert_long,
-        'string'  : convert_string,
-        None      : convert_nothing,
-        }
-    
-    def set(self,value,cfgfile=None,keys=None):
-        value = str(value)
-        if cfgfile:
-            if keys is not None:
-                keys = split_keys(keys)
-            else:
-                keys = self.keys
-            cfgfile.set_option(self.name,value,keys,self.help)
-        else:
-            keys = split_keys(keys) + self.keys
-            keys = self.parser.keys.get(keys)
-    
-            option = self._get(keys)
-        
-            if option is NOTHING_FOUND:
-                NOTHING_TO_SET = '\n'.join([
-                    'ERROR: No option found',
-                    'option name: %s' % self.name,
-                    'keys: %s' % keys])
-                raise ConfigParserUserError(NOTHING_TO_SET)
-            else:
-                option.set(value)
-            cfgfile = option.parent
-        return cfgfile
-    
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-#  O P T I O N   C O N T A I N E R   B A S E   C L A S S E S
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-class OptionContainer(object):
-
-    OptionClass = Option    
-
-    def __init__(self,description):
-        self.option_list = []
-        self.set_description(description)
-
-    def set_description(self, description):
-        self.description = description
-
-    def get_description(self):
-        return self.description
-
-    def add_option(self,name,help=None,type=None,choices=None,dest=None,metavar=None,default=NO_DEFAULT,check=None,keys=None):
-        """
-            name -- configuration file option name (used same as optparse)
-            type -- choices similar to optparse (used same as optparse)
-            default -- default value (used same as optparse)
-            help -- help string (used same as optparse)
-            dest -- option database attribute name (used same as optparse)
-            check -- check function
-            keys -- name of keys to obtain option from
-            choices -- list of choices (used same as optparse)
-            metavar -- FUTURE
-        """
-        if dest is None:
-            dest = name
-
-        kwargs = {
-            'parser' : self.parser,
-            'name' : name,
-            'type' : type,
-            'help' : help,
-            'dest' : dest,
-            'check' : check,
-            'keys' : split_keys(keys),
-            'choices' : choices,
-            'metavar' : metavar,
-            'default' : default}
-        
-        option = self.OptionClass(**kwargs)
-        self.parser.master_option_list.append(option)
-        self.parser.master_option_dict[dest] = option
-        self.option_list.append(option)
-        return option
-
-    # <borrowed file="Lib/optparse.py" version="python2.4" modified="yes">
-    
-    def format_option_help(self, formatter):
-        if not self.option_list:
-            return ""
-        result = []
-        for option in self.option_list:
-            if not option.help == SUPPRESS_HELP:
-                result.append(formatter.format_option(option))
-        return "".join(result)
-
-    def format_description(self, formatter):
-        return formatter.format_description(self.get_description())
-
-    def format_help(self, formatter):
-        result = []
-        if self.description:
-            result.append(self.format_description(formatter))
-        if self.option_list:
-            result.append(self.format_option_help(formatter))
-        return "\n".join(result)
-    # </borrowed>
-    
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-#  O P T I O N   G R O U P
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-class OptionGroup(OptionContainer):
-    def __init__(self,parser,title,description):
-        OptionContainer.__init__(self,description)
-        self.parser = parser
-        self.title = title
-
-    # <borrowed file="Lib/optparse.py" version="python2.4" modified="yes">
-    def set_title (self, title):
-        self.title = title
-
-    # -- Help-formatting methods ---------------------------------------
-
-    def format_help (self, formatter):
-        result = formatter.format_heading(self.title)
-        formatter.indent()
-        result += OptionContainer.format_help(self, formatter)
-        formatter.dedent()
-        return result
-    # </borrowed>
-        
-
-class ConfigFile(object):
-    def __init__(self,cfgfile,content,keys,parent,parser):
-        
-        p,n = os.path.split(cfgfile)
-        try:
-            p = os.path.join(parent.path,p)
-        except AttributeError:
-            pass
-        p = os.path.abspath(p)
-        
-        self.path = p
-        self.filename = n
-        self.content = content
-        self.underkeys = keys
-        self.parent = parent
-        self.parser = parser
-
-        self.parsed = False
-
-    def get_filename(self):
-        return os.path.join(self.path,self.filename)
-        
-    def __str__(self):
-        return os.path.join(self.path,self.filename)
-
-    __repr__ = _repr
-
-    def get_as_str(self):
-        content = self.content
-        if content is None:
-            cfgfile = os.path.join(self.path,self.filename)
-            f = open(cfgfile)
-            content = f.read()
-            f.close()
-        else:
-            try:
-                content = self.content.read()
-            except AttributeError:
-                pass
-        return content
-      
-    def parse_if_unparsed(self):
-        if not self.parsed:
-
-            # The parent is important in that it is used error messages but more
-            # importantly when getting ready to read a configuration script we
-            # must set the current directory of the parent so relative path
-            # specification of any configuration file works out.
-            try:
-                parent_path = self.parent.path
-            except AttributeError:
-                parent_path = os.getcwd()
-                                        
-            # Save so we can restore after we are done
-            cwd = os.getcwd()
-
-            # Make sure file is present
-            cfgfile = os.path.join(self.path,self.filename)
-            if not self.content and not os.path.exists(cfgfile):
-                lines = ["File not found: '%s'" % cfgfile]
-                # remember, top level configuration file parent is just the
-                # current working directory when ConfigParser was instantiated
-                # FUTURE parent info in here too
-                FILE_NOT_FOUND = '\n'.join(lines)
-                raise ConfigParserUserError(FILE_NOT_FOUND)
-                
-            # Change the current working directory to where the configuration 
-            # script is (to accomodate Python configuraton scripts so that it
-            # can use os.getcwd() to determine its location).
-            os.chdir(self.path)
-                
-            self.parse()
-            
-            # Restore
-            os.chdir(cwd)
-
-            # Mark it as done so it isn't parsed twice
-            self.parsed = True
-
-
-class ConfigFilePy(ConfigFile):
-
-    def parse(self):
-
-        underkeys = self.underkeys
-        parser = self.parser
-
-        # Parsing can be easy!
-        options = {}
-        if self.content is None:        
-            cfgfile = os.path.join(self.path,self.filename)
-            execfile(cfgfile,options)
-        else:
-            exec self.get_as_str() in options
-
-        # Update the keys.  "KEYS_VARIABLE" option used to specify the
-        # environment variable that holds additional default keys, if
-        # present get keys from the environment using it.  If reading
-        # configuration file that is being included under a key, don't
-        # bother with its keys because it would get too confusing.
-        if not underkeys:
-            try:
-                parser.keys.add_env_keys(options['KEYS_VARIABLE'])
-                del options['KEYS_VARIABLE']
-            except KeyError:
-                pass
-            try:
-                parser.keys.add_cfg_keys(options['KEYS'])
-                del options['KEYS']
-            except KeyError:
-                pass
-
-        try:
-            CONFIG_FILES = options['CONFIG_FILES']
-            del options['CONFIG_FILES']
-        except KeyError:
-            CONFIG_FILES = None
-
-        def merge_option(value,section_keys):
-            if value.__class__ is dict:
-                for key in value:
-                    merge_option(value[key],section_keys+[key])
-            else:
-                valueobj = Value(value,self,section_keys)
-                parser.merge_option(name,valueobj,underkeys+section_keys)
-            
-        # Merge all options that don't start with "_" into the options
-        for name,value in options.items():
-            if not name.startswith('_'):
-                merge_option(value,[])
-
-        # Process the "CONFIG_FILES" option used to merge in configuration
-        # from other files. Users specify a comma separated (string)
-        # listing of configuration file names or a dictionary of (and
-        # optionally - of dictionaries of) file name strings.
-        def add_files(value,under):
-            if isinstance(value,dict):
-                for k,v in value.iteritems():
-                    add_files(v,under+[k])
-            else:
-                for cf in split_paths(value):
-                    parser.add_file(cf,keys=under,parent=self)
-
-        if CONFIG_FILES:
-            add_files(CONFIG_FILES,underkeys)
-
-class ConfigFileIni(ConfigFile):
-  
-    def _read(self):
-    
-        try:
-            self._already_read
-            return
-        except AttributeError:
-            self._already_read = True
-                
-        underkeys = self.underkeys
-        option_parser = self.parser
-        marker_fmt = '{{{%s-(?P<id>\d+)}}}'
-        _self = self
-
-        class BaseClass(object):
-            def __init__(self,matchobj):
-                self.text = matchobj.group('text')
-                self.num = len(self.objects)
-                self.objects.append(self)
-            def restore(self):
-                return self.text
-
-        class Line(BaseClass):
-            pass
-                
-        class Block(BaseClass):
-            objects = []
-            find_re = re.compile('<b>(?P<text>.*?)</b>',re.DOTALL)
-
-        class Verbatim(BaseClass):
-            objects = []
-            find_re = re.compile('<v>(?P<text>.*?)</v>',re.DOTALL)
-
-        class Comment(BaseClass):
-            objects = []
-            find_re = re.compile('(?P<text>[ \t]*[#;].*)')
-
-        class OptionPair(Value):
-            # OptionPair must subclass Value() because it is being submitted into  the
-            # parser options dictionary (all options in the dictionary must be a 
-            # subclass of Value).  All things equal this would subclass BaseClass()
-            # but it implements all that functionality anyways.
-            objects = []
-            find_re = re.compile('(?P<indent>[ \t]*)(?P<name>.+?)(?P<sep>\s*=\s*)(?P<value>.*)')
-            section = None
-            def __init__(self,matchobj):
-                section_keys = OptionPair.section.keys
-                # get the name right            
-                name = matchobj.group('name')
-                self.extended_name = name
-                if '[' in name:
-                    name,keys = name.strip(']').split('[')
-                    section_keys = section_keys + split_keys(keys)
-                self.name = name
-                self.indent = matchobj.group('indent')
-                self.sep = matchobj.group('sep')
-                value = matchobj.group('value')
-                self.valueplus = value
-                try:
-                    value = restore(Comment,value)
-                    value = restore(Block,value)
-                    value = restore(Verbatim,value)
-                    self.linenum = re.findall(marker_fmt % 'Line',value)[0]
-                except IndexError:
-                    self.linenum = 'new'
-                self.num = len(self.objects)
-                self.objects.append(self)
-                self.section = OptionPair.section
-                self.section.options[self.extended_name] = self
-                # The following are needed for Value() functionality
-                self.parent = _self
-                self.section_keys = section_keys
-                # self.value will be set later (can't now because value may contain
-                # interpolations which cannot be expanded until all options are read
-                # for this section
-            def get_roots(self):
-                return Value.get_roots(self) + ["Line: %s" % self.linenum]
-            def set(self,value):
-                Value.set(self,value)
-                value = [value]
-                def hit(matchobj):
-                    value.append(matchobj.group(0))
-                regexp = re.compile(marker_fmt % 'Comment')
-                regexp.sub(hit,self.valueplus)
-                self.valueplus = ''.join(value)
-            def restore(self):
-                return ''.join([self.extended_name,self.sep,self.valueplus])
-            def expand(self,levellist=[]):
-                levellist = levellist + [self.name]
-                if len(levellist) > 10:
-                    lines = self.get_roots()
-                    lines.append("Interpolation: %s" % ' << '.join(levellist))
-                    lines.append("Maximum nesting level exceeded.")
-                    MAX_NESTING_LEVEL_EXCEEDED = '\n' + '\n'.join(lines)
-                    raise ConfigParserUserError(MAX_NESTING_LEVEL_EXCEEDED)
-                try:
-                    return self.value
-                except AttributeError:
-                    pass
-                value = remove(Comment,self.valueplus)
-                value = remove(Line,value)
-                value = restore(Block,value.strip(' \t'))
-                value = remove(Line,value)
-                # @future [ABSPATH] value = value.replace('%(ABSPATH(','%_(ABSPATH(')
-                regexp = re.compile('%\((?P<name>.*?)\)s')
-                def hit(matchobj):
-                    name = matchobj.group('name')
-                    try:
-                        return self.section.options[name].expand(levellist)
-                    except KeyError:
-                        try:
-                            return Section.default.options[name].expand(levellist)
-                        except KeyError:
-                            lines = self.get_roots()
-                            lines.append("Interpolation: %s" % ' << '.join(levellist+[name]))
-                            lines.append("'%s' not found in section or in [DEFAULT]." % name)
-                            INTERPOLATION_ERROR = '\n' + '\n'.join(lines)
-                            raise ConfigParserUserError(INTERPOLATION_ERROR)
-                value = regexp.sub(hit,value)
-                # @future [ABSPATH] regexp = re.compile(r'%_\(ABSPATH\((.*?)\)\)s')
-                # def hit(matchobj):
-                #     return os.path.abspath(matchobj.group(1))
-                # value = regexp.sub(hit,value)
-                self.value = remove(Line,restore(Verbatim,value))
-                return self.value
-                
-        class Section(BaseClass):
-            objects = []
-            find_re = re.compile('(?P<text>\n\[(?P<name>.*?)\].*?(?=\n\[))',re.DOTALL)
-            default = None
-            def __init__(self,matchobj):
-                self.options = {}
-                name = matchobj.group('name')
-                self.name = name
-                keys = split_keys(name)
-                if keys == ['DEFAULT']:
-                    keys = []
-                if not keys:
-                    Section.default = self
-                self.keys = keys
-                OptionPair.section = self
-                self.text =  collapse(OptionPair,matchobj.group(0))
-                self.num = len(self.objects)
-                self.objects.append(self)
-            def add_option(self,name,value,help):
-                if help:
-                    helplines = textwrap.fill(help,77).split('\n')
-                    lines = ['# %s' % line for line in helplines]
-                else:
-                    lines = []
-                lines.append('%s = %s' % (name,value))
-                OptionPair.section = self
-                block = collapse(Comment,'\n'+'\n'.join(lines))
-                self.text +=  collapse(OptionPair,block)
-                option = OptionPair.objects[-1]
-                underkeys = _self.underkeys + option.section_keys
-                if not underkeys:
-                    underkeys = ['DEFAULT']
-                # submit new value to parser
-                _self.parser.merge_option(name,option,underkeys)
-                return option
-                                                
-        def collapse(SubClass,text):
-            marker_fmt = '{{{%s-%%d}}}' % (SubClass.__name__)
-            def hit(matchobj):
-                return marker_fmt % SubClass(matchobj).num
-            return SubClass.find_re.sub(hit,text)
-
-        def remove(SubClass,text):
-            return re.compile(marker_fmt % SubClass.__name__).sub('',text)
-
-        def restore(SubClass,text):
-            def hit(matchobj):
-                return SubClass.objects[int(matchobj.group('id'))].restore()
-            return re.compile(marker_fmt % SubClass.__name__).sub(hit,text)
-
-        text = self.get_as_str()
-        lines = []
-        i = 1
-        for line in text.split('\n'):
-            lines.append(line + ('{{{Line-%d}}}' % i))
-            i += 1
-        text = '\n'.join(lines)
-        text = '\n[DEFAULT]\n#_START_MARKER_\n%s\n[' % text
-        text = collapse(Block,text)
-        text = collapse(Verbatim,text)
-        text = collapse(Comment,text)
-        text = collapse(Section,text)
-        
-        self._OptionPair = OptionPair
-        self._Line = Line
-        self._Comment = Comment
-        self._Block = Block
-        self._Verbatim = Verbatim
-        self._Section = Section
-        self._collapse = collapse 
-        self._restore = restore
-        self._remove = remove
-        self.text = text
-            
-    def parse(self):
-        self._read()
-        for option in self._OptionPair.objects:
-            name = option.name
-            underkeys = self.underkeys + option.section_keys
-            value = option.expand()
-            if name == '<include>':
-                for cf in split_paths(value):
-                    self.parser.add_file(cf,keys=underkeys,parent=self)
-                continue
-            if not underkeys:
-                if name == '<keys>':
-                    self.parser.keys.add_cfg_keys(split_keys(value))
-                    continue
-                if name == '<keys_variable>':
-                    self.parser.keys.add_env_keys(value)
-                    continue
-                underkeys = ['DEFAULT']
-            # call expand method to get .value attribute set
-            self.parser.merge_option(name,option,underkeys)
-
-    def set_option(self,name,value,keys=None,help=None):
-        self._read()
-        value = str(value)
-        keys = split_keys(keys)
-        found = False
-        for option in self._OptionPair.objects:
-            if name==option.name and keys == option.section_keys:
-                option.set(value)
-                found = True
-        if not found:
-            Section = self._Section
-            for section in Section.objects:
-                if keys == section.keys:
-                    found = True
-                    section.add_option(name,value,help)
-            if not found:
-                block = '\n\n[%s]\n\n[\n' % join_keys(keys,'.')
-                self.text = '%s%s' % (self.text[:-2],self._collapse(Section,block))
-                section = self._Section.objects[-1]
-                section.add_option(name,value,help)
-            
-    def write(self,file):
-        self._read()
-        
-        restore = self._restore
-        content = self.text
-        content = restore(self._Section,content)
-        content = restore(self._OptionPair,content) + '\n'
-        content = restore(self._Comment,content)
-        content = restore(self._Block,content)
-        content = restore(self._Verbatim,content)
-        content = self._remove(self._Line,content)
-        content = content.split('\n#_START_MARKER_\n')[1][:-3]
-        
-        try:
-            file.write(content)
-        except AttributeError:
-            f = open(file,'w')
-            f.write(content)
-            f.close()
-
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-#  C O N F I G U R A T I O N   P A R S E R
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-class ConfigParser(OptionContainer):
-
-    KeysClass = Keys
-    OptionGroupClass = OptionGroup
-    
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Initializer
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def __init__(self,description=None,allow_py=False,formatter=None,exception=False):
-        """
-        description -- Introductory text placed above configuration option
-            help text.
-        allow_py -- Set to True to allow Python based configuraton files
-            to be executed.  Defaults to False.  Enabling this feature
-            poses a potential security hole for your application.
-        formatter -- Controls configuration option help text style.  Set
-            to either the IndentedHelpFormatter or TitledHelpFormatter
-            classes found in cfgparse module (or a subclass of either).
-        exception -- set to True to raise ConfigParserUserError exception
-            when configuration error occurs (due to user error).  Omitting
-            or setting to False will write error message to sys.stderr.
-            Set to an exception class to raise that exception when a user
-            configuration file error occurs.
-        """
-        OptionContainer.__init__(self,description)
-
-        self.exception = exception
-        
-        # Needed because shares same base class as an option group
-        # (option group constructor initializes parser using an arg).
-        self.parser = self
-
-        self.option_dicts = {}
-
-        self.option_groups = []
-        self.optpar_option_partners = {}
-        
-        self.master_option_list = []
-        self.master_option_dict = {}
-
-        if formatter is None:
-            formatter = IndentedHelpFormatter()
-        self.formatter = formatter
-        self.formatter.set_parser(self)
-
-        self.notes = []
-        
-        # Set up database of option selection keys        
-        self.keys = self.KeysClass()
-
-        # Create database to store information on those configuration files
-        # to be read later (configuration files under keys are not read until
-        # all of the keys in which it is under are active.
-        self._pending = []
-
-        # Since it introduces a security risk, only allow Python based 
-        # configuration files if application explicitly sets this True.
-        self.allow_python_cfg = allow_py
-
-        self.optparse_dests = {}
-
-    def add_optparse_keys_option(self,option_group,switches=('-k','--keys'),dest='cfgparse_keys',help="Comma separated list of configuration keys."):
-        """Adds configuration file keys list option to optparse object."""
-        self.optparse_dests['keys'] = dest
-        option_group.add_option(dest=dest,metavar='LIST',help=help,*switches)
-        
-    def add_optparse_files_option(self,option_group,switches=('--cfgfiles',),dest='cfgparse_files',help="Comma separated list of configuration files."):
-        """Adds configuration file list option to optparse object."""
-        self.optparse_dests['files'] = dest
-        option_group.add_option(dest=dest,metavar='LIST',help=help,*switches)
-
-    def add_optparse_help_option(self,option_group,switches=('--cfghelp',),dest='cfgparse_help',help="Show configuration file help and exit."):
-        """Adds configuration file help option to optparse object."""
-        self.optparse_dests['help'] = dest
-        option_group.add_option(dest=dest,action='store_true',help=help,*switches)
-
-    def add_env_file(self,var,keys=[]):
-        """Adds configuration file specified by environment variable setting.
-        Arguments:
-        var -- name of environment variable holding configuration file name 
-        keys -- section key list to place configuration file options settings under
-        """
-        # Add configuration files specified by an environment variable
-        # if application script specified it.  (Don't read right away,
-        # rather hold them in pending database until they are needed
-        # because adding options causes option_dicts to be set with a 
-        # default for the option destination.
-        f = os.getenv(var,None)
-        if f:
-            f = self.add_file(cfgfile=f,keys=keys)
-        else:
-            f = None
-        return f
-
-    def get_option(self,dest):
-        """Returns option object previously added.
-        Arguments:
-        dest -- destination attribute name of option
-        """
-        opt = self.master_option_dict.get(dest,None)
-        if opt is None:
-            OPTION_NOT_FOUND = '\n'.join([
-                'ERROR: No option found',
-                'option dest: %s' % dest])
-            raise ConfigParserAppError(OPTION_NOT_FOUND)
-        return opt
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Adding Option Groups (adding options handled by base class)
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def add_option_group(self,title,description=None):
-        option_group = self.OptionGroupClass(self,title,description)
-        self.option_groups.append(option_group)
-        return option_group
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Pending Configuration
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def get_option_dict(self,name,keys):
-        self.parse_pending_cfg(keys)
-        return self.option_dicts.get(name,NOTHING_FOUND)
-
-    def parse_pending_cfg(self,keys=[],read_all=False):
-        """
-        read_all -- Set to True to read all configuration files up front.  
-            Defaults to reading "on the fly" as the configuration files are
-            needed."""
-        # Read any pending configuration files that could possibly effect the
-        # setting about to be retrieved.  Note, it was decided that if the
-        # pending configuration file's under keys are all in the key list
-        # computed above it will be installed right away.  The other
-        # alternative is to try retrieving the setting with the highest
-        # priority key alone (first reading any pending configuration files
-        # that are under that key), then if that fails try retrieving the
-        # setting with the top two highest priority keys (again first reading
-        # any pending configuration files that are under either or both of the
-        # keys), and repeating this process for each key in the list until a
-        # setting is found.  This would have the benefit of only reading
-        # pending configuration files when it is absolutely necessary but at
-        # cost of performance and more difficult to explain how it works.
-        keys = split_keys(keys)
-        d = []
-        while self._pending:
-            underkeys,cfgfileobj = self._pending.pop(0)
-            underkeys = split_keys(underkeys)
-            parse_it = read_all
-            if not parse_it:
-                for key in underkeys:
-                    if key not in keys:
-                        d.append((underkeys,cfgfileobj))
-                        break
-                else:
-                    parse_it = True
-            if parse_it:
-                cfgfileobj.parse_if_unparsed()
-        self._pending = d
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    FileClasses = {'py' : ConfigFilePy, 'ini': ConfigFileIni, 'default' : ConfigFileIni}
-
-    def add_file(self,cfgfile=None,content=None,type=None,keys=[],parent=None):
-        """
-        Adds configuration file to parser.  Note, file is not read until parse 
-        or get_option method is called (and even then it may not be read if any
-        keys in the keys list are not in the keys being used to parse).
-        
-        cfgfile -- either the filename or a file stream, defaults to None (see table below)
-        content -- either file contents string or file stream, defaults to None (see table below)
-        type -- set to either 'py', 'ini', or None (default) to control file parser used.   
-            When set to None, filename extension is used to determine parser to use.  'py'
-            interprets the file as Python code.  Otherwise the 'ini' style parser is used.
-        keys -- key list that all options in the configuration file will 
-            be placed under when the file is read.
-        parent -- Not intended to be used by the public
-
-        The following table summarizes the legal combinations of the cfgfile and
-        arguments and resulting file name and contents utilized.
-                    
-        cfgfile   content  result (when configuration is parsed)
-        --------  -------  -----------------------------------------------------------
-        filename  None     file is opened and contents read
-        stream    None     stream contents are read, filename is stream name attribute
-        filename  stream   stream contents are read, filename is cfgfile argument
-        filename  string   both filename and content are used as is
-        """
-
-        if isinstance(cfgfile,str):
-            n = cfgfile
-            c = content
-        elif hasattr(cfgfile,'name'):
-            n = cfgfile.name
-            c = cfgfile
-        elif isinstance(content,str):
-            n = 'heredoc'
-            c = content
-        elif hasattr(content,'read'):
-            n = 'stream'
-            c = content
-        else:
-            ARGUMENT_CONFICT = "Illegal combination of 'cfgfile' and 'content' arguments"
-            raise ConfigParserAppError(ARGUMENT_CONFICT)
-        
-        uk = split_keys(keys)
-
-        if type is None:
-            # calculate type (lower case extension)
-            type = os.path.splitext(n)[1][1:].lower()
-
-        if type == 'py' and not self.allow_python_cfg:
-            return None
-
-        FileClass = self.FileClasses.get(type)
-        if FileClass is None:
-            FileClass = self.FileClasses['default']
-
-        fileobj = FileClass(cfgfile=n,content=c,keys=uk,parent=parent,parser=self)
-        self._pending.append((uk,fileobj))
-        return fileobj
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Read Configuration File Utilities
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def merge_option(self,name,value,keys):
-        """ Merge value (under keys) into options dictionary.
-
-        name -- option name
-        value -- value to assign option (may be a dictionary or a option)
-        keys -- list of keys to place value in options dict under
-        """
-        
-        # Add the option name to the key list so we can start walking at
-        # the top level of the options dictionary.
-        keys = [name] + keys
-        option_dicts = self.option_dicts
-        # Move through the options dictionary using the keys we are
-        # supposed to place the value under creating dictionaries and keys 
-        # that aren't already present.
-        for key in keys[:-1]:
-            if key in option_dicts:
-                if option_dicts[key].__class__ is not dict:
-                    option_dicts[key] = dict(DEFAULT=option_dicts[key])
-            else:
-                option_dicts[key]={}
-            option_dicts = option_dicts[key]
-        option_dicts[keys[-1]] = value
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Option Parsing (not configuration file parsing)
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def write_errors(self,errors):
-        CFGPARSE_USER_ERROR = '\n' + '\n'.join(errors)
-        if not self.exception:
-            sys.stderr.write("ERROR: Configuration File Parser\n")           
-            sys.stderr.write(CFGPARSE_USER_ERROR)
-            self.system_exit()
-        else:
-            if self.exception is True:
-                UserError = ConfigParserUserError
-            else:
-                UserError = self.exception
-            raise UserError(CFGPARSE_USER_ERROR)
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Option Parsing
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def parse(self,optparser=None,args=None,read_all=False):
-        """Partners the option parser and the configuration parser together
-        read_all -- Set to True to read all configuration files up front.  
-            Defaults to reading "on the fly" as the configuration files are
-            needed.
-        """
-
-        if optparser:
-            # Marry up type, help, choices attributes between option parser and
-            # configuration parser options.
-            self.marry_options(optparser)
-
-            # Parse command line arguments
-            options, args = optparser.parse_args(args)
-            self.optparser_options = options
-
-            # generate help if requested from the command line
-            help_dest = self.optparse_dests.get('help')
-            if help_dest and getattr(options,help_dest):
-                self.print_help()
-                self.system_exit()
-
-            # add command line keys
-            keys_dest = self.optparse_dests.get('keys')
-            if keys_dest:
-                self.keys.add_cmd_keys(getattr(options,keys_dest))
-
-            # add command line configuration files (must hold it as other configuration
-            # files may be pending that should be read first)
-            files_dest = self.optparse_dests.get('files')
-            if files_dest:
-                cfgfiles = getattr(options,files_dest)
-                for cf in split_paths(cfgfiles):
-                    self.add_file(cfgfile=cf,keys=[])
-        else:
-            class ConfigOptions(object):
-                pass
-            options = ConfigOptions()
-
-        self.parse_pending_cfg([],read_all)
-
-        # Go through each option in the configuration options and add them
-        # to options object.
-        errors = []
-        for option in self.master_option_list:
-            setattr(options,option.dest,option.get(errors=errors))
-        if errors:
-            self.write_errors(errors)
-
-        if optparser:
-            return options, args
-        else:
-            return options
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def marry_options(self,optparser):
-        # create mapping: dest -> [optpar options]
-        optpar_lookup = {}
-        for option in optparser.option_list:
-            if option.dest:
-                optpar_lookup.setdefault(option.dest,[]).append(option)
-        for group in optparser.option_groups:
-            for option in group.option_list:
-                if option.dest:
-                    optpar_lookup.setdefault(option.dest,[]).append(option)
-        self.optpar_option_partners = optpar_lookup
-
-        # we are guarenteed no duplicate destinations with a configuration parser
-        for cfgpar_option in self.master_option_list:
-            optpar_options = optpar_lookup.get(cfgpar_option.dest,[])
-            for optpar_option in optpar_options:
-                for attrname in ['metavar','type','choices','help']:
-                    cfgpar_attr = getattr(cfgpar_option,attrname)
-                    optpar_attr = getattr(optpar_option,attrname)
-                    if cfgpar_attr is None:
-                        cfgpar_attr = optpar_attr
-                        setattr(cfgpar_option,attrname,cfgpar_attr)
-                if cfgpar_option.help == SUPPRESS_HELP:
-                    continue
-                try:
-                    # remove anything we've added previously
-                    optpar_option.help = optpar_option.help.replace(optpar_option._cfgparse_help,'')
-                except AttributeError:
-                    # must not have modified it previously
-                    pass
-                help = "  See also '%s' option in configuration file help." % (cfgpar_option.name)
-                if not optpar_option.help:
-                    help = help.strip()
-                    optpar_option.help = ''
-                optpar_option.help = optpar_option.help + help
-                optpar_option._cfgparse_help = help
-            if cfgpar_option.help == SUPPRESS_HELP:
-                continue
-            if cfgpar_option.help is None:
-                cfgpar_option.help = ''
-            try:
-                # remove anything we've added previously
-                cfgpar_option.help = cfgpar_option.help.replace(cfgpar_option._help_xref,'')
-            except AttributeError:
-                # must not have modified it previously
-                pass
-            switches = '/'.join([str(o) for o in optpar_options])
-            if switches:
-                help = "  See also '%s' command line switch." % (switches)
-                if not cfgpar_option.help:
-                    help = help.strip()
-                cfgpar_option.help = cfgpar_option.help + help
-                cfgpar_option._help_xref = help
-                            
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def marry_attribute(self,attrname,cfgpar_option,optpar_option):
-        cfgpar_attr = getattr(cfgpar_option,attrname)
-        optpar_attr = getattr(optpar_option,attrname)
-        if cfgpar_attr is None:
-            cfgpar_attr = optpar_attr
-            setattr(cfgpar_option,attrname,cfgpar_attr)
-            
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Help
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    # <borrowed file="Lib/optparse.py" version="python2.4" modified="yes">
-    def format_option_help(self, formatter=None):
-        if formatter is None:
-            formatter = self.formatter
-        formatter.store_option_strings(self)
-        result = []
-        result.append(formatter.format_heading(_("Configuration file options")))
-        formatter.indent()
-        if self.option_list:
-            result.append(OptionContainer.format_option_help(self, formatter))
-            result.append("\n")
-        for group in self.option_groups:
-            result.append(group.format_help(formatter))
-            result.append("\n")
-        formatter.dedent()
-        # Drop the last "\n", or the header if no options or option groups:
-        return "".join(result[:-1])
-
-    def format_help(self, formatter=None):
-        if formatter is None:
-            formatter = self.formatter
-        result = []
-        if self.description:
-            result.append(self.format_description(formatter) + "\n")
-        result.append(self.format_option_help(formatter))
-        return "".join(result)
-
-    def print_help(self, file=None):
-        """print_help(file : file = stdout)
-
-        Print an extended help message, listing all options and any
-        help text provided with them, to 'file' (default stdout).
-        """
-        if file is None:
-            file = sys.stdout
-        
-        file.write(self.format_help())
-
-        if self.notes:
-            file.write('\nNotes:\n%s\n'%'\n'.join(self.notes))
-    
-    # </borrowed>
-    
-    def add_note(self,note):
-        self.notes.append(note)
-
-    def system_exit(self):
-        sys.exit()
-
-
-def _test():
-    import doctest
-    doctest.testmod()
-
-if __name__ == "__main__":
-    _test()
-
diff --git a/synthesis/cfgparse3.py b/synthesis/cfgparse3.py
deleted file mode 100644
index c4651521886067675c76a1a2e693e9ae70e26438..0000000000000000000000000000000000000000
--- a/synthesis/cfgparse3.py
+++ /dev/null
@@ -1,1773 +0,0 @@
-# -*- coding: utf-8 -*-
-"""cfgparse - a powerful, extensible, and easy-to-use configuration parser.
-
-By Dan Gass <dan.gass@gmail.com>
-
-If you have problems with this module, please file bugs through the Source
-Forge project page:
-  http://sourceforge.net/projects/cfgparse
-"""
-
-# @future use option note when get error
-# @future print file/section/linenumber information when checks fail
-# @future - check type='choice' and choices=[] one must have the other
-# @future -- do we have a command line --cfgcheck option that expands all configuration and checks all possible keys?
-
-__version__ = "1.3"
-
-__all__ = []
-
-__copyright__ = """
-Copyright (c) 2004 by Daniel M. Gass.   All rights reserved.
-Copyright (c) 2001-2004 Gregory P. Ward.  All rights reserved.
-Copyright (c) 2002-2004 Python Software Foundation.  All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-  * Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
-  * Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-
-  * Neither the name of the author nor the names of its
-    contributors may be used to endorse or promote products derived from
-    this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""
-
-import sys
-if sys.version_info > (3,0):
-    import configparser as _ConfigParser
-else:
-    import ConfigParser as _ConfigParser
-import io
-import os
-import re
-import textwrap
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-# U T I L I T Y
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-# <borrowed file="Lib/optparse.py" version="python2.4" modified="yes">
-try:
-    from gettext import gettext as _
-except ImportError:
-    _ = lambda arg: arg
-
-class HelpFormatter:
-    """
-    Abstract base class for formatting option help.  ConfigParser
-    instances should use one of the HelpFormatter subclasses for
-    formatting help; by default IndentedHelpFormatter is used.
-
-    Instance attributes:
-      parser : OptionParser
-        the controlling OptionParser instance
-      indent_increment : int
-        the number of columns to indent per nesting level
-      max_help_position : int
-        the maximum starting column for option help text
-      help_position : int
-        the calculated starting column for option help text;
-        initially the same as the maximum
-      width : int
-        total number of columns for output (pass None to constructor for
-        this value to be taken from the $COLUMNS environment variable)
-      level : int
-        current indentation level
-      current_indent : int
-        current indentation level (in columns)
-      help_width : int
-        number of columns available for option help text (calculated)
-      default_tag : str
-        text to replace with each option's default value, "%default"
-        by default.  Set to false value to disable default value expansion.
-      option_strings : { Option : str }
-        maps Option instances to the snippet of help text explaining
-        the syntax of that option, e.g. "option=VALUE"
-    """
-
-    NO_DEFAULT_VALUE = "none"
-
-    def __init__(self,
-                 indent_increment,
-                 max_help_position,
-                 width,
-                 short_first):
-        self.parser = None
-        self.indent_increment = indent_increment
-        self.help_position = self.max_help_position = max_help_position
-        if width is None:
-            try:
-                width = int(os.environ['COLUMNS'])
-            except (KeyError, ValueError):
-                width = 80
-            width -= 2
-        self.width = width
-        self.current_indent = 0
-        self.level = 0
-        self.help_width = None          # computed later
-        self.short_first = short_first
-        self.default_tag = "%default"
-        self.option_strings = {}
-        self._short_opt_fmt = "%s %s"
-        self._long_opt_fmt = "%s=%s"
-
-    def set_parser(self, parser):
-        self.parser = parser
-
-    def indent(self):
-        self.current_indent += self.indent_increment
-        self.level += 1
-
-    def dedent(self):
-        self.current_indent -= self.indent_increment
-        assert self.current_indent >= 0, "Indent decreased below 0."
-        self.level -= 1
-
-    def format_usage(self, usage):
-        raise NotImplementedError("subclasses must implement")
-
-    def format_heading(self, heading):
-        raise NotImplementedError("subclasses must implement")
-
-    def format_description(self, description):
-        if not description:
-            return ""
-        desc_width = self.width - self.current_indent
-        indent = " "*self.current_indent
-        return textwrap.fill(description,
-                             desc_width,
-                             initial_indent=indent,
-                             subsequent_indent=indent) + "\n"
-
-    def expand_default(self, option):
-        if self.parser is None or not self.default_tag:
-            return option.help
-
-        try:
-            default_value = option.default
-        except AttributeError:
-            default_value = None
-
-        if default_value is NO_DEFAULT or default_value is None:
-            default_value = self.NO_DEFAULT_VALUE
-
-        return option.help.replace(self.default_tag, str(default_value))
-
-    def format_option(self, option):
-        # The help for each option consists of two parts:
-        #   * the opt strings and metavars
-        #     eg. ("option=VALUE")
-        #   * the user-supplied help string
-        #     eg. ("turn on expert mode", "read data from FILENAME")
-        #
-        # If possible, we write both of these on the same line:
-        #   option=VALUE  explanation of some option
-        #
-        # But if the opt string list is too long, we put the help
-        # string on a second line, indented to the same column it would
-        # start in if it fit on the first line.
-        #   thisoption=WAY_TO_LONG
-        #           explanation of the long option
-        result = []
-        opts = self.option_strings[option]
-        opt_width = self.help_position - self.current_indent - 2
-        if len(opts) > opt_width:
-            opts = "%*s%s\n" % (self.current_indent, "", opts)
-            indent_first = self.help_position
-        else:                       # start help on same line as opts
-            opts = "%*s%-*s  " % (self.current_indent, "", opt_width, opts)
-            indent_first = 0
-        result.append(opts)
-        if option.help:
-            help_text = self.expand_default(option)
-            help_lines = textwrap.wrap(help_text, self.help_width)
-            result.append("%*s%s\n" % (indent_first, "", help_lines[0]))
-            result.extend(["%*s%s\n" % (self.help_position, "", line)
-                           for line in help_lines[1:]])
-        elif opts[-1] != "\n":
-            result.append("\n")
-        return "".join(result)
-
-    def store_option_strings(self, parser):
-        self.indent()
-        max_len = 0
-        for opt in parser.option_list:
-            strings = self.format_option_strings(opt)
-            self.option_strings[opt] = strings
-            max_len = max(max_len, len(strings) + self.current_indent)
-        self.indent()
-        for group in parser.option_groups:
-            for opt in group.option_list:
-                strings = self.format_option_strings(opt)
-                self.option_strings[opt] = strings
-                max_len = max(max_len, len(strings) + self.current_indent)
-        self.dedent()
-        self.dedent()
-        self.help_position = min(max_len + 2, self.max_help_position)
-        self.help_width = self.width - self.help_position
-
-    def format_option_strings(self, option):
-        """Return a comma-separated list of option strings & metavariables."""
-        metavar = option.metavar or option.dest.upper()
-        return '%s=%s' % (option.name,metavar)
-
-class IndentedHelpFormatter (HelpFormatter):
-    """Format help with indented section bodies.
-    """
-    # NOTE optparse
-    def __init__(self,
-                 indent_increment=2,
-                 max_help_position=24,
-                 width=None,
-                 short_first=1):
-        HelpFormatter.__init__(
-            self, indent_increment, max_help_position, width, short_first)
-
-    def format_usage(self, usage):
-        return _("usage: %s\n") % usage
-
-    def format_heading(self, heading):
-        return "%*s%s:\n" % (self.current_indent, "", heading)
-
-class TitledHelpFormatter (HelpFormatter):
-    """Format help with underlined section headers.
-    """
-    # NOTE optparse
-    def __init__(self,
-                 indent_increment=0,
-                 max_help_position=24,
-                 width=None,
-                 short_first=0):
-        HelpFormatter.__init__ (
-            self, indent_increment, max_help_position, width, short_first)
-
-    def format_usage(self, usage):
-        return "%s  %s\n" % (self.format_heading(_("Usage")), usage)
-
-    def format_heading(self, heading):
-        return "%s\n%s\n" % (heading, "=-"[self.level] * len(heading))
-
-SUPPRESS_HELP = "SUPPRESS"+"HELP"
-NO_DEFAULT = ("NO", "DEFAULT")
-
-def _repr(self):
-    return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self)
-# </borrowed>
-
-NOTHING_FOUND = ("NOTHING","FOUND")
-
-def split_keys(keys):
-    """Returns list of keys resulting from keys argument.
-
-        --- NO KEYS ---
-        >>> split_keys( None )
-        []
-        >>> split_keys( [] )
-        []
-
-        --- STRINGS ---
-        >>> split_keys( "key1" )
-        ['key1']
-        >>> split_keys( "key1,key2" )
-        ['key1', 'key2']
-        >>> split_keys( "key1.key2" )
-        ['key1', 'key2']
-        >>> split_keys( "key1.key2,key3" )
-        ['key1', 'key2', 'key3']
-
-        --- LISTS ---
-        >>> split_keys( ['key1'] )          # single item
-        ['key1']
-        >>> split_keys( ['key1','key2'] )   # multiple items
-        ['key1', 'key2']
-
-        --- QUOTING ---
-        These tests check that quotes can be used to protect '.' and ','.
-        >>> split_keys( "'some.key1','some,key2'" )    # single ticks work 
-        ['some.key1', 'some,key2']
-        >>> split_keys( '"some,key1","some.key2"' )    # double ticks work
-        ['some,key1', 'some.key2']
-        >>> split_keys( '"some,key1",some.key2' )      # must quote everything
-        Traceback (most recent call last):
-        ConfigParserError: Keys not quoted properly.  Quotes must surround all keys.
-        >>> split_keys( "some,key1,'some.key2'" )      # must quote everything
-        Traceback (most recent call last):
-        ConfigParserError: Keys not quoted properly.  Quotes must surround all keys.
-        >>> split_keys( "key1,'some.key2'.key3" )      # must quote everything
-        Traceback (most recent call last):
-        ConfigParserError: Keys not quoted properly.  Quotes must surround all keys.
-        >>> split_keys('DEFAULT')
-        []
-        >>> split_keys(['DEFAULT'])
-        []
-        """
-    if (keys is None) or (keys == 'DEFAULT') or (keys == ['DEFAULT']):
-        return []
-    try:
-        keys = keys.replace('"',"'")
-        if "'" in keys:
-            keys = keys.strip("'").split("','")
-            for key in keys:
-                if "'" in key:
-                    IMPROPER_QUOTES = "Keys not quoted properly.  Quotes must surround all keys."
-                    raise ConfigParserUserError(IMPROPER_QUOTES)
-        else:
-            keys = keys.replace('.',',').split(',')
-    except AttributeError:
-        pass
-    return keys
-
-def join_keys(keys,sep=','):
-    """
-    >>> join_keys(['key1'])
-    'key1'
-    >>> join_keys(['key1','key2'])
-    'key1,key2'
-    >>> join_keys(['key1','key2'],'.')
-    'key1.key2'
-    >>> join_keys(['key.1','key2'],'.')
-    "'key.1','key2'"
-    >>> join_keys(['key,1','key2'],'.')
-    "'key,1','key2'"
-    >>> join_keys([])
-    'DEFAULT'
-    """
-    if not keys:
-        return 'DEFAULT'
-    mash = ''.join(keys)
-    if '.' in mash or ',' in mash:
-        quote = "'"
-        sep = quote + ',' + quote
-        return quote + sep.join(keys) + quote
-    return sep.join(keys)
-
-def split_paths(paths):
-    """Returns list of paths resulting from paths argument.
-
-        --- NO KEYS ---
-        >>> split_paths( None )
-        []
-        >>> split_paths( [] )
-        []
-
-        --- STRINGS ---
-        >>> split_paths( "path1" )
-        ['path1']
-        >>> split_paths( os.path.pathsep.join(["path1","path2"]) )
-        ['path1', 'path2']
-        >>> split_paths( "path.1,path.2" )
-        ['path.1', 'path.2']
-
-        --- LISTS ---
-        >>> split_paths( ['path1'] )          # single item
-        ['path1']
-        >>> split_paths( ['path1','path2'] )   # multiple items
-        ['path1', 'path2']
-        """
-    if paths is None:
-        return []
-    try:
-        return paths.replace(',',os.path.pathsep).split(os.path.pathsep)
-    except AttributeError:
-        return paths
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-#  E X C E P T I O N S
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-class ConfigParserError(Exception):
-    """Exception associated with the cfgparse module"""
-    pass
-    
-class ConfigParserAppError(Exception):
-    """Exception due to application programming error"""
-    pass
-    
-class ConfigParserUserError(Exception):
-    """Exception due to user error"""
-    pass
-    
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-#  K E Y S
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-class Keys(object):
-    """Prioritizes and stores default configuration keys.
-    
-    This class is used to store default configuration keys for an instance
-    of the Config class.  The different sources of keys are supported (stored)
-    by the following methods of this class:
-
-    add_cfg_keys -- configuration file specified default keys
-    add_cmd_keys -- command line option keys
-    add_env_keys -- environment variable keys
-    
-    The 'get' method returns a combined list of keys in the following order:
-        application keys (passed when calling 'get' method)
-        command line keys
-        environment variable keys
-        configuration file keys
-        a 'DEFAULT' key (always present)
-
-    Setup: modify os module to fake out environment variable gets
-    >>> _getenv = os.getenv
-    >>> def getenv(variable,default):
-    ...     if variable == 'VAR12':
-    ...         return 'env1,env2'
-    ...     elif variable == 'VAR3':
-    ...         return 'env3'
-    ...     elif variable == 'VAR4':
-    ...         return 'env4'
-    ...     else:
-    ...         return default
-    >>> os.getenv = getenv
-
-    Case 1: normal string lists of keys
-    >>> k = Keys()
-    >>> k.add_env_keys('VAR12,VAR3') # this has effect
-    >>> k.add_env_keys('VAR_NONE')   # no effect
-    >>> k.add_cfg_keys('cfg1,cfg2')
-    >>> k.add_cmd_keys('cmd1.cmd2')
-    >>> k.add_env_keys('VAR12')      # no effect (already read)
-    >>> k.get('app1,app2')
-    ['app1', 'app2', 'cmd1', 'cmd2', 'env1', 'env2', 'env3', 'cfg1', 'cfg2', 'DEFAULT']
-
-    Case 2: extend lists using other key input flavors just to make sure each
-            method uses split_keys()
-    >>> k.add_env_keys(['VAR4'])     # this has effect
-    >>> k.add_cfg_keys(['cfg3'])
-    >>> k.add_cmd_keys(['cmd3'])
-    >>> k.get(['app'])
-    ['app', 'cmd1', 'cmd2', 'cmd3', 'env1', 'env2', 'env3', 'env4', 'cfg1', 'cfg2', 'cfg3', 'DEFAULT']
-
-    Teardown: restore os module
-    >>> os.getenv = _getenv
-    """
-    
-    def __init__(self):
-        """Initialize Keys Instance"""
-        self.cmd_keys = []
-        self.env_keys = []
-        self.cfg_keys = []
-        self.env_vars = []
-
-    def __repr__(self):
-        """Return string representation of object"""
-        return ','.join(self.get([]))
-
-    def add_cmd_keys(self,keys):
-        """Store keys from command line interface
-
-        keys -- list of keys (typically from the command line) to store.  May
-            be a list of keys or a string with keys separated by commas.
-            Use any value which evaluates False when no keys.
-        """
-        self.cmd_keys.extend(split_keys(keys))
-
-    def add_env_keys(self,variables):
-        """Store keys from invoking shell's environment variable
-
-        variable -- (string) environment variable name from which to obtain
-            keys to store
-        """
-        variables = split_keys(variables)
-        for variable in variables:
-            # only add keys from shell environment variable if we haven't already
-            if variable not in self.env_vars:
-                # save key variable name so we can't add same keys twice
-                self.env_vars.append(variable)
-                # if shell environment variable has a option save it
-                keys = os.getenv(variable,None)
-                if keys is not None:
-                    self.env_keys.extend(split_keys(keys))
-
-    def add_cfg_keys(self,keys):
-        """Store keys from user's configuration file.
-
-        keys -- list of keys (from user's configuration file) to store.  May
-            be a list of keys or a string with keys separated by comma.
-            Use any value which evaluates False when no keys.
-        """
-        self.cfg_keys.extend(split_keys(keys))
-
-    def get(self,keys=None):
-        """Return prioritized list of stored configuration keys
-
-        keys -- list of differentiator keys.  May be a list of keys or a string
-            with keys separated by commas.  Use any valid which evaluates
-            False when no keys.
-        """
-        keys = split_keys(keys)
-        return (keys + self.cmd_keys + self.env_keys + self.cfg_keys +
-                ['DEFAULT'])
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-#  O P T I O N   V A L U E
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-class Value(object):
-    """Used to store option settings in the blended option dictionary.
-    Needed to be able to tie the option setting back to the configuration
-    file for better error reporting and for round trip get/set/write
-    capability."""
-    def __init__(self,value,parent,section_keys):
-        """Initializes instance."""
-        self.value = value
-        self.parent = parent
-        self.section_keys = section_keys
-
-    def set(self,value):
-        """Sets option setting to 'value' argument passed in.  
-        
-        By default configuration file parsers to do not support round trip.
-        If they do they should subclass Value() and override this method
-        """
-        self.value = value
-
-    def get_roots(self):
-        return ["File: %s" % self.parent.get_filename(),
-                "Section: [%s]" % join_keys(self.section_keys,'.')]
-        
-    def __str__(self):
-        """Returns string representation of the setting."""
-        return str(self.value)
-
-    __repr__ = _repr
-
-    def get(self):
-        """Returns the option setting."""
-        return self.value
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-#  O P T I O N
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-class Option(object):
-    """Options added to configuration parser are an instance of this class."""
-
-    def __init__(self,**kwargs):
-        """Instance initializer.
-        Arguments:
-        kwargs -- dictionary with keys parser,name,type,default,help,check,keys,
-                  choices (see add_option of OptionContainer)
-        """
-        self.__dict__.update(kwargs)
-        if self.dest is None:
-            self.dest = self.name
-        if self.type not in self.conversions:
-            TYPE_DOES_NOT_EXIST = "type '%s' is not valid" % self.type
-            raise ConfigParserAppError(TYPE_DOES_NOT_EXIST)
-        # help cross reference for options partnered with OptionParser
-        self._help_xref = ""
-        self.note = None
-
-    def __str__(self):
-        """Returns string representation of the option."""
-        return self.name
-
-    __repr__ = _repr
-
-    def add_note(self,note):
-        """Adds 'note' argument text to configuration parser help text and 
-        to error messages associated with this option."""
-        self.parser.add_note(note)
-        self.note = note
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Get
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def _get(self,keys):
-        # Read any pending configuration files at the top level in order to
-        # pick up user's default keys in those files.
-        self.parser.parse_pending_cfg([])
-
-        keys = split_keys(keys) + self.keys
-        keys = self.parser.keys.get(keys)
-
-        # Get the option's dictionary from the configuration parser so that
-        # any pending configuration files that are needed are read.
-        option = self.parser.get_option_dict(self.name,keys)
-
-        # When keys are given as an argument, we don't have the constraints
-        # of an exact match like a section.  Instead we use the default
-        # key list (highest priority key first) to walk the option
-        # dictionary.  At each level of the dictionary we look for the
-        # highest priority key and if it exists we move down a level
-        # otherwise the remaining keys are checked in order of priority.
-
-        def walk_option(option):
-            if option.__class__ is dict:
-                for key in keys:
-                    if key in option:
-                        v = walk_option(option[key])
-                        if v.__class__ is not dict:
-                            return v
-            if isinstance(option,Value):
-                return option
-            else:
-                return NOTHING_FOUND
-
-        return walk_option(option)
-    
-    def get(self,keys=[],errors=None):
-        """Returns option value associated with 'keys' argument or options
-        option value using 'keys' argument (in combination with other keys).
-
-        keys -- name of keys to obtain option value from
-
-        Note:
-           If option is partnered with an optparse option and that option
-           is present, the optparse option will take priority and be returned.
-        """
-
-        warnings = []
-        option = NOTHING_FOUND
-
-        def convert(value,option_help):
-            # Do conversion to the type application specified
-            value,warning = self.conversions[self.type](self,value)
-            # Do final check using application check function if supplied
-            if not warning and self.check is not None:
-                value,warning = self.check(value)
-            if warning:
-                try:
-                    warnings.extend(option_help.get_roots())
-                except AttributeError:
-                    warnings.append(option_help)
-                warnings.append(warning)
-            return value
-
-        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-        # Priority 1: Get option from optparse partner (command line)
-        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-        if self.dest in self.parser.optpar_option_partners:
-            option = getattr(self.parser.optparser_options,self.dest,None)
-            if option is None:
-                option = NOTHING_FOUND
-            else:
-                option = convert(option,'command line option')
-
-        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-        # Priority 2: Get a default option
-        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-        if option is NOTHING_FOUND and not warnings:
-
-            option = self._get(keys)
-        
-            if option is not NOTHING_FOUND:
-                value = option.get()
-                option = convert(value,option)
-
-        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-        # Priority 3: Use default specified when adding the option
-        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-        if option is NOTHING_FOUND and not warnings:
-            if self.default is not NO_DEFAULT:
-                option = self.default
-            else:
-                warnings.append('No valid default found.')
-                keys = split_keys(keys) + self.keys
-                keys = self.parser.keys.get(keys)
-                warnings.append('keys=%s' % ','.join(keys))
-                    
-        if warnings:
-            lines = ['Option: %s' % self.name] + warnings
-            lines = '\n'.join(lines) + '\n'
-            if errors is not None:
-                errors.append(lines)
-            else:
-                # not coming back
-                self.parser.write_errors([lines])
-        
-        return option
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Conversions
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def convert_choice(self,value):
-        if value in self.choices:
-            return value,None
-        else:
-            choices = str(self.choices).strip('[]()')
-            warning = "Invalid choice '%s', must be one of: %s" % (value,choices) 
-            return None,warning
-
-    def convert_complex(self,value):
-        try:
-            return complex(value),None
-        except ValueError:
-            return None,"Cannot convert '%s' to a complex number" % (value)
-
-    def convert_float(self,value):
-        try:
-            return float(value),None
-        except ValueError:
-            return None,"Cannot convert '%s' to a float" % (value)
-
-    def convert_int(self,value):
-        try:
-            return int(value),None
-        except ValueError:
-            return None,"Cannot convert '%s' to an integer" % (value)
-
-    def convert_long(self,value):
-        try:
-            return int(value),None
-        except ValueError:
-            return None,"Cannot convert '%s' to a long" % (value)
-
-    def convert_string(self,value):
-        try:
-            return str(value),None
-        except ValueError:
-            return None,"Cannot convert '%s' to a string" % (value)
-
-    def convert_nothing(self,value):
-        return value,None
-
-    conversions = {
-        'choice'  : convert_choice,
-        'complex' : convert_complex,
-        'float'   : convert_float,
-        'int'     : convert_int,
-        'long'    : convert_long,
-        'string'  : convert_string,
-        None      : convert_nothing,
-        }
-    
-    def set(self,value,cfgfile=None,keys=None):
-        value = str(value)
-        if cfgfile:
-            if keys is not None:
-                keys = split_keys(keys)
-            else:
-                keys = self.keys
-            cfgfile.set_option(self.name,value,keys,self.help)
-        else:
-            keys = split_keys(keys) + self.keys
-            keys = self.parser.keys.get(keys)
-    
-            option = self._get(keys)
-        
-            if option is NOTHING_FOUND:
-                NOTHING_TO_SET = '\n'.join([
-                    'ERROR: No option found',
-                    'option name: %s' % self.name,
-                    'keys: %s' % keys])
-                raise ConfigParserUserError(NOTHING_TO_SET)
-            else:
-                option.set(value)
-            cfgfile = option.parent
-        return cfgfile
-    
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-#  O P T I O N   C O N T A I N E R   B A S E   C L A S S E S
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-class OptionContainer(object):
-
-    OptionClass = Option    
-
-    def __init__(self,description):
-        self.option_list = []
-        self.set_description(description)
-
-    def set_description(self, description):
-        self.description = description
-
-    def get_description(self):
-        return self.description
-
-    def add_option(self,name,help=None,type=None,choices=None,dest=None,metavar=None,default=NO_DEFAULT,check=None,keys=None):
-        """
-            name -- configuration file option name (used same as optparse)
-            type -- choices similar to optparse (used same as optparse)
-            default -- default value (used same as optparse)
-            help -- help string (used same as optparse)
-            dest -- option database attribute name (used same as optparse)
-            check -- check function
-            keys -- name of keys to obtain option from
-            choices -- list of choices (used same as optparse)
-            metavar -- FUTURE
-        """
-        if dest is None:
-            dest = name
-
-        kwargs = {
-            'parser' : self.parser,
-            'name' : name,
-            'type' : type,
-            'help' : help,
-            'dest' : dest,
-            'check' : check,
-            'keys' : split_keys(keys),
-            'choices' : choices,
-            'metavar' : metavar,
-            'default' : default}
-        
-        option = self.OptionClass(**kwargs)
-        self.parser.master_option_list.append(option)
-        self.parser.master_option_dict[dest] = option
-        self.option_list.append(option)
-        return option
-
-    # <borrowed file="Lib/optparse.py" version="python2.4" modified="yes">
-    
-    def format_option_help(self, formatter):
-        if not self.option_list:
-            return ""
-        result = []
-        for option in self.option_list:
-            if not option.help == SUPPRESS_HELP:
-                result.append(formatter.format_option(option))
-        return "".join(result)
-
-    def format_description(self, formatter):
-        return formatter.format_description(self.get_description())
-
-    def format_help(self, formatter):
-        result = []
-        if self.description:
-            result.append(self.format_description(formatter))
-        if self.option_list:
-            result.append(self.format_option_help(formatter))
-        return "\n".join(result)
-    # </borrowed>
-    
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-#  O P T I O N   G R O U P
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-class OptionGroup(OptionContainer):
-    def __init__(self,parser,title,description):
-        OptionContainer.__init__(self,description)
-        self.parser = parser
-        self.title = title
-
-    # <borrowed file="Lib/optparse.py" version="python2.4" modified="yes">
-    def set_title (self, title):
-        self.title = title
-
-    # -- Help-formatting methods ---------------------------------------
-
-    def format_help (self, formatter):
-        result = formatter.format_heading(self.title)
-        formatter.indent()
-        result += OptionContainer.format_help(self, formatter)
-        formatter.dedent()
-        return result
-    # </borrowed>
-        
-
-class ConfigFile(object):
-    def __init__(self,cfgfile,content,keys,parent,parser):
-        
-        p,n = os.path.split(cfgfile)
-        try:
-            p = os.path.join(parent.path,p)
-        except AttributeError:
-            pass
-        p = os.path.abspath(p)
-        
-        self.path = p
-        self.filename = n
-        self.content = content
-        self.underkeys = keys
-        self.parent = parent
-        self.parser = parser
-
-        self.parsed = False
-
-    def get_filename(self):
-        return os.path.join(self.path,self.filename)
-        
-    def __str__(self):
-        return os.path.join(self.path,self.filename)
-
-    __repr__ = _repr
-
-    def get_as_str(self):
-        content = self.content
-        if content is None:
-            cfgfile = os.path.join(self.path,self.filename)
-            f = open(cfgfile)
-            content = f.read()
-            f.close()
-        else:
-            try:
-                content = self.content.read()
-            except AttributeError:
-                pass
-        return content
-      
-    def parse_if_unparsed(self):
-        if not self.parsed:
-
-            # The parent is important in that it is used error messages but more
-            # importantly when getting ready to read a configuration script we
-            # must set the current directory of the parent so relative path
-            # specification of any configuration file works out.
-            try:
-                parent_path = self.parent.path
-            except AttributeError:
-                parent_path = os.getcwd()
-                                        
-            # Save so we can restore after we are done
-            cwd = os.getcwd()
-
-            # Make sure file is present
-            cfgfile = os.path.join(self.path,self.filename)
-            if not self.content and not os.path.exists(cfgfile):
-                lines = ["File not found: '%s'" % cfgfile]
-                # remember, top level configuration file parent is just the
-                # current working directory when ConfigParser was instantiated
-                # FUTURE parent info in here too
-                FILE_NOT_FOUND = '\n'.join(lines)
-                raise ConfigParserUserError(FILE_NOT_FOUND)
-                
-            # Change the current working directory to where the configuration 
-            # script is (to accomodate Python configuraton scripts so that it
-            # can use os.getcwd() to determine its location).
-            os.chdir(self.path)
-                
-            self.parse()
-            
-            # Restore
-            os.chdir(cwd)
-
-            # Mark it as done so it isn't parsed twice
-            self.parsed = True
-
-
-class ConfigFilePy(ConfigFile):
-
-    def parse(self):
-
-        underkeys = self.underkeys
-        parser = self.parser
-
-        # Parsing can be easy!
-        options = {}
-        if self.content is None:        
-            cfgfile = os.path.join(self.path,self.filename)
-            if sys.version_info < (3,0):
-                execfile(cfgfile,options)
-            else:
-                exec(compile(open(cfgfile).read(), cfgfile, 'exec'),options)
-        else:
-            exec(self.get_as_str(), options)
-            #if sys.version_info < (3,0):
-            #    execfile(self.,options)               
-            #else:
-            #    exec(self.get_as_str(), options)
-
-        # Update the keys.  "KEYS_VARIABLE" option used to specify the
-        # environment variable that holds additional default keys, if
-        # present get keys from the environment using it.  If reading
-        # configuration file that is being included under a key, don't
-        # bother with its keys because it would get too confusing.
-        if not underkeys:
-            try:
-                parser.keys.add_env_keys(options['KEYS_VARIABLE'])
-                del options['KEYS_VARIABLE']
-            except KeyError:
-                pass
-            try:
-                parser.keys.add_cfg_keys(options['KEYS'])
-                del options['KEYS']
-            except KeyError:
-                pass
-
-        try:
-            CONFIG_FILES = options['CONFIG_FILES']
-            del options['CONFIG_FILES']
-        except KeyError:
-            CONFIG_FILES = None
-
-        def merge_option(value,section_keys):
-            if value.__class__ is dict:
-                for key in value:
-                    merge_option(value[key],section_keys+[key])
-            else:
-                valueobj = Value(value,self,section_keys)
-                parser.merge_option(name,valueobj,underkeys+section_keys)
-            
-        # Merge all options that don't start with "_" into the options
-        for name,value in list(options.items()):
-            if not name.startswith('_'):
-                merge_option(value,[])
-
-        # Process the "CONFIG_FILES" option used to merge in configuration
-        # from other files. Users specify a comma separated (string)
-        # listing of configuration file names or a dictionary of (and
-        # optionally - of dictionaries of) file name strings.
-        def add_files(value,under):
-            if isinstance(value,dict):
-                for k,v in value.items():
-                    add_files(v,under+[k])
-            else:
-                for cf in split_paths(value):
-                    parser.add_file(cf,keys=under,parent=self)
-
-        if CONFIG_FILES:
-            add_files(CONFIG_FILES,underkeys)
-
-class ConfigFileIni(ConfigFile):
-  
-    def _read(self):
-    
-        try:
-            self._already_read
-            return
-        except AttributeError:
-            self._already_read = True
-                
-        underkeys = self.underkeys
-        option_parser = self.parser
-        marker_fmt = '{{{%s-(?P<id>\d+)}}}'
-        _self = self
-
-        class BaseClass(object):
-            def __init__(self,matchobj):
-                self.text = matchobj.group('text')
-                self.num = len(self.objects)
-                self.objects.append(self)
-            def restore(self):
-                return self.text
-
-        class Line(BaseClass):
-            pass
-                
-        class Block(BaseClass):
-            objects = []
-            find_re = re.compile('<b>(?P<text>.*?)</b>',re.DOTALL)
-
-        class Verbatim(BaseClass):
-            objects = []
-            find_re = re.compile('<v>(?P<text>.*?)</v>',re.DOTALL)
-
-        class Comment(BaseClass):
-            objects = []
-            find_re = re.compile('(?P<text>[ \t]*[#;].*)')
-
-        class OptionPair(Value):
-            # OptionPair must subclass Value() because it is being submitted into  the
-            # parser options dictionary (all options in the dictionary must be a 
-            # subclass of Value).  All things equal this would subclass BaseClass()
-            # but it implements all that functionality anyways.
-            objects = []
-            find_re = re.compile('(?P<indent>[ \t]*)(?P<name>.+?)(?P<sep>\s*=\s*)(?P<value>.*)')
-            section = None
-            def __init__(self,matchobj):
-                section_keys = OptionPair.section.keys
-                # get the name right            
-                name = matchobj.group('name')
-                self.extended_name = name
-                if '[' in name:
-                    name,keys = name.strip(']').split('[')
-                    section_keys = section_keys + split_keys(keys)
-                self.name = name
-                self.indent = matchobj.group('indent')
-                self.sep = matchobj.group('sep')
-                value = matchobj.group('value')
-                self.valueplus = value
-                try:
-                    value = restore(Comment,value)
-                    value = restore(Block,value)
-                    value = restore(Verbatim,value)
-                    self.linenum = re.findall(marker_fmt % 'Line',value)[0]
-                except IndexError:
-                    self.linenum = 'new'
-                self.num = len(self.objects)
-                self.objects.append(self)
-                self.section = OptionPair.section
-                self.section.options[self.extended_name] = self
-                # The following are needed for Value() functionality
-                self.parent = _self
-                self.section_keys = section_keys
-                # self.value will be set later (can't now because value may contain
-                # interpolations which cannot be expanded until all options are read
-                # for this section
-            def get_roots(self):
-                return Value.get_roots(self) + ["Line: %s" % self.linenum]
-            def set(self,value):
-                Value.set(self,value)
-                value = [value]
-                def hit(matchobj):
-                    value.append(matchobj.group(0))
-                regexp = re.compile(marker_fmt % 'Comment')
-                regexp.sub(hit,self.valueplus)
-                self.valueplus = ''.join(value)
-            def restore(self):
-                return ''.join([self.extended_name,self.sep,self.valueplus])
-            def expand(self,levellist=[]):
-                levellist = levellist + [self.name]
-                if len(levellist) > 10:
-                    lines = self.get_roots()
-                    lines.append("Interpolation: %s" % ' << '.join(levellist))
-                    lines.append("Maximum nesting level exceeded.")
-                    MAX_NESTING_LEVEL_EXCEEDED = '\n' + '\n'.join(lines)
-                    raise ConfigParserUserError(MAX_NESTING_LEVEL_EXCEEDED)
-                try:
-                    return self.value
-                except AttributeError:
-                    pass
-                value = remove(Comment,self.valueplus)
-                value = remove(Line,value)
-                value = restore(Block,value.strip(' \t'))
-                value = remove(Line,value)
-                # @future [ABSPATH] value = value.replace('%(ABSPATH(','%_(ABSPATH(')
-                regexp = re.compile('%\((?P<name>.*?)\)s')
-                def hit(matchobj):
-                    name = matchobj.group('name')
-                    try:
-                        return self.section.options[name].expand(levellist)
-                    except KeyError:
-                        try:
-                            return Section.default.options[name].expand(levellist)
-                        except KeyError:
-                            lines = self.get_roots()
-                            lines.append("Interpolation: %s" % ' << '.join(levellist+[name]))
-                            lines.append("'%s' not found in section or in [DEFAULT]." % name)
-                            INTERPOLATION_ERROR = '\n' + '\n'.join(lines)
-                            raise ConfigParserUserError(INTERPOLATION_ERROR)
-                value = regexp.sub(hit,value)
-                # @future [ABSPATH] regexp = re.compile(r'%_\(ABSPATH\((.*?)\)\)s')
-                # def hit(matchobj):
-                #     return os.path.abspath(matchobj.group(1))
-                # value = regexp.sub(hit,value)
-                self.value = remove(Line,restore(Verbatim,value))
-                return self.value
-                
-        class Section(BaseClass):
-            objects = []
-            find_re = re.compile('(?P<text>\n\[(?P<name>.*?)\].*?(?=\n\[))',re.DOTALL)
-            default = None
-            def __init__(self,matchobj):
-                self.options = {}
-                name = matchobj.group('name')
-                self.name = name
-                keys = split_keys(name)
-                if keys == ['DEFAULT']:
-                    keys = []
-                if not keys:
-                    Section.default = self
-                self.keys = keys
-                OptionPair.section = self
-                self.text =  collapse(OptionPair,matchobj.group(0))
-                self.num = len(self.objects)
-                self.objects.append(self)
-            def add_option(self,name,value,help):
-                if help:
-                    helplines = textwrap.fill(help,77).split('\n')
-                    lines = ['# %s' % line for line in helplines]
-                else:
-                    lines = []
-                lines.append('%s = %s' % (name,value))
-                OptionPair.section = self
-                block = collapse(Comment,'\n'+'\n'.join(lines))
-                self.text +=  collapse(OptionPair,block)
-                option = OptionPair.objects[-1]
-                underkeys = _self.underkeys + option.section_keys
-                if not underkeys:
-                    underkeys = ['DEFAULT']
-                # submit new value to parser
-                _self.parser.merge_option(name,option,underkeys)
-                return option
-                                                
-        def collapse(SubClass,text):
-            marker_fmt = '{{{%s-%%d}}}' % (SubClass.__name__)
-            def hit(matchobj):
-                return marker_fmt % SubClass(matchobj).num
-            return SubClass.find_re.sub(hit,text)
-
-        def remove(SubClass,text):
-            return re.compile(marker_fmt % SubClass.__name__).sub('',text)
-
-        def restore(SubClass,text):
-            def hit(matchobj):
-                return SubClass.objects[int(matchobj.group('id'))].restore()
-            return re.compile(marker_fmt % SubClass.__name__).sub(hit,text)
-
-        text = self.get_as_str()
-        lines = []
-        i = 1
-        for line in text.split('\n'):
-            lines.append(line + ('{{{Line-%d}}}' % i))
-            i += 1
-        text = '\n'.join(lines)
-        text = '\n[DEFAULT]\n#_START_MARKER_\n%s\n[' % text
-        text = collapse(Block,text)
-        text = collapse(Verbatim,text)
-        text = collapse(Comment,text)
-        text = collapse(Section,text)
-        
-        self._OptionPair = OptionPair
-        self._Line = Line
-        self._Comment = Comment
-        self._Block = Block
-        self._Verbatim = Verbatim
-        self._Section = Section
-        self._collapse = collapse 
-        self._restore = restore
-        self._remove = remove
-        self.text = text
-            
-    def parse(self):
-        self._read()
-        for option in self._OptionPair.objects:
-            name = option.name
-            underkeys = self.underkeys + option.section_keys
-            value = option.expand()
-            if name == '<include>':
-                for cf in split_paths(value):
-                    self.parser.add_file(cf,keys=underkeys,parent=self)
-                continue
-            if not underkeys:
-                if name == '<keys>':
-                    self.parser.keys.add_cfg_keys(split_keys(value))
-                    continue
-                if name == '<keys_variable>':
-                    self.parser.keys.add_env_keys(value)
-                    continue
-                underkeys = ['DEFAULT']
-            # call expand method to get .value attribute set
-            self.parser.merge_option(name,option,underkeys)
-
-    def set_option(self,name,value,keys=None,help=None):
-        self._read()
-        value = str(value)
-        keys = split_keys(keys)
-        found = False
-        for option in self._OptionPair.objects:
-            if name==option.name and keys == option.section_keys:
-                option.set(value)
-                found = True
-        if not found:
-            Section = self._Section
-            for section in Section.objects:
-                if keys == section.keys:
-                    found = True
-                    section.add_option(name,value,help)
-            if not found:
-                block = '\n\n[%s]\n\n[\n' % join_keys(keys,'.')
-                self.text = '%s%s' % (self.text[:-2],self._collapse(Section,block))
-                section = self._Section.objects[-1]
-                section.add_option(name,value,help)
-            
-    def write(self,file):
-        self._read()
-        
-        restore = self._restore
-        content = self.text
-        content = restore(self._Section,content)
-        content = restore(self._OptionPair,content) + '\n'
-        content = restore(self._Comment,content)
-        content = restore(self._Block,content)
-        content = restore(self._Verbatim,content)
-        content = self._remove(self._Line,content)
-        content = content.split('\n#_START_MARKER_\n')[1][:-3]
-        
-        try:
-            file.write(content)
-        except AttributeError:
-            f = open(file,'w')
-            f.write(content)
-            f.close()
-
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-#
-#  C O N F I G U R A T I O N   P A R S E R
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-
-class ConfigParser(OptionContainer):
-
-    KeysClass = Keys
-    OptionGroupClass = OptionGroup
-    
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Initializer
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def __init__(self,description=None,allow_py=False,formatter=None,exception=False):
-        """
-        description -- Introductory text placed above configuration option
-            help text.
-        allow_py -- Set to True to allow Python based configuraton files
-            to be executed.  Defaults to False.  Enabling this feature
-            poses a potential security hole for your application.
-        formatter -- Controls configuration option help text style.  Set
-            to either the IndentedHelpFormatter or TitledHelpFormatter
-            classes found in cfgparse module (or a subclass of either).
-        exception -- set to True to raise ConfigParserUserError exception
-            when configuration error occurs (due to user error).  Omitting
-            or setting to False will write error message to sys.stderr.
-            Set to an exception class to raise that exception when a user
-            configuration file error occurs.
-        """
-        OptionContainer.__init__(self,description)
-
-        self.exception = exception
-        
-        # Needed because shares same base class as an option group
-        # (option group constructor initializes parser using an arg).
-        self.parser = self
-
-        self.option_dicts = {}
-
-        self.option_groups = []
-        self.optpar_option_partners = {}
-        
-        self.master_option_list = []
-        self.master_option_dict = {}
-
-        if formatter is None:
-            formatter = IndentedHelpFormatter()
-        self.formatter = formatter
-        self.formatter.set_parser(self)
-
-        self.notes = []
-        
-        # Set up database of option selection keys        
-        self.keys = self.KeysClass()
-
-        # Create database to store information on those configuration files
-        # to be read later (configuration files under keys are not read until
-        # all of the keys in which it is under are active.
-        self._pending = []
-
-        # Since it introduces a security risk, only allow Python based 
-        # configuration files if application explicitly sets this True.
-        self.allow_python_cfg = allow_py
-
-        self.optparse_dests = {}
-
-    def add_optparse_keys_option(self,option_group,switches=('-k','--keys'),dest='cfgparse_keys',help="Comma separated list of configuration keys."):
-        """Adds configuration file keys list option to optparse object."""
-        self.optparse_dests['keys'] = dest
-        option_group.add_option(dest=dest,metavar='LIST',help=help,*switches)
-        
-    def add_optparse_files_option(self,option_group,switches=('--cfgfiles',),dest='cfgparse_files',help="Comma separated list of configuration files."):
-        """Adds configuration file list option to optparse object."""
-        self.optparse_dests['files'] = dest
-        option_group.add_option(dest=dest,metavar='LIST',help=help,*switches)
-
-    def add_optparse_help_option(self,option_group,switches=('--cfghelp',),dest='cfgparse_help',help="Show configuration file help and exit."):
-        """Adds configuration file help option to optparse object."""
-        self.optparse_dests['help'] = dest
-        option_group.add_option(dest=dest,action='store_true',help=help,*switches)
-
-    def add_env_file(self,var,keys=[]):
-        """Adds configuration file specified by environment variable setting.
-        Arguments:
-        var -- name of environment variable holding configuration file name 
-        keys -- section key list to place configuration file options settings under
-        """
-        # Add configuration files specified by an environment variable
-        # if application script specified it.  (Don't read right away,
-        # rather hold them in pending database until they are needed
-        # because adding options causes option_dicts to be set with a 
-        # default for the option destination.
-        f = os.getenv(var,None)
-        if f:
-            f = self.add_file(cfgfile=f,keys=keys)
-        else:
-            f = None
-        return f
-
-    def get_option(self,dest):
-        """Returns option object previously added.
-        Arguments:
-        dest -- destination attribute name of option
-        """
-        opt = self.master_option_dict.get(dest,None)
-        if opt is None:
-            OPTION_NOT_FOUND = '\n'.join([
-                'ERROR: No option found',
-                'option dest: %s' % dest])
-            raise ConfigParserAppError(OPTION_NOT_FOUND)
-        return opt
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Adding Option Groups (adding options handled by base class)
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def add_option_group(self,title,description=None):
-        option_group = self.OptionGroupClass(self,title,description)
-        self.option_groups.append(option_group)
-        return option_group
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Pending Configuration
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def get_option_dict(self,name,keys):
-        self.parse_pending_cfg(keys)
-        return self.option_dicts.get(name,NOTHING_FOUND)
-
-    def parse_pending_cfg(self,keys=[],read_all=False):
-        """
-        read_all -- Set to True to read all configuration files up front.  
-            Defaults to reading "on the fly" as the configuration files are
-            needed."""
-        # Read any pending configuration files that could possibly effect the
-        # setting about to be retrieved.  Note, it was decided that if the
-        # pending configuration file's under keys are all in the key list
-        # computed above it will be installed right away.  The other
-        # alternative is to try retrieving the setting with the highest
-        # priority key alone (first reading any pending configuration files
-        # that are under that key), then if that fails try retrieving the
-        # setting with the top two highest priority keys (again first reading
-        # any pending configuration files that are under either or both of the
-        # keys), and repeating this process for each key in the list until a
-        # setting is found.  This would have the benefit of only reading
-        # pending configuration files when it is absolutely necessary but at
-        # cost of performance and more difficult to explain how it works.
-        keys = split_keys(keys)
-        d = []
-        while self._pending:
-            underkeys,cfgfileobj = self._pending.pop(0)
-            underkeys = split_keys(underkeys)
-            parse_it = read_all
-            if not parse_it:
-                for key in underkeys:
-                    if key not in keys:
-                        d.append((underkeys,cfgfileobj))
-                        break
-                else:
-                    parse_it = True
-            if parse_it:
-                cfgfileobj.parse_if_unparsed()
-        self._pending = d
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    FileClasses = {'py' : ConfigFilePy, 'ini': ConfigFileIni, 'default' : ConfigFileIni}
-
-    def add_file(self,cfgfile=None,content=None,type=None,keys=[],parent=None):
-        """
-        Adds configuration file to parser.  Note, file is not read until parse 
-        or get_option method is called (and even then it may not be read if any
-        keys in the keys list are not in the keys being used to parse).
-        
-        cfgfile -- either the filename or a file stream, defaults to None (see table below)
-        content -- either file contents string or file stream, defaults to None (see table below)
-        type -- set to either 'py', 'ini', or None (default) to control file parser used.   
-            When set to None, filename extension is used to determine parser to use.  'py'
-            interprets the file as Python code.  Otherwise the 'ini' style parser is used.
-        keys -- key list that all options in the configuration file will 
-            be placed under when the file is read.
-        parent -- Not intended to be used by the public
-
-        The following table summarizes the legal combinations of the cfgfile and
-        arguments and resulting file name and contents utilized.
-                    
-        cfgfile   content  result (when configuration is parsed)
-        --------  -------  -----------------------------------------------------------
-        filename  None     file is opened and contents read
-        stream    None     stream contents are read, filename is stream name attribute
-        filename  stream   stream contents are read, filename is cfgfile argument
-        filename  string   both filename and content are used as is
-        """
-
-        if isinstance(cfgfile,str):
-            n = cfgfile
-            c = content
-        elif hasattr(cfgfile,'name'):
-            n = cfgfile.name
-            c = cfgfile
-        elif isinstance(content,str):
-            n = 'heredoc'
-            c = content
-        elif hasattr(content,'read'):
-            n = 'stream'
-            c = content
-        else:
-            ARGUMENT_CONFICT = "Illegal combination of 'cfgfile' and 'content' arguments"
-            raise ConfigParserAppError(ARGUMENT_CONFICT)
-        
-        uk = split_keys(keys)
-
-        if type is None:
-            # calculate type (lower case extension)
-            type = os.path.splitext(n)[1][1:].lower()
-
-        if type == 'py' and not self.allow_python_cfg:
-            return None
-
-        FileClass = self.FileClasses.get(type)
-        if FileClass is None:
-            FileClass = self.FileClasses['default']
-
-        fileobj = FileClass(cfgfile=n,content=c,keys=uk,parent=parent,parser=self)
-        self._pending.append((uk,fileobj))
-        return fileobj
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Read Configuration File Utilities
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def merge_option(self,name,value,keys):
-        """ Merge value (under keys) into options dictionary.
-
-        name -- option name
-        value -- value to assign option (may be a dictionary or a option)
-        keys -- list of keys to place value in options dict under
-        """
-        
-        # Add the option name to the key list so we can start walking at
-        # the top level of the options dictionary.
-        keys = [name] + keys
-        option_dicts = self.option_dicts
-        # Move through the options dictionary using the keys we are
-        # supposed to place the value under creating dictionaries and keys 
-        # that aren't already present.
-        for key in keys[:-1]:
-            if key in option_dicts:
-                if option_dicts[key].__class__ is not dict:
-                    option_dicts[key] = dict(DEFAULT=option_dicts[key])
-            else:
-                option_dicts[key]={}
-            option_dicts = option_dicts[key]
-        option_dicts[keys[-1]] = value
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Option Parsing (not configuration file parsing)
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def write_errors(self,errors):
-        CFGPARSE_USER_ERROR = '\n' + '\n'.join(errors)
-        if not self.exception:
-            sys.stderr.write("ERROR: Configuration File Parser\n")           
-            sys.stderr.write(CFGPARSE_USER_ERROR)
-            self.system_exit()
-        else:
-            if self.exception is True:
-                UserError = ConfigParserUserError
-            else:
-                UserError = self.exception
-            raise UserError(CFGPARSE_USER_ERROR)
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Option Parsing
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def parse(self,optparser=None,args=None,read_all=False):
-        """Partners the option parser and the configuration parser together
-        read_all -- Set to True to read all configuration files up front.  
-            Defaults to reading "on the fly" as the configuration files are
-            needed.
-        """
-
-        if optparser:
-            # Marry up type, help, choices attributes between option parser and
-            # configuration parser options.
-            self.marry_options(optparser)
-
-            # Parse command line arguments
-            options, args = optparser.parse_args(args)
-            self.optparser_options = options
-
-            # generate help if requested from the command line
-            help_dest = self.optparse_dests.get('help')
-            if help_dest and getattr(options,help_dest):
-                self.print_help()
-                self.system_exit()
-
-            # add command line keys
-            keys_dest = self.optparse_dests.get('keys')
-            if keys_dest:
-                self.keys.add_cmd_keys(getattr(options,keys_dest))
-
-            # add command line configuration files (must hold it as other configuration
-            # files may be pending that should be read first)
-            files_dest = self.optparse_dests.get('files')
-            if files_dest:
-                cfgfiles = getattr(options,files_dest)
-                for cf in split_paths(cfgfiles):
-                    self.add_file(cfgfile=cf,keys=[])
-        else:
-            class ConfigOptions(object):
-                pass
-            options = ConfigOptions()
-
-        self.parse_pending_cfg([],read_all)
-
-        # Go through each option in the configuration options and add them
-        # to options object.
-        errors = []
-        for option in self.master_option_list:
-            setattr(options,option.dest,option.get(errors=errors))
-        if errors:
-            self.write_errors(errors)
-
-        if optparser:
-            return options, args
-        else:
-            return options
-
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def marry_options(self,optparser):
-        # create mapping: dest -> [optpar options]
-        optpar_lookup = {}
-        for option in optparser.option_list:
-            if option.dest:
-                optpar_lookup.setdefault(option.dest,[]).append(option)
-        for group in optparser.option_groups:
-            for option in group.option_list:
-                if option.dest:
-                    optpar_lookup.setdefault(option.dest,[]).append(option)
-        self.optpar_option_partners = optpar_lookup
-
-        # we are guarenteed no duplicate destinations with a configuration parser
-        for cfgpar_option in self.master_option_list:
-            optpar_options = optpar_lookup.get(cfgpar_option.dest,[])
-            for optpar_option in optpar_options:
-                for attrname in ['metavar','type','choices','help']:
-                    cfgpar_attr = getattr(cfgpar_option,attrname)
-                    optpar_attr = getattr(optpar_option,attrname)
-                    if cfgpar_attr is None:
-                        cfgpar_attr = optpar_attr
-                        setattr(cfgpar_option,attrname,cfgpar_attr)
-                if cfgpar_option.help == SUPPRESS_HELP:
-                    continue
-                try:
-                    # remove anything we've added previously
-                    optpar_option.help = optpar_option.help.replace(optpar_option._cfgparse_help,'')
-                except AttributeError:
-                    # must not have modified it previously
-                    pass
-                help = "  See also '%s' option in configuration file help." % (cfgpar_option.name)
-                if not optpar_option.help:
-                    help = help.strip()
-                    optpar_option.help = ''
-                optpar_option.help = optpar_option.help + help
-                optpar_option._cfgparse_help = help
-            if cfgpar_option.help == SUPPRESS_HELP:
-                continue
-            if cfgpar_option.help is None:
-                cfgpar_option.help = ''
-            try:
-                # remove anything we've added previously
-                cfgpar_option.help = cfgpar_option.help.replace(cfgpar_option._help_xref,'')
-            except AttributeError:
-                # must not have modified it previously
-                pass
-            switches = '/'.join([str(o) for o in optpar_options])
-            if switches:
-                help = "  See also '%s' command line switch." % (switches)
-                if not cfgpar_option.help:
-                    help = help.strip()
-                cfgpar_option.help = cfgpar_option.help + help
-                cfgpar_option._help_xref = help
-                            
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    def marry_attribute(self,attrname,cfgpar_option,optpar_option):
-        cfgpar_attr = getattr(cfgpar_option,attrname)
-        optpar_attr = getattr(optpar_option,attrname)
-        if cfgpar_attr is None:
-            cfgpar_attr = optpar_attr
-            setattr(cfgpar_option,attrname,cfgpar_attr)
-            
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-    #  Help
-    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-    # <borrowed file="Lib/optparse.py" version="python2.4" modified="yes">
-    def format_option_help(self, formatter=None):
-        if formatter is None:
-            formatter = self.formatter
-        formatter.store_option_strings(self)
-        result = []
-        result.append(formatter.format_heading(_("Configuration file options")))
-        formatter.indent()
-        if self.option_list:
-            result.append(OptionContainer.format_option_help(self, formatter))
-            result.append("\n")
-        for group in self.option_groups:
-            result.append(group.format_help(formatter))
-            result.append("\n")
-        formatter.dedent()
-        # Drop the last "\n", or the header if no options or option groups:
-        return "".join(result[:-1])
-
-    def format_help(self, formatter=None):
-        if formatter is None:
-            formatter = self.formatter
-        result = []
-        if self.description:
-            result.append(self.format_description(formatter) + "\n")
-        result.append(self.format_option_help(formatter))
-        return "".join(result)
-
-    def print_help(self, file=None):
-        """print_help(file : file = stdout)
-
-        Print an extended help message, listing all options and any
-        help text provided with them, to 'file' (default stdout).
-        """
-        if file is None:
-            file = sys.stdout
-        
-        file.write(self.format_help())
-
-        if self.notes:
-            file.write('\nNotes:\n%s\n'%'\n'.join(self.notes))
-    
-    # </borrowed>
-    
-    def add_note(self,note):
-        self.notes.append(note)
-
-    def system_exit(self):
-        sys.exit()
-
-
-def _test():
-    import doctest
-    doctest.testmod()
-
-if __name__ == "__main__":
-    _test()
-
diff --git a/synthesis/configparser.py b/synthesis/configparser.py
index 0ddbb22f95dfd16abc1a3c9d7ecc62cd4069c45f..784b402246cd3c1a95f502269e0e554da558b3a4 100644
--- a/synthesis/configparser.py
+++ b/synthesis/configparser.py
@@ -1,4 +1,5 @@
 # -*- coding: utf-8 -*-
+import msg as p
 
 class ConfigParser(object):
     """Class for parsing python configuration files
@@ -14,7 +15,7 @@ class ConfigParser(object):
     >>> p.add_config_file("test.py")
     >>> p.parse()
     {'modules': {'svn': 'path/to/svn', 'local': '/path/to/local'}, 'fetchto': '..'}
-    
+
     Case2: Default value and lack of a variable
     >>> f = open("test.py", "w")
     >>> f.write('a="123"')
@@ -25,7 +26,7 @@ class ConfigParser(object):
     >>> p.add_config_file("test.py")
     >>> p.parse()
     {'a': '123', 'b': 'borsuk'}
-    
+
     Case3: Multiple types for a variable
     >>> f = open("test.py", "w")
     >>> f.write('a=[1,2,3]')
@@ -36,7 +37,7 @@ class ConfigParser(object):
     >>> p.add_config_file("test.py")
     >>> p.parse()
     {'a': [1, 2, 3]}
-    
+
     Case4: Unrecognized options
     >>> f = open("test.py", "w")
     >>> f.write('a = 123')
@@ -50,7 +51,7 @@ class ConfigParser(object):
         File "configparser.py", line 107, in parse
         raise NameError("Unrecognized option: " + key)
     NameError: Unrecognized option: a
-    
+
     Case5: Invalid parameter type
     >>> f = open("test.py","w")
     >>> f.write('a="123"')
@@ -64,17 +65,44 @@ class ConfigParser(object):
         File "configparser.py", line 110, in parse
         raise RuntimeError("Given option: "+str(type(val))+" doesn't match specified types:"+str(opt.types))
     RuntimeError: Given option: <type 'str'> doesn't match specified types:[<type 'int'>]
-        
+
+    Case6:
+    >>> f = open("test.py","w")
+    >>> f.write('a={"zupa":1}')
+    >>> f.close()
+    >>> p = ConfigParser()
+    >>> p.add_option("a", type={})
+    >>> p.add_allowed_key("a", "zupa")
+    >>> p.add_config_file("test.py")
+    >>> p.parse()
+    {'a': {'zupa': 1}}
+
+    Case7
+    >>> f = open("test.py","w")
+    >>> f.write('a={"kot":1}')
+    >>> f.close()
+    >>> p = ConfigParser()
+    >>> p.add_option("a", type={})
+    >>> p.add_allowed_key("a", "kniaz")
+    >>> p.add_config_file("test.py")
+    >>> p.parse()
+    Traceback (most recent call last):
+        File "<stdin>", line 1, in <module>
+        File "configparser.py", line 184, in parse
+        raise RuntimeError("Encountered unallowed key: " +key+ " for options '"+opt_name+"'")
+    RuntimeError: Encountered unallowed key: kot for options 'a'
+
     Cleanup:
     >>> import os
     >>> os.remove("test.py")
     """
-    
+
     class Option:
         def __init__(self, name, **others):
             self.name = name
             self.keys = []
             self.types = []
+            self.help = ""
 
             for key in others:
                 if key == "help":
@@ -82,15 +110,10 @@ class ConfigParser(object):
                 elif key == "default":
                     self.default = others["default"]
                 elif key == "type":
-                    self.add_type(others["type"]) 
+                    self.add_type(type_obj=others["type"]) 
                 else:
                     raise ValueError("Option not recognized: " + key)
 
-            if "default" in others:
-                self.hasdefault = True
-            else:
-                self.hasdefault = False
-
         def add_type(self, type_obj):
             self.types.append(type(type_obj))
 
@@ -102,6 +125,20 @@ class ConfigParser(object):
         self.description = description
         self.options = {}
 
+    def help(self):
+        p.rawprint("Variables available in a manifest:")
+        for key in self.options:
+            opt = self.options[key]
+            line = '  {0:10}; {1:15}; {2:40}{3}{4:10}'
+            try:
+                tmp_def = opt.default
+                if tmp_def == "":
+                    tmp_def = '""'
+                line = line.format(key, str(opt.types), opt.help,', default=', tmp_def)
+            except AttributeError: #no default value
+                line = line.format(key, str(opt.types), opt.help, "","")
+            p.rawprint(line)
+
     def add_option(self, name, **others):
         if name in self.options:
             raise ValueError("Option already added: " + name)
@@ -112,6 +149,18 @@ class ConfigParser(object):
             raise RuntimeError("Can't add type to a non-existing option")
         self.options[name].add_type(type_obj=type)
 
+    def add_allowed_key(self, name, key):
+        if not isinstance(key, basestring):
+            raise ValueError("Allowed key must be a string")
+        try:
+            self.options[name].allowed_keys.append(key)
+        except AttributeError:
+            if type(dict()) not in self.options[name].types:
+                raise RuntimeError("Allowing a key makes sense for dictionaries only")
+            self.options[name].allowed_keys = [key]
+
+        self.options[name].allowed_keys.append(key)
+
     def add_config_file(self, config_file):
         try:
             self.file #check if there is such attribute
@@ -123,7 +172,7 @@ class ConfigParser(object):
             return
 
         raise RuntimeError("Config file should be added only once")
- 
+
     def parse(self):
         options = {}
         ret = {}
@@ -134,26 +183,35 @@ class ConfigParser(object):
             self.file = "/dev/null"
 
         execfile(self.file, options)
-        for key, val in list(options.items()):
-            if key.startswith('__'):
+        for opt_name, val in list(options.items()): #check delivered options
+            if opt_name.startswith('__'):
                 continue
-            if key not in self.options:
-                raise NameError("Unrecognized option: " + key)
-            opt = self.options[key]
+            if opt_name not in self.options:
+                raise NameError("Unrecognized option: " + opt_name)
+            opt = self.options[opt_name]
             if type(val) not in opt.types:
                 raise RuntimeError("Given option: "+str(type(val))+" doesn't match specified types:"+str(opt.types))
-            ret[key] = val 
-        for name, opt in self.options.items():
-            if opt.hasdefault == True:
+            ret[opt_name] = val
+            if type(val) == type(dict()):
+                try:
+                    for key in val:
+                        if key not in self.options[opt_name].allowed_keys:
+                            raise RuntimeError("Encountered unallowed key: " +key+ " for options '"+opt_name+"'")
+                except AttributeError: #no allowed_keys member - don't perform any check
+                    pass
+
+        for name, opt in self.options.items(): #set values for not listed items with defaults
+            try:
                 if opt.name not in ret:
                     ret[opt.name] = opt.default
+            except AttributeError: #no default value in the option
+                pass
         return ret
 
-            
-        
+
 def _test():
     import doctest
     doctest.testmod()
-    
+
 if __name__ == "__main__":
     _test()
\ No newline at end of file
diff --git a/synthesis/connection.py b/synthesis/connection.py
index 3b507d0386e6284386e2a3cd215770b633fd7eb3..3c83d72d5b10e939fbbd1a7794899c813457f595 100644
--- a/synthesis/connection.py
+++ b/synthesis/connection.py
@@ -2,11 +2,23 @@
 import os
 import random
 import string
+import msg
 
 class Connection:
     def __init__(self, ssh_user, ssh_server):
         self.ssh_user = ssh_user
         self.ssh_server = ssh_server
+    
+    def __str__(self):
+        return self.ssh_user + '@' + self.ssh_server
+
+    def __data_given(self):
+        return self.ssh_user != None and self.ssh_server != None
+
+    def __check(self):
+        if not self.__data_given():
+            p.echo("Error: no data for connection given")
+            quit()
 
     def system(self, cmd):
         return os.system("ssh " + self.ssh_user + "@" + self.ssh_server + ' "' + cmd + '"')
@@ -19,25 +31,25 @@ class Connection:
         Takes list of files and sends them to remote machine. Name of a directory, where files are put
         is returned
         """
+        self.__check()
         if not isinstance(files, list):
             return None;
 
-        ssh_cmd = "ssh " + self.ssh_user + "@" + self.ssh_server
-
         #create a new catalogue on remote machine
         if dest_folder == None:
             dest_folder = ''.join(random.choice(string.ascii_letters + string.digits) for x in range(8)) 
 
         mkdir_cmd = 'mkdir ' + dest_folder 
         import msg as p
-        p.vprint("Connecting to " + ssh_cmd + " and creating directory " + dest_folder + ": " + mkdir_cmd)
+        p.vprint("Connecting to " + str(self) + " and creating directory " + dest_folder + ": " + mkdir_cmd)
         self.system(mkdir_cmd)
 
         #create a string with filenames
         from pipes import quote
-        local_files_str = ' '.join(quote(os.path.abspath(x)) for x in files)
+        local_files_str = ' '.join(quote(file.path) for file in files)
 
-        rsync_cmd = "rsync -Rav " + local_files_str + " " + self.ssh_user + "@" + self.ssh_server + ":" + dest_folder 
+        rsync_cmd = "rsync -Rav " + local_files_str + " " + self.ssh_user + "@" + self.ssh_server + ":" + dest_folder
+        rsync_cmd += " > /dev/null"
         p.vprint("Coping files to remote machine: "+rsync_cmd) 
         import subprocess
         p = subprocess.Popen(rsync_cmd, shell=True)
@@ -45,6 +57,7 @@ class Connection:
         return dest_folder
 
     def transfer_files_back(self, dest_folder):
+        self.__check()
         rsync_cmd = "rsync -av " + self.ssh_user + "@" + self.ssh_server + ":" + dest_folder + ' /'
         p.vprint(rsync_cmd)
         os.system(rsync_cmd)
@@ -54,16 +67,16 @@ class Connection:
             return 0
         else:
             return 1
-            
-def check_address_length(module):
-    p = module.popen("uname -a")
-    p = p.readlines()
-    if not len(p):
-        p.echo("Checking address length failed")
-        return None
-    elif "i686" in p[0]:
-        return 32
-    elif "x86_64" in p[0]:
-        return 64
-    else:
-        return None
\ No newline at end of file
+
+    def check_address_length(self):
+        p = self.popen("uname -a")
+        p = p.readlines()
+        if not len(p):
+            p.echo("Checking address length failed")
+            return None
+        elif "i686" in p[0]:
+            return 32
+        elif "x86_64" in p[0]:
+            return 64
+        else:
+            return None
\ No newline at end of file
diff --git a/synthesis/depend.py b/synthesis/depend.py
index 1e97c886335556d364563abfaa7dad87b5e2f555..f1e64545d8327919b00eebe6571e78cacd657e2d 100644
--- a/synthesis/depend.py
+++ b/synthesis/depend.py
@@ -111,34 +111,42 @@ def generate_fetch_makefile(top_module):
 
     f = open("Makefile.fetch", "w")
 
+    modules = [top_module]
     f.write("fetch: ")
-    for m in top_module.svn:
-        basename = path.url_basename(m.url)
-        f.write(basename+"__fetch \n")
-    for m in top_module.git:
-        basename = path.url_basename(m.url)
-        f.write(basename+"__fetch \n")
 
-    f.write("\n")
-    for m in top_module.svn:
-        basename = path.url_basename(m.url)
-        dir = os.path.join(m.fetchto, basename)
-        f.write(basename+"__fetch:\n")
-        f.write("\t\t")
-        f.write("PWD=$(shell pwd) ; ")
-        f.write("cd " + rp(m.fetchto) + ' ; ')
-        f.write("svn checkout "+ m.url + ' ; ')
-        f.write("cd $(PWD) \n\n")
-
-    for m in top_module.git:
-        basename = path.url_basename(m.url)
-        dir = os.path.join(m.fetchto, basename)
-        f.write(basename+"__fetch:\n")
-        f.write("\t\t")
-        f.write("PWD=$(shell pwd) ; ")
-        f.write("cd " + rp(m.fetchto) + ' ; ')
-        f.write("git clone "+ m.url + ' ; ')
-        f.write("cd $(PWD) \n\n")
+    while(len(modules) > 0):
+        module = modules.pop()
+        for m in module.svn:
+            modules.append(m)
+            basename = path.url_basename(m.url)
+            f.write(basename+"__fetch \\\n")
+        for m in module.git:
+            modules.append(m)
+            basename = path.url_basename(m.url)
+            f.write(basename+"__fetch \\\n")
+
+        f.write("\n")
+        for m in module.svn:
+            basename = path.url_basename(m.url)
+            dir = os.path.join(m.fetchto, basename)
+            f.write(basename+"__fetch:\n")
+            f.write("\t\t")
+            f.write("PWD=$(shell pwd); ")
+            f.write("cd " + rp(m.fetchto) + '; ')
+            f.write("svn checkout "+ m.url + '; ')
+            f.write("cd $(PWD) \n\n")
+
+        for m in module.git:
+            basename = path.url_basename(m.url)
+            dir = os.path.join(m.fetchto, basename)
+            f.write(basename+"__fetch:\n")
+            f.write("\t\t")
+            f.write("PWD=$(shell pwd); ")
+            f.write("cd " + rp(m.fetchto) + '; ')
+            f.write("if [ -d " + basename + " ]; then cd " + basename + '; ')
+            f.write("git pull; ")
+            f.write("else git clone "+ m.url + '; fi; ')
+            f.write("cd $(PWD) \n\n")
     f.close()
 
 def generate_pseudo_ipcore(file_deps_dict, filename="ipcore"):
diff --git a/synthesis/global_mod.py b/synthesis/global_mod.py
index b802c1006c100b96d80387c5679e9c7af13ce30c..e911e395e1e74c55b89e253986097cae60074610 100644
--- a/synthesis/global_mod.py
+++ b/synthesis/global_mod.py
@@ -4,8 +4,6 @@
 options = None
 t0 = None
 ssh = None
-synth_user = None
-synth_server = None
 top_manifest = None
 cwd = None
 opt_map = None
diff --git a/synthesis/hdlmake.py b/synthesis/hdlmake.py
index 768b84194b40f099be1a9cd1d37aed76aa6c3c98..1701b1ceb7871041d33da54a6b4b8a39c53e8f7b 100755
--- a/synthesis/hdlmake.py
+++ b/synthesis/hdlmake.py
@@ -8,7 +8,6 @@ import path
 import path
 import time
 import os
-from connection import check_address_length
 from connection import Connection
 import random
 import string
@@ -16,14 +15,14 @@ import global_mod
 import msg as p
 import optparse
 from module import Module
-from helper_classes import Manifest, SourceFile
+from helper_classes import Manifest, SourceFile, ManifestParser
 
 def main():
     global_mod.t0 = time.time()
     parser = optparse.OptionParser()
     #disabled due to introducing a new parser class. Help msg printing is not ready yet.
-    #parser.add_option("--manifest-help", action="store_true", dest="manifest_help",
-    #help="print manifest file variables description")
+    parser.add_option("--manifest-help", action="store_true", dest="manifest_help",
+    help="print manifest file variables description")
     parser.add_option("-k", "--make", dest="make", action="store_true", default=None, help="prepare makefile for simulation")
     parser.add_option("-f", "--fetch", action="store_true", dest="fetch", help="fetch files from modules listed in MANIFEST")
     parser.add_option("--make-fetch", action="store_true", dest="make_fetch", help="generate makefile for fetching needed modules")
@@ -39,9 +38,13 @@ def main():
     parser.add_option("--ise-file", dest="ise", help="specify .xise file for other actions", metavar="ISE")
     parser.add_option("--synth-server", dest="synth_server", default=None, help="use given SERVER for remote synthesis", metavar="SERVER")
     parser.add_option("--synth-user", dest="synth_user", default=None, help="use given USER for remote synthesis", metavar="USER")
-    (global_mod.options, args) = parser.parse_args()
+    (options, args) = parser.parse_args()
+    global_mod.options = options
 
-    # check if manifest is given in the command line
+    if options.manifest_help == True:
+        ManifestParser().help()
+        quit()
+    # check if manifest is given in the command line 
     # if yes, then use it
     # if no, the look for it in the current directory (python manifest has priority)  
     file = None
@@ -49,7 +52,7 @@ def main():
         file = "manifest.py"
     elif os.path.exists("Manifest.py"):
         file = "Manifest.py"
-    
+
     if file != None:
         top_manifest = Manifest(path=os.path.abspath(file))
         global_mod.top_module = Module(manifest=top_manifest, parent=None, source="local", fetchto=".")
@@ -58,10 +61,7 @@ def main():
         p.echo("No manifest found. At least an empty one is needed")
         quit()
 
-    if global_mod.options.synth_server != None:
-        global_mod.synth_server = global_mod.options.synth_server
-    if global_mod.options.synth_user != None:
-        global_mod.synth_user = global_mod.options.synth_user
+    global_mod.ssh = Connection(options.synth_user, options.synth_server)
 
     #if global_mod.options.tcl == None:
     #    if global_mod.opt_map.tcl == None: #option taken, but no tcl given -> find it
@@ -73,8 +73,7 @@ def main():
     #else:
     #    global_mod.opt_map.tcl = global_mod.options.tcl
 
-    #if global_mod.options.manifest_help == True:
-    #    ManifestParser().print_help()
+
     if global_mod.options.fetch == True:
         fetch()
     elif global_mod.options.local == True:
@@ -133,78 +132,62 @@ def inject_into_ise():
         quit()
 
     tm = global_mod.top_module
-    module_files_dict = make_list_of_files(file_type="vhd")
-    p.vprint("List of used files")
-    p.vpprint(module_files_dict)
-
     depend.inject_files_into_ise(global_mod.options.ise_project, files)
 
 def generate_makefile():
     import depend
     tm = global_mod.top_module
     vhdl_deps = tm.generate_deps_for_vhdl_in_modules()
-    sv_files = tm.make_lsit_of
     depend.generate_makefile(vhdl_deps)
 
     #NOT YET TRANSFORMED INTO CLASSES
 def remote_synthesis():
-    if global_mod.opt_map.tcl == None: #option not taken but mandatory
-        p.echo("For Xilinx synthesis a .tcl file in the top module is required")
-        quit()
-    if not os.path.exists(global_mod.opt_map.tcl):
-        p.echo("Given .tcl doesn't exist: " + global_mod.opt_map.tcl)
-        quit()
-    p.vprint("The program will be using ssh connection: "+global_mod.synth_user+"@"+global_mod.synth_server)
-    global_mod.ssh = Connection(global_mod.synth_user, global_mod.synth_server)
+    ssh = global_mod.ssh
+    tm = global_mod.top_module
 
-    if not global_mod.ssh.is_good():
-        p.echo("SSH connection failure.")
+    p.vprint("The program will be using ssh connection: "+str(ssh))
+    if not ssh.is_good():
+        p.echo("SSH connection failure. Remote host doesn't response.")
         quit()
 
-    if not os.path.exists(global_mod.fetchto):
+    if not os.path.exists(tm.fetchto):
         p.echo("There are no modules fetched. Are you sure it's correct?")
 
-    module_manifest_dict = path.make_list_of_modules(global_mod.top_manifest, global_mod.opt_map)
-    p.vprint ("Modules: ")
-    p.vpprint(module_manifest_dict)
-
-    module_files_dict = path.make_list_of_files(module_manifest_dict)
-    files = []
-    for module in module_files_dict:
-        files.extend(module_files_dict[module])
+    modules = global_mod.top_module.make_list_of_modules()
 
-    p.vprint("Files that will be transfered")
-    p.vpprint(files)
-    dest_folder = global_mod.ssh.transfer_files_forth(files, global_mod.opt_map.name)
+    files = [file for mod in modules for file in mod.files]
+    dest_folder = ssh.transfer_files_forth(files, tm.name)
 
-    ret = global_mod.ssh.system("[ -e /opt/Xilinx/"+global_mod.opt_map.ise+" ]")
+    ret = ssh.system("[ -e /opt/Xilinx/" + tm.ise + " ]")
     if ret == 1:
-        p.echo("There is no "+global_mod.opt_map.ise+" ISE version installed on the remote machine")
+        p.echo("There is no " + tm.ise + " ISE version installed on the remote machine")
         quit()
 
     p.vprint("Checking address length at synthesis server")
-    address_length = check_address_length(global_mod.ssh)
+    address_length = ssh.check_address_length()
     if address_length == 32 or address_length == None:
-        path_ext = global_mod.ise_path_32[global_mod.opt_map.ise]
+        path_ext = global_mod.ise_path_32[tm.ise]
     else:
-        path_ext = global_mod.ise_path_64[global_mod.opt_map.ise]
-
-    syn_cmd ="PATH=$PATH:"+path_ext+"&& cd "+dest_folder+global_mod.cwd+"/"+os.path.dirname(global_mod.opt_map.tcl)
+        path_ext = global_mod.ise_path_64[tm.ise]
+    cwd = os.getcwd()
+    quit()
+#### tu zmienic (jak Tomek rozczai)
+    syn_cmd ="PATH=$PATH:"+path_ext+"&& cd "+dest_folder+cwd+"/"+os.path.dirname(global_mod.opt_map.tcl)
     syn_cmd += "&& xtclsh "+os.path.basename(global_mod.opt_map.tcl)+" run_process"
-
-    p.vprint("Launching synthesis on " + global_mod.synth_server + ": " + syn_cmd)
-    ret = global_mod.ssh.system(syn_cmd)
+###
+    p.vprint("Launching synthesis on " + str(ssh) + ": " + syn_cmd)
+    ret = ssh.system(syn_cmd)
     if ret == 1:
         p.echo("Synthesis failed. Nothing will be transfered back")
         quit()
 
     cur_dir = os.path.basename(global_mod.cwd)
     os.chdir("..")
-    global_mod.ssh.transfer_files_back(dest_folder+global_mod.cwd)
+    ssh.transfer_files_back(dest_folder+global_mod.cwd)
     os.chdir(cur_dir)
     if global_mod.options.no_del != True:
         p.echo("Deleting synthesis folder")
-        global_mod.ssh.system('rm -rf ' + dest_folder)
+        ssh.system('rm -rf ' + dest_folder)
 
 def local_synthesis():
     if global_mod.options.tcl == None:
@@ -238,8 +221,5 @@ def generate_list_makefile():
 if __name__ == "__main__":
     #global options' map for use in the entire script
     t0 = None
-    global_mod.synth_user = "htsynth"
-    global_mod.synth_server = "htsynth"
     global_mod.cwd = os.getcwd()
-    #globa_mod.ssh = myssh.MySSH(global_mod.synth_user, global_mod.synth_server)
     main()
diff --git a/synthesis/helper_classes.py b/synthesis/helper_classes.py
index 584e5bc1ce969ef57c66cea692b0f79e8ba1a298..295de713e635ca7647146f009adde4c6fa42a6af 100644
--- a/synthesis/helper_classes.py
+++ b/synthesis/helper_classes.py
@@ -31,11 +31,16 @@ class ManifestParser(ConfigParser):
         self.add_option('tcl', default=None, help="Path to .tcl file used in synthesis", type='')
         self.add_option('ise', default=None, help="Version of ISE to be used in synthesis", type='')
         self.add_type('ise', type=1)
+
         self.add_option('vsim_opt', default="", help="Additional options for vsim", type='')
         self.add_option('vcom_opt', default="", help="Additional options for vcom", type='')
         self.add_option('vlog_opt', default="", help="Additional options for vlog", type='')
         self.add_option('vmap_opt', default="", help="Additional options for vmap", type='')
         self.add_option('modules', default={}, help="List of local modules", type={})
+        self.add_allowed_key('modules', key="svn")
+        self.add_allowed_key('modules', key="git")
+        self.add_allowed_key('modules', key="local")
+
         self.add_option('library', default="work",
         help="Destination library for module's VHDL files", type="")
         self.add_option('files', default=[], help="List of files from the current module", type='')
@@ -71,6 +76,9 @@ class SourceFile:
         ext = tmp[len(tmp)-1]
         return ext
 
+    def isdir(self):
+        return os.path.isdir(self.path)
+
     def search_for_use(self):
         """
         Reads a file and looks for 'use' clause. For every 'use' with
diff --git a/synthesis/module.py b/synthesis/module.py
index fab18102f2618aacad706ef1eadf06507697cd17..b37ba3bf38e5242b1cc753e2b5ffd00882ea620d 100644
--- a/synthesis/module.py
+++ b/synthesis/module.py
@@ -64,8 +64,7 @@ class Module(object):
         elif os.path.exists(os.path.join(self.options["fetchto"], basename)):
             self.options["isfetched"] = True
             self.path = os.path.join(self.options["fetchto"], basename)
-        else:
-            print os.path.join(self.options["fetchto"], basename)
+
         self.options["library"] = "work"
         self.parse_manifest()
 
@@ -143,27 +142,30 @@ class Module(object):
         else:
             self.local = []
 
-        if opt_map["files"] == None:
-            directory = os.path.dirname(self.path)
-            print "listing" + directory
+        self.library = opt_map["library"]
+        if opt_map["files"] == []:
             files = []
-            for file in os.listdir(directory):
-               path = os.path.join(directory, file)
-               files.append(path)
+            for filename in os.listdir(self.path):
+                path = os.path.join(self.path, filename)
+                if not os.path.isdir(path):
+                    file = SourceFile(path=path)
+                    file.library = self.library
+                    files.append(file)
             self.files = files
         else:
-            files = []
+            paths = []
             for path in opt_map["files"]:
                 if not path_mod.is_abs_path(path):
-                    files.append(path_mod.rel2abs(path, self.path))
+                    path = path_mod.rel2abs(path, self.path)
+                    paths.append(path)
                 else:
                     p.echo(path + " is an absolute path. Omitting.")
-            self.files = files
+            self.__make_list_of_files(paths=paths)
 
         if "svn" in opt_map["modules"]:
             opt_map["modules"]["svn"] = self.make_list_(opt_map["modules"]["svn"])
             svn = []
-            for url in opt_map.svn:
+            for url in opt_map["modules"]["svn"]:
                 svn.append(Module(url=url, source="svn", fetchto=fetchto, parent=self))
             self.svn = svn
         else:
@@ -172,7 +174,7 @@ class Module(object):
         if "git" in opt_map["modules"]:
             opt_map["modules"]["git"] = self.make_list_(opt_map["modules"]["git"])
             git = []
-            for url in opt_map.git:
+            for url in opt_map["modules"]["git"]:
                 git.append(Module(url=url, source="git", fetchto=fetchto, parent=self))
             self.git = git
         else:
@@ -183,7 +185,9 @@ class Module(object):
         self.vlog_opt = opt_map["vlog_opt"]
 
         self.isparsed = True
-        self.library = opt_map["library"]
+
+
+        self.name = opt_map["name"]
         #if self.isfetched == True:  <- avoid getting all files
         #    self.make_list_of_files()
 
@@ -318,7 +322,7 @@ class Module(object):
             p.vprint("No modules were found in " + self.fetchto)
         return modules
 
-    def make_list_of_files(self, file_type = None, ret_class = SourceFile):
+    def __make_list_of_files(self, paths, file_type = None, ret_class = SourceFile):
         def get_files_(path, file_type = None, ret_class = SourceFile):
             """
             Get lists of normal files and list folders recursively
@@ -340,18 +344,17 @@ class Module(object):
             return ret
 
         files = []
-
-        if self.manifest != None:
-            if self.files != []:
-                for file in self.files:
-                    if os.path.isdir(file):
-                        files.extend(get_files_(path=file, file_type=file_type, ret_class=ret_class))
-                    else:
-                        files.append(ret_class(file))
+        for path in paths:
+            if os.path.isdir(path):
+                files.extend(get_files_(path, file_type=file_type, ret_class=ret_class))
             else:
-               files.extend(get_files_(path=self.path, file_type=file_type, ret_class=ret_class))
-        else:
-            files = get_files_(path=self.path, file_type=file_type, ret_class=ret_class)
+                if file_type == None:
+                    files.append(ret_class(path=path))
+                else:
+                    tmp = filename.rsplit('.')
+                    ext = tmp[len(tmp)-1]
+                    if ext == file_type:
+                        files.append( ret_class(path=path) )
         for file in files:
             file.library = self.library
         self.files = files
diff --git a/synthesis/msg.py b/synthesis/msg.py
index b1188294dd2fcc8a47570ddadbc88e7c347443db..6a7f0d851fa9b292abfc1613b76ffc1b43f845ee 100644
--- a/synthesis/msg.py
+++ b/synthesis/msg.py
@@ -7,6 +7,9 @@ import os
 import sys
 import pprint as prettyprinter
 
+def rawprint(msg):
+    print msg
+
 def echo(msg):
     print(("["+os.path.basename(sys.argv[0]) + " " + "%.5f" % (time.time()-global_mod.t0) + "]: " + str(msg)))