def _find_complete_block_bounds(self, table, used_cells, possible_block_start,
                                    start_pos, end_pos):
        '''
        Finds the end of a block from a start location and a suggested end location.
        '''
        block_start = list(possible_block_start)
        block_end = list(possible_block_start)
        table_row = table[block_start[0]]
        used_row = used_cells[block_start[0]]
        # Find which column the titles end on
        for column_index in range(block_start[1], end_pos[1]+1):
            # Ensure we catch the edge case of the data reaching the edge of
            # the table -- block_end should then equal end_pos
            block_end[1] = max(block_end[1], column_index)
            if (column_index == end_pos[1] or used_row[column_index] or
                    is_empty_cell(table_row[column_index])):
                break
        for row_index in range(block_start[0]+1, end_pos[0]+1):
            block_end[0] = row_index
            # Stop if we reach the end of the table space
            if block_end[0] == end_pos[0]:
                break
            table_row = table[row_index]
            blank = False
            for column_index in range(block_start[1], block_end[1]):
                if (column_index == block_end[1] or used_row[column_index] or
                        is_empty_cell(table_row[column_index])):
                    blank = True
                    break
            if blank:
                break
        return block_start, block_end
Finds the end of a block from a start location and a suggested end location.