Convert Filter/Traverse blocks and LocalField expressions within @fold to Gremlin objects.

def _convert_folded_blocks(folded_ir_blocks):
    """Convert Filter/Traverse blocks and LocalField expressions within @fold to Gremlin objects."""
    new_folded_ir_blocks = []

    def folded_context_visitor(expression):
        """Transform LocalField objects into their Gremlin-specific counterpart."""
        if not isinstance(expression, LocalField):
            return expression

        return GremlinFoldedLocalField(expression.field_name)

    for block in folded_ir_blocks:
        new_block = block

        if isinstance(block, Filter):
            new_predicate = block.predicate.visit_and_update(folded_context_visitor)
            new_block = GremlinFoldedFilter(new_predicate)
        elif isinstance(block, Traverse):
            new_block = GremlinFoldedTraverse.from_traverse(block)
        elif isinstance(block, (MarkLocation, Backtrack)):
            # We remove MarkLocation and Backtrack blocks from the folded blocks output,
            # since they do not produce any Gremlin output code inside folds.
            continue
        else:
            raise AssertionError(u'Found an unexpected IR block in the folded IR blocks: '
                                 u'{} {} {}'.format(type(block), block, folded_ir_blocks))

        new_folded_ir_blocks.append(new_block)

    return new_folded_ir_blocks