code: @Override
      public void solve(DefaultSolverScope<Solution_> solverScope) {
          LocalSearchPhaseScope<Solution_> phaseScope = new LocalSearchPhaseScope<>(solverScope);
          phaseStarted(phaseScope);
  
          while (!termination.isPhaseTerminated(phaseScope)) {
              LocalSearchStepScope<Solution_> stepScope = new LocalSearchStepScope<>(phaseScope);
              stepScope.setTimeGradient(termination.calculatePhaseTimeGradient(phaseScope));
              stepStarted(stepScope);
              decider.decideNextStep(stepScope);
              if (stepScope.getStep() == null) {
                  if (termination.isPhaseTerminated(phaseScope)) {
                      logger.trace("{}    Step index ({}), time spent ({}) terminated without picking a nextStep.",
                              logIndentation,
                              stepScope.getStepIndex(),
                              stepScope.getPhaseScope().calculateSolverTimeMillisSpentUpToNow());
                  } else if (stepScope.getSelectedMoveCount() == 0L) {
                      logger.warn("{}    No doable selected move at step index ({}), time spent ({})."
                              + " Terminating phase early.",
                              logIndentation,
                              stepScope.getStepIndex(),
                              stepScope.getPhaseScope().calculateSolverTimeMillisSpentUpToNow());
                  } else {
                      throw new IllegalStateException("The step index (" + stepScope.getStepIndex()
                              + ") has accepted/selected move count (" + stepScope.getAcceptedMoveCount() + "/"
                              + stepScope.getSelectedMoveCount()
                              + ") but failed to pick a nextStep (" + stepScope.getStep() + ").");
                  }
                  // Although stepStarted has been called, stepEnded is not called for this step
                  break;
              }
              doStep(stepScope);
              stepEnded(stepScope);
              phaseScope.setLastCompletedStepScope(stepScope);
          }
          phaseEnded(phaseScope);
      }
docs: ************************************************************************