def get_variants(self, arch=None, types=None, recursive=False):
        """
        Return all variants of given arch and types.

        Supported variant types:
            self     - include the top-level ("self") variant as well
            addon
            variant
            optional
        """
        types = types or []
        result = []

        if "self" in types:
            result.append(self)

        for variant in six.itervalues(self.variants):
            if types and variant.type not in types:
                continue
            if arch and arch not in variant.arches.union(["src"]):
                continue
            result.append(variant)
            if recursive:
                result.extend(variant.get_variants(types=[i for i in types if i != "self"], recursive=True))

        result.sort(key=lambda x: x.uid)
        return result