/*******************************************************************************
 * Copyright © 2005 VHA. All rights reserved
 ******************************************************************************/
package gov.va.med.esr.common.rule.parameter;

// Java classes
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Collection;
import java.util.Comparator;

import org.apache.commons.lang.Validate;
import gov.va.med.fw.util.DateComparator;
import gov.va.med.esr.UseCaseName;
import gov.va.med.esr.common.batchprocess.LoadVSSCDataResult;
import gov.va.med.fw.model.AbstractEntity;
import gov.va.med.esr.common.infra.ImpreciseDateUtils;
import gov.va.med.esr.common.model.ee.AbstractCombatEpisode;
import gov.va.med.esr.common.model.ee.Activation;
import gov.va.med.esr.common.model.ee.CombatEpisode;
import gov.va.med.esr.common.model.ee.CombatService;
import gov.va.med.esr.common.model.ee.ConflictExperience;
import gov.va.med.esr.common.model.ee.Deployment;
import gov.va.med.esr.common.model.ee.MedalOfHonor;
import gov.va.med.esr.common.model.ee.MedicaidFactor;
import gov.va.med.esr.common.model.ee.MilitaryService;
import gov.va.med.esr.common.model.ee.MilitaryServiceEpisode;
import gov.va.med.esr.common.model.ee.MilitaryServiceSiteRecord;
import gov.va.med.esr.common.model.ee.PrisonerOfWar;
import gov.va.med.esr.common.model.ee.SHAD;
import gov.va.med.esr.common.model.lookup.CombatPayType;
import gov.va.med.esr.common.model.lookup.CombatServiceSource;
import gov.va.med.esr.common.model.lookup.ConflictLocation;
import gov.va.med.esr.common.model.lookup.Country;
import gov.va.med.esr.common.model.lookup.DischargeType;
import gov.va.med.esr.common.model.lookup.FilipinoVeteranProof;
import gov.va.med.esr.common.model.lookup.Indicator;
import gov.va.med.esr.common.model.lookup.MHDataSource;
import gov.va.med.esr.common.model.lookup.MsdsCountry;
import gov.va.med.esr.common.model.lookup.PHDocumentType;
import gov.va.med.esr.common.model.lookup.OEFOIFSource;
import gov.va.med.esr.common.model.lookup.ServiceBranch;
import gov.va.med.esr.common.model.lookup.ServicePeriod;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.rule.MilitaryServiceInput;
import gov.va.med.esr.common.rule.data.EventInputData;
import gov.va.med.esr.common.rule.data.MilitaryServiceInputData;
import gov.va.med.esr.common.util.ActivationComparator;
import gov.va.med.esr.common.util.CombatServiceComparator;
import gov.va.med.esr.common.util.CombatEpisodeComparator;
import gov.va.med.esr.common.util.MilitaryServiceEpisodeComparator;
import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.service.LookupService;
import gov.va.med.fw.rule.RuleDataAware;
import gov.va.med.fw.rule.RuleException;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.util.StringUtils;
import gov.va.med.fw.util.DateUtils;
import gov.va.med.esr.common.util.CommonDateUtils;

/**
 * This class is a facade that provides access to military service information.
 * Parameter objects are loaded into ILOG working memory for use by rules. The
 * PersonInputData should be used as the RuleDataAware object unless a
 * validation is being done. In that case, use MilitaryServiceInputData.
 *
 * @author Carlos Ruiz
 * @version 1.0
 */
public class MilitaryServiceInputParameter extends BaseParameter
		implements MilitaryServiceInput {

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

	/**
	 * An instance of prisonerOfWarIndicator
	 */
	private Boolean prisonerOfWarIndicator = null;

	/**
	 * An instance of veteranPrisonerOfWarIndicator
	 */
	private Boolean veteranPrisonerOfWarIndicator = null;

	/**
	 * An instance of militaryServiceEpisode
	 */
	private MilitaryServiceEpisode militaryServiceEpisode = null;

	/**
	 * An instance of filipinoVeteranProof
	 */
	private FilipinoVeteranProof filipinoVeteranProof = null;

	/**
	 * An instance of mseOverLap
	 */
	private Boolean mseOverLap = null;

	/**
	 * An instance of hasHECMSERecords
	 */
	private Boolean hasHECMSERecords = null;

    /**
     * An instance of hasHECMSERecordsOnFile
     */
    private Boolean hasHECMSERecordsOnFile = null;

	/**
	 * An instance of hasVAMCMSERecords
	 */
	private Boolean hasVAMCMSERecords = null;

    /**
     * An instance of hasVAMCMSERecordsOnFile
     */
    private Boolean hasVAMCMSERecordsOnFile = null;

	/**
	 * An instance of mostRecentSSD
	 */
	private Date mostRecentSSD = null;

	/**
	 * An instance of mostRecentCombatEpisodeEndDt
	 */
	private Date mostRecentCombatEpisodeEndDt = null;


	/**
	 * An instance of periodOfService
	 */
	private String periodOfService = null;

    private boolean isOEFOIFCombatDataInconsitant = false;

    private boolean triggerZ07 = false;

    // NDAA related fields, static because they are fixed dates
    private static Date NDAADatePlus3YearsMinus1Day = null;
/*    static
    {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(2008, Calendar.JANUARY, 28); //01/28/2008
        calendar.add(Calendar.YEAR,3);
        calendar.add(Calendar.DATE,-1);
        NDAADatePlus3YearsMinus1Day = calendar.getTime(); //01/27/2011
    }*/

    private static Date NDAA_DATE = null;
/*    static {
        Calendar cal = Calendar.getInstance();
        cal.clear();
        cal.set(2008, Calendar.JANUARY, 28); //01/28/2008
        NDAA_DATE = cal.getTime();
    }*/

    public Date getNDAADate(String ndaaDate)
    {
    	if (NDAA_DATE == null && ndaaDate != null)
    	{
    		setNDAARelatedDate(ndaaDate);
    	}
        return NDAA_DATE;
    }

/*    public Date getNDAADatePlus3YearsMinus1Day()
    {
    	return NDAADatePlus3YearsMinus1Day;
    }*/

    public Date getNDAADatePlus3YearsMinus1Day(String ndaaDate)
    {
    	if (NDAADatePlus3YearsMinus1Day == null && ndaaDate != null)
    	{
    		setNDAARelatedDate(ndaaDate);
    	}
        return NDAADatePlus3YearsMinus1Day;
    }

    private void setNDAARelatedDate(String ndaaDate)
    {
    	//MM/DD/YYYY
    	String[] dates = ndaaDate.split("/");
		Calendar cal = Calendar.getInstance();

    	synchronized (cal){
    	     cal.clear();
    	     cal.set(Integer.parseInt(dates[2]),
    	    		 Integer.parseInt(dates[0])-1, //months start with 0
    	    		 Integer.parseInt(dates[1]));
    	     NDAA_DATE = cal.getTime(); //01/28/2008

    	     cal.add(Calendar.YEAR,3);
    	     cal.add(Calendar.DATE,-1);
    	     NDAADatePlus3YearsMinus1Day = cal.getTime(); //01/27/2011
    	};
    }
	/**
	 * A default constructor
	 */
	public MilitaryServiceInputParameter() {
		super();
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getCombatVeteranEligibilityEndDate()
	 */
	public Date getCombatVeteranEligibilityEndDate() {
	    return this.getCombatVeteranEligibilityEndDate(this.getIncomingPerson());
	}

	public Date getOnFileCVEligibilityEndDate() {
	    return this.getCombatVeteranEligibilityEndDate(this.getPristinePerson());
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#isConflictDateInRange(java.util.Date, java.util.Date)
	 */
	public boolean isConflictDateInRange(Date startDate, Date endDate) {

	    //If any one of the dates is null, return false
	    if(startDate == null || endDate == null) return false;

        AbstractCombatEpisode ce = this.getCE();

        MilitaryServiceSiteRecord hecSite = (ce instanceof ConflictExperience) ? ((ConflictExperience)ce).getMilitaryServiceSiteRecord() : ((CombatEpisode)ce).getMilitaryService().getHECMilitaryServiceSiteRecord();

		if(hecSite != null) {
            //Get HEC MSEs
		    Set episodes = hecSite.getMilitaryServiceEpisodes();

		    // Loop through a collection of episodes
		    for( Iterator ie=episodes.iterator(); ie.hasNext(); ) {

		        MilitaryServiceEpisode episode = (MilitaryServiceEpisode)ie.next();

				// Get a start and end date
				Date lower_range = (episode.getStartDate() != null) ? ImpreciseDateUtils.getDateWithDefault( episode.getStartDate()) : null;
				Date upper_range = (episode.getEndDate() != null) ? ImpreciseDateUtils.getDateWithDefault(episode.getEndDate()) : null;

				if( this.isInRange(startDate,endDate,lower_range,upper_range) ) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getPrisonerOfWarIndicator()
	 */
	public boolean getPrisonerOfWarIndicator() {
		if (this.prisonerOfWarIndicator == null ) {
			this.prisonerOfWarIndicator = this.getWasPrisonerOfWar(this
					.getIncomingPerson());
		}
		return (this.prisonerOfWarIndicator != null) ? this.prisonerOfWarIndicator
				.booleanValue()
				: false;
	}

	/**
	 * Returns the Prisoner of War indicator for current person.
	 */
	public boolean getVeteranPrisonerOfWarIndicator() {
		if (this.veteranPrisonerOfWarIndicator == null ) {
			this.veteranPrisonerOfWarIndicator = this.getWasPrisonerOfWar(this
					.getPristinePerson());
		}
		return (this.veteranPrisonerOfWarIndicator != null) ? this.veteranPrisonerOfWarIndicator
				.booleanValue()
				: false;
	}

	public String getCurrentPeriodOfService() {
		ServicePeriod period = getHelperService().getCurrentServicePeriod(getPristinePerson().getMilitaryService());
		return period != null ? period.getCode(): null;
	}

	/**
	 * Gets the HEC site number. This method should be used for UI only.
	 */
	public String getPeriodOfService() {

		if(  this.periodOfService == null ) {

		    // Get the site data from incoming veteran.
			MilitaryService incomingMilitaryService = this.getIncomingPerson().getMilitaryService();
			if( incomingMilitaryService != null )
			{
			    MilitaryServiceSiteRecord record = incomingMilitaryService.getHECMilitaryServiceSiteRecord();
				if( record != null )
				{
					ServicePeriod period = record.getServicePeriod();
					this.periodOfService = (period != null) ? period.getCode(): null;
				}
			}
		}
		return this.periodOfService;
	}

	public boolean hasAtLeastOnePeriodOfService() {
		boolean result = false;
		MilitaryService ms = this.getIncomingPerson().getMilitaryService();
		Set siteRecs = ms.getMilitaryServiceSiteRecords();
		Iterator itr = siteRecs != null ? siteRecs.iterator() : null;
		MilitaryServiceSiteRecord siteRec = null;
		while(itr != null && itr.hasNext()) {
			siteRec = (MilitaryServiceSiteRecord) itr.next();
			if(siteRec.getServicePeriod() != null) {
				result = true;
				break;
			}
		}
		return result;
	}

    /**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMedalOfHonorIndicator(gov.va.med.esr.common.model.person.Person)
	 */
	public String getMedalOfHonorIndicator(Person person) throws ServiceException {
		MedalOfHonor mh = person.getMedalOfHonor();
		Boolean indicator = (mh != null) ? mh.getMhIndicator() : null;
		String flag = null;
		if( indicator != null ) {
			flag = Boolean.TRUE.equals( indicator ) ? YES_INDICATOR : NO_INDICATOR;
		}
		// Notice this will return NULL if there is no MH Indicator on person
		return flag;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setMHDataSource(java.lang.String)
	 */
	public void setMHDataSource(String dataSource) throws ServiceException {
		// Apply change to incoming, update the onfile later
		if (dataSource != null) {
			Person person = this.getIncomingPerson();
			MedalOfHonor mh = person.getMedalOfHonor();
			if (mh != null) {
				mh.setDataSource(this.getLookupService().getMHDataSourceByCode(dataSource));
			}
		}
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setMHDecorationStatus(java.lang.String)
	 */
	public void setMHDecorationStatus(String status) throws ServiceException {
		// Apply change to incoming, update the onfile later
		if (status != null) {
			Person person = this.getIncomingPerson();
			MedalOfHonor mh = person.getMedalOfHonor();
			if (mh != null) {
				mh.setStatus(this.getLookupService().getDecorationStatusByCode(status));
			}
		}
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setMHDocumentReceiptDate(java.util.Date)
	 */
	public void setMHDocumentReceiptDate(Date receiptDate) {
		// Apply change to incoming, update the onfile later
		Person person = this.getIncomingPerson();
		MedalOfHonor mh = person.getMedalOfHonor();
		if (mh != null) {
			mh.setDocumentReceiptDate(receiptDate);
		}
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setMHDocumentType(java.lang.String)
	 */
	public void setMHDocumentType(String documentType) throws ServiceException {
		// Apply change to incoming, update the onfile later
		if (documentType != null) {
			Person person = this.getIncomingPerson();
			MedalOfHonor mh = person.getMedalOfHonor();
			if (mh != null) {
				mh.setDocumentType((PHDocumentType)this.getLookupService().getByCode(PHDocumentType.class, documentType));
			}
		}
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setMHIndicator(java.lang.String)
	 */
	public void setMHIndicator(String indicator) throws ServiceException {
		// Apply change to incoming, update the onfile later
		if (indicator != null) {
			Person person = this.getIncomingPerson();
			MedalOfHonor mh = person.getMedalOfHonor();
			if (mh != null) {
				mh.setMhIndicator(YES_INDICATOR.equals( indicator ) ? Boolean.TRUE : Boolean.FALSE );
			}
		}
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setMHLastEditedDate(java.util.Date)
	 */
	public void setMHLastEditedDate(Date lastEditDate) {
		// Apply change to incoming, update the onfile later
		Person person = this.getIncomingPerson();
		MedalOfHonor mh = person.getMedalOfHonor();
		if (mh != null) {
			mh.setDateLastEdited(lastEditDate);
		}
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setMHStatusUpdateDate(java.util.Date)
	 */
	public void setMHStatusUpdateDate(Date statusUpdateDate) {
		// Apply change to incoming, update the onfile later
		Person person = this.getIncomingPerson();
		MedalOfHonor mh = person.getMedalOfHonor();
		if (mh != null) {
			mh.setStatusLastUpdateDate(statusUpdateDate);
		}
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#isCVEndDateImproved(gov.va.med.esr.common.model.person.Person, gov.va.med.esr.common.model.person.Person)
	 */
	public boolean isCVEndDateImproved(Person incoming, Person onFile) {
		// Evaluate if CV End Date IS GREATER THAN Existing CV End Date
		MilitaryService onfileMS = (onFile != null) ? onFile.getMilitaryService() : null;
		MilitaryService incomingMS = (incoming != null) ? incoming.getMilitaryService() : null;
		Date date1 = (incomingMS != null) ? incomingMS.getCombatVeteranEligibilityEndDate() : null;
		Date date2 = (onfileMS != null) ? onfileMS.getCombatVeteranEligibilityEndDate() : null;
		return DateUtils.isAfterIgnoreTime(date1, date2);
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#acceptMHFromMSDS()
	 */
	public void acceptMHFromMSDS() throws ServiceException {
		MedalOfHonor incoming = this.getIncomingPerson().getMedalOfHonor();
		MedalOfHonor result = this.getResultPerson().getMedalOfHonor();
		if (incoming != null) {
			if (result == null) {
				result = new MedalOfHonor();
				this.getResultPerson().setMedalOfHonor(result);
			}
			this.getMergeRuleService().mergeMedalOfHonor(incoming, result);
		}
	}

	/* (non-Javadoc)
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#isImprovedByMSDS()
	 */
	public boolean isImprovedByMSDS() {
		if (getMilitaryServiceInputData() != null) {
			return getMilitaryServiceInputData().isImprovedByMSDS();
		}
		return false;
	}

	public boolean isProcessQMSEflow() {
		if (getMilitaryServiceInputData() != null) {
			return getMilitaryServiceInputData().isProcessQMSEflow();
		}
		return false;
	}

	// CCR 10802
	public void acceptOrDeleteMH() throws ServiceException {
		if (getIncomingPerson().getMedalOfHonor() == null) {
			if (this.getResultPerson().getMedalOfHonor() != null) {
				this.getResultPerson().setMedalOfHonor(null);
			}
		}
		else {
			acceptMHFromMSDS();
		}
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getServiceOfficialEndDate(java.lang.String)
	 */
	public Date getServiceOfficialEndDate( String code ) throws ServiceException {
        if(StringUtils.isNotEmpty(code)) {
    		try {
    			ServicePeriod period = this.getLookupService().getServicePeriodByCode( code );
    			return period.getEndDate();
    		}
    		catch( Exception e ) {
    			if( logger.isDebugEnabled() ) {
    				logger.debug( "Failed to get a service period by code " + code, e );
    				throw new ServiceException( "Failed to get a service period by code " + code, e );
    			}
    		}
        }
		return null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getServiceOfficialStartDate(java.lang.String)
	 */
	public Date getServiceOfficialStartDate(String code) throws ServiceException {
        if(StringUtils.isNotEmpty(code)) {
    		try {
    			ServicePeriod period = this.getLookupService().getServicePeriodByCode( code );
    			return period.getStartDate();
    		}
    		catch( Exception e ) {
    			if( logger.isDebugEnabled() ) {
    				logger.debug( "Failed to get a service period by code " + code, e );
    				throw new ServiceException( "Failed to get a service period by code " + code, e );
    			}
    		}
        }
		return null;
	}

    /**
     * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getCEStartDate()
     */
    public Date getCEStartDate() {
        return ImpreciseDateUtils.getDateWithDefault( (this.getCE() != null) ? this.getCE().getStartDate() : null );
    }

    // CCR 8395
	public Date getCombatPayStartDate() {
		CombatService cs = (this.getMilitaryServiceInputData() != null) ? this.getMilitaryServiceInputData().getCombatService() : null;
		return ImpreciseDateUtils.getDateWithDefault( (cs != null) ? cs.getPayStartDate() : null );
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getCEEndDate()
	 */
	public Date getCEEndDate() {
		return ImpreciseDateUtils.getDateWithDefault( (this.getCE() != null) ? this.getCE().getEndDate() : null );
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getCombatLocation()
	 */
	public ConflictLocation getCombatLocation() {
		return (getCE() != null) ? getCE().getConflictLocation() : null;
	}

    /**
     * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getCombatLocationCode()
     */
    public String getCombatLocationCode() {
        return (this.getCombatLocation() != null) ? this.getCombatLocation().getCode() : null;
    }

    public MsdsCountry getMsdsCountryCode() {
    	CombatService cs = (this.getMilitaryServiceInputData() != null) ? this.getMilitaryServiceInputData().getCombatService() : null;
		return cs != null ? cs.getMsdsCountry() : null;
	}

	/**
     * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getgetOEFOIFSource()
     */
    public String getOEFOIFSource() {
        CombatEpisode ce = (this.getCE() instanceof CombatEpisode) ? (CombatEpisode)this.getCE() : null;
        return (ce != null && ce.getOEFOIFSource() != null) ? ce.getOEFOIFSource().getCode() : null;
    }

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getServiceBranch()
	 */
	public ServiceBranch getServiceBranch() {
	    MilitaryServiceEpisode mse = this.getMilitaryServiceEpisode();
	    return (mse != null) ? mse.getServiceBranch() : null;
	}

    /**
     * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getServiceComponent()
     */
    public String getServiceComponent() {
        MilitaryServiceEpisode mse = this.getMilitaryServiceEpisode();
        return (mse != null && mse.getMilitaryServiceComponent() != null) ? mse.getMilitaryServiceComponent().getCode() : null;
    }

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getServiceEntryDate()
	 */
	public Date getServiceEntryDate() {
		return ImpreciseDateUtils.getDateWithDefault( (this.getMilitaryServiceEpisode() != null) ? this.getMilitaryServiceEpisode().getStartDate() : null );
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getServiceSeparationDate()
	 */
	public Date getServiceSeparationDate() {
		return ImpreciseDateUtils.getDateWithDefault( (this.getMilitaryServiceEpisode() != null) ?	this.getMilitaryServiceEpisode().getEndDate() : null );
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#isMSEEndDateMonthPrecise()
	 */
	public boolean isSEDPrecise() {
		MilitaryServiceEpisode mse = this.getMilitaryServiceEpisode();
		return this.isDatePrecise( (mse != null) ? mse.getEndDate() : null );
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#isMSEStartDateMonthPrecise()
	 */
	public boolean isSSDPrecise() {
		MilitaryServiceEpisode mse = this.getMilitaryServiceEpisode();
		return this.isDatePrecise( (mse != null) ? mse.getStartDate() : null );
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#isCEEndDatePrecise()
	 */
	public boolean isCEEndDatePrecise() {
        AbstractCombatEpisode ce = this.getCE();
		return this.isDatePrecise( (ce != null) ? ce.getEndDate() : null );
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#isCEStartDatePrecise()
	 */
	public boolean isCEStartDatePrecise() {
        AbstractCombatEpisode ce = this.getCE();
		return this.isDatePrecise( (ce != null) ? ce.getStartDate() : null );
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#isOverlappingMSE()
	 */
	public boolean isOverlappingMSE() {

		// Get a list of mse from an incoming person
		MilitaryServiceEpisode mse = this.getMilitaryServiceEpisode();
		if( mse != null &&  this.mseOverLap == null ) {

			MilitaryServiceSiteRecord mssr = mse.getMilitaryServiceSiteRecord();
			Set episodes = mssr.getMilitaryServiceEpisodes();

			// Loop through a collection of episodes
			for( Iterator i=episodes.iterator(); i.hasNext(); ) {

				MilitaryServiceEpisode episode = (MilitaryServiceEpisode)i.next();

				// This check is to skip the same record and for a collection with
				// only one record of military service episode - VL
				if( episode == mse ) {
					continue;
				}

				// Get a start and end date
				Date lower_range = (episode.getStartDate() != null) ?
						ImpreciseDateUtils.getDateWithDefault( episode.getStartDate()) : null;

				Date upper_range = (episode.getEndDate() != null) ?
						ImpreciseDateUtils.getDateWithDefault(episode.getEndDate()) : null;

				// Check for the following scenarios:
				// start < lower < upper < end
				// start < lower < end < upper
				// lower < start < upper < end
				// lower < start < end < upper
				boolean overlapped = false;
				if( (overlapped = this.isOverlapped( this.getServiceEntryDate(),
											  					 this.getServiceSeparationDate(),
											  					 lower_range,
											  					 upper_range )) ) {

					this.mseOverLap = Boolean.valueOf( overlapped );
					break;
				}
			}
		}
		return this.mseOverLap == null ? false : this.mseOverLap.booleanValue();
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#hasPeriodOfService(java.lang.String)
	 */
	public boolean hasPeriodOfService(String period) {
		return containsServicePeriod(period, this.getIncomingPerson());
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getConflictOfficialEndDate(gov.va.med.esr.common.model.lookup.ConflictLocation)
	 */
	public Date getConflictOfficialEndDate(ConflictLocation conflictLocation) {
		return (conflictLocation != null) ? conflictLocation.getEndDate() : null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getConflictOfficialStartDate(gov.va.med.esr.common.model.lookup.ConflictLocation)
	 */
	public Date getConflictOfficialStartDate(ConflictLocation conflictLocation) {
		return (conflictLocation != null) ? conflictLocation.getStartDate() : null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getFilipinoVeteranProof()
	 */
	public FilipinoVeteranProof getFilipinoVeteranProof() {
		if(  this.filipinoVeteranProof == null ) {
			this.filipinoVeteranProof =
				this.getMilitaryServiceEpisode().getMilitaryServiceSiteRecord().getFilipinoVeteranProof();
		}
		return this.filipinoVeteranProof;
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getServiceDischargeType()
	 */
	public DischargeType getServiceDischargeType() {

		DischargeType type = null;
		MilitaryServiceEpisode mse = this.getMilitaryServiceEpisode();
		if( mse != null ) {
			type = mse.getDischargeType();
		}
		return type;
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#hasNoMilitaryServiceEpisodes()
	 */
	public boolean hasMilitaryServiceEpisodes() {

		boolean hasMSE = false;
		Person incoming = this.getIncomingPerson();
		MilitaryService ms = incoming.getMilitaryService();
		Set records = ms.getMilitaryServiceSiteRecords();
		for( Iterator i=records.iterator(); i.hasNext(); ) {
			MilitaryServiceSiteRecord record = (MilitaryServiceSiteRecord)i.next();
			if( !record.getMilitaryServiceEpisodes().isEmpty() ) {
				hasMSE = true;
				break;
			}
		}
		return hasMSE;
	}


	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#isOverlappingCombatEpisode()
	 */
	public boolean isOverlappingCombatEpisode() {
        AbstractCombatEpisode ce = this.getCE();
        if(ce instanceof CombatEpisode) {
            Set ces = ((CombatEpisode)ce).getMilitaryService().getCombatEpisodes();
            return isOverlappingCE(ce,ces);
        }
        return false;
	}


    public boolean hasCombatEpisodeWithOverlap(CombatEpisode ce) {
    	// This method checks result person in order to detect whether
    	// the Combat Episode overlaps data accepted to this point.
    	MilitaryService ms = getResultPerson().getMilitaryService();
    	return ms != null ? this.isOverlappingCE(ce, ms.getCombatEpisodes()) : false;
	}

    /**
     * Identifies whether record has a Start Date that falls within the
     * range of existing record, but End Date is outside and >
     */
	public boolean hasCombatEpisodeWithStartDateOnlyOverlap(CombatEpisode ce) {

    	MilitaryService ms = getResultPerson().getMilitaryService();
    	this.setMatchedCombatEpisode(null); //always reset the matched record
    	if (ce != null && ms != null && ms.getCombatEpisodes().size() > 0 &&
    			ce.getStartDate() != null && ce.getEndDate() != null) {
            Date startDate = ImpreciseDateUtils.getDateWithDefault(ce.getStartDate());
            Date endDate = ImpreciseDateUtils.getDateWithDefault(ce.getEndDate());
    		for( Iterator i=ms.getCombatEpisodes().iterator(); i.hasNext(); ) {
    			CombatEpisode episode = (CombatEpisode)i.next();
				Date lower_range = (episode.getStartDate() != null) ?
						ImpreciseDateUtils.getDateWithDefault( episode.getStartDate()) : null;
				Date upper_range = (episode.getEndDate() != null) ?
						ImpreciseDateUtils.getDateWithDefault(episode.getEndDate()) : null;
            	if (isDateBetween(startDate, lower_range, upper_range) &&
            			!isDateBetween(endDate, lower_range, upper_range) &&
            			this.isAfterIgnoreTime(endDate, lower_range) &&
            			this.isAfterIgnoreTime(endDate, upper_range)) {
            		this.setMatchedCombatEpisode(episode);
            		return true;
            	}
    		}
    	}
    	return false;
	}

	/**
     * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#isOverlappingConflictExperience()
     */
    public boolean isOverlappingConflictExperience() {
        AbstractCombatEpisode ce = this.getCE();
        if(ce instanceof ConflictExperience) {
            Set ces = ((ConflictExperience)ce).getMilitaryServiceSiteRecord().getConflictExperiences();
            return isOverlappingCE(ce,ces);
        }
        return false;
    }

    private List getOverlappingEpisodes(AbstractCombatEpisode ce, Set combatEpisodes) {
    	List overLapList = new ArrayList();

    	if (ce == null)
    		return overLapList;

        // Loop through a collection of conflicts
        for( Iterator i=combatEpisodes.iterator(); i.hasNext(); ) {

            AbstractCombatEpisode episode = (AbstractCombatEpisode)i.next();

            // This check is to skip the same record and for a collection with
            // only one record of military service episode - VL
            if( episode == ce ) {
                continue;
            }

            // Get a start and end date
            Date lower_range = (episode.getStartDate() != null) ?
                    ImpreciseDateUtils.getDateWithDefault( episode.getStartDate()) : null;

            Date upper_range = (episode.getEndDate() != null) ?
                    ImpreciseDateUtils.getDateWithDefault(episode.getEndDate()) : null;

            Date startDate = (ce.getStartDate() != null) ?
                    ImpreciseDateUtils.getDateWithDefault( ce.getStartDate()) : null;

            Date endDate = (ce.getEndDate() != null) ?
                    ImpreciseDateUtils.getDateWithDefault(ce.getEndDate()) : null;

            if(this.isOverlapped( startDate,endDate,lower_range,upper_range )){
            	overLapList.add(episode);
            }
        }
        return overLapList;
    }

    /**
     * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#isOverlappingConflictExperience()
     */
    private boolean isOverlappingCE(AbstractCombatEpisode ce, Set combatEpisodes) {

        Boolean ceOverlap = null;
        if( ce != null ) {

        	Date ceStartDate = (ce.getStartDate() != null) ?
                    ImpreciseDateUtils.getDateWithDefault( ce.getStartDate()) : null;

            Date ceEndDate = (ce.getEndDate() != null) ?
                    ImpreciseDateUtils.getDateWithDefault(ce.getEndDate()) : null;

            // Loop through a collection of conflicts
            for( Iterator i=combatEpisodes.iterator(); i.hasNext(); ) {

                AbstractCombatEpisode episode = (AbstractCombatEpisode)i.next();

                // This check is to skip the same record and for a collection with
                // only one record of military service episode - VL
                if( episode == ce ) {
                    continue;
                }

                // Get a start and end date
                Date lower_range = (episode.getStartDate() != null) ?
                        ImpreciseDateUtils.getDateWithDefault( episode.getStartDate()) : null;

                Date upper_range = (episode.getEndDate() != null) ?
                        ImpreciseDateUtils.getDateWithDefault(episode.getEndDate()) : null;

                // Check for the following scenarios:
                // start < lower < upper < end
                // start < lower < end < upper
                // lower < start < upper < end
                // lower < start < end < upper

                boolean overlapped = false;
                if( (overlapped = this.isOverlapped( ceStartDate,
                                                     ceEndDate,
                                                     lower_range,
                                                     upper_range )) ) {

                    ceOverlap = Boolean.valueOf( overlapped );
                    break;
                }
            }
        }
        return ceOverlap == null ? false : ceOverlap.booleanValue();
    }

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getCurrentCVEligEndDate()
	 */
	public Date getCurrentCVEligEndDate() {

		Date date = null;

		// Return the current combat veteran's elligibility end date of an on file person
		Person onFile = this.getResultPerson();
		MilitaryService currentMilitaryInfo = onFile.getMilitaryService();
		if( currentMilitaryInfo != null ) {
			date = currentMilitaryInfo.getCombatVeteranEligibilityEndDate();
		}
		return date;
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getDischargeDueToDisability()
	 */
	public Boolean getDischargeDueToDisability() {
		return this.getDischargeDueToDisability( this.getIncomingPerson() );
	}

   public Boolean getDischargeDueToDisability( Person person ) {
      MilitaryService ms = person != null ? person.getMilitaryService() : null;
      return ms != null ? ms.getDischargeDueToDisability() : null;
   }

	public Boolean getMilitaryDisabilityRetirement() {
	    return this.getMilitaryDisabilityRetirement( this.getIncomingPerson() );
	}

   public Boolean getMilitaryDisabilityRetirement( Person person ) {
      MilitaryService ms = person != null ? person.getMilitaryService() : null;
      return ms != null ? ms.getDisabilityRetirementIndicator() : null;
   }

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getMostRecentReceivedSSD()
	 */
	public Date getMostRecentReceivedSSD() {

		if(  this.mostRecentSSD == null ) {
			// need to loop thru all (updated)MSEs and return the Service Separation date which is most recent
			MilitaryService ms = this.getResultPerson().getMilitaryService();
			if( ms != null ) {

				// A temp collection to hold all MSEs
				HashSet episodes = new HashSet();

				// Get all site records
				Set records = ms.getMilitaryServiceSiteRecords();

				// Loop through all site records to put all MSEs in a temp collection
				// to search for the most recent MSE by service separation date.
				Iterator i = records != null ? records.iterator() : null;
				while( i != null && i.hasNext() ) {
					MilitaryServiceSiteRecord site_record = (MilitaryServiceSiteRecord)i.next();
					Set site_episodes = (site_record != null) ? site_record.getMilitaryServiceEpisodes() : null;
					if(site_episodes != null && !site_episodes.isEmpty()) {
						episodes.addAll( site_episodes );
					}
				}

				// Now use a collection comparator to search for an MSE
				// with the most recent service separation date
				MilitaryServiceEpisodeComparator comparator = new MilitaryServiceEpisodeComparator();
				if( !episodes.isEmpty() ) {
					MilitaryServiceEpisode episode = (MilitaryServiceEpisode)Collections.max( episodes, comparator );
					this.mostRecentSSD = (episode != null) ? ImpreciseDateUtils.getDateWithDefault( episode.getEndDate() ) : null;
				}
			}
		}
		return this.mostRecentSSD;
	}

    /*
     * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMostRecentReceivedCombatEpisodeEndDate()
     */
    public Date getMostRecentReceivedCombatEpisodeEndDate() {

    	if (this.mostRecentCombatEpisodeEndDt == null)
    	{
	        // Find the most recent Combat Episode End Date(after merging the incoming data)
	        MilitaryService ms = this.getResultPerson().getMilitaryService();

	        // Get all site records
	        Set ces = (ms != null) ? ms.getCombatEpisodes() : null;

	        // Now use a collection comparator to search for an Combat Episode with end Date.
	        if(ces != null &&  !ces.isEmpty()) {
	            CombatEpisode episode = (CombatEpisode)Collections.max( ces,new CombatEpisodeComparator());
	            mostRecentCombatEpisodeEndDt = (episode != null) ? ImpreciseDateUtils.getDateWithDefault( episode.getEndDate() ) : null;
	        }
    	}
        return mostRecentCombatEpisodeEndDt;
    }

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#getMostRecentSSDPlus2Years()
	 */
	public Date getMostRecentSSDPlus2Years() {
        return this.getDatePlus2YearsMinus1Day(this.getMostRecentReceivedSSD());
	}

    /**
     * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMostRecentCombatEpisodeEndDatePlus2Years()
     */
    public Date getMostRecentCombatEpisodeEndDatePlus2Years() {
        return this.getDatePlus2YearsMinus1Day(this.getMostRecentReceivedCombatEpisodeEndDate());
    }


    /* (non-Javadoc)
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getLoadVSSCDataResult()
	 */
	public LoadVSSCDataResult getLoadVSSCDataResult() {
		return this.getMilitaryServiceInputData().getLoadVSSCDataResult();
	}

	/* (non-Javadoc)
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#isDataFromVSSC()
	 */
	public boolean isDataFromVSSC() {
		return this.getMilitaryServiceInputData().isDataFromVSSC();
	}

	private Date getDatePlus2YearsMinus1Day(Date date) {
        if( date != null ) {
            Calendar calendar = Calendar.getInstance();
            calendar.clear();
            calendar.setTime( date );
            calendar.add(Calendar.YEAR,2);
            calendar.add(Calendar.DATE,-1);
            return calendar.getTime();
        }
        return null;
    }


	/**
	 * Loops through a collection of conflict experience to find the most
	 * recent one by end date for the specific conflict location.  If found,
	 * check if the most recent conflict's end date is after the specific date
	 *
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#isMostRecentConflictToDateAfterForLocation(java.util.Date, java.lang.String)
	 */
	public boolean isMostRecentConflictToDateAfterForLocation( Date date, String code ) {

        if (date == null)
        {
            return false;
        }

        boolean mostRecent = false;

		// Get an updated military service (after incoming data is merged)
		MilitaryService ms = this.getResultPerson().getMilitaryService();
		if( ms != null ) {

			// A temp collection to hold all conflicts
			HashSet conflicts = new HashSet();

			// Get all site records
			Set records = ms.getMilitaryServiceSiteRecords();

			// Loop through all site records to put all MSEs in a temp collection
			// to search for the most recent CE by service separation date.
			Iterator i = records != null ? records.iterator() : null;
			while( i != null && i.hasNext() ) {
    			MilitaryServiceSiteRecord site_record = (MilitaryServiceSiteRecord)i.next();
    			Set site_conflicts = (site_record != null) ? site_record.getConflictExperiences() : null;
    			if(site_conflicts != null && !site_conflicts.isEmpty()) {
    				conflicts.addAll( site_conflicts );
    			}
			}

			// Now use a collection comparator to search for a conflict experience
			// with the most recent end date.  If found, check if a conflict's location
			// is the specific location and if a conflict's end date is after the specific date
            CombatEpisodeComparator comparator = new CombatEpisodeComparator();
			if( !conflicts.isEmpty() ) {
				ConflictExperience conflict = (ConflictExperience)Collections.max( conflicts, comparator );
				if( conflict != null ) {
					ConflictLocation location = conflict.getConflictLocation();
					Date toDate = ImpreciseDateUtils.getDateWithDefault( conflict.getEndDate() );
					if( location != null && toDate != null &&
						 location.getCode().equals( code ) && toDate.after( date ) ) {
						mostRecent = true;
					}
				}
			}
		}
		return mostRecent;
	}

    /**
     * Loops through a collection of conflict experience to find the most
     * recent one by end date for the specific conflict location.  If found,
     * check if the most recent conflict's end date is after the specific date
     *
     * @see gov.va.med.esr.common.rule.MilitaryServiceInput#isMostRecentConflictToDateAfterForLocation(java.util.Date, java.lang.String)
     */
    public String getMostRecentCombatLocation() {

        // Get an updated military service(after incoming data is updated)
        MilitaryService ms = this.getResultPerson().getMilitaryService();
        if( ms != null ) {
            Set CEs = ms.getCombatEpisodes();
            //Find and return the most recent combat location by combat episode end date
            if(!CEs.isEmpty() ) {
                CombatEpisode CE = (CombatEpisode)Collections.max(CEs,new CombatEpisodeComparator());
                return (CE != null && CE.getConflictLocation() != null) ? CE.getConflictLocation().getCode() : null;
            }
        }
        return null;
    }

    public String getMostRecentCombatLocation(Person person) {
        // CCR 8395
    	if (person == null) return null;
        MilitaryService ms = person.getMilitaryService();
        if( ms != null ) {
            Set CEs = ms.getCombatEpisodes();
            //Find and return the most recent combat location by combat episode end date
            if(!CEs.isEmpty() ) {
                CombatEpisode CE = (CombatEpisode)Collections.max(CEs,new CombatEpisodeComparator());
                return (CE != null && CE.getConflictLocation() != null) ? CE.getConflictLocation().getCode() : null;
            }
        }
        return null;
	}

	/**
     * Update Combat Episodes
     */
    public void updateCombatEpisodes() {

        isOEFOIFCombatDataInconsitant = false;
        Person onFile = this.getResultPerson();
        MilitaryService onFileMS = (onFile.getMilitaryService() != null) ? onFile.getMilitaryService() : new MilitaryService();

        // Get the site data from incoming veteran.
        MilitaryService incomingMS = this.getMilitaryServiceInputData().getMilitaryService();

        if(incomingMS != null)
        {
            if(isUpdateFromGUI()) {
            	updateCombatEpisodesFromGUI(incomingMS, onFileMS);
            } else if (isDataFromVSSC()){
            	updateCombatEpisodesFromVSSC(incomingMS, onFileMS);
            }else {
            	updateCombatEpisodesFromMessage(incomingMS, onFileMS);
            }
        }
    }

    public boolean isOEFOIFCombatDataInconsitant() {
        return isOEFOIFCombatDataInconsitant;
    }

    /**
     * Update Combat Episodes when received from Message (HL7)
     * @param incomingMS
     * @param onFileMS
     */
    private void updateCombatEpisodesFromMessage(MilitaryService incomingMS, MilitaryService onFileMS){

        Set onFileCEs = new HashSet(onFileMS.getCombatEpisodes());
        Set incomingCEs = incomingMS.getCombatEpisodes();
        for(Iterator iter=incomingCEs.iterator(); iter.hasNext();) {
            CombatEpisode incomingCE = (CombatEpisode)iter.next();

            //Match Start date and End date, if matched ignore
            CombatEpisode onFileCE = this.getMatchingCombatEpisode(incomingCE,onFileCEs);

            if(onFileCE != null) {
                String onFileComLoc = (onFileCE.getConflictLocation() != null) ? onFileCE.getConflictLocation().getCode() : null;

                //6289 [UC48.3.10.1.15.4]
                if(isEqual(onFileComLoc,ConflictLocation.CODE_UNKNOWN_OEF_OIF.getCode())) {
                    this.getMergeRuleService().mergeCombatEpisode(incomingCE,onFileCE);
                } else {
                    if(this.isEqual(incomingCE.getConflictLocation(),onFileCE.getConflictLocation())) {
                        //6286 [UC48.3.10.1.15.1]
                        continue;
                    } else {
                        //OEF/OIF Dates on HL7 Match ESR but Conflict Location is Different
                        isOEFOIFCombatDataInconsitant = true;
                    }
                }
            } else {
                if(!this.isOverlappingCE(incomingCE,onFileMS.getCombatEpisodes())) {
                    onFileCE = new CombatEpisode();
                    this.getMergeRuleService().mergeCombatEpisode(incomingCE,onFileCE);
                    onFileMS.addCombatEpisode(onFileCE);
                } else {
                    //OEF/OIF Dates on Hl7 overlap with dates on ESR
                    isOEFOIFCombatDataInconsitant = true;
                }
            }
        }
    }

    /**
     * Update Combat Episodes from GUI (HEC)
     */
    private void updateCombatEpisodesFromGUI(MilitaryService incomingMS, MilitaryService onFileMS){

    	// CCR 11558 - old algorithm not actually removing the deleted episodes.
        Set incomingCEs = incomingMS.getCombatEpisodes();
    	Set<CombatEpisode> toAddCEs = new HashSet<CombatEpisode>();

        for(Iterator iter=incomingCEs.iterator(); iter.hasNext();) {
            CombatEpisode incomingCE = (CombatEpisode)iter.next();
            if(incomingCE.getEntityKey() == null) {
                CombatEpisode newCE= new CombatEpisode();
                this.getMergeRuleService().mergeCombatEpisode(incomingCE,newCE);
                onFileMS.addCombatEpisode(newCE);
                toAddCEs.add(newCE);
            } else {
                CombatEpisode onFileCE = (CombatEpisode)onFileMS.getCombatEpisodeByEntityKey(incomingCE.getEntityKey());
                this.getMergeRuleService().mergeCombatEpisode(incomingCE,onFileCE);
                toAddCEs.add(onFileCE);
            }
        }
        onFileMS.removeAllCombatEpisodes();
        if (!toAddCEs.isEmpty()) {
        	// Add back the new ones and updated ones
            onFileMS.addAllCombatEpisodes(toAddCEs);
        }

        /*
   Set incomingCEs = incomingMS.getCombatEpisodes();

        for(Iterator iter=incomingCEs.iterator(); iter.hasNext();) {
            CombatEpisode incomingCE = (CombatEpisode)iter.next();
            if(incomingCE.getEntityKey() == null) {
                CombatEpisode newCE= new CombatEpisode();
                this.getMergeRuleService().mergeCombatEpisode(incomingCE,newCE);
                onFileMS.addCombatEpisode(newCE);
            } else {
                CombatEpisode onFileCE = (CombatEpisode)onFileMS.getCombatEpisodeByEntityKey(incomingCE.getEntityKey());
                this.getMergeRuleService().mergeCombatEpisode(incomingCE,onFileCE);
            }
        }

        //Remove the user deleted combat episodes
        Set onFileCEs = new HashSet(onFileMS.getCombatEpisodes());
        for(Iterator iter=onFileCEs.iterator(); iter.hasNext();) {
            CombatEpisode onFileCE = (CombatEpisode)iter.next();
            if(onFileCE.getEntityKey() != null && incomingMS.getCombatEpisodeByEntityKey(onFileCE.getEntityKey()) == null) {
                onFileMS.removeCombatEpisode(onFileCE);
            }
        }
         */
    }

    /**
     * Update combat episods received from VSSC
     * @param incomingMS
     * @param onFileMS
     */
    private void updateCombatEpisodesFromVSSC(MilitaryService incomingMS, MilitaryService onFileMS){
    	//get the result object to update
    	LoadVSSCDataResult result = getLoadVSSCDataResult();

        //Set onFileCEs = new HashSet(onFileMS.getCombatEpisodes());
        Set incomingCEs = incomingMS.getCombatEpisodes();

        //if ESR doesn't have any data upload the data
        //This is implemented indirectly when nomatch is found on onFileMS

        for(Iterator iter=incomingCEs.iterator(); iter.hasNext();) {
            CombatEpisode incomingCE = (CombatEpisode)iter.next();

            CombatEpisode onFileCE =
            	this.getExactMatchingCombatEpisode(incomingCE,onFileMS.getCombatEpisodes());

            //If an exact match is found ignore the record
            if (onFileCE != null) {
            	//update result status to ignored (duplicate) and process next record
            	result.incrementRejected(incomingCE);
            	continue;
            }

            //If VSSC data is not overallpping update esr
            List overLappingEpisodes =
            	getOverlappingEpisodes(incomingCE,onFileMS.getCombatEpisodes());

            //Multiple overlapping episodes
            if (overLappingEpisodes.size() > 1) {
            	//error ignore data
            	result.incrementRejected(incomingCE);
            }
            //No overlapping episodes
            else if (overLappingEpisodes.size() == 0){
                onFileCE = new CombatEpisode();
                this.getMergeRuleService().mergeCombatEpisode(incomingCE,onFileCE);
                onFileMS.addCombatEpisode(onFileCE);
                //update result status to accepted
                result.incrementAccepted(incomingCE);
                continue;
            }
            //single overlapping episode - extend(adjust dates in esr)
            else {
            	//case 1: extend the end date
            	onFileCE = (CombatEpisode)overLappingEpisodes.get(0);
            	if (this.isEqual(incomingCE.getStartDate(),onFileCE.getStartDate()) &&
                    this.isAfter(incomingCE.getEndDate().getCalendar().getTime(),
                    		onFileCE.getEndDate().getCalendar().getTime()))
            	{
            		onFileCE.setEndDate(incomingCE.getEndDate());
            		onFileCE.setOEFOIFSource(incomingCE.getOEFOIFSource());
            		onFileCE.setCombatPayType(incomingCE.getCombatPayType());
            		//If onfile has unknown oefoif or conflict unspecified accept
            		if (ConflictLocation.CODE_CONFLICT_UNSPECIFIED.getCode().equals(
            				onFileCE.getConflictLocation().getCode()) ||
            				ConflictLocation.CODE_UNKNOWN_OEF_OIF.getCode().equals(
                    				onFileCE.getConflictLocation().getCode()))
            		{
            			if (ConflictLocation.CODE_OEF.getCode().equals(
            					incomingCE.getConflictLocation().getCode()) ||
                				ConflictLocation.CODE_OIF.getCode().equals(
                						incomingCE.getConflictLocation().getCode()))
                		{
                			onFileCE.setConflictLocation(incomingCE.getConflictLocation());
                		}
            		}
            		//Accepted update count
            		result.incrementAccepted(incomingCE);
            		continue;
            	}
            	//case 2: extend the end date
            	if (onFileCE.getOEFOIFStationNumber() != null ||
            			(onFileCE.getOEFOIFSource() != null &&
            			OEFOIFSource.CODE_CENTRALIZED_ELIGIBILITY_VERIFICATION.getCode().equals(
            			onFileCE.getOEFOIFSource().getCode())))
            	{
            		Calendar onFileStart = onFileCE.getStartDate().getCalendar();
            		Calendar incomingStart = incomingCE.getStartDate().getCalendar();

            		if (onFileStart.get(Calendar.YEAR) == incomingStart.get(Calendar.YEAR) &&
            				onFileStart.get(Calendar.MONTH) == incomingStart.get(Calendar.MONTH) &&
            				onFileStart.get(Calendar.DAY_OF_MONTH) > 1 &&
            				this.isAfter(incomingCE.getEndDate().getCalendar().getTime(),
                    		onFileCE.getEndDate().getCalendar().getTime()))
            		{
                		onFileCE.setEndDate(incomingCE.getEndDate());
                		if (onFileCE.getOEFOIFSource() == null ||
                			!OEFOIFSource.CODE_CENTRALIZED_ELIGIBILITY_VERIFICATION.getCode().equals(
                            			onFileCE.getOEFOIFSource().getCode()))
                        {
                			//accept oefoif source
                			onFileCE.setOEFOIFSource(incomingCE.getOEFOIFSource());
                        }
                		onFileCE.setCombatPayType(incomingCE.getCombatPayType());
                		//If onfile has unknown oefoif or conflict unspecified accept
                		if (ConflictLocation.CODE_CONFLICT_UNSPECIFIED.getCode().equals(
                				onFileCE.getConflictLocation().getCode()) ||
                				ConflictLocation.CODE_UNKNOWN_OEF_OIF.getCode().equals(
                        				onFileCE.getConflictLocation().getCode()))
                		{
                			if (ConflictLocation.CODE_OEF.getCode().equals(
                					incomingCE.getConflictLocation().getCode()) ||
                    				ConflictLocation.CODE_OIF.getCode().equals(
                    						incomingCE.getConflictLocation().getCode()))
                    		{
                    			onFileCE.setConflictLocation(incomingCE.getConflictLocation());
                    		}
                		}
                		//Update result count
                		result.incrementAccepted(incomingCE);
                		continue;
            		}
            	}
            	//Rejected doesn't meet the conditions for update
            	result.incrementRejected(incomingCE);
            }
        }
    }

    /**
     * Get Matching episode by comparing start and end dates
     * @param incomingCE
     * @param onFileCEs
     * @return
     */
    private CombatEpisode getMatchingCombatEpisode(CombatEpisode incomingCE,Set onFileCEs) {
        for(Iterator iter=onFileCEs.iterator(); iter.hasNext();) {
            CombatEpisode onFileCE = (CombatEpisode)iter.next();
            if(this.isEqual(incomingCE.getStartDate(),onFileCE.getStartDate()) &&
               this.isEqual(incomingCE.getEndDate(),onFileCE.getEndDate())) {
                return onFileCE;
            }
        }
        return null;
    }

    /**
     * Get Matching episode by comparing location, start and end dates (VSSC)
     * @param incomingCE
     * @param onFileCEs
     * @return
     */
    private CombatEpisode getExactMatchingCombatEpisode(CombatEpisode incomingCE,Set onFileCEs) {
        for(Iterator iter=onFileCEs.iterator(); iter.hasNext();) {
            CombatEpisode onFileCE = (CombatEpisode)iter.next();
            if(this.isEqual(incomingCE.getConflictLocation(),onFileCE.getConflictLocation()) &&
               this.isEqual(incomingCE.getStartDate(),onFileCE.getStartDate()) &&
               this.isEqual(incomingCE.getEndDate(),onFileCE.getEndDate()) &&
               this.isEqual(incomingCE.getCombatPayType(),onFileCE.getCombatPayType()) &&
               this.isEqual(incomingCE.getOEFOIFSource(),onFileCE.getOEFOIFSource()) &&
               this.isEqual(incomingCE.getOEFOIFStationNumber(),onFileCE.getOEFOIFStationNumber()))
            {
                return onFileCE;
            }
        }
        return null;
    }

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#setMilitaryServiceInfoBySiteToReceived()
	 */
	public void setMilitaryServiceInfoBySiteToReceived() {
		// Replace the military service information object on the person on file
		// with what it is coming in from HEC or Vista

		// Create a military service information for the veteran on file
		// if one is not yet available.
		Person onFile = this.getResultPerson();
		MilitaryService currentMilitaryService = onFile.getMilitaryService();
		if( currentMilitaryService == null ) {
			onFile.setMilitaryService( (currentMilitaryService = new MilitaryService()) );
		}

		// Get the site data from incoming veteran.
		MilitaryService incomingMilitaryService = this.getMilitaryServiceInputData().getMilitaryService();
		if( incomingMilitaryService != null )
		{
			// An incoming military service should always has data because
			// If an incoming veteran doesn't military service information
			// the update process will have already stopped and removed
			// military service from an on file veteran
		    if(isUpdateFromGUI())
		    {
		        // For UI add/update only the HEC Site record
		        MilitaryServiceSiteRecord incomingHECSiteRecord = incomingMilitaryService.getHECMilitaryServiceSiteRecord();
		        if(incomingHECSiteRecord != null)
		        {
			        MilitaryServiceSiteRecord currentHECSiteRecord = currentMilitaryService.getHECMilitaryServiceSiteRecord();
			        if(currentHECSiteRecord == null)
			        {
			            currentHECSiteRecord = new MilitaryServiceSiteRecord();
			            this.getMergeRuleService().mergeMilitaryServiceSiteRecord(incomingHECSiteRecord,currentHECSiteRecord);
			            currentMilitaryService.addMilitaryServiceSiteRecord(currentHECSiteRecord);
			        }
			        else
			        {
			            this.getMergeRuleService().mergeMilitaryServiceSiteRecord(incomingHECSiteRecord,currentHECSiteRecord);
			        }
		        }
		    }
		    else
		    {
		        // For Messaging add/update only the incoming site record. The incoming military service object for messaging
		        // should have only one site record, but any way go in to loop.
		        Set incomingSiteRecords = incomingMilitaryService.getMilitaryServiceSiteRecords();
		        for(Iterator iter=incomingSiteRecords.iterator(); iter.hasNext();)
		        {
		            MilitaryServiceSiteRecord incomingSiteRecord = (MilitaryServiceSiteRecord)iter.next();
		            if(incomingSiteRecord != null)
		            {
			            MilitaryServiceSiteRecord currentSiteRecord = currentMilitaryService.getMilitaryServiceSiteRecordsBySite(incomingSiteRecord.getSite());
			            if(currentSiteRecord == null)
			            {
			                currentSiteRecord = new MilitaryServiceSiteRecord();
			                this.getMergeRuleService().mergeMilitaryServiceSiteRecord(incomingSiteRecord,currentSiteRecord);
			                currentMilitaryService.addMilitaryServiceSiteRecord(currentSiteRecord);
			            }
			            else
			            {
			                this.getMergeRuleService().mergeMilitaryServiceSiteRecord(incomingSiteRecord,currentSiteRecord);
			            }
		            }
		        }
		    }
		}
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#setCVEligibilityEndDate(java.util.Date)
	 */
	public void setCVEligibilityEndDate(Date date) {
		// Set a combat veteran elligibility end date in a veteran on file
		Person onFile = this.getResultPerson();
		MilitaryService currentMilitaryInfo = onFile.getMilitaryService();
		if( currentMilitaryInfo == null ) {
			// Create a military service to store a combat veteran
			// eligibility end date.  This method is called during
			// a process of replacing military service info on file
			// with the incoming data.
			onFile.setMilitaryService( (currentMilitaryInfo = new MilitaryService()) );
		}
		currentMilitaryInfo.setCombatVeteranEligibilityEndDate( date );
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#setDischargeDueToDisability(java.lang.String)
	 */
	public void setDischargeDueToDisability( Boolean flag ) {
		// Set a combat veteran elligibility end date in a veteran on file
		Person onFile = this.getResultPerson();
		MilitaryService currentMilitaryInfo = onFile.getMilitaryService();
		if( currentMilitaryInfo == null ) {
			// Create a military service to store a discharge due to
			// disability flag.  This method is called during a process
			// of replacing military service info on file with the incoming data.
			onFile.setMilitaryService( (currentMilitaryInfo = new MilitaryService()) );
		}
		currentMilitaryInfo.setDischargeDueToDisability( flag );
	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#setMilitaryDisabilityRetirement(java.lang.String)
	 */
	public void setMilitaryDisabilityRetirement( Boolean flag ) {
		// Set the on file person with incoming disability flag
		Person onFile = this.getResultPerson();
		MilitaryService ms = onFile.getMilitaryService();
		if( ms == null ) {
			// Create a military service to store a disability
			// retirement flag.  This method is called during
			// a process of replacing military service info
			// on file with the incoming data.
			onFile.setMilitaryService( (ms = new MilitaryService()) );
		}
		ms.setDisabilityRetirementIndicator( flag );
	}

    /*
     * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getShad()
     */
    public SHAD getShad() {
        return this.getShad(this.getIncomingPerson());
    }

    /*
     * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getShadIndicator()
     */
    public String getShadIndicator() throws ServiceException {
        SHAD shad = this.getShad();
        return (shad != null && shad.getShadIndicator() != null) ? shad.getShadIndicator().getCode() : null;
    }

    /*
     * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getPristineShadIndicator()
     */
    public String getPristineShadIndicator() throws ServiceException {
        SHAD shad = this.getShad(this.getPristinePerson());
        return (shad != null && shad.getShadIndicator() != null) ? shad.getShadIndicator().getCode() : null;
    }

    /*
     * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setShadIndicator()
     */
    public void setShadIndicator(String indicator) throws ServiceException {
        SHAD shad = this.getShad(this.getResultPerson());
        if(shad == null) {
            shad = new SHAD();
            this.getResultPerson().setShad(shad);
        }
        Indicator ind = (Indicator)this.getLookupService().getByCode(Indicator.class,Indicator.NO.getCode());
        shad.setShadIndicator(ind);
    }

    /*
     * @see gov.va.med.esr.common.rule.MilitaryServiceInput#updateShad()
     */
    public void setShad(SHAD shad) throws ServiceException {
        Person onFile = this.getResultPerson();
        if(shad != null) {
            SHAD onFileShad = this.getShad(onFile);
            if(onFileShad == null) {
                onFileShad = new SHAD();
                onFile.setShad(onFileShad);
            }
            onFileShad.setShadIndicator(shad.getShadIndicator());
        }
        else {
            onFile.setShad(null);
        }
    }

	/** Checks if a MSE's date range is inclusive of a from and to date
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#hasAMSEWithinDateRange(boolean,
	 *      java.util.Date, java.util.Date)
	 */
	public boolean hasAMSEWithinDateRange(boolean useHECEnteredMSEDate,
										  Date fromDate,
										  Date toDate ) throws ServiceException {
		// useHECEnteredMSEData -
		// if True look only at MSE Data enterd by HEC
		// if False, look at MSE data for all VAMC sites
		// fromDate - toDate range is inclusive of
		// if either date is null, assume current date
		boolean found = false;
        MilitaryServiceInputData data = this.getMilitaryServiceInputData();
        MilitaryService ms = data != null ? data.getMilitaryService() : getIncomingPerson().getMilitaryService();
        if( ms != null ) {
            if( useHECEnteredMSEDate ) {
				MilitaryServiceSiteRecord hecRecord = ms.getHECMilitaryServiceSiteRecord();
				if( hecRecord != null ) {
					found = this.isOverlapped( hecRecord.getMilitaryServiceEpisodes(), fromDate, toDate );
				}
            } else {
				Set records = ms.getMilitaryServiceSiteRecords();
				Iterator i = records != null ? records.iterator() : null;
				while( i != null && i.hasNext() ) {
					MilitaryServiceSiteRecord mssr = (MilitaryServiceSiteRecord)i.next();
					VAFacility facility = mssr.getSite();
					if( facility != null && !facility.getCode().equals( VAFacility.CODE_HEC ) ) {
						found = this.isOverlapped( mssr.getMilitaryServiceEpisodes(), fromDate, toDate );
						if( found ) {
							break;
						}
					}
				}
            }
        }
		return found;
	}


    /**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#hasHECMSEwithinDateRange(gov.va.med.esr.common.model.person.Person, java.util.Date, java.util.Date)
	 */
	public boolean hasHECMSEwithinDateRange(Person person, Date fromDate, Date toDate) throws ServiceException {
		// This strictly uses HEC episodes only.
        Set msEpisodes = this.getHECMSEs(person.getMilitaryService());
        return (msEpisodes != null && !msEpisodes.isEmpty()) ?
        		this.isOverlapped(msEpisodes,fromDate,toDate) : false;
	}

	/**
     * Checks if a MSE's date range is inclusive of a from and to date
	 *
     * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#hasAMSEWithinDateRange(java.util.Date, java.util.Date)
     */
    public boolean hasAMSEWithinDateRange(Date fromDate,Date toDate) throws ServiceException {

        // If True look only at MSE Data enterd by HEC if False, look at MSE data for all VAMC sites
        // fromDate - toDate range is inclusive of if either date is null, assume current date
        MilitaryService ms = null;
        if(this.isUpdateFromGUI() || this.isMessageFromVOA()) { //CCR 12551 added VOA
            MilitaryServiceInputData data = this.getMilitaryServiceInputData();
            ms = (data != null) ? data.getMilitaryService() : this.getIncomingPerson().getMilitaryService();
        } else {
            //Because person coming from messaging client only has site entered MSEs use on file HEC MSEs(if present)
            ms = this.getResultPerson().getMilitaryService();
        }
        Set msEpisodes = this.getHECMSEs(ms);
        msEpisodes = (msEpisodes == null || msEpisodes.isEmpty()) ? this.getSiteMSEs(ms) : msEpisodes;
        return this.isOverlapped(msEpisodes,fromDate,toDate);
    }


	/**
	 * Sets military service site record from HEC to the specific period of service
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#setHECPeriodOfService(java.lang.String)
	 */
	public void setHECPeriodOfService( String pos ) throws ServiceException {

		// Update period of service in both incoming and on file for UI purpose
		this.updatePeriodOfService( this.getResultPerson(), pos );
		this.updatePeriodOfService( this.getIncomingPerson(), pos );
	}


	/**
	 * Sets military service site record from HEC to the specific period of service
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#setHECPeriodOfService(java.lang.String)
	 */
	public void setVOAPeriodOfService( String pos ) throws ServiceException { //CCR 12551 added VOA

		// Update period of service on file for VOA purpose
		//If the on file site POS is more recent than the calculated POS (based on the top-down order of the above table),
		//then do not overwrite the site’s on file POS.
		this.updateVOAPeriodOfService( this.getResultPerson(), pos );
	}

	/**
	 * Indicates whether or not there are MSEs from HEC
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#hasHECEnteredMilitaryServiceEpisodes()
	 */
	public boolean hasHECEnteredMilitaryServiceEpisodes() throws ServiceException {

		if(  this.hasHECMSERecords == null ) {
			// Get incoming military service
            MilitaryServiceInputData data = this.getMilitaryServiceInputData();
            MilitaryService ms = (data != null) ? data.getMilitaryService() : this.getIncomingPerson().getMilitaryService();
            Set msEpisodes = this.getHECMSEs(ms);
            if(msEpisodes != null && !msEpisodes.isEmpty()) {
                this.hasHECMSERecords = Boolean.TRUE;
            }
		}
		return this.hasHECMSERecords != null ? this.hasHECMSERecords.booleanValue() : false;
	}

    /**
     * Indicates whether or not there are MSEs from HEC
     * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#hasHECEnteredMilitaryServiceEpisodesOnFile()
     */
    public boolean hasHECEnteredMilitaryServiceEpisodesOnFile() throws ServiceException {

        if(  this.hasHECMSERecordsOnFile == null ) {
            // Get incoming military service
            Set msEpisodes = this.getHECMSEs(this.getResultPerson().getMilitaryService());
            if(msEpisodes != null && !msEpisodes.isEmpty()) {
                this.hasHECMSERecordsOnFile = Boolean.TRUE;
            }
        }
        return this.hasHECMSERecordsOnFile != null ? this.hasHECMSERecordsOnFile.booleanValue() : false;
    }

    /**
     * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#hasVAMCEnteredMilitaryServiceEpisodes()
     */
    public boolean hasVAMCEnteredMilitaryServiceEpisodes() throws ServiceException {
        if(  this.hasVAMCMSERecords == null ) {
            // Get all the incoming site MSEs
            MilitaryServiceInputData data = this.getMilitaryServiceInputData();
            MilitaryService ms = (data != null) ? data.getMilitaryService() : this.getIncomingPerson().getMilitaryService();
            Set msEpisodes =  this.getSiteMSEs(ms);
            if(msEpisodes != null && !msEpisodes.isEmpty()) {
                this.hasVAMCMSERecords = Boolean.TRUE;
            }
        }
        return this.hasVAMCMSERecords != null ? this.hasVAMCMSERecords.booleanValue() : false;
    }

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#hasVAMCEnteredMilitaryServiceEpisodesOnFile()
	 */
	public boolean hasVAMCEnteredMilitaryServiceEpisodesOnFile() throws ServiceException {
		if(  this.hasVAMCMSERecordsOnFile == null ) {
			// Get all the site MSEs on file
            Set msEpisodes =  this.getSiteMSEs(this.getResultPerson().getMilitaryService());
            if(msEpisodes != null && !msEpisodes.isEmpty()) {
                this.hasVAMCMSERecordsOnFile = Boolean.TRUE;
            }
		}
		return this.hasVAMCMSERecordsOnFile != null ? this.hasVAMCMSERecordsOnFile.booleanValue() : false;
	}

    private Set getHECMSEs(MilitaryService ms) throws ServiceException {
        if(ms != null) {
            MilitaryServiceSiteRecord mssRecord = ms.getHECMilitaryServiceSiteRecord();
            return mssRecord != null ? mssRecord.getMilitaryServiceEpisodes() : null;
        }
        return null;
    }


    /********************* new CV End date due to NDAA -BEGIN **************/

    public boolean hasNoEnrollRecordPriorNDAA(String ndaaDate)  throws ServiceException
    {
        try {
            return !this.getEligibilityEnrollmentService().hasAnyEnrollmentRecordBeforeDate(
            		this.getIncomingPerson().getEntityKey(), this.getNDAADate(ndaaDate));
        }
        catch( RuleException ex ) {
            throw new ServiceException("Error getting enrollment record before NDAA", ex);
        }
    }
    /*
     * The enrollment status on the CURRENT enrollment record is
     * Rejected; Below Enrollment Group Threshold or Rejected; Initial Application at VAMC
     */
/*    public boolean isCurrEnrollRejectedBelowEGTOrInitApplVAMC() throws ServiceException
    {
        String code = null;
//        try {
           EnrollmentStatus enrollmentStatus = getHelperService().getEnrollmentStatus(
        		   this.getPristinePerson());
           code = ( enrollmentStatus != null ) ? enrollmentStatus.getCode() : null;
        }
        catch( ServiceException e ) {
           throw new RuleException(
                 "Failed to get a process state of type enrollment status", e);
        }

        if (code != null &&
        		(code.equals(EnrollmentStatus.CODE_REJECTED_BELOW_ENROLLMENT_GROUP_THRESHOLD.getCode()) ||
        		 code.equals(EnrollmentStatus.CODE_REJECTED_INITIAL_APPLICATION_BY_VAMC.getCode())) )
        {
        	return true;
        }

        return false;
    }*/


    /*
     * get the most recent of [SSD (if one exists) or Combat To Date]
     * 	From: 	Sheppard, Laurie (EDS)
		Sent:	Thursday, February 28, 2008 10:28 AM
		To:	Tsai, George (EDS)
		Cc:	Brownrigg, Peter (EDS); Ryan, Thomas (EDS); Innis, John (EDS); Ickes, Melissa (OIFO)
		Subject:	RE: CV End Date - they've changed it again!!

		Essentially, but we should never see the conflict to date in Option 1 being later
		than the SSD.  A combat episode outside of the MSE should only be possible for
		Option 2.  I have no problem in terms of selecting the later of
		[SSD or Combat To Date] if you only check combat_episode for that reason.

     */
    public Date getMostRecentSSDOrCombatToDate()
    {
        Date ssdDt = this.getMostRecentReceivedSSD();
        Date ceEndDt = this.getMostRecentReceivedCombatEpisodeEndDate();

        if (ssdDt == null)
        {
        	return ceEndDt;
        }

        if (ceEndDt == null)
        {
            return ssdDt;
        }

        return ssdDt.after(ceEndDt) ? ssdDt : ceEndDt;
    }

    public Date getMostRecentSSDOrCombatEndDatePlus5YearsMinus1Day()
    {
    	return getDatePlus5YearsMinus1Day(getMostRecentSSDOrCombatToDate());
    }

    private Date getDatePlus5YearsMinus1Day(Date date) {
        if( date != null ) {
            Calendar calendar = Calendar.getInstance();
            calendar.clear();
            calendar.setTime( date );
            calendar.add(Calendar.YEAR,5);
            calendar.add(Calendar.DATE,-1);
            return calendar.getTime();
        }
        return null;
    }


    /**
     * Loops through a collection of conflict experience to find the most
     * recent one by end date.  If found,
     * check if the most recent conflict's end date is after the specific date
     *
     * @see gov.va.med.esr.common.rule.MilitaryServiceInput#isMostRecentConflictToDateAfterForLocation(java.util.Date, java.lang.String)
     */
    public boolean isMostRecentConflictToDateAfter( Date date) {

        if (date == null)
        {
            return false;
        }

        boolean mostRecent = false;

        // Get an updated military service (after incoming data is merged)
        MilitaryService ms = this.getResultPerson().getMilitaryService();
        if( ms != null ) {

            // A temp collection to hold all conflicts
            HashSet conflicts = new HashSet();

            // Get all site records
            Set records = ms.getMilitaryServiceSiteRecords();

            // Loop through all site records to put all MSEs in a temp collection
            // to search for the most recent CE by service separation date.
            Iterator i = records != null ? records.iterator() : null;
            while( i != null && i.hasNext() ) {
                MilitaryServiceSiteRecord site_record = (MilitaryServiceSiteRecord)i.next();
                Set site_conflicts = (site_record != null) ? site_record.getConflictExperiences() : null;
                if(site_conflicts != null && !site_conflicts.isEmpty()) {
                    conflicts.addAll( site_conflicts );
                }
            }

            // Now use a collection comparator to search for a conflict experience
            // with the most recent end date.  If found, check if a conflict's location
            // is the specific location and if a conflict's end date is after the specific date
            CombatEpisodeComparator comparator = new CombatEpisodeComparator();
            if( !conflicts.isEmpty() ) {
                ConflictExperience conflict = (ConflictExperience)Collections.max( conflicts, comparator );
                if( conflict != null ) {
                    Date toDate = ImpreciseDateUtils.getDateWithDefault( conflict.getEndDate() );
                    if( toDate != null &&
                        toDate.after( date ) ) {
                        mostRecent = true;
                    }
                }
            }
        }
        return mostRecent;
    }



    /********************* new CV End date due to NDAA -END **************/

    private Set getSiteMSEs(MilitaryService ms) throws ServiceException {
        Set mses = new HashSet();
        MilitaryServiceSiteRecord hecMSSRecord = ms.getHECMilitaryServiceSiteRecord();
        Set records = (ms != null) ? ms.getMilitaryServiceSiteRecords() : null;
        if(records != null) {
            for(Iterator iter=records.iterator(); iter.hasNext();) {
                MilitaryServiceSiteRecord siteMSSRecord = (MilitaryServiceSiteRecord)iter.next();
                if(hecMSSRecord == null || (!hecMSSRecord.equals(siteMSSRecord))) {
                    mses.addAll(siteMSSRecord.getMilitaryServiceEpisodes());
                }
            }
        }
        return mses;
    }


    private SHAD getShad(Person person) {
        return (person != null) ? person.getShad() : null;
    }

	/**
	 * This method is for validations. The MilitaryServiceInputData must be used
	 * as input.
	 *
	 * @return the ConflictExperience
	 */
	private AbstractCombatEpisode getCE() {
		return (this.getMilitaryServiceInputData() != null) ? this.getMilitaryServiceInputData().getIncomingConflictExperience() : null;
	}

	/**
	 * This method is for validations. The MilitaryServiceInputData must be used
	 * as input.
	 *
	 * @return the incoming MilitaryServiceEpisode
	 */
	private MilitaryServiceEpisode getMilitaryServiceEpisode() {
		// CCR 11407 - Don't use lazy init load since it reduces flexibility in ILOG loops.
		this.militaryServiceEpisode = (this.getMilitaryServiceInputData() != null) ? this
					.getMilitaryServiceInputData().getIncomingMilitaryServiceEpisode() : null;
		return this.militaryServiceEpisode;
	}

	/**
	 *
	 * @param person
	 * @return
	 */
	private Boolean getWasPrisonerOfWar(Person person) {
		if (person != null) {
            PrisonerOfWar pow = person.getPrisonerOfWar();
			if(pow != null && pow.getPowIndicator() != null) {
                return pow.getPowIndicator().toBoolean();
            }
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getCombatVeteranEligibilityEndDate(gov.va.med.esr.common.model.person.Person)
	 */
	public Date getCombatVeteranEligibilityEndDate(Person person) {
		MilitaryService militaryService = (person != null) ? person
				.getMilitaryService() : null;
		return (militaryService != null) ? militaryService
				.getCombatVeteranEligibilityEndDate() : null;
	}

	private boolean isOverlapped( Set episodes, Date fromDate, Date toDate ) {

		boolean found = false;
		if( episodes != null ) {
			for( Iterator i=episodes.iterator(); i.hasNext(); ) {
				MilitaryServiceEpisode episode = (MilitaryServiceEpisode)i.next();
				if( this.isOverlapped( ImpreciseDateUtils.getDateWithDefault( episode.getStartDate() ),
											  ImpreciseDateUtils.getDateWithDefault( episode.getEndDate() ),
											  fromDate,
											  toDate ) ) {
					found = true;
					break;
				}
			}
		}
		return found;
	}

	private boolean isInRange(Date startDate,Date endDate,Date lower_range,Date upper_range)
	{
	    if( startDate != null && endDate != null && lower_range != null &&  upper_range != null &&
	        (startDate.equals(endDate) || startDate.before(endDate))&&
	        (lower_range.equals(upper_range) || lower_range.before(upper_range)))
	    {
	        if( (startDate.equals(lower_range) || startDate.after(lower_range)) &&
	            (startDate.equals(upper_range) || startDate.before(upper_range)) &&
	            (endDate.equals(lower_range)   || endDate.after(lower_range)) &&
	            (endDate.equals(upper_range)   || endDate.before(upper_range)) )
	        {
	            return true;
	        }
	    }
	    return false;
	}

	/**
	 * Calculates if a start and end date overlaps the lower and upper range
	 * @param startDate
	 * @param endDate
	 * @param lower_range
	 * @param upper_range
	 * @return
	 */
	private boolean isOverlapped( Date startDate,
										   Date endDate,
											Date lower_range,
											Date upper_range ) {

		boolean overlapped = false;

		if( startDate != null && endDate != null && lower_range != null && upper_range != null ) {

            // If the start = lower or end = upper or start = upper or end = lower
            if(startDate.equals( lower_range ) || startDate.equals( upper_range ) || endDate.equals( lower_range ) || endDate.equals( upper_range ) ) {
                overlapped = true;
            }
			// start < lower < upper < end
            else if( startDate.before( lower_range ) && lower_range.before( upper_range ) && upper_range.before( endDate ) ) {
				overlapped = true;
			}
			// start < lower < end < upper
			else if( startDate.before( lower_range ) && lower_range.before( endDate ) && endDate.before( upper_range ) ) {
				overlapped = true;
			}
			// lower < start < upper < end
			else if( lower_range.before( startDate ) && startDate.before( upper_range ) && upper_range.before( endDate ) ) {
				overlapped = true;
			}
			// lower < start < end < upper
			else if( lower_range.before( startDate ) && startDate.before( endDate ) && endDate.before( upper_range ) ) {
				overlapped = true;
			}
		}
		return overlapped;
	}

	/**
	 * @param servicePeriod
	 * @param person
	 * @return
	 */
	private boolean containsServicePeriod(String servicePeriod, Person person) {
		boolean found = false;
		MilitaryService militaryService = (person != null) ? person
				.getMilitaryService() : null;
		Set militaryServiceSiteRecords = (militaryService != null) ? militaryService
				.getMilitaryServiceSiteRecords()
				: null;
		if (militaryServiceSiteRecords != null
				&& militaryServiceSiteRecords.size() > 0) {
			Iterator iterMilitaryServiceSiteRecords = militaryServiceSiteRecords
					.iterator();
			while (iterMilitaryServiceSiteRecords.hasNext()) {
				MilitaryServiceSiteRecord militaryServiceSiteRecord = (MilitaryServiceSiteRecord) iterMilitaryServiceSiteRecords
						.next();
				if (militaryServiceSiteRecord.getServicePeriod() != null
						&& militaryServiceSiteRecord.getServicePeriod().getCode()
								.equals(servicePeriod)) {
					found = true;
					break;
				}
			}
		}
		return found;
	}

	/**
	 * Use this when doing validations where you need to access objects in
	 * piece-meal fashion or to access special input parameters.
	 *
	 * @return MilitaryServiceInputData
	 */
	private MilitaryServiceInputData getMilitaryServiceInputData() {
		RuleDataAware ruleDataAware = this.getRuleDataAware();
		if (ruleDataAware instanceof MilitaryServiceInputData) {
			return (MilitaryServiceInputData) ruleDataAware;
		}
		return null;
	}

	/** Updates a period of service on the specific person
	 *
	 * @param person A person to be updated
	 * @param pos A period of service
	 */
	private void updatePeriodOfService( Person person, String pos ) throws ServiceException {
		Validate.notNull( person, "A person to update period of service must not be NULL" );

		LookupService lookupService = this.getLookupService();
		// Get a service period
		ServicePeriod period = (StringUtils.isNotEmpty(pos)) ? lookupService.getServicePeriodByCode(pos) : null;

		MilitaryService ms = person.getMilitaryService();
		MilitaryServiceSiteRecord record = ms != null ? ms.getHECMilitaryServiceSiteRecord() : null;

		if( record != null ) {
			record.setServicePeriod( period );
		}
		else if(period != null) {
			record = new MilitaryServiceSiteRecord();
			record.setSite( lookupService.getVaFacilityByCode( VAFacility.CODE_HEC.getName() ) );

			if(ms == null) {
			    ms = new MilitaryService();
			    person.setMilitaryService(ms);
			}
			ms.addMilitaryServiceSiteRecord( record );
			record.setServicePeriod(period);
		}
	}

	/** Updates a VOA period of service on the specific person
	 * @param person A person to be updated
	 * @param pos A period of service
	 */
	private void updateVOAPeriodOfService( Person person, String pos ) throws ServiceException { ////CCR 12551 added VOA
		Validate.notNull( person, "A person to update period of service must not be NULL" );

		if (this.getIncomingPerson() == null || this.getIncomingPerson().getMilitaryService() == null || this.getIncomingPerson().getPreferredFacility() == null)
			return; //nothing to do

		String stationNum = this.getIncomingPerson().getPreferredFacility().getCode();

		LookupService lookupService = this.getLookupService();

		// Get a service period
		ServicePeriod period = (StringUtils.isNotEmpty(pos)) ? lookupService.getServicePeriodByCode(pos) : null;

		MilitaryService ms = person.getMilitaryService();
		MilitaryServiceSiteRecord record = ms != null ? ms.getMilitaryServiceSiteRecordsBySite(stationNum) : null;

		if( record != null ) {
			record.setServicePeriod( period );
		}
		else if(period != null) {
			record = new MilitaryServiceSiteRecord();
			record.setSite( this.getIncomingPerson().getPreferredFacility() );

			if(ms == null) {
			    ms = new MilitaryService();
			    person.setMilitaryService(ms);
			}
			ms.addMilitaryServiceSiteRecord( record );
			record.setServicePeriod(period);
		}
	}

	// START MSDS Final changes

	public Date getCombatPayEndDate() {
		return (getCombatService() != null && getCombatService().getPayEndDate() != null) ?
				ImpreciseDateUtils.getDateWithDefault(getCombatService().getPayEndDate()) : null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMostRecentCombatPayEndDate()
	 */
	public Date getMostRecentCombatPayEndDate() {
		// Find the most recent Combat Pay End Date after merging the incoming data
        MilitaryService ms = this.getResultPerson().getMilitaryService();
        Date endDate = null;

        Set combatPays = (ms != null) ? ms.getCombatServices() : new HashSet();

        // Now use a collection comparator
        if(!combatPays.isEmpty()) {
            CombatService cs = (CombatService)Collections.max( combatPays,new CombatServiceComparator());
            endDate = (cs != null) ? ImpreciseDateUtils.getDateWithDefault(cs.getPayEndDate()) : null;
        }
		return endDate;
	}

	public Date getCombatPayEndDateADR() {
		CombatService cs = this.getMatchedCombatPay();
		return (cs != null && cs.getPayEndDate() != null) ?
				ImpreciseDateUtils.getDateWithDefault(cs.getPayEndDate()) : null;
	}

	public boolean isCharacterOfDischargeOfLastNonbreakServiceEpisodeEqual(String code) throws ServiceException {
		NonBreakingEpisodesInfo info = this.determineNonbreakServiceEpisodeInfo(this.getResultPerson());
		MilitaryServiceEpisode mse = info.getLastMSE();
		String cd = (mse != null && mse.getDischargeType() != null) ? mse.getDischargeType().getCode() : null;
		return code != null ? code.equals(cd) : false;
	}

	public boolean isCharacterOfDischargeOfLastNonbreakServiceEpisodeEqual(String code, Set episodes) throws ServiceException {
		// CCR 11570
		NonBreakingEpisodesInfo info = this.determineNonbreakServiceEpisodeInfoFromSet(episodes);
		MilitaryServiceEpisode mse = info.getLastMSE();
		String cd = (mse != null && mse.getDischargeType() != null) ? mse.getDischargeType().getCode() : null;
		return code != null ? code.equals(cd) : false;
	}

	public void setHasQmse(boolean value) {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			((MilitaryServiceInputData)this.getRuleDataAware()).setHasQmse(value);
		}
	}

	public boolean hasQmse() {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			return ((MilitaryServiceInputData)this.getRuleDataAware()).hasQmse();
		}
		return false;
	}

	public String getMseCreatedBy() {
		MilitaryServiceEpisode mse = this.getMSEFromMSDS();
		return (mse != null && mse.getCreatedBy() != null) ? mse.getCreatedBy().getName() : null;
	}

	public String getActivationTerminationReasonCode() {
		MilitaryServiceEpisode mse = this.getMSEFromMSDS();
		if (mse == null) return null;
		Activation act = getActivationForServicePeriod(mse.getStartDate(), mse.getEndDate());
		return (act != null && act.getTerminationReason() != null)? act.getTerminationReason().getCode() : null;
	}

	private Activation getActivationForServicePeriod(ImpreciseDate begin, ImpreciseDate end) {
		Set activations = this.getActivations(this.getResultPerson());
		if (begin != null && end != null && activations != null && activations.size() > 0) {
			Date startDate = ImpreciseDateUtils.getDateWithDefault(begin);
			Date endDate = ImpreciseDateUtils.getDateWithDefault(end);
			Iterator itr = activations.iterator();
			while(itr != null && itr.hasNext()) {
				Activation activation = (Activation) itr.next();
				if (this.isOverlapped(activation.getActivationBeginDate(), activation.getActivationEndDate(),startDate, endDate)) {
					return activation;
				}
			}
		}
		return null;
	}
	public boolean hasMultNonbreakServiceEpisodeEQorGT24ContinuousMonths() throws ServiceException {
		NonBreakingEpisodesInfo info = this.determineNonbreakServiceEpisodeInfo(this.getResultPerson());
		return info.getCount() > 1 && info.meets24MonthCriteria();
	}

	private NonBreakingEpisodesInfo determineNonbreakServiceEpisodeInfoFromSet(Set episodes) {
		// Check the result person since the requirement expects that this occurs
		// after the data has been accepted.
		// Requirement: "MULTIPLE, non-breaking “service episodes” EXISTS AND IS EQUAL TO OR
		// GREATER THAN 24 continuous months."
		//
		NonBreakingEpisodesInfo info = new NonBreakingEpisodesInfo();
		if (episodes == null)
			return info;
		Set msEpisodes = episodes;
		int numberOfEpisodes = 1;

		if (msEpisodes != null && msEpisodes.size() > 0) {
			Date start = null;
			Date end = null;
			List list = sortMilitaryServiceEpisodes(msEpisodes);

			for (Iterator iter = list.iterator(); iter.hasNext();) {
				MilitaryServiceEpisode mse = (MilitaryServiceEpisode) iter
						.next();
				Date startTmp = ImpreciseDateUtils.getDateWithDefault(mse
						.getStartDate());
				Date endTmp = ImpreciseDateUtils.getDateWithDefault(mse
						.getEndDate());
				if (startTmp == null || endTmp == null)
					continue;
				// Initialize
				if (start == null) {
					start = startTmp;
					end = endTmp;
					info.setFirstMSE(mse);
				}
				// Determine contiguous episodes
				if (end != null && end.before(startTmp) && startTmp.before(endTmp)) {
					if (end.equals(getDateMinusOneDay(startTmp))) {
						// Met non-breaking criteria so slide the end date
						end = endTmp;
						numberOfEpisodes++;
						info.setLastMSE(mse); // Never know when it's last one
					} else {
						// Start the window again
						start = startTmp;
						end = endTmp;
					}
				}
				Date minDate = get24MonthDate(start);
				if ((end != null) && (end.equals(minDate) || end.after(minDate))) {
					info.setMeets24MonthCriteria(true);
				}
			}
			info.setCount(numberOfEpisodes);
		}
		return info;
	}

	private NonBreakingEpisodesInfo determineNonbreakServiceEpisodeInfo(Person person) throws ServiceException {
		if (person == null)
			return new NonBreakingEpisodesInfo();

		Set msEpisodes = this.getHECMSEs(person.getMilitaryService());
		return this.determineNonbreakServiceEpisodeInfoFromSet(msEpisodes);
	}
	/*
	private NonBreakingEpisodesInfo determineNonbreakServiceEpisodeInfo(Person person) throws ServiceException {
		// Check the result person since the requirement expects that this occurs
		// after the data has been accepted.
		// Requirement: "MULTIPLE, non-breaking “service episodes” EXISTS AND IS EQUAL TO OR
		// GREATER THAN 24 continuous months."
		//
		NonBreakingEpisodesInfo info = new NonBreakingEpisodesInfo();
		if (person == null)
			return info;
		Set msEpisodes = this.getHECMSEs(person.getMilitaryService());
		int numberOfEpisodes = 1;

		if (msEpisodes != null && msEpisodes.size() > 0) {
			boolean firstSet = false;
			Date start = null;
			Date end = null;
			List list = sortMilitaryServiceEpisodes(msEpisodes);

			for (Iterator iter = list.iterator(); iter.hasNext();) {
				MilitaryServiceEpisode mse = (MilitaryServiceEpisode) iter
						.next();
				Date startTmp = ImpreciseDateUtils.getDateWithDefault(mse
						.getStartDate());
				Date endTmp = ImpreciseDateUtils.getDateWithDefault(mse
						.getEndDate());
				if (startTmp == null || endTmp == null)
					continue;
				// Initialize
				if (start == null) {
					start = startTmp;
					end = endTmp;
					info.setFirstMSE(mse);
				}
				// Determine contiguous episodes
				if (end.before(startTmp) && startTmp.before(endTmp)) {
					if (end.equals(getDateMinusOneDay(startTmp))) {
						// Met non-breaking criteria so slide the end date
						end = endTmp;
						numberOfEpisodes++;
						info.setLastMSE(mse); // Never know when it's last one
					} else {
						// Start the window again
						start = startTmp;
						end = endTmp;
					}
				}
				Date minDate = get24MonthDate(start);
				if (end.equals(minDate) || end.after(minDate)) {
					info.setMeets24MonthCriteria(true);
				}
			}
			info.setCount(numberOfEpisodes);
		}
		return info;
	}
	*/
	private Date getDateMinusOneDay(Date date) {
		if (date == null) return null;
	    Calendar calendar = Calendar.getInstance();
        calendar.clear();
	    calendar.setTime(date);
	    calendar.add(Calendar.DATE, -1);
	    return calendar.getTime();
	}
	private Date get24MonthDate(Date date) {
		if (date == null) return null;
	    Calendar calendar = Calendar.getInstance();
        calendar.clear();
	    calendar.setTime(date);
	    int month = calendar.get(Calendar.MONTH);
	    month += 24;
	    calendar.set(Calendar.MONTH, month);
	    return calendar.getTime();
	}

	private List sortMilitaryServiceEpisodes(Set mses) {
		MilitaryServiceEpisodeComparator comparator = new MilitaryServiceEpisodeComparator();
		if (mses == null || mses.isEmpty()) return new ArrayList();
		List list = new ArrayList(mses);
	    Collections.sort(list,comparator);
	    return list;
	}

	public boolean isCharacterOfDischargeOfFirstNonbreakServiceEpisodeEqual(String code) throws ServiceException {
		//MULTIPLE, non-breaking “service episodes” EXISTS AND IS EQUAL TO OR GREATER THAN 24 continuous months,
		//Character of Discharge of the FIRST non-breaking “service episode” IS EQUAL “HON”
		NonBreakingEpisodesInfo info = this.determineNonbreakServiceEpisodeInfo(this.getResultPerson());
		MilitaryServiceEpisode mse = info.getFirstMSE();
		String cd = (mse != null && mse.getDischargeType() != null) ? mse.getDischargeType().getCode() : null;
		return code != null ? code.equals(cd) : false;
	}

	public boolean hasMultNonbreakServiceEpisode() throws ServiceException {
		NonBreakingEpisodesInfo info =
			this.determineNonbreakServiceEpisodeInfo(this.getResultPerson());
		return info.getCount() > 1;
	}

	public Date getEnteredOnDuty() {
		MilitaryServiceEpisode mse = this.getMSEFromMSDS();
		if (mse != null && mse.getStartDate() != null) {
			return ImpreciseDateUtils.getDateWithDefault(mse.getStartDate());
		}
		return null;
	}

	public boolean hasSingleServiceEpisodeEQorGT24ContinuousMonths() throws ServiceException {
		NonBreakingEpisodesInfo info =
			this.determineNonbreakServiceEpisodeInfo(this.getResultPerson());
		return info.getCount() == 1 && info.meets24MonthCriteria();
	}

	public boolean isAnyMilitaryServiceEpisodeEQorGT24Months(Set episodes) throws ServiceException {
		// CCR 11570
		// Keep in mind that VA considers contiguous episodes as equivalent to single episode
		// The term "non-breaking" means the periods run without any interruption
		NonBreakingEpisodesInfo info = this.determineNonbreakServiceEpisodeInfoFromSet(episodes);
		return info.meets24MonthCriteria();
	}

	public boolean isMilitaryServiceEpisodeEQorGT24Months(MilitaryServiceEpisode mse) throws ServiceException {
		// CCR 11570
		if (mse == null)
			return false;
		Set<MilitaryServiceEpisode> episodes = new HashSet<MilitaryServiceEpisode>();
		episodes.add(mse);
		NonBreakingEpisodesInfo info = this.determineNonbreakServiceEpisodeInfoFromSet(episodes);
		return info.getCount() == 1 && info.meets24MonthCriteria();
	}

	public boolean isPeriodOfServiceAtLeastOneDay(MilitaryServiceEpisode mse) throws ServiceException {
		// CCR 11570 - by VA customer definition, period with same start/end date is one day
		if (mse == null) return false;

		Date lower_range = (mse.getStartDate() != null) ? ImpreciseDateUtils.getDateWithDefault(mse.getStartDate()) : null;
		Date upper_range = (mse.getEndDate() != null) ? ImpreciseDateUtils.getDateWithDefault(mse.getEndDate()) : null;

		if (lower_range == null || upper_range == null) return false;

		return isAfterIgnoreTime(upper_range,lower_range) || isSameDay(lower_range,upper_range);

	}

	public CombatPayType getCombatPayType() {
		MilitaryServiceInputData data = getMilitaryServiceInputData();
		if (data != null) {
			CombatService cs = data.getCombatService();
			return cs != null ? cs.getCombatPayType() : null;
		}
		return null;
	}

	public boolean hasCombatPayMatch(CombatPayType type, Date begin) {
		//CCR10610 use result person
		Set combatServices = this.getCombatServices(this.getResultPerson());
		this.setMatchedCombatPay(null); // always reset since ILOG controls loop
		if (combatServices != null &&  combatServices.size() > 0 &&
				type != null && begin != null) {
			Iterator iter = combatServices.iterator();
			// Loop through a collection of episodes
			for( Iterator i=iter ; i.hasNext(); ) {
				CombatService cs = (CombatService)i.next();
				// Get a start and end date
				Date beginDate = (cs.getPayStartDate() != null) ?
						ImpreciseDateUtils.getDateWithDefault( cs.getPayStartDate()) : null;
				CombatPayType payType = (cs.getCombatPayType() != null) ? cs.getCombatPayType() : null;
				if (beginDate != null && payType != null && beginDate.equals(begin) &&
						payType.getCode().equals(type.getCode())) {
					this.setMatchedCombatPay(cs);
					return true;
				}
			}
		}
		return false;
	}

	public Date getDeploymentEndDate() {
		Deployment dep = this.getDeployment();
		return dep != null ? dep.getDeploymentEndDate(): null;
	}

	public Date getDeploymentEndDate(Person person) {
		Deployment dep = this.getDeployment();
		return dep != null ? dep.getDeploymentEndDate(): null;
	}


	public boolean hasDeploymentExactMatch(Deployment deployment) {
		// ALL elements must match
		return this.hasDeploymentExactOrSimpleMatch(deployment, null);
	}

	public String getCharacterOfServiceCode() {
		MilitaryServiceEpisode mse = this.getMSEFromMSDS();
		return (mse != null && mse.getDischargeType() != null) ? mse.getDischargeType().getCode() : null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMsdsServiceComponent()
	 */
	public String getMsdsServiceComponent() {
		MilitaryServiceEpisode mse = this.getMSEFromMSDS();
		return (mse != null && mse.getMilitaryServiceComponent() != null) ? mse.getMilitaryServiceComponent().getCode() : null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getHECMostRecentServiceComponent()
	 */
	public String getHECMostRecentServiceComponent() {
		// Uses the result person since that it contains the received data as well as original/updated
		MilitaryServiceEpisode mse = this.getHECMostRecentMSE(this.getResultPerson().getMilitaryService());
		return (mse != null && mse.getMilitaryServiceComponent() != null) ? mse.getMilitaryServiceComponent().getCode() : null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMsdsWorkItem()
	 */
	public String getMsdsWorkItem() {
		MilitaryServiceInputData data = getMilitaryServiceInputData();
		return (data != null) ? data.getMsdsWorkItem() : null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setMsdsWorkItem(java.lang.String)
	 */
	public void setMsdsWorkItem(String item) {
		MilitaryServiceInputData data = getMilitaryServiceInputData();
		if (data != null) {
			data.setMsdsWorkItem(item);
		}
	}

	public boolean isCombayPayPeriodLessThanADR(Date start, Date end) {
		if (start == null || end == null) {
			return true; // default when incoming is null
		}
		Set combatServices = this.getCombatServices(this.getPristinePerson());
	    if (combatServices != null &&  combatServices.size() > 0) {
	    	CombatService cs = (CombatService)Collections.max( combatServices,new CombatServiceComparator());
	        Date endDate = (cs != null) ? ImpreciseDateUtils.getDateWithDefault(cs.getPayEndDate()) : null;
	        Date startDate = (cs != null) ? ImpreciseDateUtils.getDateWithDefault(cs.getPayStartDate()) : null;
			if (startDate != null && endDate != null ) {
	            if (start.after(startDate) && start.before(endDate)) {
	            	return true;
	            }
			}
	    }
		return false;
	}

	public boolean isCombatPayPeriodLessThan(Date start, Date end) {
		/*
		 * Requirements: Combat Pay Start Date in the message IS GREATER THAN the Combat Pay
		 * Start Date in the repository (ADR) AND Combat Pay Start Date in the
		 * message IS LESS THAN the Combat Pay End Date in the repository (ADR)
		 */
		Set combatServices = this.getCombatServices(this.getPristinePerson());
		if( start != null && end != null && combatServices != null &&  combatServices.size() > 0) {

			Iterator iter = combatServices.iterator();

			// Loop through a collection of episodes
			for( Iterator i=iter ; i.hasNext(); ) {

				CombatService cs = (CombatService)i.next();

				// Get a start and end date
				Date lower_range = (cs.getPayStartDate() != null) ?
						ImpreciseDateUtils.getDateWithDefault( cs.getPayStartDate()) : null;

				Date upper_range = (cs.getPayEndDate() != null) ?
						ImpreciseDateUtils.getDateWithDefault(cs.getPayEndDate()) : null;

				if (lower_range != null && upper_range != null ) {
		            // If the start = lower or end = upper or start = upper or end = lower
		            if (start.after(lower_range) && start.before(end)) {
		            	return true;
		            }

				}
			}
		}
		return false;
	}

	public boolean hasServiceEpisodeWithOverlap(MilitaryServiceEpisode mse) throws ServiceException {
		if (mse == null) return false;
		Date fromDate = ImpreciseDateUtils.getDateWithDefault(mse.getStartDate());
		Date toDate = ImpreciseDateUtils.getDateWithDefault(mse.getEndDate());
		// Need to look at result person since process is contantly adding episodes
        Set msEpisodes = this.getHECMSEs(this.getResultPerson().getMilitaryService());
        return this.isOverlapped(msEpisodes,fromDate,toDate);
	}

	public MilitaryServiceEpisode getMSEFromMSDS() {
		// Don't store - need to get it each time
		MilitaryServiceInputData data = this.getMilitaryServiceInputData();
		MilitaryServiceEpisode mse = (data != null) ? data.getIncomingMilitaryServiceEpisode() : null;
		return mse;
	}

	public Date getMostRecentHECrecordSSD() {
		MilitaryServiceEpisode mse = this.getMatchedMSE();
		return (mse != null && mse.getEndDate() != null) ?
				ImpreciseDateUtils.getDateWithDefault( mse.getEndDate() ) : null;
	}

	/**
	 * Please note that was copied from an existing method with similar name, except that
	 * method was specific to incoming person and only returned a date. This method reuses the logic
	 * from the method and can be used in general way to obtain most recent MSE from any person. At
	 * the moment, the method is not available from ILOG mil serv virtual class, but is instead
	 * used from Java helper methods.
	 *
	 * @param person
	 * @return
	 */
	public MilitaryServiceEpisode getMostRecentMSE(Person person) {
			if (person == null) return null;

			MilitaryServiceEpisode mostRecentMSE = null;

			// need to loop thru all (updated)MSEs and return the Service Separation date which is most recent
			MilitaryService ms = person.getMilitaryService();
			if( ms != null ) {
				// A temp collection to hold all MSEs
				HashSet episodes = new HashSet();

				// Get all site records
				Set records = ms.getMilitaryServiceSiteRecords();

				// Loop through all site records to put all MSEs in a temp collection
				// to search for the most recent MSE by service separation date.
				Iterator i = records != null ? records.iterator() : null;
				while( i != null && i.hasNext() ) {
					MilitaryServiceSiteRecord site_record = (MilitaryServiceSiteRecord)i.next();
					Set site_episodes = (site_record != null) ? site_record.getMilitaryServiceEpisodes() : null;
					if(site_episodes != null && !site_episodes.isEmpty()) {
						episodes.addAll( site_episodes );
					}
				}

				// Now use a collection comparator to search for an MSE
				// with the most recent service separation date
				MilitaryServiceEpisodeComparator comparator = new MilitaryServiceEpisodeComparator();
				if( !episodes.isEmpty() ) {
					MilitaryServiceEpisode episode = (MilitaryServiceEpisode)Collections.max( episodes, comparator );
					mostRecentMSE = episode;
				}
			}

		return mostRecentMSE;
	}


	/* (non-Javadoc)
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMatchedServiceDischargeType(gov.va.med.esr.common.model.person.Person)
	 */
	public DischargeType getMatchedServiceDischargeType() {
		MilitaryServiceEpisode mse = this.getMatchedMSE();
		return mse != null ? mse.getDischargeType() : null;
	}

	/* (non-Javadoc)
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMatchedServiceDischargeTypeCode()
	 */
	public String getMatchedServiceDischargeTypeCode() {
		DischargeType type = this.getMatchedServiceDischargeType();
		return type != null ? type.getCode() : null;
	}

	public boolean hasDeployment(Person person) {
		Set activations = getActivations(person);
		if (activations != null && activations.size() > 0) {
			Iterator itr = activations.iterator();
			while(itr != null && itr.hasNext()) {
				Activation activation = (Activation) itr.next();
				if(activation.getDeployments() != null && activation.getDeployments().size() > 0) {
					return true;
				}
			}
		}
		return false;
	}

	public Deployment getDeployment() {
		MilitaryServiceInputData data = getMilitaryServiceInputData();
		return data != null ? data.getDeployment() : null;
	}

	private Set getActivations(Person person) {
		return (person != null && person.getMilitaryService() != null) ?
				person.getMilitaryService().getActivations() : null;


	}
	public CombatService getCombatService() {
		MilitaryServiceInputData data = getMilitaryServiceInputData();
		return (data != null && data.getCombatService() != null) ? data.getCombatService() : null;
	}

	public Activation getActivation() {
		MilitaryServiceInputData data = getMilitaryServiceInputData();
		return (data != null) ? data.getActivation() : null;
	}


	public boolean hasCombatService(Person person) {
		Set cServices = getCombatServices(person);
		return (cServices != null && cServices.size() > 0) ? true : false;
	}

	public Set getCombatServices(Person person) {
		return (person != null && person.getMilitaryService() != null) ? person.getMilitaryService().getCombatServices() : null;
	}
	public boolean hasCombatServiceWithOverlap(CombatService cs) {
		/*
		 * that OVERLAPS the data received in the message, based on the dates
		 * contained in the message. Use Result person to prevent accepting
		 * record that overlap.
		 */
		Set cServices = getCombatServices(getResultPerson());
		boolean found = false;
		if (cServices != null && cs != null) {
			Date start = ImpreciseDateUtils.getDateWithDefault(cs.getPayStartDate());
			Date end = ImpreciseDateUtils.getDateWithDefault(cs.getPayEndDate());
			for (Iterator i=cServices.iterator(); i.hasNext();) {
				CombatService combatService = (CombatService)i.next();
				if (this.isOverlapped(ImpreciseDateUtils.getDateWithDefault(combatService.getPayStartDate()),
						ImpreciseDateUtils.getDateWithDefault(combatService.getPayEndDate()), start, end)) {
					found = true;
					break;
				}
			}
		}
		return found;
	}

	public String getNameContingencyCode() {
		Activation activation = this.getActivation();
		return activation != null && activation.getNamedContingency() != null ? activation.getNamedContingency().getCode() : null;
	}

	public String getSpecialOperationCode() {
		Deployment dep = this.getDeployment();
		return (dep != null && dep.getSpecialOperation() != null) ? dep.getSpecialOperation().getCode(): null;
	}

	public String getTerminationReasonCode() {
		// From Deployment
		Deployment deployment = this.getDeployment();
		return (deployment != null && deployment.getTerminationReason() != null) ?
				deployment.getTerminationReason().getCode() : null;
	}

	public Date getActivationEndDate() {
		Activation activation = this.getActivation();
		return activation != null ? activation.getActivationEndDate() : null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMostRecentActivationEndDate()
	 */
	public Date getMostRecentActivationEndDate() {
        // Find the most recent Activation End Date after merging the incoming data
        MilitaryService ms = this.getResultPerson().getMilitaryService();
        Date endDate = null;

        Set activations = (ms != null) ? ms.getActivations() : new HashSet();

        // Now use a collection comparator
        if(!activations.isEmpty()) {
            Activation activation = (Activation)Collections.max( activations,new ActivationComparator());
            endDate = (activation != null) ? activation.getActivationEndDate() : null;
        }
		return endDate;
	}

	public Date getActivationEndDate(Person person) {
//		Activation activation = this.getActivation(person);
//		return activation != null ? activation.getActivationEndDate() : null;
		return null;
	}

	public Date getMatchedRADDate() {
		MilitaryServiceEpisode mse = this.getMatchedMSE(); // CCR10610 - always use matched record
		return (mse != null && mse.getEndDate() != null) ?
				ImpreciseDateUtils.getDateWithDefault( mse.getEndDate() ) : null;
	}

	public Date getRADDate() {
		MilitaryServiceEpisode mse = this.getMSEFromMSDS();
		return mse != null ? ImpreciseDateUtils.getDateWithDefault( mse.getEndDate() )  : null;
	}

	public MsdsCountry getDeploymentCountry() {
		Deployment deployment = this.getDeployment();
		return deployment != null ? deployment.getCountry() : null;
	}

	public Date getDeploymentBeginDate() {
		Deployment deployment = this.getDeployment();
		return deployment != null ? deployment.getDeploymentBeginDate() : null;
	}

	public String getCombatServiceSourceCode() {
		CombatService cs = this.getCombatService();
		return (cs != null && cs.getCombatServiceSource() != null) ?
				cs.getCombatServiceSource().getCode() : null;
	}

	public DischargeType getServiceDischargeType(Person person) {
		DischargeType type = null;
		MilitaryServiceEpisode mse = this.getMostRecentMSE(person);
		if( mse != null ) {
			type = mse.getDischargeType();
		}
		return type;
	}

	public void acceptCombatEpisodesFromVadir() {
		CombatEpisode ce = this.getCombatEpisode();
		CombatEpisode matched = this.getMatchedCombatEpisode();
		if (ce != null) {
			MilitaryService currentMilitaryService = this.getResultPerson().getMilitaryService();
			if (currentMilitaryService == null) {
				this.getResultPerson().setMilitaryService( (currentMilitaryService = new MilitaryService()) );
			}
			if (matched == null) {
				matched = new CombatEpisode();
				this.getResultPerson().getMilitaryService().addCombatEpisode(matched);
			}
			this.getMergeRuleService().mergeCombatEpisode(ce, matched);
		}
	}

	public void updateCombatPayData() {
		CombatService cs = this.getCombatService();
		CombatService matched = this.getMatchedCombatPay();
		if (cs != null && this.getResultPerson().getMilitaryService() != null) {
			if (matched == null) {
				matched = new CombatService();
				this.getResultPerson().getMilitaryService().addCombatService(matched);
			}
			this.getMergeRuleService().mergeCombatService(cs, matched);
		}
	}
	public void updateActivation() throws ServiceException {
		Activation act = this.getActivation();
		if (act == null) {
			return;
		}
		Activation matched = this.getMatchedActivationFromResult(act);
		if (matched == null) {
			matched = new Activation();
			MilitaryService currentMilitaryService = this.getResultPerson().getMilitaryService();
			if (currentMilitaryService == null) {
				this.getResultPerson().setMilitaryService( (currentMilitaryService = new MilitaryService()) );
			}

			this.getResultPerson().getMilitaryService().addActivation(matched);
		}
		this.getMergeRuleService().mergeActivation(act, matched);
	}
	private Activation getMatchedActivationFromResult(Activation incoming) {
		// There are no requirements for matching Activation. In future, an Activation will be
		// mapped to an ESR mse.
		Set activations = this.getActivations(this.getResultPerson());
		if (incoming != null && activations != null && activations.size() > 0) {
	        for(Iterator iter=activations.iterator(); iter.hasNext();) {
	            Activation activation = (Activation)iter.next();
	            Date begin = activation.getActivationBeginDate();
	            Date incomingBegin = incoming.getActivationBeginDate();
	            if (begin != null && incomingBegin != null) {
	            	if (begin.equals(incomingBegin)) {
	            		return activation;
	            	}
	            }
	        }
		}
		return null;
	}

	public void updateCombatPayEndDate() {
		CombatService cs = this.getMatchedCombatPay();
		CombatService incoming = this.getCombatService();
		if (cs != null && incoming != null) {
			cs.setPayEndDate(incoming.getPayEndDate());
		}
	}

	public void updateDeploymentData() throws ServiceException {
		Deployment deployment = this.getDeployment();
		Activation incomingActivation = this.getActivation();
		if (deployment == null || incomingActivation == null) {
			return; // There was nothing to save
		}
		Activation matchedActivationFromResult = this.getMatchedActivationFromResult(incomingActivation);
		if (matchedActivationFromResult == null) {
			matchedActivationFromResult = new Activation();
			this.getMergeRuleService().mergeActivation(incomingActivation, matchedActivationFromResult);
			Person resultPerson = this.getResultPerson();
			MilitaryService currentMilitaryService = resultPerson.getMilitaryService();
			if (currentMilitaryService == null) {
				resultPerson.setMilitaryService( (currentMilitaryService = new MilitaryService()) );
			}
			resultPerson.getMilitaryService().addActivation(matchedActivationFromResult);
		}

		Deployment matched = this.getMatchedDeployment();
		if (matched == null) {
			matched = new Deployment();
			matchedActivationFromResult.addDeployment(matched);
		}

		this.getMergeRuleService().mergeDeployment(deployment, matched);
	}

	public void updateDeploymentEndDate() {
		Deployment dep = this.getMatchedDeployment();
		Deployment incoming = this.getDeployment();
		if (dep != null && incoming != null) {
			dep.setDeploymentEndDate(incoming.getDeploymentEndDate());
		}
	}

	public MHDataSource getDeploymentSourceOfData() {
		Deployment deployment = this.getDeployment();
		return deployment != null ? deployment.getDataSource() : null;
	}

	public boolean hasCombatPayExactMatch(CombatService cp) {
		Set combatServices = this.getCombatServices(this.getResultPerson());
		CombatService csExactMatch = null;
		this.setMatchedCombatPay(null); // always reset since ILOG controls loop
		if (cp != null && combatServices != null) {
			csExactMatch = (CombatService)this.getMergeRuleService().getMatchRuleService().findMatchingElement(cp, combatServices);
			if (csExactMatch != null) {
				this.setMatchedCombatPay(csExactMatch);
			}
		}
		return csExactMatch != null ? true : false;
	}

	public void setDeploymentDateLastUpdated() {
		Deployment dep = this.getMatchedDeployment();
		Deployment incoming = this.getDeployment();
		if (dep != null && incoming != null) {
			dep.setModifiedOn(incoming.getModifiedOn());
		}
	}

	public void setDeploymentSourceOfData(MHDataSource source) {
		Deployment dep = this.getMatchedDeployment();
		Deployment incoming = this.getDeployment();
		if (dep != null && incoming != null) {
			dep.setDataSource(incoming.getDataSource());
		}
	}

	// CCR 11570
	public void setMsdsMessageDate() {
		// Use the Created On date of MSE as the message date. Will be used by VBA rules.
		MilitaryServiceEpisode mse = this.getMilitaryServiceEpisode();
		Date date = (mse != null) ? mse.getCreatedOn() : this.getCurrentDate();
		if (date != null) {
			MilitaryServiceInputData data = getMilitaryServiceInputData();
			if (data != null) {
				data.setMsdsMessageDate(ImpreciseDateUtils.createImpreciseDateWithoutTime(date));
			}
		}
	}

	public void setServiceEndDate() {
		MilitaryServiceEpisode mse = this.getMilitaryServiceEpisode();
		MilitaryServiceEpisode matched = getMatchedMSE();
		if (matched != null && mse != null) {
			matched.setEndDate(mse.getEndDate());
		}
	}

	public void setServiceEpisodeDateLastUpdated() {
		MilitaryServiceEpisode mse = this.getMilitaryServiceEpisode();
		MilitaryServiceEpisode matched = getMatchedMSE();
		if (matched != null && mse != null) {
			matched.setModifiedOn(mse.getModifiedOn());
		}
	}

	public void acceptServiceEpisodeFromMSDS()  throws ServiceException {
		if (this.getMilitaryServiceInputData() != null) {
			MilitaryServiceSiteRecord incomingHECSiteRecord = (this.getMilitaryServiceInputData().getMilitaryService() != null) ?
					this.getMilitaryServiceInputData().getMilitaryService().getHECMilitaryServiceSiteRecord() : null;

			if (incomingHECSiteRecord != null) {
				// Overview: For MSDS data, EST must never delete data. This means ESR needs to avoid using a merge that
				// deletes. This method only adds MSEs provided via the data object to rules.
				Person onFile = this.getResultPerson();
				MilitaryService currentMilitaryService = onFile.getMilitaryService();
				if (currentMilitaryService == null) {
					onFile.setMilitaryService( (currentMilitaryService = new MilitaryService()) );
				}
				MilitaryServiceSiteRecord currentHECSiteRecord = currentMilitaryService.getHECMilitaryServiceSiteRecord();
				if(currentHECSiteRecord == null) {
					currentHECSiteRecord = new MilitaryServiceSiteRecord();
					this.getMergeRuleService().mergeMilitaryServiceSiteRecord(incomingHECSiteRecord,currentHECSiteRecord);
					currentMilitaryService.addMilitaryServiceSiteRecord(currentHECSiteRecord);
				}
				MilitaryServiceEpisode toAdd = this.getMilitaryServiceInputData().getIncomingMilitaryServiceEpisode();
				if (toAdd != null) {
					MilitaryServiceEpisode mse = null;
					if (toAdd.getEntityKey() != null) {
						// check if it exists already
						mse = currentHECSiteRecord.getMilitaryServiceEpisodeByEntityKey(toAdd.getEntityKey());
					}
					if (mse == null) {
						// Check for match
						Set episodes = currentHECSiteRecord.getMilitaryServiceEpisodes();
						for (Iterator i = episodes.iterator(); i.hasNext();) {
							AbstractEntity obj = (AbstractEntity) i.next();
							if (this.getMergeRuleService().getMatchRuleService().match((AbstractEntity) obj, toAdd)) {
								mse = (MilitaryServiceEpisode)obj;
								break;
							}
						}
						if (mse == null) {
							mse = new MilitaryServiceEpisode();
							currentHECSiteRecord.addMilitaryServiceEpisode(mse);
						}
					}
					this.getMergeRuleService().mergeMilitaryServiceEpisode(toAdd, mse);
				}
			}
		}
	}

	public void setServiceEpisodeSourceOfData() {
		MilitaryServiceEpisode mse = this.getMilitaryServiceEpisode();
		// Update
		MilitaryServiceEpisode matched = getMatchedMSE();
		if (matched != null && mse != null) {
			// Placeholder since no source
		}
	}

	public MilitaryServiceEpisode getMatchedMSE() {
		 MilitaryServiceInputData data = getMilitaryServiceInputData();
		 return (data != null) ? data.getMatchedMSE() : null;
	}

	/**
	 * @return the matchedActivation
	 */
	public Activation getMatchedActivation() {
		 MilitaryServiceInputData data = getMilitaryServiceInputData();
		 return (data != null) ? data.getMatchedActivation() : null;
	}

	/**
	 * @param matchedActivation the matchedActivation to set
	 */
	public void setMatchedActivation(Activation matchedActivation) {
		 MilitaryServiceInputData data = getMilitaryServiceInputData();
		 if (data != null) {
			 data.setMatchedActivation(matchedActivation);
		 }
	}



	public boolean hasServiceEpisodeExactMatch()  throws ServiceException {
		/*Per requirements :
		 * Looks for an EXACT MATCH (all data elements) to the information contained in the “message”
		 **/
		MilitaryServiceEpisode mse = this.getMSEFromMSDS();
		// CCR 10610 - This needs to use result person
		Set mses = this.getHECMSEs(this.getResultPerson().getMilitaryService());
		this.setMatchedMSE(null); // always reset since ILOG controls loop
		MilitaryServiceEpisode mseExactMatch = null;
		if (mse != null && mses != null) {
			mseExactMatch = (MilitaryServiceEpisode)this.getMergeRuleService().getMatchRuleService().findMatchingElement(mse, mses);
			this.setMatchedMSE(mseExactMatch);
		}
		return mseExactMatch != null ? true : false;
	}

	public String getMSDSdataSource() {
		MilitaryServiceInputData data = getMilitaryServiceInputData();
		return data != null ? data.getMsdsDataSource() : null;
	}

	public void setCharacterOfDischarge(DischargeType type) {
		MilitaryServiceEpisode mse = this.getMatchedMSE();
		if (mse != null & type != null) {
			mse.setDischargeType(type);
		}
	}

	public void setCombatPayDateLastUpdated() {
		CombatService cs = this.getMatchedCombatPay();
		CombatService incoming = this.getCombatService();
		if (cs != null && incoming != null) {
			cs.setModifiedOn(incoming.getModifiedOn());
		}
	}

	public CombatServiceSource getCombatPaySourceOfData() {
		CombatService cs = this.getCombatService();
		return (cs != null && cs.getCombatServiceSource() != null) ? cs.getCombatServiceSource() : null;
	}

	public void setCombatPaySourceOfData(CombatServiceSource source) {
		CombatService cs = this.getMatchedCombatPay();
		CombatService incoming = this.getCombatService();
		if (cs != null && incoming != null) {
			cs.setCombatServiceSource(source);
		}
	}

	public void adjustMSDSImpreciseDates() {
		/*
		 * Combat Pay Start Date and Combat Pay End Date contained in the
		 * “message” can be imprecise, meaning in the format of MONTH & YEAR
		 * only.
		 *
		 * When the Combat Pay Start Date contained in the “message” is
		 * imprecise, the system will set the DAY to be the first day of the
		 * month.
		 *
		 * When the Combat Pay End Date contained in the “message” is imprecise,
		 * the system will set the DAY to be the last day of the month.
		 */
		CombatService cs = this.getCombatService();
		if (cs != null && cs.getPayEndDate() != null && cs.getPayStartDate() != null) {
			if (!cs.getPayStartDate().isDayPrecise()) {
				ImpreciseDate adjustedStart =
					ImpreciseDateUtils.createImpreciseDateWithoutTime(
							ImpreciseDateUtils.getDateWithDefault(cs.getPayStartDate(), ImpreciseDateUtils.DEFAULT_MONTH, 1));
				cs.setPayStartDate(adjustedStart);
			}
			if (!cs.getPayEndDate().isDayPrecise()) {
				Date tmpEnd = ImpreciseDateUtils.getDateWithDefault(cs.getPayEndDate());
				Calendar calendar = Calendar.getInstance();
		        calendar.clear();
			    calendar.setTime(tmpEnd);
				int lastDate = calendar.getActualMaximum(Calendar.DATE);
				calendar.set(Calendar.DATE, lastDate);
				int lastDay = calendar.get(Calendar.DAY_OF_MONTH);
				ImpreciseDate adjustedEnd =
					ImpreciseDateUtils.createImpreciseDateWithoutTime(
						ImpreciseDateUtils.getDateWithDefault(cs.getPayEndDate(), ImpreciseDateUtils.DEFAULT_MONTH, lastDay));
				cs.setPayEndDate(adjustedEnd);
			}

		}
	}

	public void setRAD(Date rad) {
		MilitaryServiceEpisode mse = this.getMatchedMSE();
		if (mse != null && rad != null) {
			mse.setEndDate(ImpreciseDateUtils.createImpreciseDateWithoutTime(rad));
		}
	}

	public boolean hasMatchingBOSandBegDateOfServiceInADR(ServiceBranch branch, Date begin) throws ServiceException {
		Set mses = this.getHECMSEs(this.getResultPerson().getMilitaryService());
    	this.setMatchedMSE(null); // Reset each time called CodeCR10610 since ILOG loops
		if (mses != null && branch != null && begin != null) {
	        for(Iterator iter=mses.iterator(); iter.hasNext();) {
	            MilitaryServiceEpisode mse = (MilitaryServiceEpisode)iter.next();
	            if (mse.getServiceBranch() != null && mse.getStartDate() != null &&
	            		branch.getCode().equals(mse.getServiceBranch().getCode()) && begin.equals(ImpreciseDateUtils.getDateWithDefault(mse.getStartDate()))) {
	            	this.setMatchedMSE(mse);
	            	return true;
	            }
	        }
		}
		return false;
	}

	public boolean hasDeploymentMatch(Date begin) {
		/*
		 * matching “deployment” exists in the repository (ADR) WHEN the
		 * condition is true, as follows: Deployment Begin Date is the same.
		 */
		return this.hasDeploymentExactOrSimpleMatch(null, begin);
	}

	private boolean hasDeploymentExactOrSimpleMatch(Deployment incoming, Date begin) {
		// CCR 10610 - use result person
		Set activations = this.getActivations(this.getResultPerson());
		if (activations != null && activations.size() > 0) {
	        for(Iterator iter=activations.iterator(); iter.hasNext();) {
	            Activation activation = (Activation)iter.next();
	            Set deployments = activation.getDeployments();
	            if (deployments != null && deployments.size() > 0) {
		    	        for(Iterator itr=deployments.iterator(); itr.hasNext();) {
		    	        	Deployment deployment = (Deployment)itr.next();
		    	        	if (begin != null && incoming == null) {
		    	        		if (begin.compareTo(deployment.getDeploymentBeginDate())==0) {
		    	        			this.setMatchedDeployment(deployment);
		    	        			this.setMatchedActivation(activation);
		    	        			return true;
		    	        		}
		    	        	}
		    	        	else if (begin == null && incoming != null) {
		    	        		boolean match =
		    	        			this.getMergeRuleService().getMatchRuleService().match(incoming, deployment);
		    	        		if (match) {
		    	        			this.setMatchedDeployment(deployment);
		    	        			this.setMatchedActivation(activation);
		    	        			return true;
		    	        		}
		    	        	}
		    	        }
	            }
	        }
		}
		return false;
	}


	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getHECMostRecentReceivedSSD()
	 */
	public Date getHECMostRecentReceivedSSD() {
		// This method was introduced for new CV algorithm that does not use site data
		if(  this.mostRecentSSD == null ) {
			// need to loop thru all (updated)MSEs and return the Service Separation date which is most recent
			MilitaryService ms = this.getResultPerson().getMilitaryService();
			if( ms != null ) {

				// A temp collection to hold all MSEs
				HashSet episodes = new HashSet();

				// Get all site records
				MilitaryServiceSiteRecord record = ms.getHECMilitaryServiceSiteRecord();

				Set site_episodes = (record != null) ? record.getMilitaryServiceEpisodes() : null;
				if (site_episodes != null && !site_episodes.isEmpty()) {
					episodes.addAll( site_episodes );
				}

				// Now use a collection comparator to search for an MSE
				// with the most recent service separation date
				MilitaryServiceEpisodeComparator comparator = new MilitaryServiceEpisodeComparator();
				if( !episodes.isEmpty() ) {
					MilitaryServiceEpisode episode = (MilitaryServiceEpisode)Collections.max( episodes, comparator );
					this.mostRecentSSD = (episode != null) ? ImpreciseDateUtils.getDateWithDefault( episode.getEndDate() ) : null;
				}
			}
		}
		return this.mostRecentSSD;
	}
	private MilitaryServiceEpisode getHECMostRecentMSE(MilitaryService ms) {
		if( ms != null ) {
			// A temp collection to hold all MSEs
			HashSet episodes = new HashSet();

			// Get all site records
			MilitaryServiceSiteRecord record = ms.getHECMilitaryServiceSiteRecord();

			Set site_episodes = (record != null) ? record.getMilitaryServiceEpisodes() : null;
			if (site_episodes != null && !site_episodes.isEmpty()) {
				episodes.addAll( site_episodes );
			}

			// Now use a collection comparator to search for an MSE
			// with the most recent service separation date
			MilitaryServiceEpisodeComparator comparator = new MilitaryServiceEpisodeComparator();
			if( !episodes.isEmpty() ) {
				return (MilitaryServiceEpisode)Collections.max( episodes, comparator );
			}
		}
		return null;
	}

	public Date getHECMostRecentDtSsdCombatEpisodeActivationCombatPay() {
		// Notice it gets HEC only data and meant for MSDS context only.
		// CCR 11681 use this method to get most recent of four End Dates,
		// including from Activation and CombatService
		Date ssdDt = this.getHECMostRecentReceivedSSD();
		Date ceEndDt = this.getMostRecentReceivedCombatEpisodeEndDate();
		Date actDt = this.getMostRecentActivationEndDate();
		Date payDt = this.getMostRecentCombatPayEndDate();

		HashSet<Date> dates = new HashSet<Date>();

		if (ssdDt != null) dates.add(ssdDt);
		if (ceEndDt != null) dates.add(ceEndDt);
		if (actDt != null) dates.add(actDt);
		if (payDt != null) dates.add(payDt);
		DateComparator dc = new DateComparator();

		if (!dates.isEmpty()) return (Date)Collections.max(dates, dc);
		return null;
	}
	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getHECMostRecentSSDOrCombatToDate()
	 */
	public Date getHECMostRecentSSDOrCombatToDate() {
		// Notice it gets HEC only data and meant for MSDS context only.
		Date ssdDt = this.getHECMostRecentReceivedSSD();
		Date ceEndDt = this.getMostRecentReceivedCombatEpisodeEndDate();

		if (ssdDt == null) {
			return ceEndDt;
		}

		if (ceEndDt == null) {
			return ssdDt;
		}

		return ssdDt.after(ceEndDt) ? ssdDt : ceEndDt;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getHECMostRecentSSDOrCombatEndDatePlus5YearsMinus1Day()
	 */
	public Date getHECMostRecentSSDOrCombatEndDatePlus5YearsMinus1Day() {
    	return getDatePlus5YearsMinus1Day(getHECMostRecentSSDOrCombatToDate());
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#isHECMostRecentConflictToDateAfterForLocation(java.util.Date, java.lang.String)
	 */
	public boolean isHECMostRecentConflictToDateAfterForLocation(Date date, String code) {
		// This method only looks at HEC Record per MSDS rules
        if (date == null)
        {
            return false;
        }

        boolean mostRecent = false;

		// Get an updated military service (after incoming data is merged)
		MilitaryService ms = this.getResultPerson().getMilitaryService();
		if( ms != null ) {
			// A temp collection to hold all conflicts
			HashSet conflicts = new HashSet();

			// Get HEC site record
			MilitaryServiceSiteRecord site_record = ms.getHECMilitaryServiceSiteRecord();

			Set site_conflicts = (site_record != null) ? site_record.getConflictExperiences() : null;
			if(site_conflicts != null && !site_conflicts.isEmpty()) {
				conflicts.addAll( site_conflicts );
			}

			// Now use a collection comparator to search for a conflict experience
			// with the most recent end date.  If found, check if a conflict's location
			// is the specific location and if a conflict's end date is after the specific date
            CombatEpisodeComparator comparator = new CombatEpisodeComparator();
			if( !conflicts.isEmpty() ) {
				ConflictExperience conflict = (ConflictExperience)Collections.max( conflicts, comparator );
				if( conflict != null ) {
					ConflictLocation location = conflict.getConflictLocation();
					Date toDate = ImpreciseDateUtils.getDateWithDefault( conflict.getEndDate() );
					if( location != null && toDate != null &&
						 location.getCode().equals(code) && toDate.after( date ) ) {
						mostRecent = true;
					}
				}
			}
		}
		return mostRecent;
	}


	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMsdsQueryStatusCode(Person person)
	 */
	public String getMsdsQueryStatusCode(Person person) {
		// CCR 8395
		MilitaryService ms = person.getMilitaryService();
		return (ms != null && ms.getMilitaryServiceQueryStatus() != null) ?
				ms.getMilitaryServiceQueryStatus().getCode() : null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setMsdsQueryStatus(java.lang.String)
	 */
	public void setMsdsQueryStatus(String status) throws ServiceException {
		MilitaryService ms = this.getResultPerson().getMilitaryService();
		if (ms == null) {
			ms = new MilitaryService();
			this.getResultPerson().setMilitaryService(ms);
		}
		ms.setMilitaryServiceQueryStatus(this.getLookupService().getMilitaryServiceQueryStatusByCode(status));
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMsdsReceiveStatus()
	 */
	public String getMsdsReceiveStatus() {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			return ((MilitaryServiceInputData)this.getRuleDataAware()).getMsdsReceiveStatus();
		}
		return null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMsdsBirlsStatus()
	 */
	public String getMsdsBirlsStatus() {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			return ((MilitaryServiceInputData)this.getRuleDataAware()).getMsdsBirlsStatus();
		}
		return null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMsdsVadirStatus()
	 */
	public String getMsdsVadirStatus() {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			return ((MilitaryServiceInputData)this.getRuleDataAware()).getMsdsVadirStatus();
		}
		return null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMsdsOefOifIndicator()
	 */
	public String getMsdsOefOifIndicator() {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			return ((MilitaryServiceInputData)this.getRuleDataAware()).getMsdsOefOifIndicator();
		}
		return null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMsdsServiceDischargeType()
	 */
	public DischargeType getMsdsServiceDischargeType() {
		MilitaryServiceEpisode mse = this.getMSEFromMSDS();
		return mse != null ? mse.getDischargeType() : null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getMsdsServiceBranch()
	 */
	public ServiceBranch getMsdsServiceBranch() {
		MilitaryServiceEpisode mse = this.getMSEFromMSDS();
		return mse != null ? mse.getServiceBranch() : null;
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setOefOifIndicatorOfMostRecent(java.lang.String)
	 */
	public void setOefOifIndicatorOfMostRecent(String ind) throws ServiceException {
        MilitaryService ms = this.getResultPerson().getMilitaryService();
        if( ms != null && ind != null) {
            Set CEs = ms.getCombatEpisodes();
            CombatEpisode mostRecent = null;
            //Find and return the most recent combat location by combat episode end date
            if(!CEs.isEmpty() ) {
            	mostRecent = (CombatEpisode)Collections.max(CEs,new CombatEpisodeComparator());
            	if (mostRecent != null) {
            		mostRecent.setConflictLocation(this.getLookupService().getConflictByCode(ind));
            	}
            }
        }

	}

	public boolean hasDeploymentWithOverlap(Deployment deployment) {
		/*
		 * that OVERLAPS the data received in the message, based on the dates
		 * contained in the message
		 */
		Set activations = this.getActivations(getPristinePerson());
		if (deployment != null && activations != null && !activations.isEmpty()) {
			Date start = deployment.getDeploymentBeginDate();
			Date end = deployment.getDeploymentEndDate();

			for (Iterator itr=activations.iterator(); itr.hasNext();) {
				Activation activation = (Activation)itr.next();
				Set deployments = activation.getDeployments();
				if (deployments != null && !deployments.isEmpty()) {
					for (Iterator depItr=deployments.iterator(); depItr.hasNext();) {
						Deployment temp = (Deployment)depItr.next();
						if (this.isOverlapped(temp.getDeploymentBeginDate(),
								temp.getDeploymentEndDate(), start, end)) {
							return true;
						}
					}
				}
			}
		}

		return false;
	}

	/* (non-Javadoc)
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#hasNewMilitaryServiceEpisode()
	 */
	public boolean hasNewMilitaryServiceEpisode() {

		Set overlapMSEList = new HashSet();
		Set newMSEList = new HashSet();
		Set incomingMSE = new HashSet();
		Set hecMSE = new HashSet();
		if(this.getPristinePerson().getMilitaryService() != null ){
			if(this.getPristinePerson().getMilitaryService().getHECMilitaryServiceSiteRecord()!= null){
				hecMSE = this.getPristinePerson().getMilitaryService().getHECMilitaryServiceSiteRecord().getMilitaryServiceEpisodes();
			}
		}

		if( this.getRuleDataAware() instanceof EventInputData ) {
			if(this.getIncomingPerson().getMilitaryService() != null ){
				if(this.getIncomingPerson().getMilitaryService().getMilitaryServiceSiteRecordsBySite(((EventInputData)this.getRuleDataAware()).getVerificationInfo().getSiteNumber())!= null){
					incomingMSE = this.getIncomingPerson().getMilitaryService().getMilitaryServiceSiteRecordsBySite(((EventInputData)this.getRuleDataAware()).getVerificationInfo().getSiteNumber()).getMilitaryServiceEpisodes();
				}
			}
		}

		if(incomingMSE != null && !incomingMSE.isEmpty()){
			for(Iterator itr=incomingMSE.iterator(); itr.hasNext();){
				MilitaryServiceEpisode incoming = (MilitaryServiceEpisode)itr.next();

					boolean overlap = isOverlapped(hecMSE,ImpreciseDateUtils.getDateWithDefault(incoming.getStartDate()),ImpreciseDateUtils.getDateWithDefault(incoming.getEndDate()));
					if(overlap){
						overlapMSEList.add(incoming);
					}
					else{
						newMSEList.add(incoming);
					}
			}
		}

		if(newMSEList.isEmpty()){
			return false;
		}

		return true;
	}

	/* (non-Javadoc)
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#hasNewOEFOIFdata()
	 */
	public boolean hasNewOEFOIFdata() {

		Set pristineCE = new HashSet();
		Set resultCE = new HashSet();
		Set overlapCEList = new HashSet();
		Set newCEList = new HashSet();

		if(this.getPristinePerson().getMilitaryService() != null ){
			pristineCE = this.getPristinePerson().getMilitaryService().getCombatEpisodes();
		}

		if(this.getResultPerson().getMilitaryService() != null){
			resultCE = this.getResultPerson().getMilitaryService().getCombatEpisodes();
		}

		if(resultCE != null && !resultCE.isEmpty()){
			for(Iterator itr=resultCE.iterator(); itr.hasNext();){

				CombatEpisode incoming = (CombatEpisode)itr.next();

				boolean overlap = hasMatchingCombatEpisode(incoming,pristineCE);
				if(overlap){
					overlapCEList.add(incoming);
				}
				else{
					newCEList.add(incoming);
				}
			}
		}

		if(newCEList.isEmpty()){
			return false;
		}

		return true;
	}


	 /**
	     * Get Matching episode by comparing start and end dates
	     * @param incomingCE
	     * @param onFileCEs
	     * @return
	     */
	    private boolean hasMatchingCombatEpisode(CombatEpisode incomingCE,Set onFileCEs) {
	    	if(onFileCEs != null){
	    		for(Iterator iter=onFileCEs.iterator(); iter.hasNext();) {
	    			CombatEpisode onFileCE = (CombatEpisode)iter.next();
	    			if(this.isEqual(incomingCE.getStartDate(),onFileCE.getStartDate()) &&
	    					this.isEqual(incomingCE.getEndDate(),onFileCE.getEndDate())) {
	    				return true;
	    			}
	    		}
	    	}
	    	return false;
    }



	/* (non-Javadoc)
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#hasNoMSDSdata()
	 */
	public boolean hasNoMSDSdata() {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			return ((MilitaryServiceInputData)this.getRuleDataAware()).isNoMSDSdata();
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#isMsdsRetryCountGreaterThanLimit()
	 */
	public boolean isMsdsRetryCountGreaterThanLimit() throws ServiceException {
		return super.getLogMessagingService().findCountCompletion(this.getResultPerson().getEntityKey());

	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getActivations()
	 */
	public Set getActivations() {
		return this.getActivations(this.getIncomingPerson());
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getCombatEpisodes()
	 */
	public Set getCombatEpisodes() {
		return this.getIncomingPerson().getMilitaryService() != null ?
				this.getIncomingPerson().getMilitaryService().getCombatEpisodes() : new HashSet();
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getCombatPays()
	 */
	public Set getCombatPays() {
		return this.getCombatServices(this.getIncomingPerson());
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getHECMilitaryServiceEpisodes()
	 */
	public Set getHECMilitaryServiceEpisodes() throws ServiceException {
		return this.getHECMSEs(this.getIncomingPerson().getMilitaryService());
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#getHECMilitaryServiceEpisodesResult()
	 */
	public Set getHECMilitaryServiceEpisodesResult() throws ServiceException {
		return this.getHECMSEs(this.getResultPerson().getMilitaryService());
	}

	public void addFilteredMse(MilitaryServiceEpisode mse) {
		// CCR 11570
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			((MilitaryServiceInputData)this.getRuleDataAware()).addFilteredMseEntry(mse);
		}
	}

	public Set getFilteredMseSet() {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			return ((MilitaryServiceInputData)this.getRuleDataAware()).getFilteredMseSet();
		}
		return null;
	}

	public void removeAllFilteredMse() {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			((MilitaryServiceInputData)this.getRuleDataAware()).removeAllFilteredMseEntries();
		}
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setActivation(gov.va.med.esr.common.model.ee.Activation)
	 */
	public void setActivation(Activation activation) {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			((MilitaryServiceInputData)this.getRuleDataAware()).setActivation(activation);
		}
	}

	public CombatEpisode getCombatEpisode() {
		MilitaryServiceInputData data = getMilitaryServiceInputData();
		return (data != null) ? data.getCombatEpisode() : null;
	}

	public void setCombatEpisode(CombatEpisode combatEpisode) {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			((MilitaryServiceInputData)this.getRuleDataAware()).setCombatEpisode(combatEpisode);
		}
	}

	public void setMatchedCombatEpisodeEndDate() {
		CombatEpisode matched = this.getMatchedCombatEpisode();
		CombatEpisode incoming = this.getCombatEpisode();
		if (matched != null && incoming != null) {
			matched.setEndDate(incoming.getEndDate());
		}
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setCombatPay(gov.va.med.esr.common.model.ee.CombatService)
	 */
	public void setCombatPay(CombatService combatPay) {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			((MilitaryServiceInputData)this.getRuleDataAware()).setCombatService(combatPay);
		}
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setDeployment(gov.va.med.esr.common.model.ee.Deployment)
	 */
	public void setDeployment(Deployment deployment) {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			((MilitaryServiceInputData)this.getRuleDataAware()).setDeployment(deployment);
		}
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setMilitaryServiceEpisode(gov.va.med.esr.common.model.ee.MilitaryServiceEpisode)
	 */
	public void setMilitaryServiceEpisode(MilitaryServiceEpisode mse) {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			((MilitaryServiceInputData)this.getRuleDataAware()).setIncomingMilitaryServiceEpisode(mse);
		}
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#setMSDSdataSource(java.lang.String)
	 */
	public void setMSDSdataSource(String source) {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			((MilitaryServiceInputData)this.getRuleDataAware()).setMsdsDataSource(source);
		}
	}

	/**
	 * @see gov.va.med.esr.common.rule.MilitaryServiceInput#terminateRuleFlow(boolean)
	 */
	public void terminateRuleFlow(boolean flag) {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			((MilitaryServiceInputData)this.getRuleDataAware()).setTerminateRuleFlow(flag);
		}
	}
	// MSDS end

	//Seeding
	public boolean getSeedingIndicator(){
    	return this.getMilitaryServiceInputData().getIsSeeding();
    }

	public void updateSeedingCombatEpisodes()throws ServiceException{

		setSeedingCombatEpisode();

    }

	public boolean updateSeedingCVEndDate(){

    	Person onFile = this.getResultPerson();
    	MilitaryService currentMilitaryService = onFile.getMilitaryService();
    	if( currentMilitaryService != null ) {
			if(!(getOnFileCVEligibilityEndDate()== null)){
				if(getOnFileCVEligibilityEndDate().before(getCombatVeteranEligibilityEndDate())){
					triggerZ07 = true;
				}
			}
		}
    	return triggerZ07;


    }


	public CombatService getMatchedCombatPay() {
		 MilitaryServiceInputData data = getMilitaryServiceInputData();
		 return (data != null) ? data.getMatchedCombatPay() : null;
	}

	public void setMatchedCombatPay(CombatService matchedCombatPay) {
		 MilitaryServiceInputData data = getMilitaryServiceInputData();
		 if(data != null) {
			 data.setMatchedCombatPay(matchedCombatPay);
		 }
	}

	public void setMatchedMSE(MilitaryServiceEpisode matchedMSE) {
		 MilitaryServiceInputData data = getMilitaryServiceInputData();
		 if(data != null) {
			 data.setMatchedMSE(matchedMSE);
		 }
	}

	public Deployment getMatchedDeployment() {
		 MilitaryServiceInputData data = getMilitaryServiceInputData();
		 return (data != null) ? data.getMatchedDeployment() : null;
	}

	public void setMatchedDeployment(Deployment matchedDeployment) {
		 MilitaryServiceInputData data = getMilitaryServiceInputData();
		 if(data != null) {
			 data.setMatchedDeployment(matchedDeployment);
		 }
	}

	/**
	 * An inner class to hold information about non-breaking episodes.
	 * @author DNS   ruizc
	 */
	private class NonBreakingEpisodesInfo {
		private int count = 0;
		private MilitaryServiceEpisode firstMSE = null;
		private MilitaryServiceEpisode lastMSE = null;
		private boolean meets24MonthCriteria = false;
		public int getCount() {
			return count;
		}
		public void setCount(int count) {
			this.count = count;
		}
		public MilitaryServiceEpisode getFirstMSE() {
			return firstMSE;
		}
		public void setFirstMSE(MilitaryServiceEpisode firstMSE) {
			this.firstMSE = firstMSE;
		}
		public MilitaryServiceEpisode getLastMSE() {
			return lastMSE;
		}
		public void setLastMSE(MilitaryServiceEpisode lastMSE) {
			this.lastMSE = lastMSE;
		}
		public boolean meets24MonthCriteria() {
			return meets24MonthCriteria;
		}
		public void setMeets24MonthCriteria(boolean meets24MonthCriteria) {
			this.meets24MonthCriteria = meets24MonthCriteria;
		}
	}

//Handling Seeding Military Service Episode

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#setMilitaryServiceInfoBySiteToReceived()
	 */
	public void setSeedingMilitaryServiceSiteInformation() throws ServiceException{

		Person onFile = this.getResultPerson();
		MilitaryService currentMilitaryService = onFile.getMilitaryService();
		if (currentMilitaryService == null) {
			onFile.setMilitaryService((currentMilitaryService = new MilitaryService()));
		}

		Set incomingSitesMSE = new HashSet();

		MilitaryServiceInputData data = this.getMilitaryServiceInputData();
		MilitaryService incomingMilitaryService = data != null ? data
				.getMilitaryService() : getIncomingPerson()
				.getMilitaryService();
				if (incomingMilitaryService != null){
					incomingSitesMSE = populateIncomingSitesMSE(incomingMilitaryService);

				}

				MilitaryServiceSiteRecord currentSiteRecord = currentMilitaryService
				.getHECMilitaryServiceSiteRecord();
				if(!incomingSitesMSE.isEmpty()){
					if(currentSiteRecord == null){
						currentSiteRecord = new MilitaryServiceSiteRecord();
						updateHECSeedingEpisode(incomingSitesMSE, currentSiteRecord);
						createHECMSSR(currentMilitaryService, currentSiteRecord);

					}
					else{

						updateHECSeedingEpisode(incomingSitesMSE, currentSiteRecord);

					}

				}


	}

	private Set populateIncomingSitesMSE(MilitaryService incomingMilitaryService){
		Set incomingSitesMSE = new HashSet();
		Set incomingSiteRecords = incomingMilitaryService
		.getMilitaryServiceSiteRecords();
		if (incomingSiteRecords != null && !incomingSiteRecords.isEmpty()) {
			for (Iterator iter = incomingSiteRecords.iterator(); iter.hasNext();) {
				MilitaryServiceSiteRecord incomingSiteRecord = (MilitaryServiceSiteRecord) iter
				.next();
				if (incomingSiteRecord.getSite() != null) {
					if (!(incomingSiteRecord.getSite().getCode()
							.equals(VAFacility.CODE_HEC.getName()))
							&& !(incomingSiteRecord
									.getMilitaryServiceEpisodes().isEmpty())) {

						for (Iterator iterator = incomingSiteRecord
								.getMilitaryServiceEpisodes().iterator(); iterator
								.hasNext();) {
							MilitaryServiceEpisode incomingEpisode = (MilitaryServiceEpisode) iterator
							.next();
							if (incomingEpisode.getEndDate() != null
									&& incomingEpisode.getStartDate() != null) {
								incomingSitesMSE.add(incomingEpisode);
							}
						}

					}

				}

			}

		}
		return incomingSitesMSE;

	}

	private void updateHECSeedingEpisode(Set incomingSitesMSE, MilitaryServiceSiteRecord currentSiteRecord) throws ServiceException {
		for(Iterator iterator = (sortServiceSeparationDateRecentToOld(incomingSitesMSE)).iterator(); iterator.hasNext();){
			MilitaryServiceEpisode incomingEpisode = (MilitaryServiceEpisode) iterator
			.next();
			if (currentSiteRecord
					.getMilitaryServiceEpisodes().isEmpty()) {
				mergeMilitaryServiceEpisode(incomingEpisode, null,
						currentSiteRecord);

			}
			else{

				Set hecMSE = getHecMilitaryServiceEpisode(
						currentSiteRecord
								.getMilitaryServiceEpisodes());
				if (hecMSE.isEmpty()) {
					mergeMilitaryServiceEpisode(incomingEpisode, null,
							currentSiteRecord);
				} else {
					boolean hasOverlap = this
							.hasAMSEWithinDateRange(
									hecMSE,
									ImpreciseDateUtils
											.getDateWithDefault(incomingEpisode
													.getStartDate()),
									ImpreciseDateUtils
											.getReconcilitationDateWithDefault(incomingEpisode
													.getEndDate()));
					if (hasOverlap) {
						MilitaryServiceEpisode overlappedEpisode = this
								.getOverlappedMSE(
										hecMSE,
										ImpreciseDateUtils
												.getDateWithDefault(incomingEpisode
														.getStartDate()),
										ImpreciseDateUtils
												.getReconcilitationDateWithDefault(incomingEpisode
														.getEndDate()));
						if (overlappedEpisode != null) {
							seedingRule(
									overlappedEpisode,
									incomingEpisode,
									hecMSE,
									currentSiteRecord);
						}
					} else {
						mergeMilitaryServiceEpisode(incomingEpisode,
								null, currentSiteRecord);

					}

				}

			}

		}
	}

	private void createHECMSSR(MilitaryService currentMilitaryService, MilitaryServiceSiteRecord currentSiteRecord) throws ServiceException {
		currentSiteRecord.setSite(getLookupService()
				.getVaFacilityByCode(
						VAFacility.CODE_HEC.getName()));
		currentMilitaryService.addMilitaryServiceSiteRecord(currentSiteRecord);

	}

	private List sortServiceSeparationDateRecentToOld(Collection incomingMSEs)
	{
		List sortedIncomingMSEs = new ArrayList();
	    if(incomingMSEs != null && !incomingMSEs.isEmpty()) {
	    	sortedIncomingMSEs.addAll(incomingMSEs);
	        Comparator comparator = new Comparator() {
	            public int compare(Object pObject1, Object pObject2) {
	                Date date1 = (pObject1 instanceof MilitaryServiceEpisode) ? ImpreciseDateUtils.getReconcilitationDateWithDefault(((MilitaryServiceEpisode)pObject1).getEndDate()) : null;
	                Date date2 = (pObject2 instanceof MilitaryServiceEpisode) ? ImpreciseDateUtils.getReconcilitationDateWithDefault(((MilitaryServiceEpisode)pObject2).getEndDate()) : null;
	                return (date1 != null && date2 != null) ? (-date1.compareTo(date2)) : 0;
	            }
	        };
	        Collections.sort(sortedIncomingMSEs,comparator);
	    }
	    return sortedIncomingMSEs;
	}

	private void mergeMilitaryServiceEpisode(MilitaryServiceEpisode incomingEpisode,MilitaryServiceEpisode overlappedEpisode, MilitaryServiceSiteRecord currentSiteRecord){
		this.getMergeRuleService().mergeSeedingMilitaryServiceEpisode(incomingEpisode,overlappedEpisode,currentSiteRecord);
	}

	private Set getHecMilitaryServiceEpisode(Set hecMilitaryServiceEpisodes){
		Set hecMSE = new HashSet();
		for (Iterator iterator = hecMilitaryServiceEpisodes.iterator(); iterator
		.hasNext();){
			MilitaryServiceEpisode hecEpisode = (MilitaryServiceEpisode) iterator.next();
			if(hecEpisode.getEndDate() != null && hecEpisode.getStartDate() != null){
				hecMSE.add(hecEpisode);
			}

		}
		return hecMSE;

	}

	public boolean hasAMSEWithinDateRange(Set episodes,
			Date fromDate,
			Date toDate ) throws ServiceException {

		List orderedOnFileEpisodes = sortServiceSeparationDateRecentToOld(episodes);
		boolean found = false;
		found = this.isOverlapped( orderedOnFileEpisodes, fromDate, toDate );
		return found;
	}

	private void seedingRule(MilitaryServiceEpisode overlappedEpisode, MilitaryServiceEpisode incomingEpisode, Set hecMSEByType, MilitaryServiceSiteRecord currentSiteRecord){

		Date overlappedStartDate = ImpreciseDateUtils.getDateWithDefault(overlappedEpisode.getStartDate());
		Date overlappedEndDate = ImpreciseDateUtils.getReconcilitationDateWithDefault(overlappedEpisode.getEndDate());
		Date incomingEpisodeStartDate = ImpreciseDateUtils.getDateWithDefault(incomingEpisode.getStartDate());
		Date incomingEpisodeEndDate = ImpreciseDateUtils.getReconcilitationDateWithDefault(incomingEpisode.getEndDate());

		if(overlappedStartDate.equals(incomingEpisodeStartDate)){
			if(overlappedEndDate.equals(incomingEpisodeEndDate)){
				//directly setting the onFile result person info for the update
				if(overlappedEpisode.getServiceBranch()== null){
					if(incomingEpisode.getServiceBranch()!= null){
						overlappedEpisode.setServiceBranch(incomingEpisode.getServiceBranch());
					}
				}
				if(overlappedEpisode.getMilitaryServiceComponent()== null){
					if(incomingEpisode.getMilitaryServiceComponent()!= null){
						overlappedEpisode.setMilitaryServiceComponent(incomingEpisode.getMilitaryServiceComponent());
					}
				}
				if(overlappedEpisode.getServiceNumber()== null){
					if(incomingEpisode.getServiceNumber()!= null){
						overlappedEpisode.setServiceNumber(incomingEpisode.getServiceNumber());
					}
				}
				if(overlappedEpisode.getDischargeType()== null){
					if(incomingEpisode.getDischargeType()!= null){
						overlappedEpisode.setDischargeType(incomingEpisode.getDischargeType());
					}
				}

			}
			else{
				if(overlappedEndDate.before(incomingEpisodeEndDate)){
					if(hecMSEByType.size() > 1){
						Set tempOnFileEpisodes = hecMSEByType;
						MilitaryServiceEpisode tempOnfileOverlap = checkUpdateOverlap(tempOnFileEpisodes,overlappedEpisode,incomingEpisodeStartDate,incomingEpisodeEndDate);
						if(tempOnfileOverlap == null){
							mergeMilitaryServiceEpisode(incomingEpisode,overlappedEpisode,currentSiteRecord);
						}
					}
					else{
						mergeMilitaryServiceEpisode(incomingEpisode,overlappedEpisode,currentSiteRecord);
					}
				}
			}

		}
		else{
			if(overlappedEndDate.equals(incomingEpisodeEndDate)){
				if(overlappedStartDate.after(incomingEpisodeStartDate)){
					if(hecMSEByType.size() > 1){
						Set tempOnFileEpisodes = hecMSEByType;
						MilitaryServiceEpisode tempOnfileOverlap = checkUpdateOverlap(tempOnFileEpisodes,overlappedEpisode,incomingEpisodeStartDate,incomingEpisodeEndDate);
						if(tempOnfileOverlap == null){
							mergeMilitaryServiceEpisode(incomingEpisode,overlappedEpisode,currentSiteRecord);
						}
					}
					else{
						mergeMilitaryServiceEpisode(incomingEpisode,overlappedEpisode,currentSiteRecord);
					}
				}
			}
		}
	}


	private boolean isOverlapped( List episodes, Date fromDate, Date toDate ) {

		boolean found = false;
		if( episodes != null ) {
			for( Iterator i=episodes.iterator(); i.hasNext(); ) {
				MilitaryServiceEpisode episode = (MilitaryServiceEpisode)i.next();
				if( this.isOverlapped( ImpreciseDateUtils.getDateWithDefault( episode.getStartDate() ),
											  ImpreciseDateUtils.getDateWithDefault( episode.getEndDate() ),
											  fromDate,
											  toDate ) ) {
					found = true;
					break;
				}
			}
		}
		return found;
	}

	private MilitaryServiceEpisode getOverlappedMSE( Set episodes, Date fromDate, Date toDate ) {
		//order the onfile episodes
		List orderedOnFileEpisodes = sortServiceSeparationDateRecentToOld(episodes);

		MilitaryServiceEpisode overlappingEpisode = null;
		if( episodes != null && !episodes.isEmpty() ) {
			for( Iterator i=orderedOnFileEpisodes.iterator(); i.hasNext(); ) {
				MilitaryServiceEpisode episode = (MilitaryServiceEpisode)i.next();
				if( this.isOverlapped( ImpreciseDateUtils.getDateWithDefault( episode.getStartDate() ),
											  ImpreciseDateUtils.getReconcilitationDateWithDefault( episode.getEndDate() ),
											  fromDate,
											  toDate ) ) {
					overlappingEpisode = episode;
					break;
				}
			}
		}
		return overlappingEpisode;
	}

	private MilitaryServiceEpisode checkUpdateOverlap(Set tempOnfileEpisodes,MilitaryServiceEpisode overlappedEpisode, Date incomingEpisodeStartDate, Date incomingEpisodeEndDate){
		MilitaryServiceEpisode tempOnfileOverlap = null;
		tempOnfileEpisodes.remove(overlappedEpisode);
		tempOnfileOverlap = getOverlappedMSE(tempOnfileEpisodes,incomingEpisodeStartDate,incomingEpisodeEndDate );
		return tempOnfileOverlap;
	}

	//Handling Seeding Combat Episode

	private void setSeedingCombatEpisode() throws ServiceException {


		Person onFile = this.getResultPerson();
		MilitaryService currentMilitaryService = onFile.getMilitaryService();
		if (currentMilitaryService == null) {
			onFile.setMilitaryService((currentMilitaryService = new MilitaryService()));
		}

		Set incomingCEs = new HashSet();

		MilitaryServiceInputData data = this.getMilitaryServiceInputData();
		MilitaryService incomingMilitaryService = data != null ? data
				.getMilitaryService() : getIncomingPerson()
				.getMilitaryService();
				if (incomingMilitaryService != null){
					incomingCEs = populateIncomingSitesCE(incomingMilitaryService);

				}

				if(!incomingCEs.isEmpty()){
					updateCESeedingEpisode(incomingCEs,currentMilitaryService);
				}
	}

	private Set populateIncomingSitesCE(MilitaryService incomingMilitaryService) {
		Set incomingSitesCE = new HashSet();
		Set allCEs = incomingMilitaryService.getCombatEpisodes();

		if (allCEs != null && !allCEs.isEmpty()) {
			for (Iterator iter = allCEs.iterator(); iter.hasNext();) {
				CombatEpisode incomingCE = (CombatEpisode) iter.next();
				if (incomingCE.getConflictLocation() != null) {
					String incomingConflictLocation = incomingCE
					.getConflictLocation().getCode();
					if (((incomingCE.getOEFOIFStationNumber() == null) || !(incomingCE
							.getOEFOIFStationNumber().getCode()
							.equals(VAFacility.CODE_HEC.getName())))
							&& ((incomingConflictLocation
									.equals(ConflictLocation.CODE_UNKNOWN_OEF_OIF
											.getCode()))
											|| (incomingConflictLocation
													.equals(ConflictLocation.CODE_OEF
															.getCode())) || (incomingConflictLocation
																	.equals(ConflictLocation.CODE_OIF.getCode())))
																	&& (incomingCE.getEndDate() != null)
																	&& (incomingCE.getStartDate() != null)) {

						incomingSitesCE.add(incomingCE);

					}

				}

			}

		}
		return incomingSitesCE;

	}

	private void updateCESeedingEpisode(Set incomingSitesCE, MilitaryService currentMilitaryService) throws ServiceException {
		for(Iterator iterator = (sortCEServiceSeparationDateRecentToOld(incomingSitesCE)).iterator(); iterator.hasNext();){
			CombatEpisode incomingEpisode = (CombatEpisode) iterator
			.next();
			boolean removeIncoming = false;
			Set hecCEs = buildHecCEs(currentMilitaryService.getCombatEpisodes());
			if (hecCEs.isEmpty()) {
				updateCE(currentMilitaryService, incomingEpisode);

			}
			else{
				Set hecCEByConfLoc = getHecCEByConflictLoc(hecCEs,incomingEpisode.getConflictLocation());
				if (hecCEByConfLoc.isEmpty()) {
					updateCE(currentMilitaryService, incomingEpisode);
				} else {
					boolean hasOverlap = this
							.hasACEWithinDateRange(
									hecCEByConfLoc,
									ImpreciseDateUtils
											.getDateWithDefault(incomingEpisode
													.getStartDate()),
									ImpreciseDateUtils
											.getReconcilitationDateWithDefault(incomingEpisode
													.getEndDate()));
					if (hasOverlap) {
						CombatEpisode overlappedEpisode = this
								.getOverlappedCE(
										hecCEByConfLoc,
										ImpreciseDateUtils
												.getDateWithDefault(incomingEpisode
														.getStartDate()),
										ImpreciseDateUtils
												.getReconcilitationDateWithDefault(incomingEpisode
														.getEndDate()));
						if (overlappedEpisode != null) {
							seedingCERule(
									overlappedEpisode,
									incomingEpisode,
									hecCEByConfLoc,
									currentMilitaryService);
							removeIncoming = true;
						}
					} else {
						updateCE(currentMilitaryService, incomingEpisode);

					}

				}

			}
			//remove incoming episode
			if(removeIncoming){
				incomingEpisode.getEntityKey();
				CombatEpisode onFileCE = currentMilitaryService.getCombatEpisodeByEntityKey(incomingEpisode.getEntityKey());
				currentMilitaryService.removeCombatEpisode(onFileCE);

			}

		}
	}

	private List sortCEServiceSeparationDateRecentToOld(Collection incomingCEs)
	{
		List sortedIncomingCEs = new ArrayList();
	    if(incomingCEs != null && !incomingCEs.isEmpty()) {
	    	sortedIncomingCEs.addAll(incomingCEs);
	        Comparator comparator = new Comparator() {
	            public int compare(Object pObject1, Object pObject2) {
	                Date date1 = (pObject1 instanceof CombatEpisode) ? ImpreciseDateUtils.getReconcilitationDateWithDefault(((CombatEpisode)pObject1).getEndDate()) : null;
	                Date date2 = (pObject2 instanceof CombatEpisode) ? ImpreciseDateUtils.getReconcilitationDateWithDefault(((CombatEpisode)pObject2).getEndDate()) : null;
	                return (date1 != null && date2 != null) ? (-date1.compareTo(date2)) : 0;
	            }
	        };
	        Collections.sort(sortedIncomingCEs,comparator);
	    }
	    return sortedIncomingCEs;
	}

	private Set buildHecCEs(Set onFileCEs) {
		Set hecCEs = new HashSet();
		if (onFileCEs != null && !onFileCEs.isEmpty()) {
			for (Iterator iterator = onFileCEs.iterator(); iterator.hasNext();) {
				CombatEpisode hecCE = (CombatEpisode) iterator.next();
				if ((hecCE.getOEFOIFStationNumber() != null)
						&& hecCE.getOEFOIFStationNumber().getCode().equals(
								VAFacility.CODE_HEC.getName())
								&& (hecCE.getEndDate() != null)
								&& (hecCE.getStartDate() != null)) {
					hecCEs.add(hecCE);
				}
			}

		}
		return hecCEs;

	}

	private void updateCE(MilitaryService currentMilitaryService, CombatEpisode incomingEpisode) throws ServiceException {

		incomingEpisode.getEntityKey();
		CombatEpisode onFileCE = currentMilitaryService.getCombatEpisodeByEntityKey(incomingEpisode.getEntityKey());
		onFileCE.setOEFOIFStationNumber(getLookupService()
				.getVaFacilityByCode(
						VAFacility.CODE_HEC.getName()));
	}

	private Set getHecCEByConflictLoc(Set hecCEs,ConflictLocation conflictLoc){
		Set hecCEByconfLoc = new HashSet();
		for (Iterator iterator = hecCEs.iterator(); iterator
		.hasNext();){
			CombatEpisode hecCE = (CombatEpisode) iterator.next();
			if(hecCE.getConflictLocation() != null){
				if(this.isEqual(hecCE.getConflictLocation(),conflictLoc)){
					hecCEByconfLoc.add(hecCE);
				}
			}

		}
		return hecCEByconfLoc;

	}

	public boolean hasACEWithinDateRange(Set episodes,
			Date fromDate,
			Date toDate ){

		List orderedOnFileEpisodes = sortCEServiceSeparationDateRecentToOld(episodes);
		boolean found = false;
		found = this.isCEOverlapped( orderedOnFileEpisodes, fromDate, toDate );
		return found;
	}

	private CombatEpisode getOverlappedCE( Set episodes, Date fromDate, Date toDate ) {
		//order the onfile episodes
		List orderedOnFileEpisodes = sortCEServiceSeparationDateRecentToOld(episodes);
		CombatEpisode overlappingEpisode = null;
		if( episodes != null && !episodes.isEmpty() ) {
			for( Iterator i=orderedOnFileEpisodes.iterator(); i.hasNext(); ) {
				CombatEpisode episode = (CombatEpisode)i.next();
				if( this.isOverlapped( ImpreciseDateUtils.getDateWithDefault( episode.getStartDate() ),
											  ImpreciseDateUtils.getReconcilitationDateWithDefault( episode.getEndDate() ),
											  fromDate,
											  toDate ) ) {
					overlappingEpisode = episode;
					break;
				}
			}
		}
		return overlappingEpisode;
	}

	private void seedingCERule(CombatEpisode overlappedEpisode, CombatEpisode incomingEpisode, Set hecCEByConfLoc, MilitaryService onFile) throws ServiceException{

		Date overlappedStartDate = ImpreciseDateUtils.getDateWithDefault(overlappedEpisode.getStartDate());
		Date overlappedEndDate = ImpreciseDateUtils.getReconcilitationDateWithDefault(overlappedEpisode.getEndDate());
		Date incomingEpisodeStartDate = ImpreciseDateUtils.getDateWithDefault(incomingEpisode.getStartDate());
		Date incomingEpisodeEndDate = ImpreciseDateUtils.getReconcilitationDateWithDefault(incomingEpisode.getEndDate());

		if(overlappedStartDate.equals(incomingEpisodeStartDate)){
			if(overlappedEndDate.equals(incomingEpisodeEndDate)){
				//directly setting the onFile result person info for the update
				if(overlappedEpisode.getOEFOIFSource()== null){
					if(incomingEpisode.getOEFOIFSource()!= null){
						overlappedEpisode.setOEFOIFSource(incomingEpisode.getOEFOIFSource());
					}
				}
				if(overlappedEpisode.getCombatPayType()== null){
					if(incomingEpisode.getCombatPayType()!= null){
						overlappedEpisode.setCombatPayType(incomingEpisode.getCombatPayType());
					}
				}
				overlappedEpisode.setOEFOIFStationNumber(getLookupService()
						.getVaFacilityByCode(
								VAFacility.CODE_HEC.getName()));

			}
			else{
				if(overlappedEndDate.before(incomingEpisodeEndDate)){
					if(hecCEByConfLoc.size() > 1){
						Set tempOnFileEpisodes = hecCEByConfLoc;
						CombatEpisode tempOnfileOverlap = checkCEUpdateOverlap(tempOnFileEpisodes,overlappedEpisode,incomingEpisodeStartDate,incomingEpisodeEndDate);
						if(tempOnfileOverlap == null){
							mergeCombatEpisode(incomingEpisode,overlappedEpisode);
						}
					}
					else{
						mergeCombatEpisode(incomingEpisode,overlappedEpisode);
					}
				}
			}

		}
		else{
			if(overlappedEndDate.equals(incomingEpisodeEndDate)){
				if(overlappedStartDate.after(incomingEpisodeStartDate)){
					if(hecCEByConfLoc.size() > 1){
						Set tempOnFileEpisodes = hecCEByConfLoc;
						CombatEpisode tempOnfileOverlap = checkCEUpdateOverlap(tempOnFileEpisodes,overlappedEpisode,incomingEpisodeStartDate,incomingEpisodeEndDate);
						if(tempOnfileOverlap == null){
							mergeCombatEpisode(incomingEpisode,overlappedEpisode);
						}
					}
					else{
						mergeCombatEpisode(incomingEpisode,overlappedEpisode);
					}
				}
			}
		}
	}

	private boolean isCEOverlapped( List episodes, Date fromDate, Date toDate ) {

		boolean found = false;
		if( episodes != null && !episodes.isEmpty() ) {
			for( Iterator i=episodes.iterator(); i.hasNext(); ) {
				CombatEpisode episode = (CombatEpisode)i.next();
				if( this.isOverlapped( ImpreciseDateUtils.getDateWithDefault( episode.getStartDate() ),
											  ImpreciseDateUtils.getReconcilitationDateWithDefault( episode.getEndDate() ),
											  fromDate,
											  toDate ) ) {
					found = true;
					break;
				}
			}
		}
		return found;
	}

	private CombatEpisode checkCEUpdateOverlap(Set tempOnfileEpisodes,CombatEpisode overlappedEpisode, Date incomingEpisodeStartDate, Date incomingEpisodeEndDate){
		CombatEpisode tempOnfileOverlap = null;
		tempOnfileEpisodes.remove(overlappedEpisode);
		tempOnfileOverlap = getOverlappedCE(tempOnfileEpisodes,incomingEpisodeStartDate,incomingEpisodeEndDate );
		return tempOnfileOverlap;
	}

	private void mergeCombatEpisode(CombatEpisode incomingEpisode,CombatEpisode overlappedEpisode) throws ServiceException{
		this.getMergeRuleService().mergeCombatEpisode(incomingEpisode,overlappedEpisode);
		overlappedEpisode.setOEFOIFStationNumber(getLookupService()
				.getVaFacilityByCode(
						VAFacility.CODE_HEC.getName()));

	}

	public boolean getServiceIndicator() throws ServiceException{
		return super.getSystemParameterService().getMSDSServiceIndicator().booleanValue();

	}

	/**
	 * @see gov.va.med.esr.common.rule.parameter.MilitaryServiceInput#setMilitaryServiceInfoBySiteToReceived()
	 */
	public void createHECFromIncoming() throws ServiceException {
		// Copy the military service information object on the incoming person
		// to HEC if person does not have hec record yet

		Person onFile = this.getResultPerson();
		MilitaryService currentMilitaryService = onFile.getMilitaryService();
		if( currentMilitaryService == null ) {
			onFile.setMilitaryService( (currentMilitaryService = new MilitaryService()) );
		}

		// Get the site data from incoming veteran.
		MilitaryService incomingMilitaryService = this.getMilitaryServiceInputData().getMilitaryService();
		if( incomingMilitaryService != null )
		{
			// For Messaging add/update only the incoming site record. The incoming military service object for messaging
			// should have only one site record, but any way go in to loop.
			Set incomingSiteRecords = incomingMilitaryService.getMilitaryServiceSiteRecords();
			if(!incomingSiteRecords.isEmpty()){
				for(Iterator iter=incomingSiteRecords.iterator(); iter.hasNext();)
				{
					MilitaryServiceSiteRecord incomingSiteRecord = (MilitaryServiceSiteRecord)iter.next();
					if(incomingSiteRecord != null)
					{
						MilitaryServiceSiteRecord hecSiteRecord = currentMilitaryService.getHECMilitaryServiceSiteRecord();
						if(hecSiteRecord == null)
						{
							hecSiteRecord = new MilitaryServiceSiteRecord();
							this.getMergeRuleService().mergeIncomingMSEToHEC(incomingSiteRecord,hecSiteRecord);
							hecSiteRecord.setSite(getLookupService()
									.getVaFacilityByCode(
											VAFacility.CODE_HEC.getName()));
							currentMilitaryService.addMilitaryServiceSiteRecord(hecSiteRecord);
						}
					}
				}

			}


		}
	}


	public boolean isHecTransfer(){
		return this.getMilitaryServiceInputData().isTransferToHec();
	}

	//10634 changes
//	 CodeCR 10634
	public boolean hasMatchingImpreciseDate() throws ServiceException {
		MilitaryServiceEpisode mse = this.getMSEFromMSDS();
		Set mses = this.getHECMSEs(this.getResultPerson().getMilitaryService());
		this.setMatchedMSE(null); // Reset each time called CodeCR10610 since
		// ILOG loops
		if (mse != null && mse.getStartDate() != null
				&& mse.getEndDate() != null) {
			if (mses != null && !mses.isEmpty()) {
				for (Iterator iter = mses.iterator(); iter.hasNext();) {
					MilitaryServiceEpisode hecmse = (MilitaryServiceEpisode) iter
					.next();
					if (hecmse.getStartDate().isImprecise()
							|| hecmse.getEndDate().isImprecise()) {
						if (impreciseDateMatch(hecmse.getStartDate(), hecmse
								.getEndDate(), mse)) {
							this.setMatchedMSE(hecmse);
							return true;
						}

					}
				}

			}

		}

		return false;

	}

	private boolean impreciseDateMatch(ImpreciseDate hecStartDate, ImpreciseDate hecEndDate, MilitaryServiceEpisode incomingMSE){
		if(hecStartDate.isImprecise()){
			return impreciseMatchCheck(hecStartDate, incomingMSE.getStartDate());

		}
		else if(hecEndDate.isImprecise()){
			return impreciseMatchCheck(hecEndDate, incomingMSE.getEndDate());

		}

		return false;


	}

	private boolean impreciseMatchCheck(ImpreciseDate hecDate, ImpreciseDate incomingDate){
		if(!hecDate.isDayPrecise() && !hecDate.isMonthPrecise()){
			if(hecDate.getYear().equals(incomingDate.getYear())){
				return true;
			}
		}
		else if(!hecDate.isDayPrecise()){
			if(hecDate.getYear().equals(incomingDate.getYear()) && hecDate.getMonth().equals(incomingDate.getMonth())){
				return true;
			}
		}
		return false;
	}

	public void acceptPreciseServiceEpisodeFromMSDS() throws ServiceException {

		MilitaryServiceEpisode mse = this.getMatchedMSE();
		MilitaryServiceEpisode incomingMse = this.getMSEFromMSDS();
		if (mse != null && incomingMse != null) {
			this.getMergeRuleService().mergeMilitaryServiceEpisode(incomingMse, mse);
		}

	}

	public boolean hasImpreciseData() {
		if( this.getRuleDataAware() instanceof MilitaryServiceInputData ) {
			return ((MilitaryServiceInputData)this.getRuleDataAware()).isImpreciseData();
		}
		return false;
	}

	public void setImpreciseData(boolean isImprecise) {
		MilitaryServiceInputData data = getMilitaryServiceInputData();
		if (data != null) {
			data.setImpreciseDateDetected(isImprecise);
		}
	}

	 public boolean isDischargeDueToDisabilityChanged(){
	    	Boolean incomingDisability = this.getDischargeDueToDisability();
	    	Boolean PristineDisability = this.getDischargeDueToDisability(this.getPristinePerson());
	    	if(incomingDisability !=null &&PristineDisability !=null){
	    	    	return !(this.isEqual(incomingDisability, PristineDisability));
	    	}
	    	else if(incomingDisability==null &&PristineDisability==null){
	    		return false;
	    	}
	    	else if((incomingDisability==null &&PristineDisability!=null && PristineDisability.booleanValue())||
	    			(incomingDisability!=null &&PristineDisability==null && incomingDisability.booleanValue())){
	    	    return true;
	    	}
	    	else
	    		return false;
	    }


	 public CombatEpisode getMatchedCombatEpisode() {
		 MilitaryServiceInputData data = getMilitaryServiceInputData();
		 return (data != null) ? data.getMatchedCombatEpisode() : null;
	 }

	 public void setMatchedCombatEpisode(CombatEpisode matchedCombatEpisode) {
		 MilitaryServiceInputData data = getMilitaryServiceInputData();
		 if(data != null) {
			 data.setMatchedCombatEpisode(matchedCombatEpisode);
		 }
	 }
	 //CLV
	    public boolean isResultCLVeligible()
	    {
	    	return calculateCLVeligibilitybyMSE(this.getResultPerson());
	    }
	    public boolean isResultCLVeligibleForNoHEC()
	    {
	    	return calculateCLVeligibilitybyMSEForNoHEC(this.getResultPerson());
	    }
	    public boolean isResultVeteran()
	    {
	    	if(this.getResultPerson()!=null)
	    	{
	    		if(this.getResultPerson().isVeteran())
	    		{
	    			return true;
	    		}
	    	}
	    	return false;
	    }
	    public boolean isResultCLVeligibleForNoHECNoVeteran()
	    {
	    	return calculateCLVeligibilitybyMSEForNoHECNoVeteran(this.getResultPerson());
	    }
	    public boolean isResultCLVeligibleNoVeteran()
	    {
	    	return calculateCLVeligibilitybyMSENoVeteran(this.getResultPerson());
	    }
	    public boolean isPristineCLVeligibile(){
	    	return calculateCLVeligibilitybyMSE(this.getPristinePerson());
	    }
	    public boolean isIncomingCLVeligibile(){
	    	return calculateCLVeligibilitybyMSE(this.getIncomingPerson());
	    }
	    public boolean isCLVEligibleSamePOn()
	    {
	    	return (isResultCLVeligible()==isPristineCLVeligibile());
	    }
	    public boolean isCLVEligibleNoToYesPOn()
	    {
	    	if(isPristineCLVeligibile()==false && isResultCLVeligible()== true)
	    	{
	    		  return true;
	    	}
	    	if(isCLVEligibleSamePOn())
	    		  return true;

	    	return false;
	    }
	    public boolean calculateCLVeligibilitybyMSE(Person person) {

	    	long totalServiceDays =0;
	    	ImpreciseDate startday = new ImpreciseDate("19530801");
	    	ImpreciseDate endday = new ImpreciseDate("19871231");
	    	Set<MilitaryServiceSiteRecord> mssrs = person.getMilitaryService().getMilitaryServiceSiteRecords();
	    	VAFacility site = null;
	    	for( MilitaryServiceSiteRecord mssr : mssrs )
	    	{
	    		site = mssr.getSite();
				if (site== null || !site.getStationNumber().equals(VAFacility.CODE_HEC.getName()))
				{
					continue;
				}

	    		Set<MilitaryServiceEpisode> mses = mssr.getMilitaryServiceEpisodes();
	    		for(MilitaryServiceEpisode mse :mses)
	    		{
	    			if((mse.getDischargeType() !=null) &&(! mse.getDischargeType().getCode().equals(DischargeType.CODE_BAD_CONDUCT.getCode()))
	    					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_DISHONORABLE.getCode()))
	    					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_OTHER_THAN_HONORABLE.getCode()))
	    					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_DISHONORABLE_VA.getCode()))
	    					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_UNDESIRABLE.getCode())))
	    			{

	    				if (person.isVeteran())
	    				{
	    					/*boolean test = CommonDateUtils.isDateBefore(mse.getStartDate(), endday);
							boolean test1 = CommonDateUtils.isDateAfter(mse.getStartDate(), startday);
							boolean test2 = CommonDateUtils.isDateAfter(mse.getEndDate(), endday);

	    					System.out.println("Is MSE Start before the endday:" +test);
							System.out.println("Is MSE Start after the startday:" +test1);
							System.out.println("Is MSE End after the endday:" +test2);*/


	    					if((CommonDateUtils.isDateAfter(mse.getStartDate(), startday) || startday.equals(mse.getStartDate()))
	    							&& (CommonDateUtils.isDateBefore(mse.getEndDate(), endday) ||endday.equals(mse.getEndDate()))
	    					)
	    					{
	    						totalServiceDays+=CommonDateUtils.getDays(mse.getStartDate(),mse.getEndDate());

	    					}
	    					else if((CommonDateUtils.isDateAfter(mse.getEndDate(), startday) || startday.equals(mse.getEndDate()) )
	    							&& (CommonDateUtils.isDateBefore(mse.getStartDate(), startday)|| startday.equals(mse.getStartDate()))
	    							&& (CommonDateUtils.isDateBefore(mse.getEndDate(), endday) ||endday.equals(mse.getEndDate())))
	    					{
	    						totalServiceDays+=CommonDateUtils.getDays(startday,mse.getEndDate());

	    					}
	    					else if((CommonDateUtils.isDateAfter(mse.getEndDate(), endday)||endday.equals(mse.getEndDate()))
	    							&& (CommonDateUtils.isDateBefore(mse.getStartDate(), startday)|| startday.equals(mse.getStartDate()))
	    					)
	    					{
	    						totalServiceDays+=CommonDateUtils.getDays(startday,endday);

	    					}
	    					else if(CommonDateUtils.isDateBefore(mse.getStartDate(), endday)==true || endday.equals(mse.getStartDate()))
	    					{

	    						if (CommonDateUtils.isDateAfter(mse.getStartDate(), startday) ==true || startday.equals(mse.getStartDate()))
	    						{
	    							if (CommonDateUtils.isDateAfter(mse.getEndDate(), endday) ==true || endday.equals(mse.getEndDate()))
	    							{
	    							/*	boolean test = CommonDateUtils.isDateBefore(mse.getStartDate(), endday);
	    								boolean test1 = CommonDateUtils.isDateAfter(mse.getStartDate(), startday);
	    								boolean test2 = CommonDateUtils.isDateAfter(mse.getEndDate(), endday);
	    								System.out.println("Is MSE Start before the endday:" +test);
	    								System.out.println("Is MSE Start after the startday:" +test1);
	    								System.out.println("Is MSE End after the endday:" +test2);*/

	    								totalServiceDays+=CommonDateUtils.getDays(mse.getStartDate(),endday);

	    							}
	    						}
	    					}
	    				}
	    			}
	    		}
	    	}
	    	if (totalServiceDays>=30)
	    		return true;
	    	else
	    		return false;
	    }

 public boolean calculateCLVeligibilitybyMSEForNoHEC(Person person) {

	    	long totalServiceDays =0;
	    	ImpreciseDate startday = new ImpreciseDate("19530801");
	    	ImpreciseDate endday = new ImpreciseDate("19871231");
	    	Set<MilitaryServiceSiteRecord> mssrs = person.getMilitaryService().getMilitaryServiceSiteRecords();
	    	VAFacility site = null;
	    	for( MilitaryServiceSiteRecord mssr : mssrs )
	    	{
	    		site = mssr.getSite();
				if (site== null || site.getStationNumber().equals(VAFacility.CODE_HEC.getName()))
				{
					continue;
				}

	    		Set<MilitaryServiceEpisode> mses = mssr.getMilitaryServiceEpisodes();
	    		for(MilitaryServiceEpisode mse :mses)
	    		{
	    			if((mse.getDischargeType() !=null) &&(! mse.getDischargeType().getCode().equals(DischargeType.CODE_BAD_CONDUCT.getCode()))
	    					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_DISHONORABLE.getCode()))
	    					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_OTHER_THAN_HONORABLE.getCode()))
	    					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_DISHONORABLE_VA.getCode()))
	    					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_UNDESIRABLE.getCode())))
	    			{

	    				if (person.isVeteran())
	    				{
	    					/*boolean test = CommonDateUtils.isDateBefore(mse.getStartDate(), endday);
							boolean test1 = CommonDateUtils.isDateAfter(mse.getStartDate(), startday);
							boolean test2 = CommonDateUtils.isDateAfter(mse.getEndDate(), endday);

	    					System.out.println("Is MSE Start before the endday:" +test);
							System.out.println("Is MSE Start after the startday:" +test1);
							System.out.println("Is MSE End after the endday:" +test2);*/


	    					if((CommonDateUtils.isDateAfter(mse.getStartDate(), startday) || startday.equals(mse.getStartDate()))
	    							&& (CommonDateUtils.isDateBefore(mse.getEndDate(), endday) ||endday.equals(mse.getEndDate()))
	    					)
	    					{
	    						totalServiceDays+=CommonDateUtils.getDays(mse.getStartDate(),mse.getEndDate());

	    					}
	    					else if((CommonDateUtils.isDateAfter(mse.getEndDate(), startday) || startday.equals(mse.getEndDate()) )
	    							&& (CommonDateUtils.isDateBefore(mse.getStartDate(), startday)|| startday.equals(mse.getStartDate()))
	    							&& (CommonDateUtils.isDateBefore(mse.getEndDate(), endday) ||endday.equals(mse.getEndDate())))
	    					{
	    						totalServiceDays+=CommonDateUtils.getDays(startday,mse.getEndDate());

	    					}
	    					else if((CommonDateUtils.isDateAfter(mse.getEndDate(), endday)||endday.equals(mse.getEndDate()))
	    							&& (CommonDateUtils.isDateBefore(mse.getStartDate(), startday)|| startday.equals(mse.getStartDate()))
	    					)
	    					{
	    						totalServiceDays+=CommonDateUtils.getDays(startday,endday);

	    					}
	    					else if(CommonDateUtils.isDateBefore(mse.getStartDate(), endday)==true || endday.equals(mse.getStartDate()))
	    					{

	    						if (CommonDateUtils.isDateAfter(mse.getStartDate(), startday) ==true || startday.equals(mse.getStartDate()))
	    						{
	    							if (CommonDateUtils.isDateAfter(mse.getEndDate(), endday) ==true || endday.equals(mse.getEndDate()))
	    							{
	    							/*	boolean test = CommonDateUtils.isDateBefore(mse.getStartDate(), endday);
	    								boolean test1 = CommonDateUtils.isDateAfter(mse.getStartDate(), startday);
	    								boolean test2 = CommonDateUtils.isDateAfter(mse.getEndDate(), endday);
	    								System.out.println("Is MSE Start before the endday:" +test);
	    								System.out.println("Is MSE Start after the startday:" +test1);
	    								System.out.println("Is MSE End after the endday:" +test2);*/

	    								totalServiceDays+=CommonDateUtils.getDays(mse.getStartDate(),endday);

	    							}
	    						}
	    					}
	    				}
	    			}
	    		}
	    	}
	    	if (totalServiceDays>=30)
	    		return true;
	    	else
	    		return false;
	    }


 ////////////////////////////////////////////////////Veteran Indicator/////////////////////////////////
 public boolean calculateCLVeligibilitybyMSENoVeteran(Person person) {

 	long totalServiceDays =0;
 	ImpreciseDate startday = new ImpreciseDate("19530801");
 	ImpreciseDate endday = new ImpreciseDate("19871231");
 	Set<MilitaryServiceSiteRecord> mssrs = person.getMilitaryService().getMilitaryServiceSiteRecords();
 	VAFacility site = null;
 	for( MilitaryServiceSiteRecord mssr : mssrs )
 	{
 		site = mssr.getSite();
 		if (site== null || !site.getStationNumber().equals(VAFacility.CODE_HEC.getName()))
 		{
 			continue;
 		}

 		Set<MilitaryServiceEpisode> mses = mssr.getMilitaryServiceEpisodes();
 		for(MilitaryServiceEpisode mse :mses)
 		{
 			if((mse.getDischargeType() !=null) &&(! mse.getDischargeType().getCode().equals(DischargeType.CODE_BAD_CONDUCT.getCode()))
 					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_DISHONORABLE.getCode()))
 					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_OTHER_THAN_HONORABLE.getCode()))
 					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_DISHONORABLE_VA.getCode()))
 					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_UNDESIRABLE.getCode())))
 			{

 				//if (person.isVeteran())
 				//{
 				/*boolean test = CommonDateUtils.isDateBefore(mse.getStartDate(), endday);
						boolean test1 = CommonDateUtils.isDateAfter(mse.getStartDate(), startday);
						boolean test2 = CommonDateUtils.isDateAfter(mse.getEndDate(), endday);

 					System.out.println("Is MSE Start before the endday:" +test);
						System.out.println("Is MSE Start after the startday:" +test1);
						System.out.println("Is MSE End after the endday:" +test2);*/


 				if((CommonDateUtils.isDateAfter(mse.getStartDate(), startday) || startday.equals(mse.getStartDate()))
 						&& (CommonDateUtils.isDateBefore(mse.getEndDate(), endday) ||endday.equals(mse.getEndDate()))
 				)
 				{
 					totalServiceDays+=CommonDateUtils.getDays(mse.getStartDate(),mse.getEndDate());

 				}
 				else if((CommonDateUtils.isDateAfter(mse.getEndDate(), startday) || startday.equals(mse.getEndDate()) )
 						&& (CommonDateUtils.isDateBefore(mse.getStartDate(), startday)|| startday.equals(mse.getStartDate()))
 						&& (CommonDateUtils.isDateBefore(mse.getEndDate(), endday) ||endday.equals(mse.getEndDate())))
 				{
 					totalServiceDays+=CommonDateUtils.getDays(startday,mse.getEndDate());

 				}
 				else if((CommonDateUtils.isDateAfter(mse.getEndDate(), endday)||endday.equals(mse.getEndDate()))
 						&& (CommonDateUtils.isDateBefore(mse.getStartDate(), startday)|| startday.equals(mse.getStartDate()))
 				)
 				{
 					totalServiceDays+=CommonDateUtils.getDays(startday,endday);

 				}
 				else if(CommonDateUtils.isDateBefore(mse.getStartDate(), endday)==true || endday.equals(mse.getStartDate()))
 				{

 					if (CommonDateUtils.isDateAfter(mse.getStartDate(), startday) ==true || startday.equals(mse.getStartDate()))
 					{
 						if (CommonDateUtils.isDateAfter(mse.getEndDate(), endday) ==true || endday.equals(mse.getEndDate()))
 						{
 							/*	boolean test = CommonDateUtils.isDateBefore(mse.getStartDate(), endday);
 								boolean test1 = CommonDateUtils.isDateAfter(mse.getStartDate(), startday);
 								boolean test2 = CommonDateUtils.isDateAfter(mse.getEndDate(), endday);
 								System.out.println("Is MSE Start before the endday:" +test);
 								System.out.println("Is MSE Start after the startday:" +test1);
 								System.out.println("Is MSE End after the endday:" +test2);*/

 							totalServiceDays+=CommonDateUtils.getDays(mse.getStartDate(),endday);

 						}
 					}
 				}
 			}
 		}
 	}
 	//}
 	if (totalServiceDays>=30)
 		return true;
 	else
 		return false;
 }

public boolean calculateCLVeligibilitybyMSEForNoHECNoVeteran(Person person) {

 	long totalServiceDays =0;
 	ImpreciseDate startday = new ImpreciseDate("19530801");
 	ImpreciseDate endday = new ImpreciseDate("19871231");
 	Set<MilitaryServiceSiteRecord> mssrs = person.getMilitaryService().getMilitaryServiceSiteRecords();
 	VAFacility site = null;
 	for( MilitaryServiceSiteRecord mssr : mssrs )
 	{
 		site = mssr.getSite();
			if (site== null || site.getStationNumber().equals(VAFacility.CODE_HEC.getName()))
			{
				continue;
			}

 		Set<MilitaryServiceEpisode> mses = mssr.getMilitaryServiceEpisodes();
 		for(MilitaryServiceEpisode mse :mses)
 		{
 			if((mse.getDischargeType() !=null) &&(! mse.getDischargeType().getCode().equals(DischargeType.CODE_BAD_CONDUCT.getCode()))
 					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_DISHONORABLE.getCode()))
 					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_OTHER_THAN_HONORABLE.getCode()))
 					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_DISHONORABLE_VA.getCode()))
 					&& (! mse.getDischargeType().getCode().equals(DischargeType.CODE_UNDESIRABLE.getCode())))
 			{

 				//if (person.isVeteran())
 				//{
 					/*boolean test = CommonDateUtils.isDateBefore(mse.getStartDate(), endday);
						boolean test1 = CommonDateUtils.isDateAfter(mse.getStartDate(), startday);
						boolean test2 = CommonDateUtils.isDateAfter(mse.getEndDate(), endday);

 					System.out.println("Is MSE Start before the endday:" +test);
						System.out.println("Is MSE Start after the startday:" +test1);
						System.out.println("Is MSE End after the endday:" +test2);*/


 					if((CommonDateUtils.isDateAfter(mse.getStartDate(), startday) || startday.equals(mse.getStartDate()))
 							&& (CommonDateUtils.isDateBefore(mse.getEndDate(), endday) ||endday.equals(mse.getEndDate()))
 					)
 					{
 						totalServiceDays+=CommonDateUtils.getDays(mse.getStartDate(),mse.getEndDate());

 					}
 					else if((CommonDateUtils.isDateAfter(mse.getEndDate(), startday) || startday.equals(mse.getEndDate()) )
 							&& (CommonDateUtils.isDateBefore(mse.getStartDate(), startday)|| startday.equals(mse.getStartDate()))
 							&& (CommonDateUtils.isDateBefore(mse.getEndDate(), endday) ||endday.equals(mse.getEndDate())))
 					{
 						totalServiceDays+=CommonDateUtils.getDays(startday,mse.getEndDate());

 					}
 					else if((CommonDateUtils.isDateAfter(mse.getEndDate(), endday)||endday.equals(mse.getEndDate()))
 							&& (CommonDateUtils.isDateBefore(mse.getStartDate(), startday)|| startday.equals(mse.getStartDate()))
 					)
 					{
 						totalServiceDays+=CommonDateUtils.getDays(startday,endday);

 					}
 					else if(CommonDateUtils.isDateBefore(mse.getStartDate(), endday)==true || endday.equals(mse.getStartDate()))
 					{

 						if (CommonDateUtils.isDateAfter(mse.getStartDate(), startday) ==true || startday.equals(mse.getStartDate()))
 						{
 							if (CommonDateUtils.isDateAfter(mse.getEndDate(), endday) ==true || endday.equals(mse.getEndDate()))
 							{
 							/*	boolean test = CommonDateUtils.isDateBefore(mse.getStartDate(), endday);
 								boolean test1 = CommonDateUtils.isDateAfter(mse.getStartDate(), startday);
 								boolean test2 = CommonDateUtils.isDateAfter(mse.getEndDate(), endday);
 								System.out.println("Is MSE Start before the endday:" +test);
 								System.out.println("Is MSE Start after the startday:" +test1);
 								System.out.println("Is MSE End after the endday:" +test2);*/

 								totalServiceDays+=CommonDateUtils.getDays(mse.getStartDate(),endday);

 							}
 						}
 					}
 				//}
 			}
 		}
 	}
 	if (totalServiceDays>=30)
 		return true;
 	else
 		return false;
 }








}