def __new__(cls, name, bases, attrs):
        # TODO: Think of a better test to avoid processing Metadata parent class
        if bases == (object,):
            return type.__new__(cls, name, bases, attrs)

        # Save options as a dict for now (we will be editing them)
        # TODO: Is this necessary, should we bother relaying Django Meta options?
        Meta = attrs.pop('Meta', {})
        if Meta:
            Meta = Meta.__dict__.copy()

        # Remove our options from Meta, so Django won't complain
        help_text = attrs.pop('HelpText', {})

        # TODO: Is this necessary
        if help_text:
            help_text = help_text.__dict__.copy()

        options = Options(Meta, help_text)

        # Collect and sort our elements
        elements = [(key, attrs.pop(key)) for key, obj in attrs.items() 
                                        if isinstance(obj, MetadataField)]
        elements.sort(lambda x, y: cmp(x[1].creation_counter, 
                                                y[1].creation_counter))
        elements = SortedDict(elements)

        # Validation:
        # TODO: Write a test framework for seo.Metadata validation
        # Check that no group names clash with element names
        for key,members in options.groups.items():
            assert key not in elements, "Group name '%s' clashes with field name" % key
            for member in members:
                assert member in elements, "Group member '%s' is not a valid field" % member

        # Check that the names of the elements are not going to clash with a model field
        for key in elements:
            assert key not in RESERVED_FIELD_NAMES, "Field name '%s' is not allowed" % key


        # Preprocessing complete, here is the new class
        new_class = type.__new__(cls, name, bases, attrs)

        options.metadata = new_class
        new_class._meta = options

        # Some useful attributes
        options._update_from_name(name)
        options._register_elements(elements)

        try:
            for backend_name in options.backends:
                new_class._meta._add_backend(backend_registry[backend_name])
            for backend_name in options.backends:
                backend_registry[backend_name].validate(options)
        except __HOLE__:
            raise Exception('Metadata backend "%s" is not installed.' % backend_name)

        #new_class._meta._add_backend(PathBackend)
        #new_class._meta._add_backend(ModelInstanceBackend)
        #new_class._meta._add_backend(ModelBackend)
        #new_class._meta._add_backend(ViewBackend)

        registry[name] = new_class

        return new_class


    # TODO: Move this function out of the way (subclasses will want to define their own attributes)
dataset/ETHPy150Open willhardy/django-seo/rollyourown/seo/base.py/MetadataBase.__new__