# Buggy code
def get_availability(self):
    """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.
    """
    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:
        # count the number of complete copies due to overlapping leecher bitfields
        nr_leechers_complete = min(merged_bitfields)

        # detect remainder of bitfields which are > 0
        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


# Traceback (IndexError)
ERROR   1521645350.53    rest_manager:53    [Failure instance: Traceback: <type 'exceptions.IndexError'>: list index out of range
/usr/lib/python2.7/dist-packages/twisted/protocols/basic.py:571:dataReceived
/usr/lib/python2.7/dist-packages/twisted/web/http.py:1752:lineReceived
/usr/lib/python2.7/dist-packages/twisted/web/http.py:1845:allContentReceived
/usr/lib/python2.7/dist-packages/twisted/web/http.py:766:requestReceived
--- <exception caught here> ---
/usr/lib/python2.7/dist-packages/twisted/web/server.py:190:process
/usr/lib/python2.7/dist-packages/twisted/web/server.py:241:render
/usr/lib/python2.7/dist-packages/twisted/web/resource.py:250:render
/usr/share/tribler/Tribler/Core/Modules/restapi/downloads_endpoint.py:211:render_GET
/usr/share/tribler/Tribler/Core/DownloadState.py:187:get_availability
]
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/twisted/web/server.py", line 190, in process
self.render(resrc)
File "/usr/lib/python2.7/dist-packages/twisted/web/server.py", line 241, in render
body = resrc.render(self)
File "/usr/lib/python2.7/dist-packages/twisted/web/resource.py", line 250, in render
return m(request)
File "/usr/share/tribler/Tribler/Core/Modules/restapi/downloads_endpoint.py", line 211, in render_GET
"destination": download.get_dest_dir(), "availability": state.get_availability(),
File "/usr/share/tribler/Tribler/Core/DownloadState.py", line 187, in get_availability
merged_bitfields[i] += 1
IndexError: list index out of range

# Fixed code
def get_availability(self):
    """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.
    """
    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
        elif have:
            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:
        # count the number of complete copies due to overlapping leecher bitfields
        nr_leechers_complete = min(merged_bitfields)

        # detect remainder of bitfields which are > 0
        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