/**
   * Copy SorNames to Calculated Person
   *
   * @param person
   * @param sorPersons
   */
  protected void copySorNamesToPerson(final Person person, final List<SorPerson> sorPersons) {
    person.getNames().clear();

    for (final SorPerson sorPerson : sorPersons) {
      for (final SorName sorName : sorPerson.getNames()) {
        boolean alreadyAdded = false;

        for (final Name calculatedName : person.getNames()) {
          if (calculatedName.sameAs(sorName)) {
            alreadyAdded = true;
            break;
          }
        }

        if (!alreadyAdded) {
          person.addName(sorName);
        }
      }
    }
  }
  protected Person recalculatePersonBiodemInfo(
      final Person person,
      final SorPerson sorPerson,
      final RecalculationType recalculationType,
      boolean mistake) {
    final List<SorPerson> sorPersons = this.personRepository.getSoRRecordsForPerson(person);
    logger.info("recalculatePersonBiodemInfo: start");
    if (recalculationType == RecalculationType.ADD
        || (recalculationType == RecalculationType.DELETE && !mistake)) {
      sorPersons.add(sorPerson);
    }

    copySorNamesToPerson(person, sorPersons);

    final Date birthDate =
        this.birthDateFieldElector.elect(
            sorPerson, sorPersons, recalculationType == RecalculationType.DELETE);
    final String gender =
        this.genderFieldElector.elect(
            sorPerson, sorPersons, recalculationType == RecalculationType.DELETE);
    final SorName preferredName =
        this.preferredNameFieldElector.elect(
            sorPerson, sorPersons, recalculationType == RecalculationType.DELETE);
    final SorName officialName =
        this.officialNameFieldElector.elect(
            sorPerson, sorPersons, recalculationType == RecalculationType.DELETE);
    final EmailAddress emailAddress =
        this.preferredContactEmailAddressFieldElector.elect(
            sorPerson, sorPersons, recalculationType == RecalculationType.DELETE);
    final Phone phone =
        this.preferredContactPhoneNumberFieldElector.elect(
            sorPerson, sorPersons, recalculationType == RecalculationType.DELETE);
    final Map<String, String> attributes =
        this.attributesElector.elect(
            sorPerson, sorPersons, recalculationType == RecalculationType.DELETE);
    final SorDisclosureSettings disclosure =
        this.disclosureFieldElector.elect(
            sorPerson, sorPersons, recalculationType == RecalculationType.DELETE);

    final String ssn =
        this.ssnFieldElector.elect(
            sorPerson, sorPersons, recalculationType == RecalculationType.DELETE);
    Identifier primarySSN = person.getPrimaryIdentifiersByType().get("SSN");
    // check if the elector elcted some ssn and person does have previous ssn assigned to it
    if (!org.apache.commons.lang.StringUtils.isEmpty(ssn) && primarySSN != null) {
      try {
        this.identifierChangeService.change(person.getPrimaryIdentifiersByType().get("SSN"), ssn);
      } catch (IllegalArgumentException e) {
        logger.debug(e.getStackTrace().toString());
      } // all other exception should be propogated
    }

    person.setDateOfBirth(birthDate);
    person.setGender(gender);
    person.getPreferredContactEmailAddress().update(emailAddress);
    person.getPreferredContactPhoneNumber().update(phone);
    person.calculateDisclosureSettings(disclosure);
    person.setAttributes(attributes);

    String affiliation = "";
    Type affiliationType = null;
    if (disclosure != null) {
      logger.info(
          "after person.calculateDisclosureSettings, disclosure code : "
              + disclosure.getDisclosureCode());
    } else {
      logger.info("Disclosure is null");
    }
    List<SorRole> sorroles = sorPerson.getRoles();
    for (SorRole role : sorroles) {
      if (role != null) {
        logger.info("Role = " + role.getTitle());
        if (role.getAffiliationType() != null) {
          logger.info("Role desc= " + role.getAffiliationType().getDescription());
          affiliation = role.getAffiliationType().getDescription();

          if (person.getDisclosureSettings() != null) {
            logger.info("recalculating disclosure setting 1...");
            // person.getDisclosureSettings().recalculate(this.strategyRepository.getDisclosureRecalculationStrategy());
            person
                .getDisclosureSettings()
                .recalculate(
                    this.strategyRepository.getDisclosureRecalculationStrategy(),
                    affiliation,
                    referenceRepository);
          }
        }
      }
    }

    // SSN election is happening in the ssn identifier assigner.

    boolean preferred = false;
    boolean official = false;

    for (final Name name : person.getNames()) {
      if (!preferred && name.sameAs(preferredName)) {
        name.setPreferredName(true);
        preferred = true;
      }

      if (!official && name.sameAs(officialName)) {
        name.setOfficialName(true);
        official = true;
      }

      if (official && preferred) {
        break;
      }
    }
    logger.info("recalculatePersonBiodemInfo: end");
    //        return this.personRepository.savePerson(person);
    return person;
  }