Given a list of commands (which are assumed groupable), return
    a new command which is a batch (multi) command.

    For ``set`` commands the outcome will be::

        set_multi({key: value}, **kwargs)

    For ``get`` and ``delete`` commands, the outcome will be::

        get_multi(list_of_keys, **kwargs)

    (Or respectively ``delete_multi``)

def grouped_command(commands):
    """
    Given a list of commands (which are assumed groupable), return
    a new command which is a batch (multi) command.

    For ``set`` commands the outcome will be::

        set_multi({key: value}, **kwargs)

    For ``get`` and ``delete`` commands, the outcome will be::

        get_multi(list_of_keys, **kwargs)

    (Or respectively ``delete_multi``)
    """
    base = commands[0]
    name = base.get_name()
    multi_command = EventualCommand('%s_multi' % name)
    if name in ('get', 'delete'):
        args = [c.get_args()[0] for c in commands]
    elif base.get_name() == 'set':
        args = dict(c.get_args()[0:2] for c in commands)
    else:
        raise ValueError('Command not supported: %r' % (base.get_name(),))

    multi_command(args, *grouped_args_for_command(base), **base.get_kwargs())

    return multi_command