Extend a dictionary with keys and values from other dictionaries.

    :param dict_: Dictionary to extend

    Optional keyword arguments allow to control the exact way
    in which ``dict_`` will be extended.

    :param overwrite:

        Whether repeated keys should have their values overwritten,
        retaining the last value, as per given order of dictionaries.
        This is the default behavior (equivalent to ``overwrite=True``).
        If ``overwrite=False``, repeated keys are simply ignored.

        Example::

            >> foo = {'a': 1}
            >> extend(foo, {'a': 10, 'b': 2}, overwrite=True)
            {'a': 10, 'b': 2}
            >> foo = {'a': 1}
            >> extend(foo, {'a': 10, 'b': 2}, overwrite=False)
            {'a': 1, 'b': 2}

    :param deep:

        Whether extending should proceed recursively, and cause
        corresponding subdictionaries to be merged into each other.
        By default, this does not happen (equivalent to ``deep=False``).

        Example::

            >> foo = {'a': {'b': 1}}
            >> extend(foo, {'a': {'c': 2}}, deep=False)
            {'a': {'c': 2}}
            >> foo = {'a': {'b': 1}}
            >> extend(foo, {'a': {'c': 2}}, deep=True)
            {'a': {'b': 1, 'c': 2}}

    :return: Extended ``dict_``

    .. versionadded:: 0.0.2

def extend(dict_, *dicts, **kwargs):
    """Extend a dictionary with keys and values from other dictionaries.

    :param dict_: Dictionary to extend

    Optional keyword arguments allow to control the exact way
    in which ``dict_`` will be extended.

    :param overwrite:

        Whether repeated keys should have their values overwritten,
        retaining the last value, as per given order of dictionaries.
        This is the default behavior (equivalent to ``overwrite=True``).
        If ``overwrite=False``, repeated keys are simply ignored.

        Example::

            >> foo = {'a': 1}
            >> extend(foo, {'a': 10, 'b': 2}, overwrite=True)
            {'a': 10, 'b': 2}
            >> foo = {'a': 1}
            >> extend(foo, {'a': 10, 'b': 2}, overwrite=False)
            {'a': 1, 'b': 2}

    :param deep:

        Whether extending should proceed recursively, and cause
        corresponding subdictionaries to be merged into each other.
        By default, this does not happen (equivalent to ``deep=False``).

        Example::

            >> foo = {'a': {'b': 1}}
            >> extend(foo, {'a': {'c': 2}}, deep=False)
            {'a': {'c': 2}}
            >> foo = {'a': {'b': 1}}
            >> extend(foo, {'a': {'c': 2}}, deep=True)
            {'a': {'b': 1, 'c': 2}}

    :return: Extended ``dict_``

    .. versionadded:: 0.0.2
    """
    ensure_mapping(dict_)
    dicts = list(imap(ensure_mapping, dicts))

    ensure_keyword_args(kwargs, optional=('deep', 'overwrite'))

    return _nary_dict_update([dict_] + dicts, copy=False,
                             deep=kwargs.get('deep', False),
                             overwrite=kwargs.get('overwrite', True))