'Generate a list of available catalogs.
"selections" (optional) is a list of string of the same form
as to `.get_lib()\'. It is used to determine the boolean
value of <selected> in the yielded tuples.
Generated dicts as follows:
{"name": <catalog-name>,    # \'name\' attr of <codeintel> tag
#   or file basename
"lang": <lang>,            # \'lang\' attribute of first <file> tag
"description": <desc>,     # \'description\' attr of <codeintel>
"cix_path": <cix-path>,
"selected": <selected>,
"selection": <selection>,
where <selected> is boolean indicating if this catalog is
selected according to "selections" and <selection> is the string
in "selections" that resulted in this.'

def avail_catalogs(self, selections=None):

    selection_from_selector = self._selection_from_selector(selections)
    for cix_path in (cix_path for d in self.catalog_dirs if exists(d) for cix_path in glob(join(d, '*.cix'))):
        name = lang = description = None
        try:
            for (event, elem) in ET.iterparse(cix_path, events=('start',)):
                if (elem.tag == 'codeintel'):
                    name = elem.get('name')
                    description = elem.get('description')
                elif (elem.tag == 'file'):
                    lang = elem.get('lang')
                    break
        except ET.XMLParserError as ex:
            log.warn('%s:    error    reading    catalog,    skipping    it    (%s)', cix_path, ex)
            continue
        if (lang is None):
            log.warn("%s:    no    'lang'    attribute    on    catalog    <file>    tag,    skipping    it", cix_path)
            continue
        if (name is None):
            name = splitext(basename(cix_path))[0]
        norm_name = name.lower()
        norm_cix_path = normpath(normcase(cix_path))
        if (selection_from_selector is None):
            selected = True
            selection = None
        else:
            selection = (selection_from_selector.get(norm_name) or selection_from_selector.get(norm_cix_path))
            selected = (selection is not None)
        (yield {'name': name, 'lang': lang, 'description': description, 'cix_path': cix_path, 'selected': selected, 'selection': selection})
