def doGroup(indata, group_key_func, group_data_func):
    """Group the indata based on the keys that satisfy group_key_func (applied to the value)
    Return a dict of groups summarized by group_data_func
    Each group returned by group_data_func must be a dictionary,
    possibly similar to the original value of the indata elements

    Args:
        indata:
        group_key_func:
        group_data_func:

    Returns:
        dict of groups summarized by group_data_func
    """

    gdata = {}
    for k, inel in indata.items():
        gkey = group_key_func(inel)
        if gkey in gdata:
            gdata[gkey].append(inel)
        else:
            gdata[gkey] = [inel]

    outdata = {}
    for k in gdata:
        # value is a summary of the values
        outdata[k] = group_data_func(gdata[k])

    return outdata