def METHOD_NAME(self, initial_result):
    attacked_text = initial_result.attacked_text
    # Sort words by order of importance
    index_order, search_over = self._get_index_order(attacked_text)
    i = 0
    cur_result = initial_result
    results = None
    while i < len(index_order) and not search_over:
        transformed_text_candidates = self.get_transformations(
            cur_result.attacked_text,
            original_text=initial_result.attacked_text,
            indices_to_modify=[index_order[i]],
        )
        i += 1
        if len(transformed_text_candidates) == 0:
            continue
        results, search_over = self.get_goal_results(transformed_text_candidates)
        results = sorted(results, key=lambda x: -x.score)
        # Skip swaps which don't improve the score
        if results[0].score > cur_result.score:
            cur_result = results[0]
        else:
            continue
        # If we succeeded, return the index with best similarity.
        if cur_result.goal_status == GoalFunctionResultStatus.SUCCEEDED:
            best_result = cur_result
            # @TODO: Use vectorwise operations
            max_similarity = -float("inf")
            for result in results:
                if result.goal_status != GoalFunctionResultStatus.SUCCEEDED:
                    break
                candidate = result.attacked_text
                try:
                    similarity_score = candidate.attack_attrs["similarity_score"]
                except KeyError:
                    # If the attack was run without any similarity metrics,
                    # candidates won't have a similarity score. In this
                    # case, break and return the candidate that changed
                    # the original score the most.
                    break
                if similarity_score > max_similarity:
                    max_similarity = similarity_score
                    best_result = result
            return best_result
    return cur_result