def indexes2ranges(indexes) -> str:
    """
    Transforms a list of indexes into a range representation.

    This function is used for building NEXUS-like assumption blocks,
    especially for binarized data. Given a list such as `[1, 2, 3, 5, 8, 9]`
    it will return a string representation of the ranges involved, such as
    `"1-3, 5, 8-9"`.
    """

    # We need to operate on sorted indexes
    indexes = sorted(indexes)

    # Collect ranges as a list of tuples
    ranges = []
    start, end = None, None
    for idx in indexes:
        if not start:
            start = idx
        elif not end:
            if idx > start + 1:
                ranges.append((start, start))
                start = idx
            else:
                end = idx
        else:
            if idx == end + 1:
                end = idx
            else:
                ranges.append((start, end))
                start, end = idx, None

    # We finish with whatever is in the pile; note that we add `indexes[-1]`
    # and not `end`, dealing with single sites
    ranges.append((start, indexes[-1]))

    # Build output
    ret = ", ".join(
        [
            "%i-%i" % (start, end) if start != end else str(start)
            for (start, end) in ranges
        ]
    )

    return ret