@Override
  public void findInitialSolution() throws UnlimitedProblemException {
    logger.info("Getting the initial solution through the two-phases method");

    // ==> Create the augmented model for the first phase
    Collection<Integer> firstPhaseAugmentedVariablesIds = new ArrayList<Integer>();
    // Set the values that assumes the already present variables in the initial solution for
    // the first-phase model
    Map<Integer, BigDecimal> solutionVarsValues = new HashMap<Integer, BigDecimal>();
    for (Variable var : this.model.getObjfunc().getVariables()) {
      solutionVarsValues.put(var.getId(), BigDecimal.ZERO);
    }
    ImmutableLinearObjfunc originalObjfunc = this.model.getObjfunc();
    // Set the objective function
    this.model.setObjfunc(originalObjfunc.multiply(BigDecimal.ZERO));
    // For each constraint we need to add a new variable in the model
    for (Integer idx = 0; idx < this.model.getConstraints().size(); idx++) {
      List<Variable> currentConstraintVars = new ArrayList<Variable>();
      // Add the variable for the objective-function
      Variable varForObjfunc = SmartVariable.create(BigDecimal.ONE, true);
      currentConstraintVars.add(varForObjfunc);
      // Add the variable for each constraint
      for (Integer j = 0; j < this.model.getConstraints().size(); j++) {
        currentConstraintVars.add(SmartVariable.createFromExistingId(varForObjfunc.getId(),
            idx.equals(j) ? BigDecimal.ONE : BigDecimal.ZERO));
      }
      this.model.addVariable(currentConstraintVars);
      // Add the variable value into the initial solution
      solutionVarsValues.put(varForObjfunc.getId(),
          this.model.getConstraints().get(idx).getConstantTerm());
      // Add the variable into the base
      this.base.put(idx, varForObjfunc.getId());
      // Keep track of the variable added
      firstPhaseAugmentedVariablesIds.add(varForObjfunc.getId());
    }
    // Clear the solution history
    this.model.resetSolutionHistory();
    // Add the initial solution to the solution history
    this.model.addSolution(
        DefaultImmutableSolution.create(this.model.getObjfunc(), solutionVarsValues,
            BigDecimal.ONE));

    logger.info("Created the following model for the first-phase:\n" + this.model.toString());

    // ==> Put in the base canonical form
    for (Integer firstPhaseVarId : firstPhaseAugmentedVariablesIds) {
      Integer pivotHoriz = null, pivotVert = firstPhaseVarId;
      for (Map.Entry<Integer, Integer> baseEntry : this.base.entrySet()) {
        if (baseEntry.getValue().equals(firstPhaseVarId)) {
          pivotHoriz = baseEntry.getKey();
        }
      }
      assert (pivotHoriz != null) : "Find initial solution bug.";
      this.doPivot(pivotHoriz, pivotVert);
    }

    // ==> Optimize the first-phase while the solution isn't optimal. When it is, we found the
    //     initial solution for the original model
    while(!this.isSolutionOptimal()) {
      Integer[] pivot = this.findPivot();
      this.doPivot(pivot[0], pivot[1]);
    }

    // ==> Remove the augmented variable used for the first phase
    for (Integer varId : firstPhaseAugmentedVariablesIds) {
      this.model.removeVariable(varId);
    }
    // ==> Restore the objective-function
    this.model.setObjfunc(originalObjfunc);
    this.model.addSolution(DefaultImmutableSolution.create(originalObjfunc,
        this.model.getCurrentSolution().getVarsValues(),
        this.model.getCurrentSolution().getCoefficient()));
  }