'Return overall the availability of all pieces, using connected peers
Availability is defined as the number of complete copies of a piece, thus seeders
increment the availability by 1. Leechers provide a subset of piece thus we count the
overall availability of all pieces provided by the connected peers and use the minimum
of this + the average of all additional pieces.'

def get_availability(self):

    nr_seeders_complete = 0
    merged_bitfields = None
    peers = self.get_peerlist()
    for peer in peers:
        completed = peer.get('completed', 0)
        have = peer.get('have', [])
        if ((completed == 1) or (have and all(have))):
            nr_seeders_complete += 1
        else:
            if (merged_bitfields is None):
                merged_bitfields = ([0] * len(have))
            for i in range(len(have)):
                if have[i]:
                    merged_bitfields[i] += 1
    if merged_bitfields:
        nr_leechers_complete = min(merged_bitfields)
        nr_more_than_min = len([x for x in merged_bitfields if (x > nr_leechers_complete)])
        fraction_additonal = (float(nr_more_than_min) / len(merged_bitfields))
        return ((nr_seeders_complete + nr_leechers_complete) + fraction_additonal)
    return nr_seeders_complete
