Register a new feature serializer.

        The feature type should be one of the fixed set of feature
        representations, and `name` should be one of ``StringCounter``,
        ``SparseVector``, or ``DenseVector``.  `obj` is a describing
        object with three fields: `constructor` is a callable that
        creates an empty instance of the representation; `dumps` is
        a callable that takes an instance of the representation and
        returns a JSON-compatible form made of purely primitive
        objects (lists, dictionaries, strings, numbers); and `loads`
        is a callable that takes the response from `dumps` and recreates
        the original representation.

        Note that ``obj.constructor()`` *must* return an
        object that is an instance of one of the following
        types: ``unicode``, :class:`dossier.fc.StringCounter`,
        :class:`dossier.fc.SparseVector` or
        :class:`dossier.fc.DenseVector`. If it isn't, a
        :exc:`ValueError` is raised.

def add(self, name, obj):
        '''Register a new feature serializer.

        The feature type should be one of the fixed set of feature
        representations, and `name` should be one of ``StringCounter``,
        ``SparseVector``, or ``DenseVector``.  `obj` is a describing
        object with three fields: `constructor` is a callable that
        creates an empty instance of the representation; `dumps` is
        a callable that takes an instance of the representation and
        returns a JSON-compatible form made of purely primitive
        objects (lists, dictionaries, strings, numbers); and `loads`
        is a callable that takes the response from `dumps` and recreates
        the original representation.

        Note that ``obj.constructor()`` *must* return an
        object that is an instance of one of the following
        types: ``unicode``, :class:`dossier.fc.StringCounter`,
        :class:`dossier.fc.SparseVector` or
        :class:`dossier.fc.DenseVector`. If it isn't, a
        :exc:`ValueError` is raised.
        '''
        ro = obj.constructor()
        if name not in cbor_names_to_tags:
            print(name)
            raise ValueError(
                'Unsupported feature type name: "%s". '
                'Allowed feature type names: %r'
                % (name, cbor_names_to_tags.keys()))
        if not is_valid_feature_instance(ro):
            raise ValueError(
                'Constructor for "%s" returned "%r" which has an unknown '
                'sub type "%r". (mro: %r). Object must be an instance of '
                'one of the allowed types: %r'
                % (name, ro, type(ro), type(ro).mro(), ALLOWED_FEATURE_TYPES))
        self._registry[name] = {'obj': obj, 'ro': obj.constructor()}
        self._inverse[obj.constructor] = name