def aggregate_keywords(keywords, sep, prefix, raw=False):
    """ take our keyword arguments, and a separator, and compose the list of
    flat long (and short) arguments.  example

        {'color': 'never', 't': True, 'something': True} with sep '='

    becomes

        ['--color=never', '-t', '--something']

    the `raw` argument indicates whether or not we should leave the argument
    name alone, or whether we should replace "_" with "-".  if we pass in a
    dictionary, like this:

        sh.command({"some_option": 12})

    then `raw` gets set to True, because we want to leave the key as-is, to
    produce:

        ['--some_option=12']

    but if we just use a command's kwargs, `raw` is False, which means this:

        sh.command(some_option=12)

    becomes:

        ['--some-option=12']

    eessentially, using kwargs is a convenience, but it lacks the ability to
    put a '-' in the name, so we do the replacement of '_' to '-' for you.
    but when you really don't want that to happen, you should use a
    dictionary instead with the exact names you want
    """

    processed = []
    encode = encode_to_py3bytes_or_py2str

    for k, v in keywords.items():
        # we're passing a short arg as a kwarg, example:
        # cut(d="\t")
        if len(k) == 1:
            if v is not False:
                processed.append(encode("-" + k))
                if v is not True:
                    processed.append(encode(v))

        # we're doing a long arg
        else:
            if not raw:
                k = k.replace("_", "-")

            if v is True:
                processed.append(encode("--" + k))
            elif v is False:
                pass
            elif sep is None or sep == " ":
                processed.append(encode(prefix + k))
                processed.append(encode(v))
            else:
                arg = encode("%s%s%s%s" % (prefix, k, sep, v))
                processed.append(arg)

    return processed