def search_ss_bonds(model, threshold=3.0):
    """ Searches S-S bonds based on distances
        between atoms in the structure (first model only).
        Average distance is 2.05A. Threshold is 3A default.
        Returns iterator with tuples of residues.

        ADAPTED FROM JOAO RODRIGUES' BIOPYTHON GSOC PROJECT (http://biopython.org/wiki/GSOC2010_Joao)
    """

    # Taken from http://docs.python.org/library/itertools.html
    # Python 2.4 does not include itertools.combinations

    def combinations(iterable, r):
        # combinations('ABCD', 2) --> AB AC AD BC BD CD
        # combinations(range(4), 3) --> 012 013 023 123
        pool = tuple(iterable)
        n = len(pool)
        if r > n:
            return
        indices = list(range(r))
        yield tuple(pool[i] for i in indices)
        while True:
            for i in reversed(range(r)):
                if indices[i] != i + n - r:
                    break
            else:
                return
            indices[i] += 1
            for j in range(i + 1, r):
                indices[j] = indices[j - 1] + 1
            yield tuple(pool[i] for i in indices)

    cysteines = [r for r in model.get_residues() if r.get_resname() == 'CYS']

    pairs = combinations(cysteines, 2)  # Iterator with pairs

    bridges = []
    for cys_pair in pairs:
        try:
            if cys_pair[0]['SG'] - cys_pair[1]['SG'] < threshold:
                bridges.append(cys_pair)
        except KeyError:  # This will occur when a CYS residue is missing a SG atom for some reason
            log.error('{}: no SG atom found for one or both of the cysteine residues {}'.format(model, cys_pair))
            continue

    infodict = {}
    if bridges:
        infodict = defaultdict(list)

        for disulfide_bridge in bridges:
            residue1 = disulfide_bridge[0]
            residue2 = disulfide_bridge[1]
            chain = residue1.get_parent().id
            infodict[chain].append((residue1.get_full_id()[3], residue2.get_full_id()[3]))

    return infodict