package gov.va.med.esr.service.impl;

// Java classes
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.Validate;

import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.common.model.CommonEntityKeyFactory;
import gov.va.med.esr.common.model.ee.ClinicalDetermination;
import gov.va.med.esr.common.model.ee.Decoration;
import gov.va.med.esr.common.model.ee.Eligibility;
import gov.va.med.esr.common.model.ee.EligibilityVerification;
import gov.va.med.esr.common.model.ee.EnrollmentDetermination;
import gov.va.med.esr.common.model.ee.IncompetenceRuling;
import gov.va.med.esr.common.model.ee.MilitaryService;
import gov.va.med.esr.common.model.ee.MilitaryServiceSiteRecord;
import gov.va.med.esr.common.model.ee.MonetaryBenefit;
import gov.va.med.esr.common.model.ee.MonetaryBenefitAward;
import gov.va.med.esr.common.model.ee.PurpleHeart;
import gov.va.med.esr.common.model.ee.RatedDisability;
import gov.va.med.esr.common.model.ee.ServiceConnectionAward;
import gov.va.med.esr.common.model.financials.IncomeTest;
import gov.va.med.esr.common.model.financials.IncomeTestStatus;
import gov.va.med.esr.common.model.financials.PatientVisitSummary;
import gov.va.med.esr.common.model.lookup.AACIndicator;
import gov.va.med.esr.common.model.lookup.DecorationStatus;
import gov.va.med.esr.common.model.lookup.EligibilityFactor;
import gov.va.med.esr.common.model.lookup.EligibilityStatus;
import gov.va.med.esr.common.model.lookup.EligibilityStatusPendVerfiReason;
import gov.va.med.esr.common.model.lookup.EligibilityType;
import gov.va.med.esr.common.model.lookup.EligibilityVerificationSource;
import gov.va.med.esr.common.model.lookup.EnrollmentCategory;
import gov.va.med.esr.common.model.lookup.EnrollmentPriorityGroup;
import gov.va.med.esr.common.model.lookup.EnrollmentPrioritySubGroup;
import gov.va.med.esr.common.model.lookup.EnrollmentStatus;
import gov.va.med.esr.common.model.lookup.MeansTestStatus;
import gov.va.med.esr.common.model.lookup.IncomeTestType;
import gov.va.med.esr.common.model.lookup.MonetaryBenefitType;
import gov.va.med.esr.common.model.lookup.SSNType;
import gov.va.med.esr.common.model.lookup.ServicePeriod;
import gov.va.med.esr.common.model.lookup.State;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.PersonTraits;
import gov.va.med.esr.common.model.person.SSN;
import gov.va.med.esr.common.model.person.SSNVerificationDetail;
import gov.va.med.esr.common.model.person.id.VPIDEntityKey;
import gov.va.med.esr.common.model.person.id.VPIDEntityKeyImpl;
import gov.va.med.esr.common.persistent.person.PersonTraitsDAO;
import gov.va.med.esr.common.persistent.person.SSNVerificationDetailDAO;
import gov.va.med.esr.service.LookupService;
import gov.va.med.esr.service.PSDelegateService;
import gov.va.med.esr.service.PersonHelperService;
import gov.va.med.esr.service.PersonIdentityTraits;
import gov.va.med.esr.service.SystemParameterService;
import gov.va.med.esr.service.UnknownLookupCodeException;
import gov.va.med.fw.persistent.DAOException;
import gov.va.med.fw.persistent.DAOOperations;
import gov.va.med.fw.service.AbstractComponent;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.util.builder.BuilderException;
import gov.va.med.esr.common.model.lookup.MilitaryServiceQueryStatus;

/**
 * A helper class that provides utility methods to access data elements in a
 * person's graph
 *
 * @author DNS   LEV
 */
public class PersonHelperServiceImpl extends AbstractComponent implements
        Serializable, PersonHelperService {

    /**
     * An instance of serialVersionUID
     */
    private static final long serialVersionUID = -4752320913353036219L;

    /**
     * An instance of a lookup service to access lookup data
     */
    private LookupService lookupService = null;

     /**
     * GenericDAO for generic dao operationsgenericDAO
     */
    private DAOOperations genericDAO; //insert into SSA verification queue

    private SSNVerificationDetailDAO ssnVerificationDetailDAO; //CCR11666

    /**
     * An instance of PersonTraitsDAO to retrieve traits data
     */
    private PersonTraitsDAO personTraitsDAO = null;

    private static final String CONTEXT_EE = "EE";

    private static final String CONTEXT_FINANCIALS = "FINANCIALS";

    private String systemParameterServiceName = null;

    private PSDelegateService psDelegateService = null;

    /**
     * A default constructor
     */
    public PersonHelperServiceImpl() {
        super();
    }

    /**
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    public void afterPropertiesSet() throws Exception {
        super.afterPropertiesSet();
        Validate.notNull(this.lookupService,
                "A lookup service must be configured");
        Validate.notNull(this.personTraitsDAO,
                "A PersonTraitsDAO must be configured");
        Validate.notNull(psDelegateService,
                "Missing required PSDelegateService");
    }
    //insert into SSA verification queue
	public DAOOperations getGenericDAO() {
		return genericDAO;
	}

	//insert into SSA verification queue
	public void setGenericDAO(DAOOperations genericDAO) {
		this.genericDAO = genericDAO;
	}
//	CCR11666
    public SSNVerificationDetailDAO getSsnVerificationDetailDAO() {
    	return ssnVerificationDetailDAO;
    }
    //CCR11666
	public void setSsnVerificationDetailDAO(
            SSNVerificationDetailDAO ssnVerificationDetailDAO) {
    	this.ssnVerificationDetailDAO = ssnVerificationDetailDAO;
    }

    /**
     * Returns a person's enrollment status
     *
     * @param person
     *            A person from which enrollment status is obtained
     * @return An enrollment status to which a person belongs
     * @throws ServiceException
     *             If failed to lookup an enrollment status
     */
    public EnrollmentStatus getEnrollmentStatus(Person person)
            throws ServiceException {

        Validate.notNull(person, "A person must not be null");

        return person.getEnrollmentDetermination() != null ? person
                .getEnrollmentDetermination().getEnrollmentStatus() : null;
    }

    /**
     * Returns a person's enrollment category code
     *
     * @param person
     *            A person from which enrollment status is obtained
     * @return An enrollment status to which a person belongs
     * @throws ServiceException
     *             If failed to lookup an enrollment status
     */
    public EnrollmentCategory getEnrollmentCategory(Person person)
            throws ServiceException {

        Validate.notNull(person, "A person must not be null");

        return getEnrollmentStatus(person) != null ? getEnrollmentStatus(person)
                .getEnrollmentCategory()
                : null;
    }

    /**
     * Returns a person's eligibility status Pending Verfication Reason Code 
     *
     * @param person
     *            A person from which eligibility status is obtained
     * @return An eligibility status Pending Verfication Reason Code to which a person belongs
     * @throws ServiceException
     *             If failed to lookup an eligibility status Pending Verfication Reason Code
     */
    public EligibilityStatusPendVerfiReason getEligStatusPendingVerficationReason(Person person)
            throws ServiceException {

        Validate.notNull(person, "A person must not be null");

        return person.getEligibilityVerification() != null ? person.getEligibilityVerification().getEligStatusPendingVerficationReason() : null;
    }


    /**
     * Returns a person's eligibility status
     *
     * @param person
     *            A person from which eligibility status is obtained
     * @return An eligibility status to which a person belongs
     * @throws ServiceException
     *             If failed to lookup an eligibility status
     */
    public EligibilityStatus getEligibilityStatus(Person person)
            throws ServiceException {

        Validate.notNull(person, "A person must not be null");

        return person.getEligibilityVerification() != null ? person
                .getEligibilityVerification().getEligibilityStatus() : null;
    }

    
    /**
     * Returns a purple heart status of a person
     *
     * @param person
     *            A person to look up a process status
     * @return ProcessStatus The process status of type purple heart
     * @throws ServiceException
     *             If failed to lookup a process status and type
     */
    public DecorationStatus getPurpleHeartStatus(Person person)
            throws ServiceException {
        Decoration decoration = this.getPurpleHeart(person);
        return (decoration != null && decoration instanceof PurpleHeart) ? decoration
                .getStatus()
                : null;
    }

    /**
     * Returns a set of rated disabilities from a person or an empty collection
     * if a person doesn't have any service connection award.
     *
     * @param person
     *            A person to look up
     * @return A collection of rated disabilities
     */
    public Set getRatedDisabilities(Person person) {

        Validate.notNull(person, "A person must not be null");
        ServiceConnectionAward serviceConnectionAward = person
                .getServiceConnectionAward();
        return (serviceConnectionAward != null) ? serviceConnectionAward
                .getRatedDisabilities() : new HashSet();
    }

    /**
     * This method gets a Aid and Attendant benefit from the person graph.
     *
     * @param person
     *            The person who has monetary benefit.
     * @return The monetary benefit of a Aid and Attendant type.
     * @throws ServiceException
     *             If failed to lookup a monetary benefit
     */
    public MonetaryBenefit getAABenefit(Person person) throws ServiceException {
        return getMonetaryBenefit(MonetaryBenefitType.CODE_AID_AND_ATTENDANCE
                .getName(), person);
    }

    /**
     * This method gets a house bound benefit from the person graph.
     *
     * @param person
     *            The person who has monetary benefit.
     * @return The monetary benefit of a house bound type.
     * @throws ServiceException
     *             If failed to lookup a monetary benefit
     */
    public MonetaryBenefit getHouseboundBenefit(Person person)
            throws ServiceException {
        return getMonetaryBenefit(
                MonetaryBenefitType.CODE_HOUSEBOUND.getName(), person);
    }

    /**
     * This method gets a house bound benefit from the person graph.
     *
     * @param person
     *            The person who has monetary benefit.
     * @return The monetary benefit of a house bound type.
     * @throws ServiceException
     *             If failed to lookup a monetary benefit
     */
    public MonetaryBenefit getDisabilityBenefit(Person person)
            throws ServiceException {
        return getMonetaryBenefit(
                MonetaryBenefitType.CODE_DISABILITY_COMPENSATION.getName(),
                person);
    }

    /**
     * This method gets a VA pension benefit from the person graph.
     *
     * @param person
     *            The person who has monetary benefit.
     * @return The monetary benefit of a VA pension type.
     * @throws ServiceException
     *             If failed to lookup a monetary benefit
     */
    public MonetaryBenefit getVAPensionBenefit(Person person)
            throws ServiceException {
        return getMonetaryBenefit(
                MonetaryBenefitType.CODE_VA_PENSION.getName(), person);
    }

    /**
     * Return the particular type of SSN (Official,Other,Pesudo..)
     *
     * @param code
     * @param person
     * @return
     */
    public SSN getSSN(String code, Person person) throws ServiceException {
        SSNType ssnType = this.getLookupService().getSSNTypeByCode(code);
        Set ssns = person.getSsns();
        if (ssns != null && ssnType != null) {
            for (Iterator iter = ssns.iterator(); iter.hasNext();) {
                SSN ssnValue = (SSN) iter.next();
                if (ssnValue.getType().getCode().equals(ssnType.getCode())) {
                    return ssnValue;
                }
            }
        }
        return null;
    }

    public boolean isNonVeteranEligibilityCode(String code) {

        boolean equal = false;
        for (int i = 0; i < EligibilityType.NON_VETERANS.length; i++) {
            if (EligibilityType.NON_VETERANS[i].getName().equals(code)) {
                equal = true;
                break;
            }
        }
        return equal;
    }

    public Person uploadData(Person onSitePerson, Person onFilePerson)
            throws ServiceException {

        Validate.notNull(onSitePerson, "A person from a site must not be null");
        Validate.notNull(onFilePerson, "A person on file must not be null");

        /*
         * Save the following Data: � Rated Disabilities (code, description,
         * percent) � Aid & Attendance - MonetaryBenefitAward � Housebound
         * -MonetaryBenefitAward � VA Pension - MonetaryBenefitAward � Total
         * Check Amount - MonetaryBenefitAward � Receiving VA Disability
         * Compensation - MonetaryBenefitAward � Permanent & Totally Disabled -
         * ServiceConnectionAward � Unemployable - ServiceConnectionAward �
         * Service Connected Percentage (SC%) - ServiceConnectionAward � Rated
         * Incompetent - ? Incompetent
         */

        // Update MonetaryBenefitAward
        mergeServiceConnectionAward(onSitePerson, onFilePerson);
        try {
            // Update rated disabilities

            MonetaryBenefitAward siteBenefitAward = onSitePerson
                    .getMonetaryBenefitAward();
            MonetaryBenefitAward onFileBenefitAward = onFilePerson
                    .getMonetaryBenefitAward();
            if (siteBenefitAward != null && onFileBenefitAward != null) {
                onFilePerson
                        .setMonetaryBenefitAward((MonetaryBenefitAward) siteBenefitAward
                                .clone());
            }

            // Update Rated Incompotence
            IncompetenceRuling siteIncompetence = onSitePerson
                    .getIncompetenceRuling();
            IncompetenceRuling onFileIncompetence = onFilePerson
                    .getIncompetenceRuling();
            if (siteIncompetence != null && onFileIncompetence != null) {
                onFilePerson
                        .setIncompetenceRuling((IncompetenceRuling) siteIncompetence
                                .clone());
            }
        } catch (Exception e) {
            // THIS CATCH STATEMENT MUST BE CHANGED TO CATCH ONLY APPROPRIATE
            // EXCEPTIONS
            // THIS WAS DONE BECAUSE A COPY METHOD INCORRECTLY THROWS EXCEPTION
            throw new ServiceException("Failed to upload data", e);
        }

        return onFilePerson;
    }

    /**
     * Sets the AAC indicator in a Process State object that is part of a
     * person's process states. Upon completion of method, the person will have
     * a new process state with the new process status of type AAC indicator.
     *
     * @param code
     *            A process status code to set
     * @param person
     *            The person to which a process status belongs
     * @throws ServiceException
     *             If failed to lookup a process status
     */
    public void setAACIndicator(String code, Person person)
            throws ServiceException {

        Validate.notNull(code, "An AAC Indicator code must not be NULL");
        setAACIndicator(lookupService.getAACIndicatorByCode(code), person);
    }

    /**
     * Sets the AAC indicator in a Process State object that is part of a
     * person's process states. Upon completion of method, the person will have
     * a new process state with the new process status of type AAC indicator.
     *
     * @param code
     *            A process status code to set
     * @param person
     *            The person to which a process status belongs
     * @throws ServiceException
     *             If failed to lookup a process status
     */
    public void setAACIndicator(AACIndicator code, Person person)
            throws ServiceException {

        Validate.notNull(code, "An AAC Indicator code must not be NULL");

        // We must assume that need to create an Eligibility Verification object
        // if does not exist.
        if (person.getEligibilityVerification() == null) {
            EligibilityVerification eligibilityVerification = new EligibilityVerification();
            person.setEligibilityVerification(eligibilityVerification);
        }
        person.getEligibilityVerification().setAacIndicator(code);
    }

    /**
     * Sets the eligibility status in a Process State object that is part of a
     * person's process states. Upon completion of method, the person will have
     * a new process state with the new process status of type eligibility
     * status.
     *
     * @param code
     *            A process status code to set
     * @param person
     *            The person to which a process status belongs
     * @throws ServiceException
     *             If failed to lookup a process status
     */
    public void setEligibilityStatus(String code, Person person)
            throws ServiceException {

        // We must assume that need to create an Eligibility Verification object
        // if does not exist.
        EligibilityVerification eligibility = person
                .getEligibilityVerification();
        if (eligibility == null) {
            eligibility = new EligibilityVerification();
            person.setEligibilityVerification(eligibility);
        }
        if (code != null) {
            eligibility.setEligibilityStatus(this.getLookupService()
                    .getEligibilityStatusByCode(code));
        } else {
            eligibility.setEligibilityStatus(null);
        }
    }
    
    /**
     * Sets the eligibility status Pending verification reason 
     *
     * @param code
     *            A process status code to set
     * @param person
     *            The person to which a process status belongs
     * @throws ServiceException
     *             If failed to lookup a process status
     */
    public void setEligStatusPendingVerficationReason(String code, Person person)
            throws ServiceException {

        // We must assume that need to create an Eligibility Verification object
        // if does not exist.
        EligibilityVerification eligibility = person
                .getEligibilityVerification();
        if (eligibility == null) {
            eligibility = new EligibilityVerification();
            person.setEligibilityVerification(eligibility);
        }
        if (code != null) {
            eligibility.setEligStatusPendingVerficationReason(this.getLookupService().getEligibilityStatusReasonByCode(code));
        } else {
            eligibility.setEligStatusPendingVerficationReason(null);
        }
    }

    /**
     * Sets the enrollment status in a Process State object that is part of a
     * person's process states. Upon completion of method, the person will have
     * a new process state with the new process status of type eligibility
     * status.
     *
     * @param code
     *            A process status code to set
     * @param person
     *            The person to which a process status belongs
     * @throws ServiceException
     *             If failed to lookup a process status
     */
    public void setEnrollmentStatus(String code, Person person)
            throws ServiceException {
        if (person.getEnrollmentDetermination() != null) {
            person.getEnrollmentDetermination().setEnrollmentStatus(
                    this.lookupService.getEnrollmentStatusByCode(code));
        }
    }

    /**
     * @see gov.va.med.esr.service.PersonHelperService#setEnrollmentStatus(java.lang.String,
     *      gov.va.med.esr.common.model.ee.EnrollmentDetermination)
     */
    public void setEnrollmentStatus(String code,
            EnrollmentDetermination enrollment) throws ServiceException {
        if (enrollment != null) {
            enrollment.setEnrollmentStatus(this.lookupService
                    .getEnrollmentStatusByCode(code));
        }
    }

    /*
     * (non-Javadoc)
     * @see gov.va.med.esr.service.PersonHelperService#setInitialEnrollmentPriority(java.lang.String, gov.va.med.esr.common.model.ee.EnrollmentDetermination)
     */
    public void setInitialEnrollmentPriority(String code,
            EnrollmentDetermination enrollmentDetermination)
            throws ServiceException,IllegalArgumentException {

        // verify that the enrollment determination and code are
        // not null
        Validate.notNull(code,
                "An enrollment priority group code must not be NULL");
        Validate.notNull(enrollmentDetermination,
                "An enrollment determination must not be null");

        // lookup the enrollment priority identified by the code
        // and set the initial priority on the enrollment
        // determination
        enrollmentDetermination.setInitialPriorityGroup(this
                .getEnrollmentPriority(code));
    }

    /*
     * @see gov.va.med.esr.service.PersonHelperService#setInitialEnrollmentPriority(String, EnrollmentDetermination)
     */
    public void setInitialEnrollmentPrioritySubGroup(String code,
            EnrollmentDetermination enrollmentDetermination)
            throws ServiceException,IllegalArgumentException {

        // verify that the enrollment determination and code are
        // not null
        Validate.notNull(code,
                "An enrollment priority sub group code must not be NULL");
        Validate.notNull(enrollmentDetermination,
                "An enrollment determination must not be null");

        // lookup the enrollment priority identified by the code
        // and set the initial subpriority on the enrollment
        // determination
        enrollmentDetermination.setInitialPrioritySubGroup(lookupService
                .getEnrollmentPrioritySubGroupByCode(code));
    }

    /*
     * @see gov.va.med.esr.service.PersonHelperService
     */
    public void setPurpleHeartStatus(String code, Person person)
            throws ServiceException {
        PurpleHeart purpleHeart = this.getPurpleHeart(person);
        if (purpleHeart != null) {
            purpleHeart
                    .setStatus(lookupService.getDecorationStatusByCode(code));
        }
    }

    /**
     * Adds a VA pension to a person
     *
     * @param person
     *            A person to add a VA pension
     * @throws ServiceException
     *             if failed to look up a monetary benefit
     */
    public MonetaryBenefit addVAPension(Person person) throws ServiceException {
        return addMonetaryBenefit(
                MonetaryBenefitType.CODE_VA_PENSION.getName(), person);
    }

    /**
     * Adds an AA benefit to a person
     *
     * @param person
     *            A person to add an AA benefit
     * @throws ServiceException
     *             if failed to look up a monetary benefit
     */
    public MonetaryBenefit addAABenefit(Person person) throws ServiceException {
        return addMonetaryBenefit(MonetaryBenefitType.CODE_AID_AND_ATTENDANCE
                .getName(), person);
    }

    /**
     * Removes an AA benefit to a person
     *
     * @param person
     *            A person to remove an AA benefit
     * @throws ServiceException
     *             if failed to look up a monetary benefit
     */
    public void removeAABenefit(Person person) throws ServiceException {
        this.removeMonetaryBenefit(MonetaryBenefitType.CODE_AID_AND_ATTENDANCE
                .getName(), person);
    }

    /**
     * Adds a House bound benefit to a person
     *
     * @param person
     *            A person to add a house bound benefit
     * @throws ServiceException
     *             if failed to look up a monetary benefit
     */
    public MonetaryBenefit addHouseboundBenefit(Person person)
            throws ServiceException {
        return addMonetaryBenefit(
                MonetaryBenefitType.CODE_HOUSEBOUND.getName(), person);
    }

    /**
     * Removes a house bound benefit to a person
     *
     * @param person
     *            A person to remove a house bound benefit
     * @throws ServiceException
     *             if failed to look up a monetary benefit
     */
    public void removeHouseboundBenefit(Person person) throws ServiceException {
        this.removeMonetaryBenefit(MonetaryBenefitType.CODE_HOUSEBOUND
                .getName(), person);
    }

    /**
     * Adds a VA disability benefit to a person
     *
     * @param person
     *            A person to add a VA disability benefit
     * @throws ServiceException
     *             if failed to look up a monetary benefit
     */
    public MonetaryBenefit addVADisability(Person person)
            throws ServiceException {
        return addMonetaryBenefit(
                MonetaryBenefitType.CODE_DISABILITY_COMPENSATION.getName(),
                person);
    }

    /**
     * Sets a verification source to a new person
     *
     * @param code
     *            A verification source code to lookup a verification source
     * @param person
     *            A person to set a verfification source
     * @throws ServiceException
     *             if failed to look up an eligibility verification source
     */
    public void setVerificationSource(String code, Person person)
            throws ServiceException {

        Validate.notNull(person, "A person must not be null");

        // Create an eligibility verification if one doesn't exist
        EligibilityVerification eligibilityVerification = person
                .getEligibilityVerification();
        if (eligibilityVerification == null) {
            eligibilityVerification = new EligibilityVerification();
            person.setEligibilityVerification(eligibilityVerification);
        }

        EligibilityVerificationSource source = code != null ? lookupService
                .getEligibilityVerificationSourceByCode(code) : null;

        eligibilityVerification.setVerificationSource(source);
    }

    /**
     * Sets a verification facility
     *
     * @param code
     *            A verification code to lookup a facility
     * @param person
     *            A person to set a verfification facility
     * @throws ServiceException
     *             if failed to look up an eligibility verification facility
     */
    public void setVerificationFacility(String code, Person person)
            throws ServiceException {

        Validate.notNull(code, "A verification facility code must not be NULL");

        VAFacility facility = this.lookupService.getVaFacilityByCode(code);
        this.setVerificationFacility(facility, person);
    }

    /**
     * Sets a verification facility
     *
     * @param code
     *            A verification code to lookup a facility
     * @param person
     *            A person to set a verfification facility
     * @throws ServiceException
     *             if failed to look up an eligibility verification facility
     */
    public void setVerificationFacility(VAFacility facility, Person person)
            throws ServiceException {

        Validate.notNull(person, "A person must not be null");

        // Create an eligibility verification if one doesn't exist
        EligibilityVerification eligibilityVerification = person
                .getEligibilityVerification();
        if (eligibilityVerification == null) {
            eligibilityVerification = new EligibilityVerification();
            person.setEligibilityVerification(eligibilityVerification);
        }
        eligibilityVerification.setVerificationFacility(facility);
    }

    /**
     * Sets a verification source to a new person
     *
     * @param code
     *            A verification source code to lookup a verification source
     * @param person
     *            A person to set a verfification source
     * @throws ServiceException
     *             if failed to look up an eligibility verification source
     */
    public void setVerificationMethod(String method, Person person)
            throws ServiceException {

        Validate.notNull(person, "A person must not be null");

        // Create an eligibility verification if one doesn't exist
        EligibilityVerification eligibilityVerification = person
                .getEligibilityVerification();
        if (eligibilityVerification == null) {
            eligibilityVerification = new EligibilityVerification();
            person.setEligibilityVerification(eligibilityVerification);
        }
        eligibilityVerification.setVerificationMethod(method);
    }

    
    /**
     * Sets a Verification Pending Reason Explanation to a new person
     *
     * @param code
     *            A verification source code to lookup a verification source
     * @param person
     *            A person to set a verfification Pending Reason Explanation source
     * @throws ServiceException
     *             if failed to look up an eligibility verification Pending Reason Explanation source
     */
    public void setEligStatusPendingVerfReasonExplain(String eligStatusPendingVerfReasonExplain, Person person)
            throws ServiceException {

        Validate.notNull(person, "A person must not be null");

        // Create an eligibility verification if one doesn't exist
        EligibilityVerification eligibilityVerification = person
                .getEligibilityVerification();
        if (eligibilityVerification == null) {
            eligibilityVerification = new EligibilityVerification();
            person.setEligibilityVerification(eligibilityVerification);
        }
        eligibilityVerification.setEligStatusPendingVerfReasonExplain(eligStatusPendingVerfReasonExplain);
    }
    
    /**
     * Sets a priority sub group in an enrollment determination
     *
     * @param code
     *            A priority sub group code to lookup
     * @param enrollmentDetermination
     *            An enrollment determination to set a priority sub group
     * @throws ServiceException
     *             if failed to look up a priority sub group
     */
    public void setEnrollmentPrioritySubGroup(String code,
            EnrollmentDetermination enrollmentDetermination)
            throws ServiceException {

        Validate.notNull(code,
                "An enrollment priority sub group code must not be NULL");
        Validate.notNull(enrollmentDetermination,
                "An enrollment determination must not be null");

        enrollmentDetermination.setPrioritySubGroup(this
                .getEnrollmentPrioritySubGroup(code));
    }

    /**
     * Sets a priority group in an enrollment determination
     *
     * @param code
     *            A priority group code to lookup
     * @param enrollmentDetermination
     *            An enrollment determination to set a priority group
     * @throws ServiceException
     *             if failed to look up a priority group
     */
    public void setEnrollmentPriority(String code,
            EnrollmentDetermination enrollmentDetermination)
            throws ServiceException {

        Validate.notNull(code,
                "An enrollment priority group code must not be NULL");
        Validate.notNull(enrollmentDetermination,
                "An enrollment determination must not be null");

        enrollmentDetermination.setPriorityGroup(this
                .getEnrollmentPriority(code));
    }

    /**
     * Creates an eligibility type for the specific type code
     *
     * @param code
     *            An eligibility type code
     * @return An eligibility
     * @throws ServiceException
     *             thrown if failed to look up an eligibility type
     */
    public Eligibility createEligibility(String code) throws ServiceException {

        Validate.notNull(code, "An eligibility code must not be NULL");

        Eligibility eligibility = new Eligibility();
        eligibility.setType(lookupService.getEligibilityTypeByCode(code));
        return eligibility;
    }

    /**
     * @see gov.va.med.esr.service.PersonHelperService#createOtherEligibility(java.lang.String)
     */
    public Eligibility createOtherEligibility(String code)
            throws ServiceException {
        Validate.notNull(code, "An eligibility code must not be NULL");

        Eligibility eligibility = new Eligibility();
        eligibility.setFactor((EligibilityFactor) getLookupService().getByCode(
                EligibilityFactor.class, code));
        return eligibility;
    }

    /**
     * Set the enrollment category for a person.
     *
     * @param category
     *            A category to set
     * @param person
     *            The person who owns the category
     * @throws ServiceException
     */
    public void setEnrollmentCategory(String category, Person person)
            throws ServiceException {
        if (person.getEnrollmentDetermination() != null
                && person.getEnrollmentDetermination().getEnrollmentStatus() != null) {
            person.getEnrollmentDetermination().getEnrollmentStatus()
                    .setEnrollmentCategory(
                            this.lookupService
                                    .getEnrollmentCategoryByCode(category));
        }
    }

    /**
     * @see gov.va.med.esr.service.PersonHelperService#setEnrollmentCategory(java.lang.String,
     *      gov.va.med.esr.common.model.ee.EnrollmentDetermination)
     */
    public void setEnrollmentCategory(String category,
            EnrollmentDetermination enrollment) throws ServiceException {
        if (enrollment != null && enrollment.getEnrollmentStatus() != null) {
            enrollment.getEnrollmentStatus().setEnrollmentCategory(
                    this.lookupService.getEnrollmentCategoryByCode(category));
        }
    }

    /**
     * Set the enrollment source for a person.
     *
     * @param source
     *            A source to set
     * @param enrollment
     *            The enrollment determination
     * @throws ServiceException
     * @throws UnknownLookupCodeException
     *             If failed to lookup an enrollment source
     */
    public void setEnrollmentSource(String source,
            EnrollmentDetermination enrollment) throws ServiceException {
        Validate.notNull(source, "A source must not be null");
        enrollment.setCalculationSource(this.getLookupService()
                .getEnrollmentSourceByCode(source));
    }

    /**
     * Set the "facility received from" in an enrollment determination.
     *
     * @param facility
     *            The facility to set
     * @param enrollment
     *            The enrollment who owns the facility.
     * @throws ServiceException
     */
    public void setFacilityReceivedFrom(String facility,
            EnrollmentDetermination enrollment) throws ServiceException {
        // Facility can be null
        Validate.notNull(enrollment, "An enrollment must not be null");
        if (facility == null) {
            enrollment.setFacilityReceived(null);
        } else {
            enrollment.setFacilityReceived(this.getLookupService()
                    .getVaFacilityByStationNumber(facility));
        }
    }

    /**
     * Returns the person's enrollment.
     *
     * @param person
     *            who contains the enrollment
     * @return the enrollment
     */
    public EnrollmentDetermination getEnrollmentDetermination(Person person) {
        return person.getEnrollmentDetermination();
    }

    /**
     * Returns the veteran's purple heart decoration, if it exists.
     *
     * @param person
     *            who contains the purple heart
     * @return the Purple Heart
     */
    public PurpleHeart getPurpleHeart(Person person) {
        PurpleHeart purpleHeart = null;
        if (person != null) {
            Set setOfDecoration = person.getDecorations();

            if (setOfDecoration != null && setOfDecoration.size() > 0) {
                Iterator iter = setOfDecoration.iterator();
                while (iter.hasNext()) {
                    Decoration decoration = (Decoration) iter.next();
                    if (decoration != null && decoration instanceof PurpleHeart) {
                        purpleHeart = (PurpleHeart) decoration;
                        break;
                    }
                }
            }
        }
        return purpleHeart;
    }

    /**
     * Return the particular type of clinical determination from person.
     *
     * @param classObject
     * @param person
     * @return
     */
    public ClinicalDetermination getClinicalDetermination(Class classObject,
            Person person) {

        if (person == null) {
            return null;
        }

        Set clinicalDeterminations = person.getClinicalDeterminations();
        ClinicalDetermination clinicalDetermination = null;

        if (clinicalDeterminations != null && clinicalDeterminations.size() > 0) {
            Iterator iterClinicalDeterminations = clinicalDeterminations
                    .iterator();

            while (iterClinicalDeterminations.hasNext()) {
                ClinicalDetermination temp = (ClinicalDetermination) iterClinicalDeterminations
                        .next();

                if (temp != null
                        && temp.getClass().isAssignableFrom(classObject)) {
                    clinicalDetermination = temp;
                    break;
                }
            }
        }

        return clinicalDetermination;
    }

    public void setRejectionRemark(String remark, PurpleHeart purpleHeart)
            throws ServiceException {
        Validate.notNull(purpleHeart, "A Purple Heart must not be null");
        // Note: remark could be null
        purpleHeart.setRejectionRemark(this.getLookupService()
                .getRejectionRemarkByCode(remark));
    }

    /**
     * Add a monetary benefit of the specific type to a person
     *
     * @param code
     *            A monetary benefit type code to lookup
     * @param person
     *            A person to add a monetary benefit
     * @throws ServiceException
     *             if failed to look up a monetary benefit
     * @throws UnknownLookupCodeException
     *             if failed to look up a monetary benefit
     */
    protected MonetaryBenefit addMonetaryBenefit(String code, Person person)
            throws ServiceException {

        // Get a monetary benefit of the specific code from a person
        MonetaryBenefit monetaryBenefit = getMonetaryBenefit(code, person);

        // only add if not there already
        if (monetaryBenefit == null) {
            MonetaryBenefitAward monetaryBenefitAward = person
                    .getMonetaryBenefitAward();

            // Create a monetary benefit award if one is not created
            if (monetaryBenefitAward == null) {
                monetaryBenefitAward = new MonetaryBenefitAward();
                person.setMonetaryBenefitAward(monetaryBenefitAward);
            }
            monetaryBenefit = createMonetaryBenefit(code);
            monetaryBenefitAward.addMonetaryBenefit(monetaryBenefit);
        }
        return monetaryBenefit;
    }

    /**
     * Removes a monetary benefit of the specific type from a person
     *
     * @param code
     *            A monetary benefit type code to lookup
     * @param person
     *            A person to remove a monetary benefit
     * @throws ServiceException
     *             if failed to look up a monetary benefit
     * @throws UnknownLookupCodeException
     *             if failed to look up a monetary benefit
     */
    protected void removeMonetaryBenefit(String code, Person person)
            throws ServiceException {

        MonetaryBenefit monetaryBenefit = getMonetaryBenefit(code, person);
        if (monetaryBenefit != null) {
            // If a monetary benefit exist, a monetary benefit award must
            // also exist so no need to check for null monetary benefit award
            // here
            person.getMonetaryBenefitAward().removeMonetaryBenefit(
                    monetaryBenefit);
        }
    }

    /**
     * This method gets a specific type of monetary benefit from the person
     * graph. Caller must specify a monetary benefit type and a person to which
     * the monetary benefit belongs. Null is returned if a person doesn't have
     * any moneytary benefit data.
     *
     * @param type
     *            The type of monetary benefit.
     * @param person
     *            The person who has monetary benefit.
     * @return The monetary benefit of a specific type.
     * @throws ServiceException
     *             If failed to lookup an eligibility status
     * @throws UnknownLookupCodeException
     *             If failed to lookup an eligibility status
     */
    protected MonetaryBenefit getMonetaryBenefit(String type, Person person)
            throws ServiceException {

        Validate.notNull(type, "A type must not be null");
        Validate.notNull(person, "A person must not be null");

        // Get a list of monetary benefits from a person
        // then pick out the one that has the same type
        MonetaryBenefit mb = null;
        MonetaryBenefitAward mba = person.getMonetaryBenefitAward();

        if (mba != null) {
            MonetaryBenefitType mbt = lookupService
                    .getMonetaryBenefitTypeByCode(type);
            if (mbt != null) {
                Set benefits = mba.getMonetaryBenefits();
                for (Iterator i = benefits.iterator(); i.hasNext();) {
                    MonetaryBenefit benefit = (MonetaryBenefit) i.next();
                    if (benefit.getType().getCode().equals(mbt.getCode())) {
                        mb = benefit;
                        break;
                    }
                }
            }
        }
        return mb;
    }

    /**
     * Create a monetary benefit of the specific type
     *
     * @param code
     *            A monetary benefit type code
     * @return A monetary benefit of the specific type
     * @throws ServiceException
     *             if failed to look up a monetary benefit type
     */
    protected MonetaryBenefit createMonetaryBenefit(String code)
            throws ServiceException {

        Validate.notNull(code, "A monetary benefit type code must not be null");

        // Create a monetart benefit of the specific type
        MonetaryBenefit monetaryBenefit = new MonetaryBenefit();
        monetaryBenefit.setType(lookupService
                .getMonetaryBenefitTypeByCode(code));

        return monetaryBenefit;
    }

    /**
     * @return
     */
    protected IncompetenceRuling createIncompetenceRuling() {
        IncompetenceRuling incompetenceRuling = new IncompetenceRuling();
        return incompetenceRuling;
    }

    /**
     * Merge service connection award from a person on file to a person from a
     * site
     *
     * @param source
     *            A person on file
     * @param destination
     *            A person from a site
     */
    protected void mergeServiceConnectionAward(Person source, Person destination) {

        // get service connection award
        ServiceConnectionAward incoming = source.getServiceConnectionAward();
        ServiceConnectionAward onFile = destination.getServiceConnectionAward();

        if (incoming != null) {
            if (onFile == null) {
                onFile = new ServiceConnectionAward();
            }

            onFile.setPermanentAndTotal(incoming.isPermanentAndTotal());
            onFile.setServiceConnectedPercentage(incoming
                    .getServiceConnectedPercentage());
            onFile.setUnemployable(incoming.isUnemployable());
            onFile
                    .setAwardDate(incoming.getAwardDate() != null ? (ImpreciseDate) incoming
                            .getAwardDate().clone()
                            : null);
            Set currRatedDisabilities = onFile.getRatedDisabilities();
            Set inRatedDisabilities = incoming.getRatedDisabilities();
            if (inRatedDisabilities != null && inRatedDisabilities.size() > 0) {
                currRatedDisabilities.clear();

                Iterator iter = inRatedDisabilities.iterator();
                while (iter.hasNext()) {
                    RatedDisability ratedDisability = (RatedDisability) iter
                            .next();
                    RatedDisability newRatedDisability = new RatedDisability();
                    newRatedDisability.setDisability(ratedDisability
                            .getDisability());
                    newRatedDisability.setPercentage(ratedDisability
                            .getPercentage());
                    newRatedDisability.setServiceConnected(ratedDisability
                            .isServiceConnected());
                    currRatedDisabilities.add(newRatedDisability);
                }
            }
            destination.setServiceConnectionAward(onFile);
        } else {
            // null value in the incoming person is indication to
            // delete in the person on file
            destination.setServiceConnectionAward(null);
        }
    }

    /**
     * @return Returns the lookupService.
     */
    public LookupService getLookupService() {
        return lookupService;
    }

    /**
     * @param lookupService
     *            The lookupService to set.
     */
    public void setLookupService(LookupService lookupService) {
        this.lookupService = lookupService;
    }

    /**
     * @return Returns the personTraitsDAO.
     */
    public PersonTraitsDAO getPersonTraitsDAO() {
        return personTraitsDAO;
    }

    /**
     * @return Returns the psDelegateService.
     */
    public PSDelegateService getPsDelegateService() {
        return psDelegateService;
    }

    /**
     * @param psDelegateService
     *            The psDelegateService to set.
     */
    public void setPsDelegateService(PSDelegateService psDelegateService) {
        this.psDelegateService = psDelegateService;
    }

    /**
     * @param personTraitsDAO
     *            The personTraitsDAO to set.
     */
    public void setPersonTraitsDAO(PersonTraitsDAO personTraitsDAO) {
        this.personTraitsDAO = personTraitsDAO;
    }

    /**
     * Sets a priority sub group in an enrollment determination
     *
     * @param code
     *            A priority sub group code to lookup
     * @throws ServiceException
     *             if failed to look up a priority sub group
     */
    private EnrollmentPrioritySubGroup getEnrollmentPrioritySubGroup(String code)
            throws ServiceException {

        Validate.notNull(code,
                "An enrollment priority sub group code must not be NULL");

        return lookupService.getEnrollmentPrioritySubGroupByCode(code);
    }

    /**
     * Sets a priority group in an enrollment determination
     *
     * @param code
     *            A priority group code to lookup
     * @throws ServiceException
     *             if failed to look up a priority group
     */
    private EnrollmentPriorityGroup getEnrollmentPriority(String code)
            throws ServiceException {

        Validate.notNull(code,
                "An enrollment priority group code must not be NULL");

        return lookupService.getEnrollmentPriorityGroupByCode(code);
    }

    /**
     * Gets the current income test. If no income tests are defined or no income
     * test is considered current, null is returned.
     *
     * @return The current income test or null.
     */
    public IncomeTest getCurrentIncomeTest(Person person) {
        return this.doGetCurrentIncomeTest(person, CONTEXT_FINANCIALS);
    }

    /**
     * @see gov.va.med.esr.service.PersonHelperService#getCurrentIncomeTestForEE(gov.va.med.esr.common.model.person.Person)
     */
    public IncomeTest getCurrentIncomeTestForEE(Person person) {
        return this.doGetCurrentIncomeTest(person, CONTEXT_EE);
    }

    private IncomeTest doGetCurrentIncomeTest(Person person, String context) {
        // TODO: This is implemented here for now. We might want to consider
        // moving this into ILOG in the future.

        // Create the income test completed date/time test value
        Calendar calendar = Calendar.getInstance();
        calendar.set(1999, 10, 5);
        Date incomeTestCompletionDateTest = calendar.getTime();

        // Get the map of all income tests defined for this Person
        Map incomeTests = person.getIncomeTests();

        // Get a list of all the income years for the tests
        List incomeYears = new ArrayList(incomeTests.keySet());
        if ((incomeYears == null) || (incomeYears.isEmpty())) {
            return null;
        }

        // Loop through the income years from the most current to the oldest one
        Collections.sort(incomeYears);
        for (int i = incomeYears.size() - 1; i >= 0; i--) {
            // Get an income test
            Integer incomeYear = (Integer) incomeYears.get(i);

            // Get the income test
            IncomeTest incomeTest = (IncomeTest) incomeTests.get(incomeYear);

            // Get the effective and expiry date
            Date effectiveDate = incomeTest.getEffectiveDate();
            GregorianCalendar expiryDate = null;
            if (effectiveDate != null) {
                // The expiration date is 365 days after the effective date
                expiryDate = new GregorianCalendar();
                expiryDate.setTime(effectiveDate);
            //    expiryDate.add(Calendar.DATE, 365);
                // CCR 11781 Laurie S. said Leap Year produces wrong expiration date so
                // we will handle here by using calendar year.
                expiryDate.add(Calendar.YEAR, 1);
            }

            // Get the income test completed date
            Date incomeTestCompleted = incomeTest.getCompletedDate();

            // Get other income test information
            MeansTestStatus meansTestStatus = incomeTest.getStatus();
            BigDecimal gmtThreshold = incomeTest.getGmtThresholdAmount();
            BigDecimal meansTestThreshold = incomeTest.getThresholdA(); // Is
            // this
            // truly
            // the
            // means
            // test
            // threshold?
            Boolean agreesToPayDeductable = incomeTest
                    .getAgreesToPayDeductible();
            Boolean discloseFinancialInformation = incomeTest
                    .getDiscloseFinancialInformation();

            Date today = new Date();
            // Decision 5 - Effective date in future
            if (effectiveDate != null
                    && effectiveDate.getTime() > (today.getTime())) {
                continue;
            }

            // Decision 1
            if ((incomeTestCompleted != null) && (expiryDate != null)
                    && (expiryDate.getTime().getTime() > (today.getTime()))) {
                return incomeTest;
            }

            // Decision 2
            if ((meansTestStatus != null)
                    && (MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getName()
                            .equals(meansTestStatus.getCode()))
                    && (incomeTestCompleted != null)
                    && (incomeTestCompleted.after(incomeTestCompletionDateTest))
                    && (Boolean.TRUE.equals(agreesToPayDeductable))) {
                return incomeTest;
            }

            // Decision 3
            if ((meansTestStatus != null)
                    && (MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getName()
                            .equals(meansTestStatus.getCode()))
                    && (Boolean.TRUE.equals(agreesToPayDeductable))
                    && (Boolean.FALSE.equals(discloseFinancialInformation))) {
                return incomeTest;
            }

            // Decision 4
            if ((meansTestStatus != null)
                    && (MeansTestStatus.MT_STATUS_PENDING_ADJUDICATION
                            .getName().equals(meansTestStatus.getCode()))
                    && (gmtThreshold != null)
                    && (meansTestThreshold != null)
                    && (gmtThreshold.compareTo(meansTestThreshold) <= 0)
                    && (incomeTestCompleted != null)
                    && (incomeTestCompleted.after(incomeTestCompletionDateTest))
                    && (Boolean.TRUE.equals(agreesToPayDeductable))
                    && (Boolean.TRUE.equals(discloseFinancialInformation))) {
                return incomeTest;
            }

            // Requirement 2819 only applies when in context of EE
            if (CONTEXT_EE.equals(context)) {
                IncomeTestStatus incomeStatus = IncomeTest
                        .getIncomeTestStatusOfType(incomeTest.getStatuses(),
                                IncomeTestType.CODE_MEANS_TEST);
                if (incomeStatus != null
                        && incomeStatus.getStatus() != null
                        && incomeStatus.getDeterminedStatus() != null
                        && MeansTestStatus.MT_STATUS_NO_LONGER_REQUIRED
                                .getName().equals(
                                        incomeStatus.getStatus().getCode())
                        && MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED
                                .getName().equals(
                                        incomeStatus.getDeterminedStatus()
                                                .getCode())) {
                    return incomeTest;
                }
            }

            // CR6301/CodeCR6387: Means Test should remain current when Agree to
            // Pay Copay = NO
            // If the Effective Date of Test is greater than 365 days and
            // the MT Status is MT Copay Required or GMT Copay Required or
            // Pending Adjudication and the Agree to Pay Deducible is No
            // then the test is current until the veteran completes a new income
            // test.
            if ((expiryDate != null && (expiryDate.getTime().getTime() < today
                    .getTime()))
                    && (meansTestStatus != null && (MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED
                            .getName().equals(meansTestStatus.getCode())
                            || MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED
                                    .getName()
                                    .equals(meansTestStatus.getCode()) || MeansTestStatus.MT_STATUS_PENDING_ADJUDICATION
                            .getName().equals(meansTestStatus.getCode())))
                    && (Boolean.FALSE.equals(agreesToPayDeductable))) {
                return incomeTest;
            }

            // CCR 11781 Discontinue idea of "expired" for incomes tests
            // Notice that this will only be checked one time for the most recent test. Future tests are skipped
            // and never reach here.
            if (isCurrentByVfaCriteria(incomeTest,expiryDate, meansTestStatus, incomeTestCompleted, effectiveDate)) {
            	return incomeTest;
            }

            // Decision 6 - Yields a "not current" test

            // REEG_00005898 - do not consider the old tests by looping through
            // if current is expired
            return null;
        }

        // No test was found to be current so return null
        return null;
    }

    /**
     * Gets the latest income test. If no income tests are defined, null is
     * returned.
     *
     * @return The latest income test or null.
     */
    public IncomeTest getLatestIncomeTest(Person person) {
        // TODO: Need to determine the proper logic for determining the current
        // income test instead of just
        // taking the latest year.

        Map incomeTests = person.getIncomeTests();
        List incomeYears = new ArrayList(incomeTests.keySet());
        if ((incomeYears != null) && (!incomeYears.isEmpty())) {
            Collections.sort(incomeYears);
            return (IncomeTest) incomeTests.get(incomeYears.get(incomeYears
                    .size() - 1));
        } else {
            return null;
        }
    }

    /**
     * Lookup state by state code or state name.
     *
     * @param stateNameOrCode
     * @return State
     * @throws BuilderException
     */
    public State getStateFromCodeOrName(String stateNameOrCode)
            throws ServiceException {
        State state = null;
        try {
            // The state could be a state code or a state name.
            // Lookup the state by code first, if it is null, then lookup by
            // name.If both are null, set the state to null.
            state = lookupService.getStateByCode(stateNameOrCode);
        } catch (ServiceException e) {
            state = lookupService.getStateByName(stateNameOrCode);
        }
        return state;
    }

    public String getICNChecksum(String VPIDValue) {
        if (VPIDValue == null)
            return null;

        StringBuffer ICNCheckSum = new StringBuffer(VPIDValue);

        String paddedZeroes = "000000";

        if (ICNCheckSum.substring(0, 6).equals(paddedZeroes)) {
            ICNCheckSum = ICNCheckSum.delete(0, 6);
        }
        if (ICNCheckSum.substring((ICNCheckSum.length() - 6),
                ICNCheckSum.length()).equals(paddedZeroes)) {
            ICNCheckSum = ICNCheckSum.delete((ICNCheckSum.length() - 6),
                    ICNCheckSum.length());
        }

        return ICNCheckSum.toString();
    }

    /*
     * (non-Javadoc)
     *
     * @see gov.va.med.esr.service.PersonHelperService#sortLastVisitDateRecentToOld(java.util.Collection)
     */
    public List sortLastVisitDateRecentToOld(Collection patientVisitSummaries) {
        List sortedPatientVisitSummaries = new ArrayList();
        if (patientVisitSummaries != null && !patientVisitSummaries.isEmpty()) {
            sortedPatientVisitSummaries.addAll(patientVisitSummaries);
            Comparator comparator = new Comparator() {
                public int compare(Object pObject1, Object pObject2) {
                    Date date1 = (pObject1 instanceof PatientVisitSummary) ? ((PatientVisitSummary) pObject1)
                            .getLastVisitDate()
                            : null;
                    Date date2 = (pObject2 instanceof PatientVisitSummary) ? ((PatientVisitSummary) pObject2)
                            .getLastVisitDate()
                            : null;
                    return (date1 != null && date2 != null) ? (-date1
                            .compareTo(date2)) : 0;
                }
            };
            Collections.sort(sortedPatientVisitSummaries, comparator);
        }
        return sortedPatientVisitSummaries;
    }

    public ServicePeriod getCurrentServicePeriod(MilitaryService militaryService) {
        ServicePeriod servicePeriod = null;

        if (militaryService == null)
            return null;

        MilitaryServiceSiteRecord hecSiteRecord = militaryService
                .getHECMilitaryServiceSiteRecord();

        // If ESR has a HEC Period of Service (POS) then send it.
        if (hecSiteRecord != null && hecSiteRecord.getServicePeriod() != null) {
            servicePeriod = hecSiteRecord.getServicePeriod();
        } else
        // If ESR does not have a HEC POS and there is one sites POS then send
        // the POS from this single site.
        if (militaryService.getMilitaryServiceSiteRecords() != null
                && militaryService.getMilitaryServiceSiteRecords().size() == 1) {
            MilitaryServiceSiteRecord siteRecord = (MilitaryServiceSiteRecord) militaryService
                    .getMilitaryServiceSiteRecords().iterator().next();

            servicePeriod = siteRecord.getServicePeriod();
        } else
        // If ESR has more than one site POS and the POS for each site is the
        // same
        // then send the POS from the site information.
        if (militaryService.getMilitaryServiceSiteRecords() != null
                && militaryService.getMilitaryServiceSiteRecords().size() > 1) {
            Set siteRecords = militaryService.getMilitaryServiceSiteRecords();

            ServicePeriod servicePeriodFromSites = getSameServicePeriod(siteRecords);

            if (servicePeriodFromSites != null)
                servicePeriod = servicePeriodFromSites;
            else
                servicePeriod = getMostCurrentPOS(siteRecords);

        }

        return servicePeriod;
    }

    private ServicePeriod getMostCurrentPOS(Set siteRecords) {
        List servicePeriods = new ArrayList();

        // Service Periods will be added to a list in a ordered manner
        // as per the hierarchy
        int index = 0;
        int persianGulfServicePeriodPos = index;
        int vietnamServicePeriodPos = ++index;
        int koreanServicePeriodPos = ++index;
        int worldWarTwoServicePeriodPos = ++index;
        int merchantMarineServicePeriodPos = ++index;
        int worldWarOneServicePeriodPos = ++index;
        int spanishAmericanServicePeriodPos = ++index;
        int postVietnamEraServicePeriodPos = ++index;
        int postKoreanServicePeriodPos = ++index;
        int preKoreanServicePeriodPos = ++index;

        for (int i = 0; i <= index; i++) {
            servicePeriods.add(i, null);
        }

        for (Iterator iter = siteRecords.iterator(); iter.hasNext();) {
            MilitaryServiceSiteRecord siteRecord = (MilitaryServiceSiteRecord) iter
                    .next();
            ServicePeriod currentServicePeriod = siteRecord.getServicePeriod();

            if (currentServicePeriod != null
                    && (ServicePeriod.CODE_PERSIAN_GULF_WAR.getCode()
                            .equals(currentServicePeriod.getCode())))
                servicePeriods.add(persianGulfServicePeriodPos,
                        currentServicePeriod);

            else if (currentServicePeriod != null
                    && (ServicePeriod.CODE_VIETNAM_ERA.getCode()
                            .equals(currentServicePeriod.getCode())))
                servicePeriods.add(vietnamServicePeriodPos,
                        currentServicePeriod);

            else if (currentServicePeriod != null
                    && (ServicePeriod.CODE_KOREAN.getCode()
                            .equals(currentServicePeriod.getCode())))
                servicePeriods
                        .add(koreanServicePeriodPos, currentServicePeriod);

            else if (currentServicePeriod != null
                    && (ServicePeriod.CODE_WORLD_WAR_II.getCode()
                            .equals(currentServicePeriod.getCode())))
                servicePeriods.add(worldWarTwoServicePeriodPos,
                        currentServicePeriod);

            else if (currentServicePeriod != null
                    && (ServicePeriod.CODE_MERCHANT_MARINE.getCode()
                            .equals(currentServicePeriod.getCode())))
                servicePeriods.add(merchantMarineServicePeriodPos,
                        currentServicePeriod);

            else if (currentServicePeriod != null
                    && (ServicePeriod.CODE_WORLD_WAR_I.getCode()
                            .equals(currentServicePeriod.getCode())))
                servicePeriods.add(worldWarOneServicePeriodPos,
                        currentServicePeriod);

            else if (currentServicePeriod != null
                    && (ServicePeriod.CODE_SPANISH_AMERICAN.getCode()
                            .equals(currentServicePeriod.getCode())))
                servicePeriods.add(spanishAmericanServicePeriodPos,
                        currentServicePeriod);

            else if (currentServicePeriod != null
                    && (ServicePeriod.CODE_POST_VIETNAM.getCode()
                            .equals(currentServicePeriod.getCode())))
                servicePeriods.add(postVietnamEraServicePeriodPos,
                        currentServicePeriod);

            else if (currentServicePeriod != null
                    && (ServicePeriod.CODE_POST_KOREAN.getCode()
                            .equals(currentServicePeriod.getCode())))
                servicePeriods.add(postKoreanServicePeriodPos,
                        currentServicePeriod);

            else if (currentServicePeriod != null
                    && (ServicePeriod.CODE_PRE_KOREAN.getCode()
                            .equals(currentServicePeriod.getCode())))
                servicePeriods.add(preKoreanServicePeriodPos,
                        currentServicePeriod);

        }

        ServicePeriod servicePeriod = null;
        // Loop through the ordered list and get the first one
        for (Iterator iter = servicePeriods.iterator(); iter.hasNext();) {
            ServicePeriod currentServicePeriod = (ServicePeriod) iter.next();
            if (currentServicePeriod != null) {
                servicePeriod = currentServicePeriod;
                break;
            }
        }

        return servicePeriod;
    }

    /**
     * @param servicePeriod
     * @param militaryServiceSiteRecords
     * @return
     */
    private ServicePeriod getSameServicePeriod(Set militaryServiceSiteRecords) {
        ServicePeriod servicePeriod = null;

        boolean isSamePOS = true;
        ServicePeriod currentServicePeriod = null;
        ServicePeriod servicePeriodOrig = null;

        for (Iterator iter = militaryServiceSiteRecords.iterator(); iter
                .hasNext();) {
            MilitaryServiceSiteRecord siteRecord = (MilitaryServiceSiteRecord) iter
                    .next();
            currentServicePeriod = siteRecord.getServicePeriod();

            if (currentServicePeriod != null && servicePeriodOrig == null) {
                servicePeriodOrig = currentServicePeriod;
            } else if (currentServicePeriod != null
                    && servicePeriodOrig != null) {
                if (!currentServicePeriod.getCode().equals(
                        servicePeriodOrig.getCode())) {
                    isSamePOS = false;
                    break;
                }
            }

        }
        if (isSamePOS)
            servicePeriod = currentServicePeriod;

        return servicePeriod;
    }

    /**
     * Retrieve PersonTraits by VPID.
     *
     * @param VPID
     * @return PersonTraits
     * @throws ServiceException
     */
    public PersonTraits getPersonTraitsByVPID(String VPID)
            throws ServiceException {
        //CCR12190 Remove direct dependency on PSIM RPT_PSIM_TRAITS table
        //updated 2/2013 to call MVI instead of direct query through local DAO
        //return personTraitsDAO.getPersonTraitsByVPID(VPID);
        VPIDEntityKey vpidKey =  CommonEntityKeyFactory.createVPIDEntityKey(VPID);
        PersonIdentityTraits identityTraits = psDelegateService.getIdentityTraits(vpidKey);
        PersonTraits personTraits = new PersonTraits();
        personTraits.setTraits(identityTraits);
        return personTraits;
    }


    /**
     * Returns a person's MSDS query status
     * @param person A person from which MSDS query status is obtained
     * @return A MSDS query status indicator
     * @throws ServiceException If failed to lookup a MSDS query status
     */
    public MilitaryServiceQueryStatus getMSDSQueryStatus(Person person)
    	throws ServiceException {

        Validate.notNull( person, "A person must not be null" );

        return person.getMilitaryService() != null ? person.getMilitaryService().getMilitaryServiceQueryStatus() :null;

    }

    /**
     * Gets the current or future income test. If no income tests are defined or no income
     * test is considered current or future, null is returned.
     *
     * @return The current or future income test or null.
     */
    public IncomeTest getCurrentOrFutureIncomeTest(Person person, Person pristinePerson) {
        //Subsequent Rejection Letter ESR 3.6_CodeCR10108
    	//This method was cloned from getCurrentIncomeTest method.  The reason for addressing the fix in this cloned method
    	//is to reduce the risk of impact to the rest of the ESR application as many of the ILOG rules do not have a need
    	//to return the Future Dated Income Test.
        return this.doGetCurrentOrFutureIncomeTest(person, pristinePerson, CONTEXT_FINANCIALS);
    }

    private IncomeTest doGetCurrentOrFutureIncomeTest(Person person, Person pristinePerson, String context) {
        // TODO: This is implemented here for now. We might want to consider
        // moving this into ILOG in the future.

        //Subsequent Rejection Letter ESR 3.6_CodeCR10108
    	//This method was cloned from doGetCurrentIncomeTest method.  The reason for addressing the fix in this cloned method
    	//is to reduce the risk of impact to the rest of the ESR application as many of the ILOG rules do not have a need
    	//to return the Future Dated Income Test.

        // Create the income test completed date/time test value
        Calendar calendar = Calendar.getInstance();
        calendar.set(1999, 10, 5);
        Date incomeTestCompletionDateTest = calendar.getTime();

        // Get the map of all income tests defined for this Person
        Map incomeTests = person.getIncomeTests();

        // Get the map of all income tests defined for this Pristine Person
        Map pristineIncomeTests = pristinePerson.getIncomeTests();

        // Get a list of all the income years for the tests
        List incomeYears = new ArrayList(incomeTests.keySet());
        if ((incomeYears == null) || (incomeYears.isEmpty())) {
            return null;
        }

        // Get a list of all the pristine income years for the tests--Should we return null if empty?
        List pristineIncomeYears = new ArrayList(pristineIncomeTests.keySet());
        if ((pristineIncomeYears == null) || (pristineIncomeYears.isEmpty())) {
            return null;
        }

        // Loop through the income years from the most current to the oldest one
        Collections.sort(incomeYears);
        Collections.sort(pristineIncomeYears);
        List incomingIncomeYears = new ArrayList(incomeTests.keySet());
        Collections.sort(incomingIncomeYears);
        incomingIncomeYears.removeAll(pristineIncomeYears);

        if ((incomingIncomeYears == null) || (incomingIncomeYears.isEmpty())) {
            return null;
        }

        if (incomingIncomeYears.size() != 1) {
            return null;
        }

        Integer incomingIncomeYear = null;
        IncomeTest incomingIncomeTest = null;
        for (int i = incomingIncomeYears.size() - 1; i >= 0; i--) {
            // Get an income test
            incomingIncomeYear = (Integer) incomingIncomeYears.get(i);
            incomingIncomeTest = (IncomeTest) incomeTests.get(incomingIncomeYear);
        }

        //Loop through the income years from the most current to the oldest one
        for (int i = incomeYears.size() - 1; i >= 0; i--) {
            // Get an income test
            Integer incomeYear = (Integer) incomeYears.get(i);

            // Get the income test
            IncomeTest incomeTest = (IncomeTest) incomeTests.get(incomeYear);

            // Get the effective and expiry date
            Date effectiveDate = incomeTest.getEffectiveDate();
            GregorianCalendar expiryDate = null;
            if (effectiveDate != null) {
                // The expiration date is 365 days after the effective date
                expiryDate = new GregorianCalendar();
                expiryDate.setTime(effectiveDate);
                // Use one year
                //expiryDate.add(Calendar.DATE, 365);
                expiryDate.add(Calendar.YEAR, 1);
            }

            // Get the income test completed date
            Date incomeTestCompleted = incomeTest.getCompletedDate();

            // Get other income test information
            MeansTestStatus meansTestStatus = incomeTest.getStatus();
            BigDecimal gmtThreshold = incomeTest.getGmtThresholdAmount();
            BigDecimal meansTestThreshold = incomeTest.getThresholdA(); // Is
            // this
            // truly
            // the
            // means
            // test
            // threshold?
            Boolean agreesToPayDeductable = incomeTest
                    .getAgreesToPayDeductible();
            Boolean discloseFinancialInformation = incomeTest
                    .getDiscloseFinancialInformation();

            Date today = new Date();
            // Decision 5 - Effective date in future
            if (effectiveDate != null
                    && effectiveDate.getTime() > (today.getTime())) {
            	if (incomeYear.equals(incomingIncomeYear)
            	        && incomeTest.isFutureTest() != null
            	        && incomeTest.isFutureTest().booleanValue()) {
            		return incomeTest;
            	} else {
                continue;
            	}
            }

            // Decision 1
            if ((incomeTestCompleted != null) && (expiryDate != null)
                    && (expiryDate.getTime().getTime() > (today.getTime()))) {
                return incomeTest;
            }

            // Decision 2
            if ((meansTestStatus != null)
                    && (MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getName()
                            .equals(meansTestStatus.getCode()))
                    && (incomeTestCompleted != null)
                    && (incomeTestCompleted.after(incomeTestCompletionDateTest))
                    && (Boolean.TRUE.equals(agreesToPayDeductable))) {
                return incomeTest;
            }

            // Decision 3
            if ((meansTestStatus != null)
                    && (MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getName()
                            .equals(meansTestStatus.getCode()))
                    && (Boolean.TRUE.equals(agreesToPayDeductable))
                    && (Boolean.FALSE.equals(discloseFinancialInformation))) {
                return incomeTest;
            }

            // Decision 4
            if ((meansTestStatus != null)
                    && (MeansTestStatus.MT_STATUS_PENDING_ADJUDICATION
                            .getName().equals(meansTestStatus.getCode()))
                    && (gmtThreshold != null)
                    && (meansTestThreshold != null)
                    && (gmtThreshold.compareTo(meansTestThreshold) <= 0)
                    && (incomeTestCompleted != null)
                    && (incomeTestCompleted.after(incomeTestCompletionDateTest))
                    && (Boolean.TRUE.equals(agreesToPayDeductable))
                    && (Boolean.TRUE.equals(discloseFinancialInformation))) {
                return incomeTest;
            }

            // Requirement 2819 only applies when in context of EE
            if (CONTEXT_EE.equals(context)) {
                IncomeTestStatus incomeStatus = IncomeTest
                        .getIncomeTestStatusOfType(incomeTest.getStatuses(),
                                IncomeTestType.CODE_MEANS_TEST);
                if (incomeStatus != null
                        && incomeStatus.getStatus() != null
                        && incomeStatus.getDeterminedStatus() != null
                        && MeansTestStatus.MT_STATUS_NO_LONGER_REQUIRED
                                .getName().equals(
                                        incomeStatus.getStatus().getCode())
                        && MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED
                                .getName().equals(
                                        incomeStatus.getDeterminedStatus()
                                                .getCode())) {
                    return incomeTest;
                }
            }

            // CR6301/CodeCR6387: Means Test should remain current when Agree to
            // Pay Copay = NO
            // If the Effective Date of Test is greater than 365 days and
            // the MT Status is MT Copay Required or GMT Copay Required or
            // Pending Adjudication and the Agree to Pay Deducible is No
            // then the test is current until the veteran completes a new income
            // test.
            if ((expiryDate != null && (expiryDate.getTime().getTime() < today
                    .getTime()))
                    && (meansTestStatus != null && (MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED
                            .getName().equals(meansTestStatus.getCode())
                            || MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED
                                    .getName()
                                    .equals(meansTestStatus.getCode()) || MeansTestStatus.MT_STATUS_PENDING_ADJUDICATION
                            .getName().equals(meansTestStatus.getCode())))
                    && (Boolean.FALSE.equals(agreesToPayDeductable))) {
                return incomeTest;
            }

            // NOTE - this entire method "doGetCurrentOrFutureIncomeTest" is almost duplicate of getCurrentIncomeTest and
            // should be eliminated. I had to copy following from getCurrentIncomeTest in order to
            // provide correct behavior for Vfa.
            // CCR 11781 Discontinue idea of "expired" for incomes tests
            // Notice that this will only be checked one time for the most recent test. Future tests are skipped
            // and never reach here.
            if (isCurrentByVfaCriteria(incomeTest,expiryDate, meansTestStatus, incomeTestCompleted, effectiveDate)) {
            	return incomeTest;
            }

            // Decision 6 - Yields a "not current" test

            // REEG_00005898 - do not consider the old tests by looping through
            // if current is expired
            return null;
        }

        // No test was found to be current so return null
        return null;
    }

    private boolean isCurrentByVfaCriteria(IncomeTest incomeTest, GregorianCalendar expiryDate,
    		MeansTestStatus meansTestStatus, Date incomeTestCompleted, Date effectiveDate) {
        // CCR 11781 Discontinue idea of "expired" for incomes tests
    	Date vfaStartDate = null;
    	try {
    		SystemParameterService systemParameterService =
    			(SystemParameterService)this.getComponent(this.getSystemParameterServiceName());
    		vfaStartDate = systemParameterService.getVFAStartDate();
    	}
    	catch (Exception e){
    		logger.error("error retrieving VFA Start Date from systemParameterService");
    	}

        // CCR 11781 apply logic to see if incomes test never expires
        /**
		 * Never expire if Effective Date of Test:
		 * Less than 1 year old as of the VFA start OR Later than VFA start date
		 * The requirements for the latter condition also include specific MT Statuses.
		 */
        boolean futureFlag = incomeTest.getFutureTest() != null ? incomeTest.getFutureTest().booleanValue() : false;

        if (!futureFlag && incomeTestCompleted != null && vfaStartDate != null) {
        	boolean mtStatusCriteriaMet = (meansTestStatus != null) &&
        	(MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getName().equals(meansTestStatus.getCode()) ||
        			MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED.getName().equals(meansTestStatus.getCode()) ||
        			MeansTestStatus.MT_STATUS_PENDING_ADJUDICATION.getName().equals(meansTestStatus.getCode()) ||
        			MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getName().equals(meansTestStatus.getCode()));

        	//CR12137 - Allow user to add Income Test ONLY if effective date is less than 1 year old as of the VFA start date
        	//expiry date = effective date + 1 year
        	//So check if expiry date is less than VFA start date
        	//Need to remove below rules so commenting it out
        	/*
        	boolean lessThanOrEqualToOneYearOldAsOfVfaStartDate = (expiryDate.getTime().getTime() > vfaStartDate.getTime()) ||
        		(expiryDate.equals(vfaStartDate));
        	*/

        	//CCR12847 - Decrement 1 year from VFA start date to get VFA umbrella start date
        	//VFA umbrella = (VFA start date - 1 year) to (VFA start date)
            GregorianCalendar vfaUmbrellaStartDate = null;
            if (vfaStartDate != null) {
                // The VFA umbrella start date is 365 days before the VFA start date
            	vfaUmbrellaStartDate = new GregorianCalendar();
            	vfaUmbrellaStartDate.setTime(vfaStartDate);
            	// vfaUmbrellaStartDate.add(Calendar.DATE, -365);
                // CCR 11781 Laurie S. said Leap Year produces wrong expiration date so
                // we will handle here by using calendar year.
            	vfaUmbrellaStartDate.add(Calendar.YEAR, -1);
            }
            //TED is between VFA umbrella
            /*** 
             * VFA Rules:
             * TBL776 
             * 1	Less than 1 year old as of the VFA start date
             * 2	Later than VFA start date
             * In above both cases Income Test should be considered as current i.e. TED >= VFA start date - 1 year
             * Otherwise it will considered as expired.
             * 
             * So commenting out below logic - 03/24/2016.
             *
        	boolean lessThanOrEqualToOneYearOldAsOfVfaStartDate = (expiryDate.getTime().getTime() <= vfaStartDate.getTime());
        	lessThanOrEqualToOneYearOldAsOfVfaStartDate = lessThanOrEqualToOneYearOldAsOfVfaStartDate && (effectiveDate.getTime() >= vfaUmbrellaStartDate.getTime().getTime());        	
        		
        	//MT Status Criteria if satisfied then current Income Test never expires
        	//Need to verify below condition to see if its needed 
        	boolean laterThanVfaStartDate = effectiveDate.getTime() >= vfaStartDate.getTime();
        	if (lessThanOrEqualToOneYearOldAsOfVfaStartDate || (mtStatusCriteriaMet && laterThanVfaStartDate)) {
        		return true;
        	}
        	***/
            /*** 
             * VFA Rules:
             * TBL776 
             * 1	Less than 1 year old as of the VFA start date
             * 2	Later than VFA start date
             * In above both cases Income Test should be considered as current i.e. TED >= VFA start date - 1 year
             * Otherwise it will considered as expired - 03/24/2016.
             ***/            
            if (effectiveDate != null && vfaUmbrellaStartDate != null && effectiveDate.getTime() >= vfaUmbrellaStartDate.getTime().getTime()) {
            	return true;
            }
        }
    	return false;
    }

    /**
     * iCCR 11666 nsert into SSA verification queue
     */

    public void addToSSNVerificationQueue(Person person) throws ServiceException
    {
    	if (person == null || person.getEntityKey() == null)
    		return;

        try{

        	SSNVerificationDetail detail = this.getSsnVerificationDetailDAO().getSSNVerificationDetailByPersonId(new BigDecimal(person.getEntityKey().getKeyValueAsString()));

        	//only insert detail record into SSN_Verification_Detail table for the following two cases
        	// 1) There is no record for this person in SSN_VerificationDetail table
        	// 2) This person exist in SSN_VerificationDetail table, but has been processed before (ssnVerification and HECInternalId is not null)
            if( detail == null ) {
        		detail = new SSNVerificationDetail();
        		detail.setPersonId(new BigDecimal(person.getEntityKey().getKeyValueAsString()));
       			this.getGenericDAO().insertObject(detail);
        	}
         } catch (DAOException dex)
    	{
    		throw new ServiceException(dex);
    	}
    }
    
    /**
     * Retrieve PersonIDs by VPID.
     *
     * @param VPID
     * @return PersonIDs
     * @throws ServiceException
     */
    public PersonTraits getPersonIDsByVPID(String VPID)
            throws ServiceException {
        //CCR12190 Remove direct dependency on PSIM RPT_PSIM_TRAITS table
        //updated 2/2013 to call MVI instead of direct query through local DAO
        //return personTraitsDAO.getPersonTraitsByVPID(VPID);
        VPIDEntityKey vpidKey =  CommonEntityKeyFactory.createVPIDEntityKey(VPID);
        PersonIdentityTraits identityTraits = psDelegateService.getIdentityTraits(vpidKey);
        PersonTraits personTraits = new PersonTraits();
        personTraits.setTraits(identityTraits);
        return personTraits;
    }

    /**
     * Retrieve VHIC Id by VPID.
     *
     * @param VPID
     * @return VhicId
     * @throws ServiceException
     */
    public String getVhicIdByVPID(String VPID)
            throws ServiceException {
        
        VPIDEntityKey vpidKey =  CommonEntityKeyFactory.createVPIDEntityKey(VPID);
       
        String vhicId = psDelegateService.getVhicId(vpidKey);
        return vhicId;
    }
	public String getSystemParameterServiceName() {
		return systemParameterServiceName;
	}

	public void setSystemParameterServiceName(String systemParameterServiceName) {
		this.systemParameterServiceName = systemParameterServiceName;
	}
	
	/*Ec-Begin*/
    public boolean isNonVeteranPrimaryEligibility(Person incoming) {

    	EnrollmentDetermination enrollDet = (incoming == null) ? null : incoming.getEnrollmentDetermination();
		EligibilityType type = (enrollDet != null && enrollDet.getPrimaryEligibility() != null) ? enrollDet.getPrimaryEligibility().getType() : null;
		String code = (type == null) ? null : type.getCode();
		boolean isNonVeteran = false;
		if (code != null) { 
			//System.out.printf("After-Varify NonVeteran-PrimaryEiligilityType=", code.toString());
			isNonVeteran = isNonVeteranEligibilityCode(code); 
		}
		return isNonVeteran;
    }
    
    public String getPrimaryEligibilityCode(Person incoming) {

    	EnrollmentDetermination enrollDet = (incoming == null) ? null : incoming.getEnrollmentDetermination();
		EligibilityType type = (enrollDet != null && enrollDet.getPrimaryEligibility() != null) ? enrollDet.getPrimaryEligibility().getType() : null;
		String code = (type == null) ? null : type.getCode();
		return code;
    }
/*Ec-End*/ 
	public PersonHelperService getPersonHelperService(){
		return this.getPersonHelperService();
	}
}