<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _group_tokens(cls, token_stream, range_list):
 """ Group tokens into snippet ranges. `token_stream` is a generator that produces `(token_type, value)` tuples, `range_list` is a list of `(start, end)` tuples representing the (inclusive) range of line numbers for each snippet. Assumes that `range_list` is an ascending order by start value. Returns a dict mapping ranges to lists of tokens: { } The algorithm is slightly complicated because a single token can contain multiple line breaks. """


        # Create a map from ranges (start/end tuples) to tokens
        token_map = {rng: [] for rng in range_list}

        # Keep track of the current line number; we will
        # increment this as we encounter newlines in token values
        line_num = 1

        for ttype, val in token_stream:

            # If there are newlines in this token,
            # we need to split it up and check whether
            # each line within the token is within one
            # of our ranges.
            if '\n' in val:
                val_lines = val.split('\n')

                # Check if the tokens match each range
                for (start, end), filtered_tokens in six.iteritems(token_map):

                    # Filter out lines that are not in this range
                    include_vals = [
                        val_lines[i] for i in
                        range(0, len(val_lines))
                        if i + line_num in range(start, end + 1)
                    ]

                    # If we found any lines, store the tokens
                    if len(include_vals) > 0:
                        token = (ttype, '\n'.join(include_vals))
                        filtered_tokens.append(token)

                # Increment the line number
                # by the number of lines we found
                line_num += len(val_lines) - 1

            # No newline in this token
            # If we're in the line range, add it
            else:
                # Check if the tokens match each range
                for (start, end), filtered_tokens in six.iteritems(token_map):

                    # If we got a match, store the token
                    if line_num in range(start, end + 1):
                        filtered_tokens.append((ttype, val))

                    # Otherwise, ignore the token

        return token_map