'Merge two configurations.
The configuration given as an argument (if any) takes priority;
defaults are filled in from the current configuration.
Args:
config: Configuration providing overrides, or None (but cannot
be omitted).
Returns:
Either a new configuration object or (if it would be equivalent)
self or the config argument unchanged, but never None.
Raises:
BadArgumentError if self or config are of configurations classes
with conflicting options (i.e. the same option name defined in
two different configuration classes).'

def merge(self, config):

    if ((config is None) or (config is self)):
        return self
    if (not (isinstance(config, _MergedConfiguration) or isinstance(self, _MergedConfiguration))):
        if isinstance(config, self.__class__):
            for key in self._values:
                if (key not in config._values):
                    break
            else:
                return config
        if isinstance(self, config.__class__):
            if self.__is_stronger(**config._values):
                return self
        def _quick_merge(obj):
            obj._values = self._values.copy()
            obj._values.update(config._values)
            return obj
        if isinstance(config, self.__class__):
            return _quick_merge(type(config)())
        if isinstance(self, config.__class__):
            return _quick_merge(type(self)())
    return _MergedConfiguration(config, self)
