Expand a set of labels that define a connected component.

    ``labels`` must define a *positive* connected component: it is all
    of the edges that make up the *single* connected component in the
    :class:`LabelStore`. expand will ignore subtopic assignments, and
    annotator_id will be an arbitrary one selected from ``labels``.

    Note that this function only returns the expanded labels, which
    is guaranteed to be disjoint with the given ``labels``. This
    requirement implies that ``labels`` is held in memory to ensure
    that no duplicates are returned.

    If ``subtopic`` is ``True``, then it is assumed that ``labels``
    defines a ``subtopic`` connected component. In this case, subtopics
    are included in the expanded labels.

    :param labels: iterable of :class:`Label` for the connected component.
    :rtype: generator of expanded :class:`Label`s only

def expand_labels(labels, subtopic=False):
    '''Expand a set of labels that define a connected component.

    ``labels`` must define a *positive* connected component: it is all
    of the edges that make up the *single* connected component in the
    :class:`LabelStore`. expand will ignore subtopic assignments, and
    annotator_id will be an arbitrary one selected from ``labels``.

    Note that this function only returns the expanded labels, which
    is guaranteed to be disjoint with the given ``labels``. This
    requirement implies that ``labels`` is held in memory to ensure
    that no duplicates are returned.

    If ``subtopic`` is ``True``, then it is assumed that ``labels``
    defines a ``subtopic`` connected component. In this case, subtopics
    are included in the expanded labels.

    :param labels: iterable of :class:`Label` for the connected component.
    :rtype: generator of expanded :class:`Label`s only
    '''
    labels = list(labels)
    assert all(lab.value == CorefValue.Positive for lab in labels)

    # Anything to expand?
    if len(labels) == 0:
        return

    annotator = labels[0].annotator_id

    data_backed = set()
    connected_component = set()
    for label in labels:
        ident1, ident2 = idents_from_label(label, subtopic=subtopic)
        data_backed.add(normalize_pair(ident1, ident2))
        connected_component.add(ident1)
        connected_component.add(ident2)

    # We do not want to rebuild the Labels we already have,
    # because they have true annotator_id and subtopic
    # fields that we may want to preserve.
    for ident1, ident2 in combinations(connected_component, 2):
        if normalize_pair(ident1, ident2) not in data_backed:
            (cid1, subid1), (cid2, subid2) = ident1, ident2
            yield Label(cid1, cid2, annotator, CorefValue.Positive,
                        subtopic_id1=subid1, subtopic_id2=subid2)