from typing import OrderedDict


def merge_dicts(*args, **kwargs):
    """
    Merge dictionaries. Values in later args override former with the same key.
    kwargs always override.

    .. testsetup::

       from figura.misc import merge_dicts

    >>> sorted(merge_dicts({'a':1, 'b':2}, {'b':22, 'c':33, 'd':44}, d=444).items())
    [('a', 1), ('b', 22), ('c', 33), ('d', 444)]

    """
    if not args:
        args = ({}, )
    d = args[0].copy()
    for arg in args[1:]:

        # order-perserving: if type(arg)==OrderedDict, we assume the
        # caller wants to preserve the order of the items in the ordered dict
        if isinstance(arg, OrderedDict) and not isinstance(d, OrderedDict):
            d = OrderedDict(d)  # preserve order from now on

        d.update(arg)

    d.update(kwargs)
    return d