_imm_merge_class(imm_class, parent) updates the given immutable class imm_class to have the
    appropriate attributes of its given parent class. The parents should be passed through this
    function in method-resolution order.

def _imm_merge_class(cls, parent):
    '''
    _imm_merge_class(imm_class, parent) updates the given immutable class imm_class to have the
    appropriate attributes of its given parent class. The parents should be passed through this
    function in method-resolution order.
    '''
    # If this is not an immutable parent, ignore it
    if not hasattr(parent, '_pimms_immutable_data_'): return cls
    # otherwise, let's look at the data
    cdat = cls._pimms_immutable_data_
    pdat = parent._pimms_immutable_data_
    # for params, values, and checks, we add them to cls only if they do not already exist in cls
    cparams = cdat['params']
    cvalues = cdat['values']
    cconsts = cdat['consts']
    for (param, (dflt, tx_fn, arg_lists, check_fns, deps)) in six.iteritems(pdat['params']):
        if param not in cparams and param not in cvalues:
            cparams[param] = (dflt, tx_fn, [], [], [])
    for (value, (arg_list, calc_fn, deps)) in six.iteritems(pdat['values']):
        if value in cparams:
            raise ValueError('cannot convert value into parameter: %s' % value)
        if value not in cvalues:
            cvalues[value] = (arg_list, calc_fn, [])
            if len(arg_list) == 0:
                cconsts[value] = ([], [])
    cchecks = cdat['checks']
    for (check, (arg_list, check_fn)) in six.iteritems(pdat['checks']):
        if check not in cchecks:
            cchecks[check] = (arg_list, check_fn)
    # That's it for now
    return cls