def determine_non_measured_lines(coverage_data, line_cache):
    """Given some coverage data and the line cache, determine which lines
    in which files need to be looked up by scanning the file itself.

    Returns a tuple:
    - A list of line cache keys that already have been scanned and
      determined to be needed by the coverage data.
    - A dictionary mapping from filename to a (sorted) list of lines
      that need to be extracted from the file itself.

    """

    indices = []
    non_measured_lines = {}

    for filename in coverage_data.measured_files():
        filename_index = line_cache.filename_index(filename)
        lines = [i - 1 for i in list(sorted(coverage_data.lines(filename)))]
        actual_lines = []

        next_end = None
        for start in lines:
            if next_end is not None and start >= next_end:
                next_end = None

            if next_end is None:
                key, record = line_cache.match_record(
                    filename_index, start)

                if record is not None:
                    indices.append(key)
                    _, _, next_end, _ = record
                else:
                    actual_lines.append(start)

            else:
                if start >= next_end:
                    actual_lines.append(start)
                    next_end = None

        non_measured_lines[filename] = actual_lines

    return indices, non_measured_lines