Adds item to the data, applying dimension types and ensuring
        key conforms to Dimension type and values.

def _add_item(self, dim_vals, data, sort=True, update=True):
        """
        Adds item to the data, applying dimension types and ensuring
        key conforms to Dimension type and values.
        """
        sort = sort and self.sort
        if not isinstance(dim_vals, tuple):
            dim_vals = (dim_vals,)

        self._item_check(dim_vals, data)

        # Apply dimension types
        dim_types = zip([kd.type for kd in self.kdims], dim_vals)
        dim_vals = tuple(v if None in [t, v] else t(v) for t, v in dim_types)
        valid_vals = zip(self.kdims, dim_vals)

        for dim, val in valid_vals:
            if dim.values and val is not None and val not in dim.values:
                raise KeyError('%s dimension value %s not in'
                               ' specified dimension values.' % (dim, repr(val)))

        # Updates nested data structures rather than simply overriding them.
        if (update and (dim_vals in self.data)
            and isinstance(self.data[dim_vals], (MultiDimensionalMapping, OrderedDict))):
            self.data[dim_vals].update(data)
        else:
            self.data[dim_vals] = data

        if sort:
            self._resort()