'Create a new overlay environment that shares all the data with the
current environment except of cache and the overriden attributes.
Extensions cannot be removed for a overlayed environment.  A overlayed
environment automatically gets all the extensions of the environment it
is linked to plus optional extra extensions.
Creating overlays should happen after the initial environment was set
up completely.  Not all attributes are truly linked, some are just
copied over so modifications on the original environment may not shine
through.'

def overlay(self, block_start_string=missing, block_end_string=missing, variable_start_string=missing, variable_end_string=missing, comment_start_string=missing, comment_end_string=missing, line_statement_prefix=missing, line_comment_prefix=missing, trim_blocks=missing, extensions=missing, optimized=missing, undefined=missing, finalize=missing, autoescape=missing, loader=missing, cache_size=missing, auto_reload=missing, bytecode_cache=missing):

    args = dict(locals())
    del args['self'], args['cache_size'], args['extensions']
    rv = object.__new__(self.__class__)
    rv.__dict__.update(self.__dict__)
    rv.overlayed = True
    rv.linked_to = self
    for (key, value) in args.iteritems():
        if (value is not missing):
            setattr(rv, key, value)
    if (cache_size is not missing):
        rv.cache = create_cache(cache_size)
    else:
        rv.cache = copy_cache(self.cache)
    rv.extensions = {}
    for (key, value) in self.extensions.iteritems():
        rv.extensions[key] = value.bind(rv)
    if (extensions is not missing):
        rv.extensions.update(load_extensions(extensions))
    return _environment_sanity_check(rv)
