'Implementation of the Model.param_sets property.
This internal implementation has a ``raw`` argument which controls
whether or not to return the raw parameter values (i.e. the values that
are actually stored in the ._parameters array, as opposed to the values
displayed to users.  In most cases these are one in the same but there
are currently a few exceptions.
Note: This is notably an overcomplicated device and may be removed
entirely in the near future.'

def _param_sets(self, raw=False, units=False):

    param_metrics = self._param_metrics
    values = []
    shapes = []
    for name in self.param_names:
        param = getattr(self, name)
        if raw:
            value = param._raw_value
        else:
            value = param.value
        broadcast_shape = param_metrics[name].get(u'broadcast_shape')
        if (broadcast_shape is not None):
            value = value.reshape(broadcast_shape)
        shapes.append(np.shape(value))
        if (len(self) == 1):
            value = np.array([value])
        if units:
            if (raw and (self._param_metrics[name][u'raw_unit'] is not None)):
                unit = self._param_metrics[name][u'raw_unit']
            else:
                unit = param.unit
            if (unit is not None):
                value = Quantity(value, unit)
        values.append(value)
    if ((len(set(shapes)) != 1) or units):
        psets = np.empty(len(values), dtype=object)
        psets[:] = values
        return psets
    return np.array(values)
