def read_ranges_to_gaps_and_last(read_ranges):
    """Return all texts excluded from read_ranges.

    @return: Returns a 2-tuple of a list and the first possibly
    unread text number after the last read range. The text number
    could be larger than the highest local number, if we have read
    everything in the conference. The list contains a 2-tuples for
    each gap in the read ranges, where each tuple is the first
    unread text in the gap and the length of the gap.
    """
    gaps = []
    last = 1
    for read_range in read_ranges:
        gap = read_range.first_read - last
        if gap > 0:
            gaps.append((last, gap))
        last = read_range.last_read + 1
    return gaps, last
