def METHOD_NAME(
    self,
    current_node,
    current_best_option,
    actual_parent_left,
    parent_left,
    parent_right,
    left_child,
    criterion,
    pre_split_dist,
    att_idx,
):
    if current_node is None:
        return current_best_option
    left_dist = {}
    right_dist = {}
    if parent_left is None:
        left_dist.update(dict(Counter(left_dist) + Counter(current_node.class_count_left)))
        right_dist.update(dict(Counter(right_dist) + Counter(current_node.class_count_right)))
    else:
        left_dist.update(dict(Counter(left_dist) + Counter(parent_left)))
        right_dist.update(dict(Counter(right_dist) + Counter(parent_right)))
        if left_child:
            # get the exact statistics of the parent value
            exact_parent_dist = {}
            exact_parent_dist.update(
                dict(Counter(exact_parent_dist) + Counter(actual_parent_left))
            )
            exact_parent_dist.update(
                dict(Counter(exact_parent_dist) - Counter(current_node.class_count_left))
            )
            exact_parent_dist.update(
                dict(Counter(exact_parent_dist) - Counter(current_node.class_count_right))
            )
            # move the subtrees
            left_dist.update(dict(Counter(left_dist) - Counter(current_node.class_count_right)))
            right_dist.update(
                dict(Counter(right_dist) + Counter(current_node.class_count_right))
            )
            # move the exact value from the parent
            right_dist.update(dict(Counter(right_dist) + Counter(exact_parent_dist)))
            left_dist.update(dict(Counter(left_dist) - Counter(exact_parent_dist)))
        else:
            left_dist.update(dict(Counter(left_dist) + Counter(current_node.class_count_left)))
            right_dist.update(
                dict(Counter(right_dist) - Counter(current_node.class_count_left))
            )
    post_split_dists = [left_dist, right_dist]
    merit = criterion.merit_of_split(pre_split_dist, post_split_dists)
    if merit > current_best_option.merit:
        current_best_option = BranchFactory(
            merit, att_idx, current_node.cut_point, post_split_dists
        )
    current_best_option = self.METHOD_NAME(
        current_node=current_node._left,  # noqa
        current_best_option=current_best_option,
        actual_parent_left=current_node.class_count_left,
        parent_left=post_split_dists[0],
        parent_right=post_split_dists[1],
        left_child=True,
        criterion=criterion,
        pre_split_dist=pre_split_dist,
        att_idx=att_idx,
    )
    current_best_option = self.METHOD_NAME(
        current_node=current_node._right,  # noqa
        current_best_option=current_best_option,
        actual_parent_left=current_node.class_count_left,
        parent_left=post_split_dists[0],
        parent_right=post_split_dists[1],
        left_child=False,
        criterion=criterion,
        pre_split_dist=pre_split_dist,
        att_idx=att_idx,
    )
    return current_best_option