public ChoiceSetWithCrowdingGenerator(Config config, String eventsFile) {

    if (internalizationOfCrowdingDelay)
      log.info("Internalization of external PT Travel Delay cost is enabled.");
    if (internalizationOfComfortDisutility)
      log.info("Internalization of external Crowding cost is enabled.");

    choiceGenerationControler = new ChoiceGenerationWithCrowdingControler(config, eventsFile);
    choiceGenerationControler.setInternalizationOfComfortDisutility(
        internalizationOfComfortDisutility);
    choiceGenerationControler.setInternalizationOfCrowdingDelay(internalizationOfCrowdingDelay);
    choiceGenerationControler.load();

    this.controler = choiceGenerationControler.getControler();
    this.population = controler.getScenario().getPopulation();

    controler.addControlerListener(this);
  }
  @Override
  public void notifyShutdown(ShutdownEvent event) {
    Scenario newScenario = ScenarioUtils.createScenario(ConfigUtils.createConfig());
    Population newPopulation = newScenario.getPopulation();
    MoneyEventHandler moneyHandler = choiceGenerationControler.getMoneyEventHandler();
    CrowdingPsimHandler crowdingPsimHandler = choiceGenerationControler.getCrowdingPsimHandler();

    for (Id<Person> personId : population.getPersons().keySet()) {

      Id<Person> orgPersonId = Id.create(personId.toString().split("_")[0], Person.class);

      Double monetaryPayments = moneyHandler.getPersonId2amount().get(personId);
      if (monetaryPayments == null) {
        monetaryPayments = 0.0;
      }

      Plan planToAdd = null;
      if (personId.toString().contains("_")) {
        planToAdd = population.getPersons().get(personId).getSelectedPlan();
        planToAdd.getCustomAttributes().put("toll", monetaryPayments.toString());
        if (crowdingPsimHandler.getPerson2crowdingDisutility().containsKey(personId)) {
          planToAdd.setScore(
              planToAdd.getScore()
                  + crowdingPsimHandler.getPerson2crowdingDisutility().get(personId));
        }
      } else {
        planToAdd = initialPlans.get(personId);
        // planToAdd.getCustomAttributes().put("toll", monetaryPayments.toString());
      }

      if (newPopulation.getPersons().containsKey(orgPersonId)) {
        newPopulation.getPersons().get(orgPersonId).addPlan(planToAdd);
      } else {
        Person newPerson = newPopulation.getFactory().createPerson(orgPersonId);
        newPerson.addPlan(planToAdd);
        newPopulation.addPerson(newPerson);
      }
    }

    /*Write score table to SQL*/
    Integer relativeOutputDirectory =
        event.getServices().getConfig().controler().getOutputDirectory().split("/").length;

    String tableName = schema + ".scores_";
    String tableSuffix =
        event
            .getServices()
            .getConfig()
            .controler()
            .getOutputDirectory()
            .split("/")[relativeOutputDirectory - 1];
    tableSuffix = tableSuffix.replaceAll("\\.0x", "x");
    tableSuffix = tableSuffix.replaceAll("-", "_");
    tableSuffix = tableSuffix.replaceAll("\\.5", "5");
    tableSuffix = tableSuffix.replaceAll("\\.1", "1");
    tableSuffix = tableSuffix.replaceAll("\\.0", "0");
    tableName = tableName + tableSuffix;

    IndividualScoreFromPopulationSQLWriter sqlWriter =
        new IndividualScoreFromPopulationSQLWriter(event.getServices().getConfig(), newPopulation);
    sqlWriter.writeToDatabase(connectionPropertiesPath, schema, tableName);

    new PopulationWriter(newScenario.getPopulation())
        .write(
            choiceGenerationControler.getControler().getConfig().controler().getOutputDirectory()
                + "/output_plansJoin.xml");
  }