def diagnose_embedding(emb, source, target):
    if not hasattr(source, 'edges'):
        source = nx.Graph(source)
    if not hasattr(target, 'edges'):
        target = nx.Graph(target)
    label = {}
    embedded = set()
    for x in source:
        try:
            embx = emb[x]
            missing_chain = len(embx) == 0
        except KeyError:
            missing_chain = True
        if missing_chain:
            yield MissingChainError, x
            continue
        all_present = True
        for q in embx:
            if label.get(q, x) != x:
                yield ChainOverlapError, q, x, label[q]
            elif q not in target:
                all_present = False
                yield InvalidNodeError, x, q
            else:
                label[q] = x
        if all_present:
            embedded.add(x)
            if not nx.is_connected(target.subgraph(embx)):
                yield DisconnectedChainError, x
    yielded = nx.Graph()
    for p, q in target.subgraph(label).edges():
        yielded.add_edge(label[p], label[q])
    for x, y in source.edges():
        if x == y:
            continue
        if x in embedded and y in embedded and not yielded.has_edge(x, y):
            yield MissingEdgeError, x, y