def METHOD_NAME(self, original_model, config):
    logger = config.logger
    (
        discrete_problem_util_block,
        subproblem_util_block,
    ) = _get_discrete_problem_and_subproblem(self, config)
    discrete_problem = discrete_problem_util_block.parent_block()
    subproblem = subproblem_util_block.parent_block()
    discrete_problem_obj = next(
        discrete_problem.component_data_objects(
            Objective, active=True, descend_into=True
        )
    )
    self._log_header(logger)
    # main loop
    while not config.iterlim or self.iteration < config.iterlim:
        self.iteration += 1
        # solve linear discrete problem
        with time_code(self.timing, 'mip'):
            mip_feasible = solve_MILP_discrete_problem(
                discrete_problem_util_block, self, config
            )
            self._update_bounds_after_discrete_problem_solve(
                mip_feasible, discrete_problem_obj, logger
            )
        # Check termination conditions
        if self.any_termination_criterion_met(config):
            break
        with time_code(self.timing, 'nlp'):
            self._fix_discrete_soln_solve_subproblem_and_add_cuts(
                discrete_problem_util_block, subproblem_util_block, config
            )
        # Add integer cut
        with time_code(self.timing, "integer cut generation"):
            add_no_good_cut(discrete_problem_util_block, config)
        # Check termination conditions
        if self.any_termination_criterion_met(config):
            break