(cls, block)
This is the buggy version of get_last_statements, because, you know, there can always be more than one last
        statement due to the existence of branching statements (like, If-then-else). All methods using
        get_last_statement() should switch to get_last_statements() and properly handle multiple last statements.
This is the buggy version of get_last_statements, because, you know, there can always be more than one last
        statement due to the existence of branching statements (like, If-then-else). All methods using
        get_last_statement() should switch to get_last_statements() and properly handle multiple last statements.
This is the buggy version of get_last_statements because you know there can always be more than one last statement due to the existence of branching statements ( like If - then - else ) . All methods using get_last_statement () should switch to get_last_statements () and properly handle multiple last statements .
def get_last_statement(cls, block):
        """
        This is the buggy version of get_last_statements, because, you know, there can always be more than one last
        statement due to the existence of branching statements (like, If-then-else). All methods using
        get_last_statement() should switch to get_last_statements() and properly handle multiple last statements.
        """
        if type(block) is SequenceNode:
            if block.nodes:
                return cls.get_last_statement(block.nodes[-1])
            raise EmptyBlockNotice()
        if type(block) is CodeNode:
            return cls.get_last_statement(block.node)
        if type(block) is ailment.Block:
            if not block.statements:
                raise EmptyBlockNotice()
            return block.statements[-1]
        if type(block) is Block:
            raise NotImplementedError()
        if type(block) is BlockNode:
            raise NotImplementedError()
        if type(block) is MultiNode:
            # get the last node
            for the_block in reversed(block.nodes):
                try:
                    last_stmt = cls.get_last_statement(the_block)
                    return last_stmt
                except EmptyBlockNotice:
                    continue
            raise EmptyBlockNotice()
        if type(block) is LoopNode:
            return cls.get_last_statement(block.sequence_node)
        if type(block) is ConditionalBreakNode:
            return None
        if type(block) is ConditionNode:
            s = None
            if block.true_node:
                try:
                    s = cls.get_last_statement(block.true_node)
                except EmptyBlockNotice:
                    s = None
            if s is None and block.false_node:
                s = cls.get_last_statement(block.false_node)
            return s
        if type(block) is CascadingConditionNode:
            s = None
            if block.else_node is not None:
                s = cls.get_last_statement(block.else_node)
            else:
                for _, node in reversed(block.condition_and_nodes):
                    s = cls.get_last_statement(node)
                    if s is not None:
                        break
            return s
        if type(block) is BreakNode:
            return None
        if type(block) is ContinueNode:
            return None
        if type(block) is SwitchCaseNode:
            return None
        if type(block) is GraphRegion:
            # normally this should not happen. however, we have test cases that trigger this case.
            return None

        raise NotImplementedError()
def get_last_statement ( cls , block ) : if type ( block ) is SequenceNode : if block . nodes : return cls . get_last_statement ( block . nodes [ - 1 ] ) raise EmptyBlockNotice ( ) if type ( block ) is CodeNode : return cls . get_last_statement ( block . node ) if type ( block ) is ailment . Block : if not block . statements : raise EmptyBlockNotice ( ) return block . statements [ - 1 ] if type ( block ) is Block : raise NotImplementedError ( ) if type ( block ) is BlockNode : raise NotImplementedError ( ) if type ( block ) is MultiNode : # get the last node for the_block in reversed ( block . nodes ) : try : last_stmt = cls . get_last_statement ( the_block ) return last_stmt except EmptyBlockNotice : continue raise EmptyBlockNotice ( ) if type ( block ) is LoopNode : return cls . get_last_statement ( block . sequence_node ) if type ( block ) is ConditionalBreakNode : return None if type ( block ) is ConditionNode : s = None if block . true_node : try : s = cls . get_last_statement ( block . true_node ) except EmptyBlockNotice : s = None if s is None and block . false_node : s = cls . get_last_statement ( block . false_node ) return s if type ( block ) is CascadingConditionNode : s = None if block . else_node is not None : s = cls . get_last_statement ( block . else_node ) else : for _ , node in reversed ( block . condition_and_nodes ) : s = cls . get_last_statement ( node ) if s is not None : break return s if type ( block ) is BreakNode : return None if type ( block ) is ContinueNode : return None if type ( block ) is SwitchCaseNode : return None if type ( block ) is GraphRegion : # normally this should not happen. however, we have test cases that trigger this case. return None raise NotImplementedError ( )