def parse_categories(self, headers):
        kind = action = None
        mixins = collections.Counter()
        schemes = collections.defaultdict(list)
        try:
            categories = headers["Category"]
        except KeyError:
            raise exception.OCCIInvalidSchema("No categories")
        for ctg in _quoted_split(categories):
            ll = _quoted_split(ctg, "; ")
            d = {"term": ll[0]}  # assumes 1st element => term's value
            try:
                d.update(dict([_split_unquote(i) for i in ll[1:]]))
            except __HOLE__:
                raise exception.OCCIInvalidSchema("Unable to parse category")
            ctg_class = d.get("class", None)
            ctg_type = '%(scheme)s%(term)s' % d
            if ctg_class == "kind":
                if kind is not None:
                    raise exception.OCCIInvalidSchema("Duplicated Kind")
                kind = ctg_type
            elif ctg_class == "action":
                if action is not None:
                    raise exception.OCCIInvalidSchema("Duplicated action")
                action = ctg_type
            elif ctg_class == "mixin":
                mixins[ctg_type] += 1
            schemes[d["scheme"]].append(d["term"])
        if action and kind:
            raise exception.OCCIInvalidSchema("Action and kind together?")
        return {
            "category": kind or action,
            "mixins": mixins,
            "schemes": schemes,
        }
dataset/ETHPy150Open openstack/ooi/ooi/wsgi/parsers.py/TextParser.parse_categories