def denormalize(data):
    '''
    denormalize(data) yield a denormalized version of the given JSON-friendly normalized data. This
      is the inverse of the normalize(obj) function.

    The normalize and denormalize functions use the reserved keyword '__type__' along with the
    <obj>.normalize() and <class>.denormalize(data) functions to manage types of objects that are
    not JSON-compatible. Please see help(normalize) for more details.
    '''
    if   data is None: return None
    elif pimms.is_scalar(data, ('number', 'bool', 'string', 'unicode')): return data
    elif pimms.is_map(data):
        # see if it's a non-native map
        if normalize_type_key in data:
            (mdl,cls) = data[normalize_type_key]
            if mdl is None:
                if   cls == 'ellipsis': return Ellipsis
                elif cls == 'complex':  return np.array(data['re']) + 1j*np.array(data['im'])
                elif cls == 'set':      return set(denormalize(data['elements']))
                elif cls == 'sparse_matrix':
                    return sps.csr_matrix((data['vals'], (data['rows'],data['cols'])),
                                          shape=data['shape'])
                else: raise ValueError('unrecognized builtin denormalize class: %s' % cls)
            else:
                cls = getattr(importlib.import_module(mdl), cls)
                d = {k:denormalize(v) for (k,v) in six.iteritems(data) if k != normalize_type_key}
                return cls.denormalize(d)
        else: return {k:denormalize(v) for (k,v) in six.iteritems(data)} # native map
    else:
        # must be a list of some type
        if not hasattr(data, '__iter__'):
            msg = 'denormalize does not recognized object %s with type %s' % (data, type(data))
            raise ValueError(msg)
        # lists of primitives need not be changed
        if pimms.is_array(data, ('number', 'bool', 'string', 'unicode')): return data
        return [denormalize(x) for x in data]
denormalize(data) yield a denormalized version of the given JSON-friendly normalized data. This
      is the inverse of the normalize(obj) function.

    The normalize and denormalize functions use the reserved keyword '__type__' along with the
    <obj>.normalize() and <class>.denormalize(data) functions to manage types of objects that are
    not JSON-compatible. Please see help(normalize) for more details.