@classmethod
def _snippet_ranges(cls, num_src_lines, violation_lines):
    """
        Given the number of source file lines and list of
        violation line numbers, return a list of snippet
        ranges of the form `(start_line, end_line)`.

        Each snippet contains a few extra lines of context
        before/after the first/last violation.  Nearby
        violations are grouped within the same snippet.
        """
    current_range = None, None
    lines_since_last_violation = 0
    snippet_ranges = []
    for line_num in range(1, num_src_lines + 1):
        if current_range[0] is None:
            if line_num in violation_lines:
                snippet_start = max(1, line_num - cls.NUM_CONTEXT_LINES)
                current_range = snippet_start, None
                lines_since_last_violation = 0
        elif current_range[1] is None:
            if line_num in violation_lines:
                lines_since_last_violation = 0
            elif lines_since_last_violation > cls.MAX_GAP_IN_SNIPPET:
                snippet_end = line_num - lines_since_last_violation
                snippet_end = min(num_src_lines, snippet_end + cls.
                    NUM_CONTEXT_LINES)
                current_range = current_range[0], snippet_end
                snippet_ranges.append(current_range)
                current_range = None, None
        lines_since_last_violation += 1
    if current_range[0] is not None and current_range[1] is None:
        snippet_ranges.append((current_range[0], num_src_lines))
    return snippet_ranges
