def parse_report_filter_values(request, reports):
    """Given a dictionary of GET query parameters, return a dictionary mapping
    report names to a dictionary of filter values.

    Report filter parameters contain a | in the name.  For example, request.GET
    might be
        {
            "crash_report|operating_system": "Linux",
            "crash_report|graphics_card": "nVidia",
            "apprentice_report|version": "13.0",
            "start_date": "2015-01-01",
            "end_date": "2015-01-31",
        }
    We want to return
        {
            "crash_report": {
                "operating_system": "Linux",
                "graphics_card": "nVidia",
            },
            "apprentice_report": {
                "version": "13.0",
            },
        }
    """
    report_name_to_filter_values = {}
    # Note that if there are multiple values in the request.GET dictionary,
    # as is the case for checkboxes with corresponding hidden fields, that
    # items() will simply return the last value.
    for report_and_parm_name, value in request.GET.items():
        if "|" in report_and_parm_name:
            report_name, parm_name = report_and_parm_name.split("|", 1)
            report_name_to_filter_values.setdefault(
                report_name, {})[parm_name] = value

    # Make sure that all reports are in the result, and that each of the
    # report's filters has a value.
    for report in reports:
        filter_values = report_name_to_filter_values.setdefault(
            report.name(), {})
        for filt in report.get_filters():
            if filt.name not in filter_values:
                filter_values[filt.name] = filt.default_value()

            # Give the filter a chance to convert from the GET value into
            # something that makes more sense to the report.
            filter_values[filt.name] = filt.process_GET_value(
                filter_values[filt.name])

    return report_name_to_filter_values