Lower standard folded output fields into GremlinFoldedContextField objects.

def lower_folded_outputs(ir_blocks):
    """Lower standard folded output fields into GremlinFoldedContextField objects."""
    folds, remaining_ir_blocks = extract_folds_from_ir_blocks(ir_blocks)

    if not remaining_ir_blocks:
        raise AssertionError(u'Expected at least one non-folded block to remain: {} {} '
                             u'{}'.format(folds, remaining_ir_blocks, ir_blocks))
    output_block = remaining_ir_blocks[-1]
    if not isinstance(output_block, ConstructResult):
        raise AssertionError(u'Expected the last non-folded block to be ConstructResult, '
                             u'but instead was: {} {} '
                             u'{}'.format(type(output_block), output_block, ir_blocks))

    # Turn folded Filter blocks into GremlinFoldedFilter blocks.
    converted_folds = {
        base_fold_location.get_location_name()[0]: _convert_folded_blocks(folded_ir_blocks)
        for base_fold_location, folded_ir_blocks in six.iteritems(folds)
    }

    new_output_fields = dict()
    for output_name, output_expression in six.iteritems(output_block.fields):
        new_output_expression = output_expression

        # Turn FoldedContextField expressions into GremlinFoldedContextField ones.
        if isinstance(output_expression, FoldedContextField):
            # Get the matching folded IR blocks and put them in the new context field.
            base_fold_location_name = output_expression.fold_scope_location.get_location_name()[0]
            folded_ir_blocks = converted_folds[base_fold_location_name]
            new_output_expression = GremlinFoldedContextField(
                output_expression.fold_scope_location, folded_ir_blocks,
                output_expression.field_type)

        new_output_fields[output_name] = new_output_expression

    new_ir_blocks = remaining_ir_blocks[:-1]
    new_ir_blocks.append(ConstructResult(new_output_fields))
    return new_ir_blocks