def merge(dst, src, separator="<STR_LIT:/>", afilter=None, flags=MERGE_ADDITIVE, _path="<STR_LIT>"):
if afilter:<EOL><INDENT>src = search(src, '<STR_LIT>', afilter=afilter)<EOL>return merge(dst, src)<EOL><DEDENT>def _check_typesafe(obj1, obj2, key, path):<EOL><INDENT>if not key in obj1:<EOL><INDENT>return<EOL><DEDENT>elif ( (flags & MERGE_TYPESAFE == MERGE_TYPESAFE) and (type(obj1[key]) != type(obj2[key]))):<EOL><INDENT>raise TypeError("<STR_LIT>"<EOL>"<STR_LIT>".format(type(obj1[key]), type(obj2[key]), path))<EOL><DEDENT>elif ( (flags & MERGE_TYPESAFE != MERGE_TYPESAFE) and (type(obj1[key]) != type(obj2[key]))):<EOL><INDENT>obj1.pop(key)<EOL><DEDENT><DEDENT>if isinstance(src, MutableMapping):<EOL><INDENT>for (i, v) in enumerate(src):<EOL><INDENT>_check_typesafe(dst, src, v, separator.join([_path, str(v)]))<EOL>if not v in dst:<EOL><INDENT>dst[v] = src[v]<EOL><DEDENT>else:<EOL><INDENT>if not isinstance(src[v], (MutableMapping, MutableSequence)):<EOL><INDENT>dst[v] = src[v]<EOL><DEDENT>else:<EOL><INDENT>merge(dst[v], src[v], afilter=afilter, flags=flags,<EOL>_path=separator.join([_path, str(v)]), separator=separator)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>elif isinstance(src, MutableSequence):<EOL><INDENT>for (i, v) in enumerate(src):<EOL><INDENT>_check_typesafe(dst, src, i, separator.join([_path, str(i)]))<EOL>dsti = i<EOL>if ( flags & MERGE_ADDITIVE):<EOL><INDENT>dsti = len(dst)<EOL><DEDENT>if dsti >= len(dst):<EOL><INDENT>dst += [None] * (dsti - (len(dst) - <NUM_LIT:1>))<EOL><DEDENT>if dst[dsti] == None:<EOL><INDENT>dst[dsti] = src[i]<EOL><DEDENT>else:<EOL><INDENT>if not isinstance(src[i], (MutableMapping, MutableSequence)):<EOL><INDENT>dst[dsti] = src[i]<EOL><DEDENT>else:<EOL><INDENT>merge(dst[i], src[i], afilter=afilter, flags=flags,<EOL>_path=separator.join([_path, str(i)]), separator=separator)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>
Merge source into destination. Like dict.update() but performs
    deep merging.

    flags is an OR'ed combination of MERGE_ADDITIVE, MERGE_REPLACE, or
    MERGE_TYPESAFE.
        * MERGE_ADDITIVE : List objects are combined onto one long
          list (NOT a set). This is the default flag.
        * MERGE_REPLACE : Instead of combining list objects, when
          2 list objects are at an equal depth of merge, replace
          the destination with the source.
        * MERGE_TYPESAFE : When 2 keys at equal levels are of different
          types, raise a TypeError exception. By default, the source
          replaces the destination in this situation.