'This method is used to return multiple ranges for a given length
which should represent the length of the underlying content.
The constructor method __init__ made sure that any range in ranges
list is syntactically valid. So if length is None or size of the
ranges is zero, then the Range header should be ignored which will
eventually make the response to be 200.
If an empty list is returned by this method, it indicates that there
are unsatisfiable ranges found in the Range header, 416 will be
returned.
if a returned list has at least one element, the list indicates that
there is at least one range valid and the server should serve the
request with a 206 status code.
The start value of each range represents the starting position in
the content, the end value represents the ending position. This
method purposely adds 1 to the end number because the spec defines
the Range to be inclusive.
The Range spec can be found at the following link:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.1
:param length: length of the underlying content'

def ranges_for_length(self, length):

    if ((length is None) or (not self.ranges) or (self.ranges == [])):
        return None
    all_ranges = []
    for single_range in self.ranges:
        (begin, end) = single_range
        if (begin is None):
            if (end == 0):
                continue
            elif (end > length):
                all_ranges.append((0, length))
            else:
                all_ranges.append(((length - end), length))
            continue
        if (end is None):
            if (begin < length):
                all_ranges.append((begin, length))
            else:
                continue
        elif (begin < length):
            all_ranges.append((begin, min((end + 1), length)))
    if (len(all_ranges) > MAX_RANGES):
        return []
    overlaps = 0
    for ((start1, end1), (start2, end2)) in pairs(all_ranges):
        if ((start1 < start2 < end1) or (start1 < end2 < end1) or (start2 < start1 < end2) or (start2 < end1 < end2)):
            overlaps += 1
            if (overlaps > MAX_RANGE_OVERLAPS):
                return []
    ascending = True
    for (start1, start2) in zip(all_ranges, all_ranges[1:]):
        if (start1 > start2):
            ascending = False
            break
    if ((not ascending) and (len(all_ranges) >= MAX_NONASCENDING_RANGES)):
        return []
    return all_ranges
