def errors(self):
        """
        Get the errors of the tag.
        If invalid then the list will consist of errors containing each a code and message explaining the error.
        Each error also refers to the respective (sub)tag(s).

        :return: list of errors of the tag. If the tag is valid, it returns an empty list.
        """
        errors = []
        data = self.data
        error = self.error

        # Check if the tag is grandfathered and if the grandfathered tag is deprecated (e.g. no-nyn).
        if 'record' in data:
            if 'Deprecated' in data['record']:
                errors.append(error(self.ERR_DEPRECATED))
            # Only check every subtag if the tag is not explicitly listed as grandfathered or redundant.
            return errors

        # Check that all subtag codes are meaningful.
        codes = data['tag'].split('-')
        for i, code in enumerate(codes):
            # Ignore anything after a singleton (break)
            if len(code) < 2:
                # Check that each private-use subtag is within the maximum allowed length.
                for code in codes[i + 1:]:
                    if len(code) > 8:
                        errors.append(error(self.ERR_TOO_LONG, code))
                break

            if code not in index:
                errors.append(error(self.ERR_UNKNOWN, code))
                # Continue to the next item.
                continue

        # Check that first tag is a language tag.
        subtags = self.subtags
        if not len(subtags):
            errors.append(error(self.ERR_NO_LANGUAGE))
            return errors
        elif subtags[0].type != 'language':
            errors.append(error(self.ERR_NO_LANGUAGE))
            return errors

        # Check for more than one of some types and for deprecation.
        found = dict(language=[], extlang=[], variant=[], script=[], region=[])
        for subtag in subtags:
            type = subtag.type

            if subtag.deprecated:
                errors.append(error(self.ERR_SUBTAG_DEPRECATED, subtag))

            if type in found:
                found[type].append(subtag)

            if 'language' == type:
                if len(found['language']) > 1:
                    errors.append(error(self.ERR_EXTRA_LANGUAGE, subtag))
            elif 'region' == type:
                if len(found['region']) > 1:
                    errors.append(error(self.ERR_EXTRA_REGION, subtag))
            elif 'extlang' == type:
                if len(found['extlang']) > 1:
                    errors.append(error(self.ERR_EXTRA_EXTLANG, subtag))
            elif 'script' == type:
                if len(found['script']) > 1:
                    errors.append(error(self.ERR_EXTRA_SCRIPT, subtag))
                # Check if script is same as language suppress-script.
                else:
                    script = subtags[0].script
                    if script:
                        if script.format == subtag.format:
                            errors.append(error(self.ERR_SUPPRESS_SCRIPT, subtag))
            elif 'variant' == type:
                if len(found['variant']) > 1:
                    for variant in found['variant']:
                        if variant.format == subtag.format:
                            errors.append(error(self.ERR_DUPLICATE_VARIANT, subtag))
                            break

        # Check for correct order.
        if len(subtags) > 1:
            priority = dict(language=4, extlang=5, script=6, region=7, variant=8)
            for i, subtag in enumerate(subtags[0:len(subtags)-1]):
                next = subtags[i + 1]
                if next:
                    if priority[subtag.type] > priority[next.type]:
                        errors.append(error(self.ERR_WRONG_ORDER, [subtag, next]))

        return errors