/**
 *
 */
package gov.va.med.esr.service;
import java.util.Collections;
import java.util.List;
import gov.va.med.fw.persistent.DAOOperations;
import gov.va.med.esr.service.EEResultInfo;
import gov.va.med.esr.UseCaseName;
import gov.va.med.fw.util.ObjectUtils;
import gov.va.med.esr.service.PersonIdentityTraits;
import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.common.infra.ImpreciseDateUtils;
import gov.va.med.esr.common.util.CommonDateUtils;
import org.apache.commons.lang.time.DateUtils;
import gov.va.med.esr.common.model.CommonEntityKeyFactory;
import gov.va.med.esr.common.persistent.person.hibernate.PersonEntityCacheAdvice;
import gov.va.med.esr.common.model.comms.CommsLogEntry;
import gov.va.med.esr.common.model.comms.MailingStatusLink;
import gov.va.med.esr.common.model.ee.CombatEpisode;
import gov.va.med.esr.common.model.ee.Eligibility;
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.RatedDisability;
import gov.va.med.esr.common.model.ee.ServiceConnectionAward;
import gov.va.med.esr.common.model.ee.VerificationInfo;
import gov.va.med.esr.common.model.financials.Asset;
import gov.va.med.esr.common.model.financials.Debt;
import gov.va.med.esr.common.model.financials.DependentFinancials;
import gov.va.med.esr.common.model.financials.Expense;
import gov.va.med.esr.common.model.financials.FinancialInformation;
import gov.va.med.esr.common.model.financials.Hardship;
import gov.va.med.esr.common.model.financials.Income;
import gov.va.med.esr.common.model.financials.IncomeTest;
import gov.va.med.esr.common.model.financials.IncomeTestStatus;
import gov.va.med.esr.common.model.financials.PatientVisitSummary;
import gov.va.med.esr.common.model.financials.FinancialStatement;
import gov.va.med.esr.common.model.financials.SpouseFinancials;
import gov.va.med.esr.common.model.insurance.InsuranceSubscriber;
import gov.va.med.esr.common.model.insurance.Medicare;
import gov.va.med.esr.common.model.ivmdm.IVMMigration;
import gov.va.med.esr.common.model.lookup.AACIndicator;
import gov.va.med.esr.common.model.lookup.AddressType;
import gov.va.med.esr.common.model.lookup.AssetType;
import gov.va.med.esr.common.model.lookup.BadAddressReason;
import gov.va.med.esr.common.model.lookup.ConflictLocation;
import gov.va.med.esr.common.model.lookup.DischargeType;
import gov.va.med.esr.common.model.lookup.EligibilityStatus;
import gov.va.med.esr.common.model.lookup.EligibilityType;
import gov.va.med.esr.common.model.lookup.EligibilityVerificationSource;
import gov.va.med.esr.common.model.lookup.EmploymentStatus;
import gov.va.med.esr.common.model.lookup.EnrollmentPriorityGroup;
import gov.va.med.esr.common.model.lookup.EnrollmentStatus;
import gov.va.med.esr.common.model.lookup.EnrollmentPrioritySubGroup;
import gov.va.med.esr.common.model.lookup.ExpenseType;
import gov.va.med.esr.common.model.lookup.Gender;
import gov.va.med.esr.common.model.lookup.IncomeTestSource;
import gov.va.med.esr.common.model.lookup.IncomeTestType;
import gov.va.med.esr.common.model.lookup.IncomeType;
import gov.va.med.esr.common.model.lookup.InsuredRelationship;
import gov.va.med.esr.common.model.lookup.MeansTestStatus;
import gov.va.med.esr.common.model.lookup.MessageStatus;
import gov.va.med.esr.common.model.lookup.MessageType;
import gov.va.med.esr.common.model.lookup.Relationship;
import gov.va.med.esr.common.model.lookup.SSAVerificationStatus;
import gov.va.med.esr.common.model.lookup.SSNType;
import gov.va.med.esr.common.model.lookup.SourceDesignation;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.lookup.WkfCaseStatusType;
import gov.va.med.esr.common.model.party.Address;
import gov.va.med.esr.common.model.person.Dependent;
import gov.va.med.esr.common.model.person.Employment;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.PreferredFacility;
import gov.va.med.esr.common.model.person.SSN;
import gov.va.med.esr.common.model.person.Name;
import gov.va.med.esr.common.model.person.Spouse;
import gov.va.med.esr.service.IVMFinancialInfo;
import gov.va.med.esr.common.model.lookup.EmailSourceOfChange;
import gov.va.med.esr.common.model.party.Email;
import gov.va.med.esr.service.external.person.EESummary;
import gov.va.med.esr.service.external.person.IVMCandidateInfo;
import gov.va.med.esr.service.external.person.IvmLetterCandidateInfo;
import gov.va.med.esr.service.impl.FinancialsChangeEvent;
import gov.va.med.esr.service.impl.FinancialsHelperServiceImpl;
import gov.va.med.esr.common.model.person.id.PersonEntityKey;
import gov.va.med.esr.common.model.person.id.PersonIdEntityKeyImpl;
import gov.va.med.esr.common.persistent.history.FinancialsHistoryDAO;
import gov.va.med.esr.common.persistent.person.PersonSubmittedAdvice;
import gov.va.med.esr.common.rule.data.FinancialInputData;
import gov.va.med.esr.common.rule.parameter.FinancialInputParameter;
import gov.va.med.esr.common.util.RuleAbstractTestCase;
import gov.va.med.fw.persistent.DAOException;
import gov.va.med.fw.persistent.DAOOperations;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.model.EntityKey;
import gov.va.med.fw.util.StringUtils;
import gov.va.med.fw.validation.ValidationServiceException;
import gov.va.med.esr.service.impl.ChangeEvent;
import gov.va.med.esr.service.impl.FinancialsChangeEvent;
import gov.va.med.esr.service.impl.HistoricalInfo;
import gov.va.med.esr.service.PersonService;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import gov.va.med.esr.common.model.financials.BeneficiaryTravel;
import  gov.va.med.esr.service.external.FinancialsSummaryFactory;
import  gov.va.med.esr.service.external.FinancialsSummaryFactoryImpl;

/**
 * @author DNS   ruizc
 *
 */
public class IvmInteractionsTest extends RuleAbstractTestCase {
	private DAOOperations genericDAO = null;
	private static final String PERSON_ID_PARAM_NAME = "personId";
	private IVMDMService ivmDMService;
	private static final String QUERY_GET_LATEST_MIGRATED_YEAR_BY_PERSON = "ivmDMQuery_GetLastedMigratedYearByPerson";
	private static final ExpenseType.Code[]     EXPENSE_TYPES_VETERAN      = {
		ExpenseType.EXPENSE_TYPE_FUNERAL_AND_BURIAL,
		ExpenseType.EXPENSE_TYPE_COLLEGE_AND_VOCATION};

	private static final ExpenseType.Code[]     EXPENSE_TYPES_DEPENDENT    = { ExpenseType.EXPENSE_TYPE_EDUCATIONAL_EXPENSES_BY_DEPENDENT};
	private static final Relationship.Code[]     DEPENDENT_RELATIONSHIPS    = { Relationship.CODE_DAUGHTER,
		Relationship.CODE_SON, Relationship.CODE_STEPSON,
		Relationship.CODE_STEPDAUGHTER};

	/**
	 * @param arg0
	 */
	public IvmInteractionsTest(String arg0) {
		super(arg0);
	}

	public void testBTFIReverseAConversion() throws Exception {
        Integer conversionIncomeYear = new Integer(2012);
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("373971922"));
		Person onFile = this.getPersonService().getPerson(personKey);
		Person incoming = (Person) onFile.clone();;
		assertTrue(incoming.getIncomeTest(conversionIncomeYear).getBtFinancialInd());

        IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("R");
		ivmFinancialInfo.setBtFinancialInd(Boolean.TRUE);

		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		IncomeTest result = updated.getIncomeTest(conversionIncomeYear);
		assertNull(result.getBtFinancialInd());

	}	
	
	
	public void testBTFinancialIndFromNonConversionRequest() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2012);

		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_VAMC.getCode());
		attachVerifiedEnrollment(onFile);
		setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		assertNull(incoming.getIncomeTest(incomeYear).getBtFinancialInd());    
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(incomeYear);
		ivmFinancialInfo.setIvmActionCode("N");
		ivmFinancialInfo.setBtFinancialInd(Boolean.TRUE);

		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		IncomeTest result = this.getPersonHelperService().getCurrentIncomeTest(updated);
		assertNull(result.getBtFinancialInd());
	}		
	
	/**
	 * Need to avoid copying the BT Financial Indicator during the 
	 * income test merge. ES is supposed to preserve the value when
	 * a Z07 is received. The only source that can change it is the 
	 * IVM Bidi interface and it will do so by setting the single 
	 * value after its normal processing for 
	 * conversion/reversal/non-conversion. 
	 * 
	 * @throws Exception
	 */
	public void testBTFinancialIndMerge() throws Exception {
		Person onFile = buildSimplePerson(); 
		Integer incomeYear = new Integer(2012);
		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_VAMC.getCode());
        IncomeTest original = onFile.getIncomeTest(incomeYear);
        
		Person incoming = savePerson(onFile);
		
		incoming.getIncomeTest(incomeYear).setBtFinancialInd(Boolean.TRUE);
		
		this.getMergeRuleService().mergeIncomeTest(incoming.getIncomeTest(incomeYear), original);
		assertNull(original.getBtFinancialInd());
		/**
		 * Not copying the indicator preserves on-file value and meets user story
		 * requirements. 
		 */
	}			
	
	public void testBTEligibleTriggerZ07() throws Exception {
		Person onFile = buildSimplePerson();
		// this.attachDeathRecord(onFile);
		this.setEligibilityStatusToVerified(onFile);
		onFile.getEligibilityVerification().setAacIndicator(
				this.getLookupService().getAACIndicatorByCode(
						AACIndicator.CODE_DATA_ACCEPTED.getName()));
		this.attachVerifiedEnrollment(onFile);
		// this.setEnrollmentStatus(EnrollmentStatus.CODE_PENDING_ELIGIBILITY_STATUS_IS_UNVERIFIED.getCode(),
		// onFile);
		this.attachServiceConnectionAward(onFile, new Integer(80));
		this.attachMilitaryService(onFile);
		MilitaryServiceEpisode mse = new MilitaryServiceEpisode();
		mse.setServiceBranch(this.getRandomServiceBranch());
		mse.setDischargeType(this.getLookupService().getDischargeTypeByCode(DischargeType.CODE_HONORABLE.getCode()));
		mse.setStartDate(ImpreciseDateUtils.createImpreciseDate(2008, 1, 1));
		mse.setEndDate(ImpreciseDateUtils.createImpreciseDate(2009, 1, 1));
		mse.setServiceNumber("12345");
		MilitaryServiceSiteRecord m = this.createMilitaryServiceSireRecord();
		m.setSite(this.getLookupService().getVaFacilityByStationNumber(VAFacility.CODE_HEC.getName()));
		m.addMilitaryServiceEpisode(mse);
		onFile.getMilitaryService().addMilitaryServiceSiteRecord(m);
		CombatEpisode ce = new CombatEpisode();
		ce.setConflictLocation(this.getLookupService().getConflictByCode(ConflictLocation.CODE_UNKNOWN_OEF_OIF.getCode()));
		ce.setStartDate(ImpreciseDateUtils.createImpreciseDate(2002,2,1));
		ce.setEndDate(ImpreciseDateUtils.createImpreciseDate(2007,11,1));
		onFile.getMilitaryService().addCombatEpisode(ce);
		VAFacility va = this.getRandomVAFacility();
		IncomeTest incomeTest = this.createIncomeTest(IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED, new Integer(2011));
		incomeTest.setSource(this.getLookupService().getIncomeTestSourceByCode(IncomeTestSource.CODE_VAMC.getCode()));
		incomeTest.setSiteConductingTest(va);
		Integer iy = new Integer(2011);
		onFile.setIncomeTest(iy, incomeTest);
		onFile.getEligibilityVerification().setVerificationFacility(va);
		
		Person incoming = this.savePerson(onFile);
		this.addPermanentAddress(incoming, Calendar.getInstance().getTime(),
				null);
		VerificationInfo vi = new VerificationInfo("x",
				MessageType.CODE_ORUZ07_TO_ESR.getCode(), "x");

		vi.setSiteNumber(incoming.getEligibilityVerification()
				.getVerificationFacility().getCode());
		incoming.setBeneficiaryTravel(iy, va, createBeneficiaryTravel(new Integer(2011), va));
		Person updated = this.getMessagingService().processZ07(incoming, va, vi);
		assertTrue(updated.getChangeEvents().containsKey(UseCaseName.BT_IND_CHANGE));
	}	
	
	public void testBTFinancialIndFromConversionRequest() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		// SAME INCOME YEAR as conversion
		Integer incomeYear = new Integer(2012);
        // NOTICE THAT IVM TEST IY is same as ONFILE
	    Integer conversionIncomeYear = incomeYear;
		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_VAMC.getCode());
		attachVerifiedEnrollment(onFile);
		setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
        Person pristine = (Person) onFile.clone();
        IncomeTest original = pristine.getIncomeTest(incomeYear);

        IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		ivmFinancialInfo.setBtFinancialInd(Boolean.TRUE);

        incoming.removeAllIncomeTests();
		this.attachIVMConversionTest(incoming, conversionIncomeYear, true, true, "MT");

		FinancialInputData data = new FinancialInputData(incoming, onFile, pristine, ivmFinancialInfo );
		FinancialInputParameter param = this.buildFinancialInputParameter(data);
		//****************************************************************
		//****************************************************************
		// NOTICE THAT DON'T HAVE TO CALL CLONE TEST
		param.createOrUpdateTestFromIVMConversionData(true);
		//****************************************************************
		//****************************************************************
		this.applyAssertionsUpdateTest(onFile, incoming, original, conversionIncomeYear, site);
		IncomeTest result = onFile.getIncomeTest(conversionIncomeYear);
		assertNotNull(result.getBtFinancialInd());		
		assertTrue(result.getBtFinancialInd().booleanValue());
	}	
	
	public void testBTIndicatorTrigger() throws Exception {
		VAFacility site = this.getRandomVAFacility();
		Person onFile = buildSimplePerson(); // bare-bones person
        Integer incomeYear = new Integer(2012);
        this.attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());
        onFile.setBeneficiaryTravel(incomeYear, site, null);
        Person incoming = savePerson(onFile);
        Person pristine = (Person)incoming.clone();
        
        BeneficiaryTravel bt = this.createBeneficiaryTravel(incomeYear, site);
        incoming.setBeneficiaryTravel(incomeYear, site, bt);
		assertNull(onFile.getBeneficiaryTravel(incomeYear, site));
		
        FinancialInputData data = new FinancialInputData(incoming,
                onFile, pristine, incomeYear, site , false);
		FinancialInputParameter param = this.buildFinancialInputParameter(data);

		param.processBeneficiaryTravel();
		assertTrue(onFile.getBeneficiaryTravel(incomeYear, site) != null);
		assertTrue(onFile.getChangeEvents().containsKey(UseCaseName.BT_IND_CHANGE));

	}	
	
    public void testBTFinancialInd() throws Exception {
    	Person p = this.buildSimplePerson();
    	Integer iy = new Integer(2013);
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED, iy);
		incomeTest.setBtFinancialInd(Boolean.FALSE);
    	p.setIncomeTest(iy, incomeTest);
    	
    	Person incoming = this.savePerson(p);
    	incoming.getIncomeTest(iy).setBtFinancialInd(Boolean.TRUE);
    	assertTrue(incoming.getIncomeTest(iy).getBtFinancialInd());
    	IncomeTest onFile = new IncomeTest();
    	IncomeTest result = this.getMergeRuleService().mergeIncomeTest(incoming.getIncomeTest(iy), onFile);
    	assertTrue(result.getBtFinancialInd());
    	System.out.println(result.toString());
    }

    
	public void testFinancialsHistory() throws Exception {


		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("373971922"));
		Person onFile = this.getPersonService().getPerson(personKey);
		FinancialsHistoryDAO dao = (FinancialsHistoryDAO)this.applicationContext.getBean("financialsHistoryDAO");

		Integer year = new Integer(2009);
		IncomeTest test = dao.findConversionBaseTest(onFile.getIncomeTest(year));


		Set times = this.getFinancialsService().getFinancialAssessmentHistoryChangeTimes(onFile.getEntityKey(), year);
		Iterator iterTimes = times.iterator();
		FinancialsChangeEvent eventTarget = null;
		for (Iterator i = iterTimes ; i.hasNext();) {
			ChangeEvent event = (ChangeEvent)i.next();
			System.out.println("====================");
			System.out.println("event= "+event.getTimeStamp());
			System.out.println("====================");
			if (test.getModifiedOn().equals(event.getTimeStamp())) {
				eventTarget = new FinancialsChangeEvent(event.getTimeStamp(), test.getEntityKey(), year);
				break;
			}
		}

		HistoricalInfo info = this.getFinancialsService().getFinancialAssessmentHistoryByChangeTime(eventTarget);
		System.out.println("info="+info);
		IncomeTest t = ((Person)info.getCurrentVersion()).getIncomeTest(year);
		System.out.println("status="+t.getStatus());
//		this.getFinancialsService().getFinancialAssessmentHistoryByChangeTime();



//		System.out.println("base income test historyid= "+test.getHistoryId());
//		System.out.println("base income test modifiedon= "+test.getModifiedOn());
//		System.out.println("base status= "+test.getStatus().getDescription());
//		System.out.println("base source= "+test.getSource().getDescription());
//
//		System.out.println("========================================");
//		System.out.println("========================================");
//		System.out.println("========================================");
//		IncomeTest testOnfile = onFile.getIncomeTest(year);
//		Set statusesOnFile = testOnfile.getStatuses();
//		Iterator iterOnfile = statusesOnFile.iterator();
//		for (Iterator i = iterOnfile ; i.hasNext();) {
//			IncomeTestStatus status = (IncomeTestStatus)i.next();
//			System.out.println("====================");
//			System.out.println("onfile income test status Test Type= "+status.getType().getDescription());
//			System.out.println("onfile income test status= "+status.getStatus().getDescription());
//			System.out.println("onfile income test status modified= "+status.getModifiedOn());
//			System.out.println("onfile income test status history ID= "+status.getHistoryId()+
//					"  onfile income test status identifier= "+status.getEntityKey().getKeyValueAsString());
//			System.out.println("====================");
//		}
//		System.out.println("========================================");
//		System.out.println("========================================");
//		System.out.println("========================================");
//
		List statusesHistory = this.getFinancialsService().getIncomeTestStatusesForIVMReversal(test.getHistoryId());
		Iterator iterStatuses = statusesHistory.iterator();
		System.out.println("GETTING getIncomeTestStatusesForIVMReversal");
		System.out.println("income test modifiedon= "+test.getModifiedOn());
		for (Iterator i = iterStatuses ; i.hasNext();) {
			IncomeTestStatus status = (IncomeTestStatus)i.next();
			System.out.println("====================");
			System.out.println("history income test status Test Type= "+status.getType().getDescription());
			System.out.println("history income test status Last Edit Date= "+status.getLastEditedDate());
			System.out.println("history income test status TX code= "+status.getTransactionType().getCode());
			System.out.println("history income test status= "+status.getStatus().getDescription());
			System.out.println("history income test status modified= "+status.getModifiedOn());
			System.out.println("history income test status history ID= "+status.getHistoryId()+
					"  history income test status identifier= "+status.getEntityKey().getKeyValueAsString());
			System.out.println("====================");
		}

	}


	public void testUpdateFinancialsFromUI() throws Exception {
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("375124624"));
		Person onFile = this.getPersonService().getPerson(personKey);
		Person incoming = savePerson(onFile);
		Person updated = this.getFinancialsService().updateFinancialAssessment(
				new Integer(2012), incoming);


	}

	public void testReverseExistingMeansTest() throws Exception {
		VAFacility site = this.getRandomVAFacility();
		Person onFile = buildSimplePerson(); // bare-bones person
        Integer incomeYear = new Integer(2012);
        this.attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());
        Person incoming = savePerson(onFile);
        Person pristine = (Person)incoming.clone();

        FinancialInputData data = new FinancialInputData(incoming,
                onFile, pristine, incomeYear, site , false);
		FinancialInputParameter param = this.buildFinancialInputParameter(data);

		param.reverseExistingMeansTest();


	}
	public void testSelectivelyMergeIVMConversionDataCloneScenario() throws Exception {
		VAFacility site = this.getRandomVAFacility();
		Person onFile = buildSimplePerson(); // bare-bones person
        Integer incomeYear = new Integer(2011);
        this.attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());
        Person incoming = savePerson(onFile);
        Person pristine = (Person)incoming.clone();
        IncomeTest original = pristine.getIncomeTest(incomeYear);

        Integer conversionIY  =  new Integer(2012);
        this.attachIVMConversionTest(incoming, conversionIY, true, true, "MT");

        FinancialInputData data = new FinancialInputData(incoming,
                onFile, pristine, conversionIY, site , false);
		FinancialInputParameter param = this.buildFinancialInputParameter(data);

		IncomeTest esrIncomeTest = onFile.getIncomeTest(incomeYear);
		IncomeTest ivmData = incoming.getIncomeTest(incomeYear);
		param.partialMergeIVMConversionData(ivmData, esrIncomeTest);
		param.createOrUpdateTestFromIVMConversionData(false);
		assertNotNull(esrIncomeTest.getPg8RelaxationIndicator());
		this.applyAssertionsCreateNewTest(onFile, incoming, original, conversionIY, site, false);
	}
	
	@SuppressWarnings("unchecked")
	public void testGetIVMLetterCandidates() throws Exception {
		Set s = this.getIvmDMService().findIVMLetterStatusData();
		System.out.println("count="+s.size());
		CommsLogEntry entry = (CommsLogEntry)s.iterator().next();
		System.out.println("entry="+entry.getLatestMailingStatus().getMailingStatus().getDescription());
		
		List<MailingStatusLink> links = entry.getMailingStatusLinks();
		for (MailingStatusLink link: links) {
			System.out.println("link="+link.getMailingStatus().getDescription());
			System.out.println("date="+link.getModifiedOn());
		}
		
		IvmLetterCandidateInfo[] l = this.getIvmDMService().updateIVMLetterCandidateRetrieval(s);
		System.out.println("l="+l[0]);
	}
	public void testGetIVMLetterCandidatesNoUpdate() throws Exception {
		Set s = this.getIvmDMService().findIVMLetterStatusData();
		System.out.println("count="+s.size());
		CommsLogEntry entry = (CommsLogEntry)s.iterator().next();
		if (entry == null) fail("test data is needed");
		System.out.println("entry="+entry.getLatestMailingStatus().getMailingStatus().getDescription());

		assertNotNull(entry.getSentToIVM());
		assertTrue(entry.getSentToIVM().booleanValue());
		List<MailingStatusLink> links = entry.getMailingStatusLinks();
		for (MailingStatusLink link: links) {
			System.out.println("link="+link.getMailingStatus().getDescription());
			System.out.println("date="+link.getModifiedOn());
		}
	}	
	
	public void testGetIVMCandidatesSimul() throws Exception {

		IVMMigration ivmData;
		Set s = this.getIvmDMService().findIVMMigrationData(this.getDate(2007, 1, 1));
		System.out.println("count="+s.size());
		assertTrue(s.size() > 0);
		System.out.println("count="+s.size());
		IVMCandidateInfo[] eeIVMCandidateInfo = new IVMCandidateInfo[s.size()];

		Iterator itr =s != null ? s.iterator()
				: null;
		int i = 0;
		while (itr != null && itr.hasNext()) {
			IVMCandidateInfo ivmCandidateInfo = new IVMCandidateInfo();
			ivmData = (IVMMigration) itr.next();

			if ( ivmData.getPersonEntityKey() != null)
			{
				ivmCandidateInfo.setVpid(this.getPersonService().getVPIDByPersonId(ivmData.getPersonEntityKey()).getVPID());
				ivmCandidateInfo.setIncomeYear(ivmData.getIncomeYear());
				ivmCandidateInfo.setTransactionId(ivmData.getEntityKey().getKeyValueAsString());
				this.getIvmDMService().saveIVMMigration(ivmData, MessageStatus.AWAITING_ACKNOWLEDGEMENT);
			}

			eeIVMCandidateInfo[i] = ivmCandidateInfo;
			i++;
		}
	}

	public void testArchiveCandidate() throws Exception {
		//you need to find people in IVM_MIGRATE that have one at least completed record and one
		//record in awaiting or error status. Complete the awaiting record and
		//the previous complete record will move to archive table.

		BigDecimal x = new BigDecimal(377246951);
		IVMMigration ivmRecord = this.getIvmDMService().findIVMMigration(x);
		assertNotNull(ivmRecord.getPersonEntityKey());
		this.getIvmDMService().updateIVMStatus(x, null);
		//List results = this.getGenericDAO().executeSQLQuery("select * from adr.ivm_migrate_archive where person_id = " + ivmRecord.getPersonEntityKey().getKeyValueAsString());
		//assertNotNull(results);
	}

	public void testMeansTestFunction100SC() throws Exception {
		Person onFile = buildSimplePerson();
		VAFacility site = this.getRandomVAFacility();
	    onFile.addAddress(createAddress(this.getAddressType( AddressType.CODE_PERMANENT_ADDRESS)));
		Integer iy = new Integer(2012);
		ServiceConnectionAward sc = new ServiceConnectionAward();
		sc.setServiceConnectedIndicator(Boolean.TRUE);
		sc.setServiceConnectedPercentage(new Integer(100));
		onFile.setServiceConnectionAward(sc);
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		attachUIFinancialData(incoming, iy, site, false, IncomeTestSource.CODE_HEC.getCode());
		((DependentFinancials)incoming.getFinancialStatement(iy).getDependentFinancials().iterator().next()).setAttendedSchool(Boolean.TRUE);
		Person updated = this.getFinancialsService().updateFinancialAssessment(iy, incoming);

		assertTrue(((DependentFinancials)incoming.getFinancialStatement(
				iy).getDependentFinancials().iterator().next()).getAttendedSchool().booleanValue());
		IncomeTest result = updated.getIncomeTest(iy);
		System.out.println("status="+result.getStatus());
		System.out.println("rx status="+result.getType());
		IncomeTestStatus rx = updated.getIncomeTest(iy).getIncomeTestStatus(this.getLookupService().getIncomeTestTypeByCode(
				IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST.getCode()));
		System.out.println("rx status="+rx.getStatus());
		System.out.println("rx status="+rx.getType());

	}

	public void testMeansTestFunctionReqToExempt() throws Exception {
		Person onFile = buildSimplePerson();
		VAFacility site = this.getRandomVAFacility();
	    onFile.addAddress(createAddress(this.getAddressType( AddressType.CODE_PERMANENT_ADDRESS)));
		Integer iy = new Integer(2012);
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED, iy);
		incomeTest.setGmtThresholdAmount(new BigDecimal(1010));
		incomeTest.setDiscloseFinancialInformation(Boolean.TRUE);
		incomeTest.setThresholdA(new BigDecimal(1000));
		incomeTest.setEffectiveDate(getDate(2011,1,1));
		incomeTest.setTotalIncome(new BigDecimal(100011));
		incomeTest.setAgreesToPayDeductible(Boolean.TRUE);
		onFile.setIncomeTest(iy, incomeTest);
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		this.attachServiceConnectionAward(incoming, new Integer(100));
		onFile.getEligibilityVerification().setVerificationMethod("test");
		Person updated = this.getEligibilityEnrollmentService().updateEligibilityData(incoming);
		IncomeTest result = updated.getIncomeTest(iy);
		System.out.println("status="+result.getStatus());
		System.out.println("rx status="+result.getType());
//		IncomeTestStatus rx = updated.getIncomeTest(iy).getIncomeTestStatus(this.getLookupService().getIncomeTestTypeByCode(
//				IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST.getCode()));
//		System.out.println("rx status="+rx.getStatus());
//		System.out.println("rx status="+rx.getType());
	}


	public void testUIDemographicsUpdateIdentityTraitsInProcessToVerified() throws Exception {
		/*
		 * This test does not work well since it depends on mock psdelegate and mock idm web service. But
		 * it does have value for testing basic flow of updateIdentityTraits.
		 */
		Person onFile = this.buildSimplePerson();
		onFile.setIdentityTraits(this.getPsDelegateService().getIdentityTraitsWithCompositeCall(onFile.getVPIDEntityKey()));
		this.attachVerifiedEnrollment(onFile);
		onFile.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		this.setServiceConnectedPercentage(new Integer(40),onFile);
		this.setEligibilityStatusToVerified(onFile);
		PreferredFacility fac = new PreferredFacility();
		fac.setFacility(this.getLookupService().getVaFacilityByCode("722"));
		fac.setSourceDesignation(this.getLookupService().getSourceDesignationByCode(SourceDesignation.CODE_ESR.getCode()));
		fac.setAssignmentDate(new Date());
	    onFile.addPreferredFacility(fac);
	    onFile.addAddress(createAddress(this.getAddressType( AddressType.CODE_PERMANENT_ADDRESS)));
		PersonIdentityTraits traitsOnfile = onFile.getIdentityTraits();
		assertTrue(SSAVerificationStatus.IN_PROCESS.getCode().equals(traitsOnfile.getSsn().getSsaVerificationStatus().getCode()));
		assertTrue(SSAVerificationStatus.IN_PROCESS.getCode().equals(onFile.getOfficialSsn().getSsaVerificationStatus().getCode()));
		Person incoming = savePerson(onFile);
		this.createIVMMigrationEntry(incoming, new Integer(2012), MessageStatus.COMPLETE, false);

		PersonIdentityTraits traits = incoming.getIdentityTraits();
		traits.getSsn().setSsaVerificationStatus(
				this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.VERIFIED.getCode()));
		Name name = (Name)traits.getNames().iterator().next();
		//name.setFamilyName("testtest");

		Person updated = this.getDemographicService().updateIdentityTraits(incoming);
	}

	public void testIncomeYearsAdded() {
		Set<Integer> added = Collections.synchronizedSet(new HashSet<Integer>());

		Integer iy1 = new Integer(2011);
		Integer iy2 = new Integer(2012);
		added.add(iy1);
		added.add(iy2);
		assertTrue(added.contains(new Integer(2011)));
		assertTrue(added.contains(new Integer(2012)));
	}
	public void createIVMPersonBaseFromUI() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2012);
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		onFile.addAddress(this.createAddress( this.getAddressType( AddressType.CODE_PERMANENT_ADDRESS)));
		Person incoming = savePerson(onFile);incoming.getEligibilityVerification().setVerificationMethod("test");
		VAFacility site = this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getCode());
		this.attachFullFinancialData(incoming, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());

		Person updated = this.getFinancialsService().updateFinancialAssessment(	incomeYear, (Person) incoming);
		this.setComplete();
		System.out.println("id="+updated.getEntityKey().getKeyValueAsString());
	}

	private Date getEffectiveDateForIncomeYear(Integer incomeYear) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, incomeYear);
        calendar.add(Calendar.YEAR, 1); // effective date has to be the following calendar year
        calendar.add(Calendar.MONTH, 0);
        calendar.add(Calendar.DAY_OF_MONTH, 0);
        System.out.println("effective date="+calendar.getTime());
        return calendar.getTime();
	}
	public void testPostProcessIVMEvents() throws Exception {
		VAFacility site = this.getRandomVAFacility();
		Person onFile = buildSimplePerson(); // bare-bones person
        Integer incomeYear = new Integer(2012);
        this.attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());
        Person incoming = savePerson(onFile);
        Person pristine = (Person)incoming.clone();
		EntityKey key = ((DependentFinancials)incoming.getFinancialStatement(
				incomeYear).getDependentFinancials().iterator().next()).getEntityKey();
		Gender holdGender = onFile.getFinancialStatement(incomeYear).getDependentFinancialsByEntityKey(
				key).getReportedOn().getGender();
		onFile.getFinancialStatement(incomeYear).getDependentFinancialsByEntityKey(
				key).getReportedOn().setGender(this.getLookupService().getGenderByCode(Gender.AMBIGUOUS.getCode()));

        FinancialInputData data = new FinancialInputData(incoming,
                onFile, pristine, incomeYear, site , false);
		FinancialInputParameter param = this.buildFinancialInputParameter(data);
		param.postProcessIVMEvents();

		assertTrue(onFile.getChangeEvents().containsKey(UseCaseName.FIN_DEPENDENT_CHANGE));

		onFile.getChangeEvents().clear();
		onFile.getFinancialStatement(incomeYear).getDependentFinancialsByEntityKey(key).getReportedOn().setGender(holdGender);
		Relationship holdRelation =
			onFile.getFinancialStatement(incomeYear).getDependentFinancialsByEntityKey(key).getReportedOn().getRelationship();

		onFile.getFinancialStatement(incomeYear).getDependentFinancialsByEntityKey(key).getReportedOn().setRelationship(
				this.getLookupService().getRelationshipByCode(Relationship.CODE_OTHER.getCode()));
		param.postProcessIVMEvents();
		assertTrue(onFile.getChangeEvents().containsKey(UseCaseName.FIN_DEPENDENT_CHANGE));
		onFile.getChangeEvents().clear();
		onFile.getFinancialStatement(incomeYear).getDependentFinancialsByEntityKey(key).getReportedOn().setRelationship(holdRelation);
		onFile.getFinancialStatement(incomeYear).getDependentFinancialsByEntityKey(key).setAttendedSchool(Boolean.TRUE);
		param.postProcessIVMEvents();
		assertFalse(onFile.getChangeEvents().containsKey(UseCaseName.FIN_DEPENDENT_CHANGE));
		onFile.getChangeEvents().clear();
		onFile.getFinancialStatement(incomeYear).getDependentFinancialsByEntityKey(key).setIncapableOfSelfSupport(Boolean.TRUE);
		param.postProcessIVMEvents();
		assertTrue(onFile.getChangeEvents().containsKey(UseCaseName.FIN_DEPENDENT_CHANGE));


	}
	public void testWasConversionToExistingMeansTest() throws Exception {
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("376781756"));
		Person onFile = this.getPersonService().getPerson(personKey);
		Person incoming = (Person) onFile.clone();;
        Person pristine = (Person) onFile.clone();
        Integer conversionIncomeYear = new Integer(2005);
        IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("R");
		// PRECONDITION:  NO INCOME TEST ON FILE
        FinancialInputData data = new FinancialInputData(incoming, onFile, pristine, ivmFinancialInfo );
		FinancialInputParameter param = this.buildFinancialInputParameter(data);
		assertTrue(param.wasConversionToExistingMeansTest(conversionIncomeYear));

	}
	public void testFindConversionBaseTest() throws Exception {
		//376781049
		//376779064
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("377125257"));
		Person onFile = this.getPersonService().getPerson(personKey);
		Integer iy = new Integer(2013);
		IncomeTest x = onFile.getIncomeTest(iy);
		IncomeTest y = this.getFinancialsService().findConversionBaseTest(onFile.getIncomeTest(iy));
		assertNotNull(y);
		System.out.println("income test historyid= "+y.getHistoryId());
		System.out.println("income test modifiedon= "+y.getModifiedOn());
		System.out.println("income test source= "+y.getSource().getDescription());
		System.out.println("income test status historyid= "+y.getIncomeTestStatus().getHistoryId());
		System.out.println("income test status modifiedon= "+y.getIncomeTestStatus().getModifiedOn());
	}
	public void testGetListStatuses() throws Exception {
		//377102027 377102172 377102222 373971922 376777416   375124624
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("377125257"));
		Person onFile = this.getPersonService().getPerson(personKey);
		FinancialsHistoryDAO dao = (FinancialsHistoryDAO)this.applicationContext.getBean("financialsHistoryDAO");
		Integer year = new Integer(2013);
		IncomeTest baseTest = dao.findConversionBaseTest(onFile.getIncomeTest(year));
		System.out.println("base income test historyid= "+baseTest.getHistoryId());
		System.out.println("base income test TIMESTAMP= "+baseTest.getModifiedOn());
		System.out.println("base source= "+baseTest.getSource().getDescription());
		IncomeTestStatus mtIncomeTestStatus = baseTest.getIncomeTestStatus(
				this.getLookupService().getIncomeTestTypeByCode(
				IncomeTestType.CODE_MEANS_TEST.getCode()));
		IncomeTestStatus rxIncomeTestStatus = baseTest.getIncomeTestStatus(
					this.getLookupService().getIncomeTestTypeByCode(
							IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST.getCode()));
		System.out.println("========================================");
		List statusesHistory = this.getFinancialsService().getIncomeTestStatusesForIVMReversal(baseTest.getHistoryId());
		Iterator iterHistoryStatuses = statusesHistory.iterator();
		System.out.println("GETTING getIncomeTestStatusesForIVMReversal");
		System.out.println("income test modifiedon= "+baseTest.getModifiedOn());
		for (Iterator i = iterHistoryStatuses ; i.hasNext();) {
			IncomeTestStatus status = (IncomeTestStatus)i.next();
			System.out.println("====================");
			System.out.println("history income test status Test Type= "+status.getType().getDescription());
			System.out.println("history income test status Last Edit Date= "+status.getLastEditedDate());
			System.out.println("history income test status isdeletede= "+status.isDeleted());
			System.out.println("history income test status TX code= "+status.getTransactionType().getCode());
			System.out.println("history income test status= "+status.getStatus().getDescription());
			System.out.println("history income test status modified= "+status.getModifiedOn());
			System.out.println("history income test status history ID= "+status.getHistoryId()+
					"  history income test status identifier= "+status.getEntityKey().getKeyValueAsString());
			System.out.println("====================");
		}

	}
//	public void testGetListBaseTestId() throws Exception {
//		//377102027 377102172 377102222 373971922 376777416   375124624
//		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("375124624"));
//		Person onFile = this.getPersonService().getPerson(personKey);
//		FinancialsHistoryDAO dao = (FinancialsHistoryDAO)this.applicationContext.getBean("financialsHistoryDAO");
//		Integer year = new Integer(2012);
//		/*
//		IncomeTest baseTest = dao.findConversionBaseTest(onFile.getIncomeTest(year));
//		System.out.println("base income test historyid= "+baseTest.getHistoryId());
//		System.out.println("base income test TIMESTAMP= "+baseTest.getModifiedOn());
//		System.out.println("base source= "+baseTest.getSource().getDescription());
//		*/
//		List baseTestId = dao.getIvmIncomeTestBaseHistoryId(onFile.getIncomeTest(year));
//		EntityKey key = CommonEntityKeyFactory.createIncomeTestEntityKey(baseTestId.get(0).toString());
//
//
//		List statusesHistory = dao.getIvmIncomeTestStatusesByBaseHistoryId(key);
//		Iterator iterHistoryStatuses = statusesHistory.iterator();
//		System.out.println("GETTING getIncomeTestStatusesForIVMReversal");
//		for (Iterator i = iterHistoryStatuses ; i.hasNext();) {
//			IncomeTestStatus status = (IncomeTestStatus)i.next();
//			System.out.println("====================");
//			System.out.println("history income test status Test Type= "+status.getType().getDescription());
//			System.out.println("history income test status Last Edit Date= "+status.getLastEditedDate());
//			System.out.println("history income test status isdeletede= "+status.isDeleted());
//			System.out.println("history income test status TX code= "+status.getTransactionType().getCode());
//			System.out.println("history income test status= "+status.getStatus().getDescription());
//			System.out.println("history income test status modified= "+status.getModifiedOn());
//			System.out.println("history income test status history ID= "+status.getHistoryId()+
//					"  history income test status identifier= "+status.getEntityKey().getKeyValueAsString());
//			System.out.println("====================");
//		}
//
//
//		IncomeTest baseTest = dao.getConversionBaseTestByHistoryId(key);
//
//		System.out.println("income test modifiedon= "+baseTest.getModifiedOn());
//
////		List statusKeys = dao.getIvmIncomeTestStatusesByBaseHistoryId(key);
//		IncomeTestStatus mtIncomeTestStatus = baseTest.getIncomeTestStatus(
//				this.getLookupService().getIncomeTestTypeByCode(
//				IncomeTestType.CODE_MEANS_TEST.getCode()));
//
//		IncomeTestStatus rxIncomeTestStatus = baseTest.getIncomeTestStatus(
//					this.getLookupService().getIncomeTestTypeByCode(
//							IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST.getCode()));
//
//		System.out.println("========================================");
//
//	}

//	public void testGetListOfStatusesById() throws Exception {
//		//377102027 377102172 377102222 373971922 376777416   375124624
//		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("375124624"));
//		Person onFile = this.getPersonService().getPerson(personKey);
//		FinancialsHistoryDAO dao = (FinancialsHistoryDAO)this.applicationContext.getBean("financialsHistoryDAO");
//		Integer year = new Integer(2012);
//		//List baseTestId = dao.getIvmIncomeTestBaseHistoryId(onFile.getIncomeTest(year));
//		//EntityKey key = CommonEntityKeyFactory.createIncomeTestEntityKey(baseTestId.get(0).toString());
//		List tests = dao.getIvmIncomeTestBaseHistoryId(onFile.getIncomeTest(year));
//		IncomeTest baseTest = (IncomeTest)tests.get(0);
//		System.out.println("base test="+baseTest.getHistoryId());
//		List statusesHistory = dao.getIncomeTestStatusesForIVMReversal(baseTest.getHistoryId());
//		IncomeTest empty = new IncomeTest();
//		this.getMergeRuleService().mergeFullIncomeTest(baseTest, empty);
//		/*
//		IncomeTestStatus mtIncomeTestStatus = baseTest.getIncomeTestStatus(
//				this.getLookupService().getIncomeTestTypeByCode(
//				IncomeTestType.CODE_MEANS_TEST.getCode()));
//		IncomeTestStatus rxIncomeTestStatus = baseTest.getIncomeTestStatus(
//					this.getLookupService().getIncomeTestTypeByCode(
//							IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST.getCode()));
//		*/
//
//		Iterator iterHistoryStatuses = statusesHistory.iterator();
//		System.out.println("GETTING getIncomeTestStatusesForIVMReversal");
//		for (Iterator i = iterHistoryStatuses ; i.hasNext();) {
//			IncomeTestStatus status = (IncomeTestStatus)i.next();
//			System.out.println("====================");
//			System.out.println("history income test status Test Type= "+status.getType().getDescription());
//			System.out.println("history income test status Last Edit Date= "+status.getLastEditedDate());
//			System.out.println("history income test status isdeletede= "+status.isDeleted());
//			System.out.println("history income test status TX code= "+status.getTransactionType().getCode());
//			System.out.println("history income test status= "+status.getStatus().getDescription());
//			System.out.println("history income test status modified= "+status.getModifiedOn());
//			System.out.println("history income test status history ID= "+status.getHistoryId()+
//					"  history income test status identifier= "+status.getEntityKey().getKeyValueAsString());
//			System.out.println("====================");
//		}
//	}
	public void testGetListStatusesRevised() throws Exception {
		//377102027 377102172 377102222 373971922 376777416   375124624
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("375124624"));
		Person onFile = this.getPersonService().getPerson(personKey);
		FinancialsHistoryDAO dao = (FinancialsHistoryDAO)this.applicationContext.getBean("financialsHistoryDAO");
		Integer year = new Integer(2012);
		// The order is critical. You must retrieve the base data first otherwise the objects get picked up from
		// the cache and the wrong status values are used.
		IncomeTest baseTest = dao.findConversionBaseTest(onFile.getIncomeTest(year));
		List statusesHistory = this.getFinancialsService().getIncomeTestStatusesForIVMReversal(baseTest.getHistoryId());
		System.out.println("base income test historyid= "+baseTest.getHistoryId());
		System.out.println("base income test TIMESTAMP= "+baseTest.getModifiedOn());
		System.out.println("base source= "+baseTest.getSource().getDescription());
		IncomeTestStatus mtIncomeTestStatus = baseTest.getIncomeTestStatus(
				this.getLookupService().getIncomeTestTypeByCode(
				IncomeTestType.CODE_MEANS_TEST.getCode()));
		IncomeTestStatus rxIncomeTestStatus = baseTest.getIncomeTestStatus(
					this.getLookupService().getIncomeTestTypeByCode(
							IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST.getCode()));
		System.out.println("========================================");

		Iterator iterHistoryStatuses = statusesHistory.iterator();
		System.out.println("GETTING getIncomeTestStatusesForIVMReversal");
		System.out.println("income test modifiedon= "+baseTest.getModifiedOn());
		for (Iterator i = iterHistoryStatuses ; i.hasNext();) {
			IncomeTestStatus status = (IncomeTestStatus)i.next();
			System.out.println("====================");
			System.out.println("history income test status Test Type= "+status.getType().getDescription());
			System.out.println("history income test status Last Edit Date= "+status.getLastEditedDate());
			System.out.println("history income test status isdeletede= "+status.isDeleted());
			System.out.println("history income test status TX code= "+status.getTransactionType().getCode());
			System.out.println("history income test status= "+status.getStatus().getDescription());
			System.out.println("history income test status modified= "+status.getModifiedOn());
			System.out.println("history income test status history ID= "+status.getHistoryId()+
					"  history income test status identifier= "+status.getEntityKey().getKeyValueAsString());
			System.out.println("====================");
		}
	}

	public void testHistoryChangeTimes() throws Exception {
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("373971922"));
		Person onFile = this.getPersonService().getPerson(personKey);
		FinancialsHistoryDAO dao = (FinancialsHistoryDAO)this.applicationContext.getBean("financialsHistoryDAO");
		Set changes = dao.getHistoryChangeTimes(personKey, new Integer("2012"));
		Iterator iter = changes.iterator();
		while (iter.hasNext()) {
			FinancialsChangeEvent ce = (FinancialsChangeEvent)iter.next();
			HistoricalInfo info = dao.getHistoryByChangeTime(ce);
			System.out.println("ce="+ce);
			System.out.println("info="+info.getPreviousVersion());
		}

	}
	public void updateConversionBaseTest() throws Exception {
		//376781035
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("373971922"));
		Person onFile = this.getPersonService().getPerson(personKey);
		IncomeTest incomeTest = onFile.getIncomeTest(new Integer("2009"));
		incomeTest.setBtFinancialInd(Boolean.TRUE);

		this.getPersonService().save(onFile, true);
		this.setComplete();
	}
	public void testReadBTFinancialInd() throws Exception {
		//376781035
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("373971922"));
		Person onFile = this.getPersonService().getPerson(personKey);
		IncomeTest incomeTest = onFile.getIncomeTest(new Integer("2009"));
		assertTrue(incomeTest.getBtFinancialInd());
	}	
	public void createPersonForConversionBaseTest() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2012);
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT, incomeYear);
		incomeTest.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest.setThresholdA(new BigDecimal(9));
		onFile.setIncomeTest(incomeYear, incomeTest);
		onFile.getIncomeTest(incomeYear).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		onFile.setFinancialStatement(incomeYear, this.createFinancialStatement());
		onFile.getFinancialStatement(incomeYear).setAsset(this.getLookupService().getAssetTypeByCode(
				AssetType.CODE_OTHER.getCode()), this.createAsset((double)458));
		onFile.getFinancialStatement(incomeYear).setDebt(this.createDebt((double)5));

		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		incoming.getEligibilityVerification().setVerificationMethod((new Date()).toString() );
		this.getEligibilityEnrollmentService().updateEligibilityData(incoming);
		this.setComplete();
		System.out.println("id"+incoming.getEntityKey().getKeyValueAsString());
	}

	private IncomeTest attachIVMConversionTest(Person person, Integer incomeYear, boolean hasMtStatus, boolean hasRxStatus, String statusSelection) throws Exception {
		/*
		 * This method simulates what the Builder will do: Produce an income test
		 * using the existing test as base. For a clone scenario, it will create new instance.
		 *
		 * -----Original Message----- From: Manhas, Randhir (HP) Sent: Monday,
		 * June 17, 2013 2:20 PM To: Ruiz, Carlos (HP); Palaniappan, Meena (HP)
		 *
		 * Subject: RE: <internal>RE: CodeCR ESR 3.12_CodeCR12448 Approved 2 -
		 * Major 2 - Give High Attention GMT Address Fields empty after
		 * receiving IVM conversion
		 *
		 * I sent you another email but Carlos there is another thing that you
		 * need to know, even though IVM might send spouse and dependent info
		 * (DEP and SPO tagged elements per spreadsheet), it was decided that
		 * ESR would not use it coming from IVM but would populate it from ADR
		 * and use it as ESR would have more accurate data.
		 *
		 * -Randhir
		 *
		 */

		// Modify existing test to simulate a test modified with partial data from IVM.
		// The builder will actually do this in real world, but this simulation is close.
		IncomeTest incomeTest = new IncomeTest();
		incomeTest.setIncomeYear(incomeYear);
		incomeTest.setType(this.getLookupService().getIncomeTestTypeByCode(IncomeTestType.CODE_MEANS_TEST.getCode()));
		person.setIncomeTest(incomeYear, incomeTest);

		IncomeTestStatus mtIncomeTestStatus =incomeTest.getIncomeTestStatus(this.getLookupService().getIncomeTestTypeByCode(IncomeTestType.CODE_MEANS_TEST.getCode()));
		IncomeTestStatus rxIncomeTestStatus =incomeTest.getIncomeTestStatus(this.getLookupService().getIncomeTestTypeByCode(IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST.getCode()));

		if (mtIncomeTestStatus == null && hasMtStatus) {
			mtIncomeTestStatus = new IncomeTestStatus();
			mtIncomeTestStatus.setType(this.getLookupService().getIncomeTestTypeByCode(IncomeTestType.CODE_MEANS_TEST.getCode()));
			incomeTest.addIncomeTestStatus(mtIncomeTestStatus);
		}

		if (rxIncomeTestStatus == null && hasRxStatus) {
			rxIncomeTestStatus = new IncomeTestStatus();
			rxIncomeTestStatus.setType(this.getLookupService().getIncomeTestTypeByCode(IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST.getCode()));
			incomeTest.addIncomeTestStatus(rxIncomeTestStatus);
		}

		// IVM Data Elements Shared with ESR
		// Number of Dependent Effective for the Income Year
		incomeTest.setTotalNumberOfDependents(new Integer(1));
		// Means Test Determine Status Code
		if (mtIncomeTestStatus != null) {
			mtIncomeTestStatus.setDeterminedStatus(this.getLookupService().getMeansTestStatusByCode(MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getName()));
		}
		if (rxIncomeTestStatus != null) {
			rxIncomeTestStatus.setDeterminedStatus(this.getLookupService().getMeansTestStatusByCode(MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getName()));
		}
		// Income Test Status Code
		if (mtIncomeTestStatus != null) {
			if ("MT".equals(statusSelection))
				mtIncomeTestStatus.setStatus(this.getLookupService().getMeansTestStatusByCode(MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getCode()));
			else if ("GMT".equals(statusSelection))
				mtIncomeTestStatus.setStatus(this.getLookupService().getMeansTestStatusByCode(MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED.getCode()));
			else
				mtIncomeTestStatus.setStatus(this.getLookupService().getMeansTestStatusByCode(MeansTestStatus.MT_STATUS_NO_LONGER_REQUIRED.getCode()));
		}
		if (rxIncomeTestStatus != null) {
			rxIncomeTestStatus.setStatus(this.getLookupService().getMeansTestStatusByCode(MeansTestStatus.MT_STATUS_NON_EXEMPT.getCode()));
		}
		// Income Test Effective Date
		incomeTest.setEffectiveDate(this.getDate(2013, 2,2));
		// Income Test Completed Date
		if (mtIncomeTestStatus != null) {
			mtIncomeTestStatus.setCompletedDate(new Date());
		}
		if (rxIncomeTestStatus != null) {
			rxIncomeTestStatus.setCompletedDate(new Date());
		}
		incomeTest.setIVMTestCompletionDate(new Date());
		// IVM Conversion Date
		incomeTest.setIvmConversionDate(new Date());
		// Income Test Source Code
		incomeTest.setSource(this.getLookupService().getIncomeTestSourceByCode(IncomeTestSource.CODE_IVM.getCode()));
		// Mean Test Threshold
		incomeTest.setThresholdA(new BigDecimal(9));
		// Agree to Pay Deductible Indicator
		// IVM DOES NOT SEND THIS - CCR 12532 has ESR do it.
		incomeTest.setAgreesToPayDeductible(null); // simulate IVM sending nothing
		// PG8 Relaxation Indicator
		incomeTest.setPg8RelaxationIndicator(Boolean.TRUE);
		// IVM Case Status
		incomeTest.setWorkflowCaseStatus(this.getLookupService().getWkfCaseStatusTypeByCode(
				WkfCaseStatusType.ASSIGNED.getCode()));
		/*
		 * ESR does not expect following from IVM according Randhir.
		Gender Type Code
		Spouse SSN
		Spouse Last Name
		Spouse Prefix
		Spouse First Name
		Spouse Middle Name
		Spouse Maiden Name
		Spouse Name Suffix
		Spouse Date of Birth
		Spouse Marriage Date
		Spouse Retirement
		Gender Type
		Veteran Relationship
		Dependent SSN
		Dependent Last Name
		Dependent Prefix
		Dependent First Name
		Dependent Middle Name
		Dependent Suffix
		Dependent Date of Birth
		Dependent Effective Date
		Dependent Incapable of Self Support Indicator
		*/

		return incomeTest;
	}
	public void testHasIVMTestOnFileForIncomingIY_NEG() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2012);
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT, incomeYear);
		incomeTest.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest.setThresholdA(new BigDecimal(9));
		onFile.setIncomeTest(incomeYear, incomeTest);
		onFile.getIncomeTest(incomeYear).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		onFile.setFinancialStatement(incomeYear, this.createFinancialStatement());
		onFile.getFinancialStatement(incomeYear).setAsset(this.getLookupService().getAssetTypeByCode(
				AssetType.CODE_OTHER.getCode()), this.createAsset((double)458));
		onFile.getFinancialStatement(incomeYear).setDebt(this.createDebt((double)5));
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
        Person pristine = (Person) onFile.clone();
        Integer conversionIncomeYear = new Integer(2012);
        IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");

		// PRECONDITION:  NO INCOME TEST ON FILE
		FinancialInputData data = new FinancialInputData(incoming,
				onFile, pristine, incomeYear, incomeTest.getSiteConductingTest(), false);
		FinancialInputParameter param = this.buildFinancialInputParameter(data);
		boolean flag = param.hasIVMTestOnFileForIncomingIY();
		assertTrue(flag);
	}
	public void testHasIVMTestOnFileForIncomingIY_POS() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2012);
		this.attachIVMConversionTest(onFile, incomeYear, true, true, "MT");
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
        Person pristine = (Person) onFile.clone();
 		FinancialInputData data = new FinancialInputData(incoming,
				onFile, pristine, incomeYear, onFile.getIncomeTest(incomeYear).getSiteConductingTest(), false);
		FinancialInputParameter param = this.buildFinancialInputParameter(data);
		boolean flag = param.hasIVMTestOnFileForIncomingIY();
		assertTrue(flag);
	}
	public void testUpdateIVMEventData() throws Exception {
		// Make a primary test
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2012);
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT, incomeYear);
		incomeTest.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest.setThresholdA(new BigDecimal(9));
		onFile.setIncomeTest(incomeYear, incomeTest);
		onFile.getIncomeTest(incomeYear).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		onFile.setFinancialStatement(incomeYear, this.createFinancialStatement());
		onFile.getFinancialStatement(incomeYear).setAsset(this.getLookupService().getAssetTypeByCode(
				AssetType.CODE_OTHER.getCode()), this.createAsset((double)458));
		onFile.getFinancialStatement(incomeYear).setDebt(this.createDebt((double)5));
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
        Person pristine = (Person) onFile.clone();


        Integer conversionIncomeYear = new Integer(2012);
        IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");

        incoming.removeAllIncomeTests();
        this.attachIVMConversionTest(incoming, conversionIncomeYear, true, true, "MT");

        FinancialInputData data = new FinancialInputData(incoming, onFile, pristine, ivmFinancialInfo );
		FinancialInputParameter param = this.buildFinancialInputParameter(data);
		param.createOrUpdateTestFromIVMConversionData(true);
		param.updateIVMEventData(conversionIncomeYear, onFile.getIncomeTest(conversionIncomeYear),
				pristine.getIncomeTest(conversionIncomeYear), "C");

		assertTrue(data.isMTConversion());
		assertTrue(data.isRXConversion());
	}

	public void testCreateCloneIncomeTest() throws Exception {
		/*
		 * 4.3. Clone Test
		 *
		 * If there is no primary means test on file for the same income year as
		 * the IVM conversion, the system will clone data from the primary means
		 * test on file.
		 */

		// Make a primary test
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2012);
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT, incomeYear);
		incomeTest.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest.setThresholdA(new BigDecimal(9));
		onFile.setIncomeTest(incomeYear, incomeTest);
		onFile.getIncomeTest(incomeYear).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		onFile.setFinancialStatement(incomeYear, this.createFinancialStatement());
		onFile.getFinancialStatement(incomeYear).setAsset(this.getLookupService().getAssetTypeByCode(
				AssetType.CODE_OTHER.getCode()), this.createAsset((double)458));
		onFile.getFinancialStatement(incomeYear).setDebt(this.createDebt((double)5));
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
        Person pristine = (Person) onFile.clone();
        Integer conversionIncomeYear = new Integer(2012);
        IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");

		// PRECONDITION:  NO INCOME TEST ON FILE
        FinancialInputData data = new FinancialInputData(incoming, onFile, pristine, ivmFinancialInfo );
		FinancialInputParameter param = this.buildFinancialInputParameter(data);
		param.createCloneIncomeTest();
		IncomeTest test = onFile.getIncomeTest(conversionIncomeYear);
		assertNotNull(test);
	}
	public void testCreateCloneIncomeTest_NoExistingMTSameIY() throws Exception {
		/*
		 * 4.3. Clone Test
		 *
		 * If there is no primary means test on file for the same income year as
		 * the IVM conversion, the system will clone data from the primary means
		 * test on file.
		 */

		// Make a primary test
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2011);
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT, incomeYear);
		incomeTest.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest.setThresholdA(new BigDecimal(9));
		onFile.setIncomeTest(incomeYear, incomeTest);
		onFile.getIncomeTest(incomeYear).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		onFile.setFinancialStatement(incomeYear, this.createFinancialStatement());
		onFile.getFinancialStatement(incomeYear).setAsset(this.getLookupService().getAssetTypeByCode(
				AssetType.CODE_OTHER.getCode()), this.createAsset((double)458));
		onFile.getFinancialStatement(incomeYear).setDebt(this.createDebt((double)5));
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
        Person pristine = (Person) onFile.clone();
        Integer conversionIncomeYear = new Integer(2012);
        IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");

		// PRECONDITION:  NO INCOME TEST ON FILE
        FinancialInputData data = new FinancialInputData(incoming, onFile, pristine, ivmFinancialInfo );
		FinancialInputParameter param = this.buildFinancialInputParameter(data);
		param.createCloneIncomeTest();
		IncomeTest test = onFile.getIncomeTest(conversionIncomeYear);
		assertNotNull(test);
	}
	public void testCreateNewTestFromIVMConversionDataEXISTINGTEST() throws Exception {
		/*
		 * 4.4. Create New Test
		 *
		 * The system creates a new test using data received from the IVM
		 * converted test and the cloned test. The following table lists the
		 * fields and source of data to be used for the new means test.
		 *
		 */
		Person onFile = buildSimplePerson(); // bare-bones person
		// SAME INCOME YEAR as conversion
		Integer incomeYear = new Integer(2012);
        // NOTICE THAT IVM TEST IY is same as ONFILE
	    Integer conversionIncomeYear = incomeYear;
		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_VAMC.getCode());
		attachVerifiedEnrollment(onFile);
		setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
        Person pristine = (Person) onFile.clone();
        IncomeTest original = pristine.getIncomeTest(incomeYear);

        IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		ivmFinancialInfo.setBtFinancialInd(Boolean.TRUE);

        incoming.removeAllIncomeTests();
		this.attachIVMConversionTest(incoming, conversionIncomeYear, true, true, "MT");

		FinancialInputData data = new FinancialInputData(incoming, onFile, pristine, ivmFinancialInfo );
		FinancialInputParameter param = this.buildFinancialInputParameter(data);
		//****************************************************************
		//****************************************************************
		// NOTICE THAT DON'T HAVE TO CALL CLONE TEST
		param.createOrUpdateTestFromIVMConversionData(true);
		//****************************************************************
		//****************************************************************
		this.applyAssertionsUpdateTest(onFile, incoming, original, conversionIncomeYear, site);
		assertTrue(onFile.getIncomeTest(conversionIncomeYear).getBtFinancialInd().booleanValue());

	}

	public void testFinancialChangesAttendedSchool() throws Exception {
		Person onFile = buildSimplePerson();
		VAFacility site = this.getRandomVAFacility();
		Integer iy = new Integer(2012);
		this.attachFullFinancialData(onFile, iy, site, false, IncomeTestSource.CODE_HEC.getCode());
		ServiceConnectionAward sc = new ServiceConnectionAward();
		sc.setServiceConnectedIndicator(Boolean.FALSE);
		onFile.setServiceConnectionAward(sc);

		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		((DependentFinancials)incoming.getFinancialStatement(iy).getDependentFinancials().iterator().next()).setAttendedSchool(Boolean.TRUE);
		this.createIVMMigrationEntry(incoming, iy, MessageStatus.COMPLETE, false);
		Person updated = this.getFinancialsService().updateFinancialAssessment(iy, incoming);

		assertTrue(((DependentFinancials)incoming.getFinancialStatement(
				iy).getDependentFinancials().iterator().next()).getAttendedSchool().booleanValue());
	}
	public void testCreateNewTestFromIVMConversionDataNOEXISTINGTEST() throws Exception {
		/*
		 * 4.4. Create New Test
		 *
		 * The system creates a new test using data received from the IVM
		 * converted test and the cloned test. The following table lists the
		 * fields and source of data to be used for the new means test.
		 *
		 */
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2011);
        // NOTICE THAT IVM TEST IS FOR 2012 AND 2012 DOES NOT EXIST ONFILE
        Integer conversionIncomeYear = new Integer(2012);
		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_VAMC.getCode());
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
        Person pristine = (Person) onFile.clone();

        IncomeTest original = pristine.getIncomeTest(incomeYear);

        IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		ivmFinancialInfo.setBtFinancialInd(Boolean.TRUE);		

        incoming.removeAllIncomeTests();
		this.attachIVMConversionTest(incoming, conversionIncomeYear, true, true, "MT");

		//	make sure travel is on the onfile before calling
		assertNotNull(onFile.getBeneficiaryTravel(incomeYear, site));

		FinancialInputData data = new FinancialInputData(incoming, onFile, pristine, ivmFinancialInfo );
		FinancialInputParameter param = this.buildFinancialInputParameter(data);
		//****************************************************************
		//****************************************************************
		param.createCloneIncomeTest();
		param.createOrUpdateTestFromIVMConversionData(false);
		//****************************************************************
		//****************************************************************
		this.applyAssertionsCreateNewTest(onFile, incoming, original, conversionIncomeYear, site, false);
		assertTrue(onFile.getIncomeTest(conversionIncomeYear).getBtFinancialInd().booleanValue());

	}
	private void attachFullFinancialData(Person onFile, Integer incomeYear,
			VAFacility site, boolean ltc, String source) throws Exception {
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT, incomeYear);
		incomeTest.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest.setThresholdA(new BigDecimal(9));
		incomeTest.setSiteConductingTest(site);
		incomeTest.setAdjudicationDate(new Date());
		incomeTest.setCadAdjusted(Boolean.TRUE);
		incomeTest.setAgreesToPayDeductible(Boolean.TRUE);
		incomeTest.setIncomeVerificationStatus(this.getLookupService().getMeansTestStatusByCode(
				MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode()));
		incomeTest.setIncomeVerificationStatusDate(new Date());
		incomeTest.setEffectiveDate(new Date());
		incomeTest.setSource(this.getLookupService().getIncomeTestSourceByCode(source));
		incomeTest.setTotalNumberOfDependents(new Integer(2));
		incomeTest.setPrimaryIncomeTest(Boolean.TRUE);

		PatientVisitSummary visitSummary = new PatientVisitSummary();
		visitSummary.setFacilityVisited(site);
		visitSummary.setIncomeYear(incomeYear);
		visitSummary.setOutpatientDays(new Integer(2));
		visitSummary.setInpatientDays(new Integer(2));
		visitSummary.setLastVisitDate(new Date());
	    onFile.setPatientVisitSummary(incomeYear, site, visitSummary);
		attachIncomeTestStatus(incomeTest, MeansTestStatus.MT_STATUS_EXEMPT,
				IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST, MeansTestStatus.MT_STATUS_EXEMPT);
		if (ltc) {
			attachIncomeTestStatus(incomeTest, MeansTestStatus.MT_STATUS_EXEMPT_LTC_COPAY_EXEMPTION_TEST,
					IncomeTestType.CODE_LTC_CO_PAY_EXEMPTION_TEST, MeansTestStatus.MT_STATUS_EXEMPT_LTC_COPAY_EXEMPTION_TEST);

			attachIncomeTestStatus(incomeTest, MeansTestStatus.MT_STATUS_EXEMPT_LTC_COPAY_EXEMPTION_TEST,
					IncomeTestType.CODE_LTC_CO_PAY_TEST, MeansTestStatus.MT_STATUS_EXEMPT_LTC_COPAY_EXEMPTION_TEST);
			IncomeTestStatus ltc1 = incomeTest.getIncomeTestStatus(IncomeTestType.CODE_LTC_CO_PAY_TEST);
			IncomeTestStatus ltc2 = incomeTest.getIncomeTestStatus(IncomeTestType.CODE_LTC_CO_PAY_EXEMPTION_TEST);
			assertNotNull(ltc1);
			assertNotNull(ltc2);
		}
		incomeTest.setLastEditedDate(this.getDate(2013, 2, 2));
		onFile.setIncomeTest(incomeYear, incomeTest);

		BeneficiaryTravel travel = createBeneficiaryTravel(incomeYear, incomeTest.getSiteConductingTest());
		onFile.setBeneficiaryTravel(incomeYear,incomeTest.getSiteConductingTest(), travel);

		//=== financial statement
	    buildFinancialStatementData(incomeYear, onFile);

		onFile.getFinancialStatement(incomeYear).setMarriedLastCalendarYear(Boolean.TRUE);
	}
	private void attachUIFinancialData(Person onFile, Integer incomeYear,
			VAFacility site, boolean ltc, String source) throws Exception {
		IncomeTest incomeTest = new IncomeTest();
		incomeTest.setEffectiveDate(new Date());
		incomeTest.setIncomeYear(incomeYear);
		incomeTest.setSiteConductingTest(site);
		incomeTest.setSiteConductingTest(site);
		incomeTest.setAdjudicationDate(new Date());
		incomeTest.setCadAdjusted(Boolean.TRUE);
		incomeTest.setAgreesToPayDeductible(Boolean.TRUE);
		incomeTest.setEffectiveDate(new Date());
		onFile.setIncomeTest(incomeYear, incomeTest);

		//=== financial statement
	    buildFinancialStatementData(incomeYear, onFile);
		onFile.getFinancialStatement(incomeYear).setMarriedLastCalendarYear(Boolean.FALSE);
	}

	private void applyAssertionsCreateNewTest(Person onFile, Person incoming,
			IncomeTest original, Integer conversionIncomeYear, VAFacility site, boolean ltcFlag) throws Exception {
		IncomeTest resultTest = onFile.getIncomeTest(conversionIncomeYear);
		assertNotNull(resultTest);
		IncomeTestStatus incomingMtStatus = incoming.getIncomeTest(conversionIncomeYear).getIncomeTestStatus(this.getLookupService().getIncomeTestTypeByCode(
				IncomeTestType.CODE_MEANS_TEST.getCode()));
		IncomeTestStatus resultMtStatus = resultTest.getIncomeTestStatus(this.getLookupService().getIncomeTestTypeByCode(
				IncomeTestType.CODE_MEANS_TEST.getCode()));


		// CCR 12345
		assertNotNull(resultTest.getLastEditedDate());

		// Financial Assessment Disclose Financial Income Set to "Yes"
		assertTrue(resultTest.getDiscloseFinancialInformation().booleanValue());
		// Primary Test Type Set to "Means Test"
		assertTrue(IncomeTestType.CODE_MEANS_TEST.getCode().equals(resultTest.getPrimaryTestType().getCode()));
		// Test Effective Date 1/1 (January 1) of calendar year for the income year
		assertNotNull(resultTest.getEffectiveDate());
		Date eff = incoming.getIncomeTest(conversionIncomeYear).getEffectiveDate();
		assertTrue(eff.equals(resultTest.getEffectiveDate()));

		// Test Determined Status From previous means test
		assertTrue(resultTest.getDeterminedStatus().getCode().equals(original.getDeterminedStatus().getCode()));
		// Test Status Set by IVM
		if (incomingMtStatus != null) {
			assertTrue(MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getCode().equals(resultMtStatus.getStatus().getCode())
					|| MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED.getCode().equals(resultMtStatus.getStatus().getCode()));
			// Agree to Pay Deductible Set to "Yes"
			assertTrue(resultTest.getAgreesToPayDeductible().booleanValue());
		}
		// Site Conducting Test From previous means test
		assertTrue(resultTest.getSiteConductingTest().getCode().equals(original.getSiteConductingTest().getCode()));

		// Date Test Completed Set to "current date"
		assertNotNull(resultTest.getCompletedDate());
		assertTrue(DateUtils.isSameDay(CommonDateUtils.getCurrentDate(), resultTest.getCompletedDate()));
		// Centralized Anniversary Date Adjusted Set to "No"
		assertFalse(resultTest.getCadAdjusted().booleanValue());
		// Adjudication Date Set to NULL
		assertNull(resultTest.getAdjudicationDate());
		// Pharmacy Co-Pay Exemption Status Set to status from IVM
		IncomeTestStatus incomingRxStatus = incoming.getIncomeTest(conversionIncomeYear).getIncomeTestStatus(this.getLookupService().getIncomeTestTypeByCode(
				IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST.getCode()));
		IncomeTestStatus resultRxStatus = resultTest.getIncomeTestStatus(this.getLookupService().getIncomeTestTypeByCode(
				IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST.getCode()));
		IncomeTestStatus originalRxStatus = original.getIncomeTestStatus(this.getLookupService().getIncomeTestTypeByCode(
				IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST.getCode()));
		IncomeTestStatus originalMtStatus = original.getIncomeTestStatus(this.getLookupService().getIncomeTestTypeByCode(
				IncomeTestType.CODE_MEANS_TEST.getCode()));

		if (incomingRxStatus == null && originalRxStatus != null) {
			assertTrue(originalRxStatus.getStatus().getCode().equals(resultRxStatus.getStatus().getCode()));
		}
		if (incomingMtStatus == null && originalMtStatus != null) {
			assertTrue(originalMtStatus.getStatus().getCode().equals(resultMtStatus.getStatus().getCode()));
		}

		// Long Term Care Status Set to NULL
		if (ltcFlag) {
			IncomeTestStatus ltc = resultTest.getIncomeTestStatus(this.getLookupService().getIncomeTestTypeByCode(
					IncomeTestType.CODE_LTC_CO_PAY_EXEMPTION_TEST.getCode()));
			assertNull(ltc);
		}
		if (resultTest.getHardship()!= null) {
			// Hardship Granted Set to "No"
			assertFalse(resultTest.getHardship().getHardshipGranted().booleanValue());
			// Hardship	Hardship Reason	Set to NULL
			assertNull(resultTest.getHardship().getReason());
			// Site Granting Hardship	Set to NULL
			assertNull(resultTest.getHardship().getSiteGrantingHardship());
			// Effective Date	Set to NULLx
			assertNull(resultTest.getHardship().getEffectiveDate());
			// Review Date	Set to NULL
			assertNull(resultTest.getHardship().getReviewDate());
		}
		// Source of Financial Information Set to "IVM"
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(resultTest.getSource().getCode()));
		// use existing patient visitsummary, if any
		PatientVisitSummary resultPVS = onFile.getPatientVisitSummary(conversionIncomeYear, resultTest.getSiteConductingTest());
		if (resultPVS != null) {
			// Number of Inpatient Days From previous means test
			assertNotNull(resultPVS.getInpatientDays());
			// Number of Outpatient Days From previous means test
			assertNotNull(resultPVS.getOutpatientDays());
			assertNotNull(resultPVS.getFacilityVisited());
			assertNotNull(resultPVS.getLastVisitDate());
		}
		// NOTICE THAT CONVERSION IY is used
		FinancialStatement vetStatement = onFile.getFinancialStatement(conversionIncomeYear);
		assertNotNull(vetStatement);
		// Married Last Calendar Year From previous means test
		assertTrue(vetStatement.getMarriedLastCalendarYear());
		// Dependents	All Dependent Information From previous means test
		assertTrue(vetStatement.getDependentFinancials().size() > 0);
		SpouseFinancials sf = vetStatement.getActiveSpouseFinancials();
		Set dfSet = vetStatement.getDependentFinancials();
		assertNotNull(sf);
		assertNotNull(dfSet);
		assertEquals(dfSet.size(), 2);
		assertTrue(sf.getLivedWithPatient());
		DependentFinancials df1 = ((DependentFinancials) dfSet.iterator().next());
		assertNotNull(df1.getLivedWithPatient());
		// Financial Summary	Total Income	Set to NULL
		assertNull(resultTest.getTotalIncome());
		// Net Income	Set to NULL
		assertNull(resultTest.getNetIncome());
		// Total Deductible Expenses	Set to NULL
		assertNull(resultTest.getDeductibleExpenses());
		// Adjusted Medical Expenses	Set to NULL
		Expense medical = vetStatement.getExpense(ExpenseType.EXPENSE_TYPE_ADJUSTED_MEDICAL);
		assertNotNull(medical);
		assertNotNull(medical.getAmount());
		assertTrue(medical.getAmount().equals(new BigDecimal(0)));
		// Net Worth	Set to NULL
		assertNull(resultTest.getNetWorth());
		// Relationship to Relaxation %	IVM will return a PG8 Indicator
		assertTrue(resultTest.getPg8RelaxationIndicator().booleanValue());
		// GMT Address
		assertNotNull(resultTest.getGmtAddress());
		// Income Verification IV Status Set to NULL
		assertNull(resultTest.getIncomeVerificationStatus());
		// IV Status Date	Set to NULL
		assertNull(resultTest.getIncomeVerificationStatusDate());
		// Date IVM MT Completed	Set to "current date"
		assertNull(resultTest.getIncomeVerificationStatusDate());
		//	Co-Pay Exemption Test Status	See "Pharmacy Copay Status" field above
		if (incomingRxStatus != null) {
			assertTrue(incomingRxStatus.getStatus().getCode().equals(resultRxStatus.getStatus().getCode()));
		}

		//	Test Determined Status	From previous means test
		assertTrue(resultRxStatus.getDeterminedStatus().getCode().equals(originalRxStatus.getDeterminedStatus().getCode()));
		// Threshold	Means Test	From ES (SDS table)
		assertNotNull(resultTest.getThresholdA());
		// GMT	Based on GMT Address from previous MT and income year
		assertNotNull(resultTest.getGmtThresholdAmount());
		// Net Worth Threshold	From ES (SDS table)
		assertNotNull(resultTest.getNetworthThreshold());
		// Basic Pension	From ES (SDS table)
		assertNotNull(resultTest.getChildIncomeExclusionThreshold());
		// Child Income Exclusion	From ES (SDS table)
		assertNotNull(resultTest.getChildIncomeExclusionThreshold());
		// Aid & Attendance	From ES (SDS table) NOT NEED PER JOHN INNIS
		//	DONE NOT NEED PER JOHN INNIS
		//	Beneficiary Travel	Set to NULL
		assertNull(onFile.getBeneficiaryTravel(conversionIncomeYear, site));

		//	Effective Date	Same as "Test Effective Date" above
		// DONE above
		//	Completed Date	Same as "Date Test Completed" above
		assertTrue(DateUtils.isSameDay(CommonDateUtils.getCurrentDate(), resultTest.getCompletedDate()));
		//	Means Test Status	Received from IVM
		if (incomingMtStatus != null) {
			assertTrue(incomingMtStatus.getStatus().getCode().equals(resultTest.getIncomeTestStatus().getStatus().getCode()));
		}
		//	Test Determined Status	From previous means test
		assertTrue(resultTest.getDeterminedStatus().getCode().equals(original.getDeterminedStatus().getCode()));
		//	Effective Date	1/1 (January 1) of calendar year for the income year
		assertNotNull(resultTest.getEffectiveDate());
		//	Completed Date	 Date conversion received from IVM
		assertNotNull(resultTest.getIVMTestCompletionDate());
		assertNotNull(resultTest.getIvmConversionDate());

	}
	private void applyAssertionsUpdateTest(Person onFile, Person incoming, IncomeTest original,
			Integer conversionIncomeYear, VAFacility site) throws Exception {
		IncomeTestStatus ivmStatus = incoming.getIncomeTest(conversionIncomeYear).getIncomeTestStatus();
		IncomeTest resultTest = onFile.getIncomeTest(conversionIncomeYear);
		IncomeTest ivmTest = incoming.getIncomeTest(conversionIncomeYear);
		assertNotNull(resultTest);
		// CCR 12345
		assertNotNull(resultTest.getLastEditedDate());

		assertTrue(ObjectUtils.equals(resultTest.getDiscloseFinancialInformation(),
				ivmTest.getDiscloseFinancialInformation()));
		if (MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getCode().equals(resultTest.getStatus().getCode()) ||
				MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED.getCode().equals(resultTest.getStatus().getCode())) {
			assertTrue(Boolean.TRUE.equals(resultTest.getAgreesToPayDeductible()));
		}
		else
			assertNull(resultTest.getAgreesToPayDeductible());


		assertTrue(resultTest.isPrimaryIncomeTest()); // it should be primary test for IY
		assertTrue(ObjectUtils.equals(resultTest.getEffectiveDate(), ivmTest.getEffectiveDate()));
		System.out.println("result="+resultTest.getDeterminedStatus().getDescription());
		System.out.println("original="+original.getDeterminedStatus().getDescription());
		assertTrue(ObjectUtils.equals(resultTest.getDeterminedStatus().getCode(), original.getDeterminedStatus().getCode()));
		if (!MeansTestStatus.MT_STATUS_NO_LONGER_REQUIRED.getCode().equals(ivmTest.getStatus().getCode()))
			assertTrue(ObjectUtils.equals(resultTest.getStatus().getCode(), ivmTest.getStatus().getCode()));
		assertTrue(ObjectUtils.equals(resultTest.getSiteConductingTest(), original.getSiteConductingTest()));
		assertTrue(ObjectUtils.equals(resultTest.getCompletedDate(), ivmTest.getCompletedDate()));
		assertTrue(ObjectUtils.equals(resultTest.getCadAdjusted(), original.getCadAdjusted()));
		assertTrue(ObjectUtils.equals(resultTest.getAdjudicationDate(), original.getAdjudicationDate()));
		IncomeTestStatus incomingRx = incoming.getIncomeTest(conversionIncomeYear).getIncomeTestStatus(this.getLookupService().getIncomeTestTypeByCode(
				IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST.getCode()));
		IncomeTestStatus rxResult = resultTest.getIncomeTestStatus(this.getLookupService().getIncomeTestTypeByCode(
				IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST.getCode()));
		IncomeTestStatus rxOriginal = original.getIncomeTestStatus(this.getLookupService().getIncomeTestTypeByCode(
				IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST.getCode()));
		if (rxOriginal != null) {
			assertNotNull(rxResult);
			assertTrue(ObjectUtils.equals(rxOriginal.getDeterminedStatus().getCode(), rxResult.getDeterminedStatus().getCode()));
		}

		assertTrue(ObjectUtils.equals(resultTest.getHardship(), original.getHardship()));
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(ivmTest.getSource().getCode()));
		assertNull(resultTest.getTotalIncome());
		assertNull(resultTest.getNetIncome());
		assertNull(resultTest.getDeductibleExpenses());
		assertNull(resultTest.getNetWorth());
		assertTrue(ObjectUtils.equals(resultTest.getPg8RelaxationIndicator(), ivmTest.getPg8RelaxationIndicator()));
		assertNotNull(resultTest.getPg8RelaxationIndicator());
		assertTrue(ObjectUtils.equals(resultTest.getGmtAddress(), original.getGmtAddress()));
		assertTrue(ObjectUtils.equals(resultTest.getIncomeVerificationStatus(), original.getIncomeVerificationStatus()));
		assertTrue(ObjectUtils.equals(resultTest.getIncomeVerificationStatusDate(), original.getIncomeVerificationStatusDate()));
		if (incomingRx != null) {
			assertNotNull(rxResult);
			assertTrue(ObjectUtils.equals(incomingRx.getStatus(), rxResult.getStatus()));
		}
		assertTrue(ObjectUtils.equals(resultTest.getCompletedDate(), ivmTest.getCompletedDate()));
		assertNotNull(resultTest.getCompletedDate());
		assertTrue(ObjectUtils.equals(resultTest.getEffectiveDate() ,ivmTest.getEffectiveDate()));
		assertNotNull(resultTest.getEffectiveDate());
		assertTrue(ObjectUtils.equals(resultTest.getIVMTestCompletionDate(), ivmTest.getIVMTestCompletionDate()));
		assertNotNull(resultTest.getIVMTestCompletionDate());
		assertTrue(ObjectUtils.equals(resultTest.getIvmConversionDate(), ivmTest.getIvmConversionDate()));
		assertNotNull(resultTest.getIvmConversionDate());
		assertTrue(ObjectUtils.equals(resultTest.getThresholdA(), ivmTest.getThresholdA()));
		assertNotNull(resultTest.getThresholdA());
		assertTrue(ObjectUtils.equals(resultTest.getGmtThresholdAmount(), original.getGmtThresholdAmount()));
		assertTrue(ObjectUtils.equals(resultTest.getNetworthThreshold(), ivmTest.getNetworthThreshold()));
		assertTrue(ObjectUtils.equals(resultTest.getChildIncomeExclusionThreshold(), original.getChildIncomeExclusionThreshold()));

	}

	private void attachIncomeTestStatus(IncomeTest incomeTest, MeansTestStatus.Code status, IncomeTestType.Code type,
			MeansTestStatus.Code determined) throws Exception {
		IncomeTestStatus incomeTestStatus = new IncomeTestStatus();
		incomeTestStatus.setStatus(this.getLookupService().getMeansTestStatusByCode(status.getCode()));
		incomeTestStatus.setType(this.getLookupService().getIncomeTestTypeByCode(type.getCode()));
		incomeTestStatus.setDeterminedStatus(this.getLookupService().getMeansTestStatusByCode(determined.getCode()));
		incomeTestStatus.setCompletedDate(new Date());
		incomeTestStatus.setLastEditedDate(new Date());
		incomeTest.addStatus(incomeTestStatus);
	}

	public void testDeterminePrimaryAndCurrentTestForIVM() throws Exception {
		/*
		 * 4.6. Determine Primary Test
		 *
		 * If the converted test is for a more recent income year than the
		 * current means test on file, the system will make the converted test
		 * the current means test and primary for that income year. For the
		 * basic flow the converted test is more recent than the current means
		 * test on file. Refer to alternate flow 5.4 Determine Current Test for
		 * older income year data.
		 *
		 * 5.4. Determine Current Test
		 *
		 * If the conversion test data received is for an older income year and
		 * there is a more recent test on file, the system will update the older
		 * test with the data received from IVM but keep the more recent test as
		 * the current means test for that income year. The use case resumes at
		 * step 4.7 Store Income Test Data in the basic flow.
		 *
		 */
		this.fail("todo");
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2011);
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT, incomeYear);
		incomeTest.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest.setThresholdA(new BigDecimal(9));
		onFile.setIncomeTest(incomeYear, incomeTest);
		onFile.getIncomeTest(incomeYear).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		onFile.setFinancialStatement(incomeYear, this.createFinancialStatement());
		onFile.getFinancialStatement(incomeYear).setAsset(this.getLookupService().getAssetTypeByCode(
				AssetType.CODE_OTHER.getCode()), this.createAsset((double)458));
		onFile.getFinancialStatement(incomeYear).setDebt(this.createDebt((double)5));
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
        Person pristine = (Person) onFile.clone();
        Integer conversionIncomeYear = new Integer(2012);
        IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		this.attachIVMConversionTest(incoming, conversionIncomeYear, true, true, "MT");

		// PRECONDITION:  NO INCOME TEST ON FILE
        FinancialInputData data = new FinancialInputData(incoming, onFile, pristine, ivmFinancialInfo );
		FinancialInputParameter param = this.buildFinancialInputParameter(data);
		param.createOrUpdateTestFromIVMConversionData(false);
		IncomeTest test = onFile.getIncomeTest(conversionIncomeYear);
		assertNotNull(test);


	}
	public void testProcessIVMFinancialsReversalNoExistingBase() throws Exception {
		/*
		 * 5.1. Process Reversal
		 *
		 * If the data received is for a reversal and the conversion was to an
		 * existing means test then: - Change the test source from IVM to VAMC
		 * if there was a site conducting test OR - Change the test source from
		 * IVM to HEC if the test on file was a HEC test (site conducting test =
		 * null) AND - Recalculate the totals from the saved financial data
		 *
		 * ELSE
		 *
		 * If the data received is for a reversal and the conversion was NOT to
		 * an existing means test then delete the cloned/created means test and
		 * make the most recent Primary test the Current test.
		 */
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer (2011);
		VAFacility site = this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getCode());
		this.attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());

		Integer conversionIY = new Integer (2012);
		this.attachFullFinancialData(onFile, conversionIY, site, false, IncomeTestSource.CODE_HEC.getCode());
		onFile.getIncomeTest(conversionIY).setSource(this.getLookupService().getIncomeTestSourceByCode(IncomeTestSource.CODE_IVM.getCode()));
		onFile.getIncomeTest(conversionIY).setMeansTestStatus(
				this.getLookupService().getMeansTestStatusByCode(MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getCode()));
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIY);
		ivmFinancialInfo.setIvmActionCode("R");

		IncomeTest current = this.getPersonHelperService().getCurrentIncomeTest(onFile);
		assertTrue(MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getCode().equals(current.getStatus().getCode()));
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(current.getSource().getCode()));
		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		IncomeTest result = this.getPersonHelperService().getCurrentIncomeTest(updated);
		assertNotNull(result);
		assertNotNull(result.getLastEditedDate());
		assertTrue(MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode().equals(result.getStatus().getCode()));
		assertFalse(IncomeTestSource.CODE_IVM.getCode().equals(result.getSource().getCode()));

	}
	public void testProcessIVMFinancialsReversalNoExistingBaseADRPerson() throws Exception {
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("375124624"));
		Person onFile = this.getPersonService().getPerson(personKey);
		Integer conversionIY = new Integer(2012);
		Person incoming = savePerson(onFile);
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIY);
		ivmFinancialInfo.setIvmActionCode("R");

		IncomeTest current = this.getPersonHelperService().getCurrentIncomeTest(onFile);
		assertTrue(MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getCode().equals(current.getStatus().getCode()));
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(current.getSource().getCode()));
		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		IncomeTest result = this.getPersonHelperService().getCurrentIncomeTest(updated);
		assertNotNull(result);
		assertNotNull(result.getLastEditedDate());
		assertNotNull(result.getStatus());
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(result.getSource().getCode()));

	}
	public void testMergeFullIncomeTestToSimulateReversal() throws Exception {
		/*
		 * Reversing a conversion depends on mergeFullIncomeTest method. Need to
		 * make sure critical fields are restored from original test.
		 */
		Person onFile1 = buildSimplePerson(); // bare-bones person
		Person onFile2 = (Person)onFile1.clone(); // bare-bones person
		Integer incomeYear = new Integer (2012);
		VAFacility site = this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getCode());
		this.attachFullFinancialData(onFile1, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());
		this.attachIVMConversionTest(onFile2, incomeYear, true, true, "MT");
		// this is what the original test would be prior to conversion
		IncomeTest original = onFile1.getIncomeTest(incomeYear);
		// this is the test after a conversion
		IncomeTest conversion = onFile2.getIncomeTest(incomeYear);
		assertNotNull(original.getLastEditedDate());
		assertFalse(this.getDate(2013, 2, 2).equals(conversion.getLastEditedDate()));
		this.getMergeRuleService().mergeFullIncomeTest(original, conversion);
		// make sure the conversion is reversed to look like original test
		assertTrue(MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode().equals(conversion.getStatus().getCode()));
		assertNotNull(conversion.getLastEditedDate());
		assertTrue(this.getDate(2013, 2, 2).equals(conversion.getLastEditedDate()));
	}
	public void testProcessIVMFinancialsReversalBaseExistsADRPERSON() throws Exception {

		//377102172 377102222 373971922 375124624
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("373971922"));
		Person onFile = this.getPersonService().getPerson(personKey);
		Integer conversionIncomeYear = new Integer(2008);
		IncomeTest onf = onFile.getIncomeTest(conversionIncomeYear);
		System.out.println("income test status= "+onf.getStatus().getDescription());
		System.out.println("income test deterined status= "+onf.getDeterminedStatus().getDescription());
		Person incoming = savePerson(onFile);
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("R");
		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		IncomeTest result = updated.getIncomeTest(conversionIncomeYear);
		assertNotNull(result);

		assertFalse(IncomeTestSource.CODE_IVM.getCode().equals(result.getSource().getCode()));
	//	assertTrue(MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode().equals(result.getStatus().getCode()));
		Set statuses = result.getStatuses();
		Iterator iter = statuses.iterator();
		for (Iterator i = iter ; i.hasNext();) {
			IncomeTestStatus status = (IncomeTestStatus)i.next();
			System.out.println("====================");
			System.out.println("income test status Test Type= "+status.getType().getDescription());
			System.out.println("income test status= "+status.getStatus().getDescription());
			System.out.println("income test status modified= "+status.getModifiedOn());
			System.out.println("income test status Last Edit Date= "+status.getLastEditedDate());
			System.out.println("income test status history ID= "+status.getHistoryId());
			System.out.println("income test status identifier= "+status.getEntityKey().getKeyValueAsString());
			System.out.println("====================");
		}
		System.out.println("last edit="+updated.getIncomeTest(conversionIncomeYear).getLastEditedDate());

	}


	public void testProcessIVMFinancialsConversionExistingOnfileVAMC() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2011);
		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_VAMC.getCode());
	    onFile.getIncomeTest(incomeYear).getIncomeTestStatus().setDeterminedStatus(
	    		this.getLookupService().getMeansTestStatusByCode(MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode()));
		IncomeTest original = (IncomeTest)onFile.getIncomeTest(incomeYear).clone();
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		Integer conversionIncomeYear = incomeYear;
		this.attachIVMConversionTest(incoming, conversionIncomeYear, true, true, "MT");
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		IncomeTest resultIncomeTest = updated.getIncomeTest(conversionIncomeYear);
		assertNotNull(resultIncomeTest.getStatus());
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(resultIncomeTest.getSource().getCode()));
		assertTrue(MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getCode().equals(resultIncomeTest.getStatus().getCode()));
		assertTrue(MeansTestStatus.MT_STATUS_NON_EXEMPT.getCode().equals(
				resultIncomeTest.getIncomeTestStatus(IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST).getStatus().getCode()));
		this.applyAssertionsUpdateTest(updated, incoming, original, conversionIncomeYear, site);
	}
	public void test12447ProcessIVMFinancialsConversionExistingOnfileHEC() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2011);
		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());
	    onFile.getIncomeTest(incomeYear).getIncomeTestStatus().setDeterminedStatus(
	    		this.getLookupService().getMeansTestStatusByCode(MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode()));
		IncomeTest original = (IncomeTest)onFile.getIncomeTest(incomeYear).clone();
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		Integer conversionIncomeYear = incomeYear;
		this.attachIVMConversionTest(incoming, conversionIncomeYear, true, true, "MT");
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		IncomeTest resultIncomeTest = updated.getIncomeTest(conversionIncomeYear);
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(resultIncomeTest.getSource().getCode()));
		assertTrue(MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getCode().equals(resultIncomeTest.getStatus().getCode()));
		assertTrue(MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getCode().equals(resultIncomeTest.getDeterminedStatus().getCode()));
		assertTrue(MeansTestStatus.MT_STATUS_NON_EXEMPT.getCode().equals(
				resultIncomeTest.getIncomeTestStatus(IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST).getStatus().getCode()));
		this.applyAssertionsUpdateTest(updated, incoming, original, conversionIncomeYear, site);
	}
	public void test12532ProcessIVMFinancialsConversionExistingOnfileHEC() throws Exception {
		process12532ProcessIVMFinancialsConversionExistingOnfileHEC("MT");
	}
	public void test12532ProcessIVMFinancialsConversionExistingOnfileHECGMT() throws Exception {
		process12532ProcessIVMFinancialsConversionExistingOnfileHEC("GMT");
	}
	public void test12532ProcessIVMFinancialsConversionExistingOnfileHECnull() throws Exception {
		process12532ProcessIVMFinancialsConversionExistingOnfileHEC(null);
	}
	private void process12532ProcessIVMFinancialsConversionExistingOnfileHEC(String c) throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2011);
		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());
	    onFile.getIncomeTest(incomeYear).getIncomeTestStatus().setDeterminedStatus(
	    		this.getLookupService().getMeansTestStatusByCode(MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode()));
		IncomeTest original = (IncomeTest)onFile.getIncomeTest(incomeYear).clone();
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		Integer conversionIncomeYear = incomeYear;
		this.attachIVMConversionTest(incoming, conversionIncomeYear, true, true, c);
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		IncomeTest resultIncomeTest = updated.getIncomeTest(conversionIncomeYear);
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(resultIncomeTest.getSource().getCode()));
		if ("MT".equals(c))
			assertTrue(MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getCode().equals(resultIncomeTest.getStatus().getCode()));
		else if ("GMT".equals(c))
			assertTrue(MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED.getCode().equals(resultIncomeTest.getStatus().getCode()));
		assertTrue(MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode().equals(resultIncomeTest.getDeterminedStatus().getCode()));
		assertTrue(MeansTestStatus.MT_STATUS_NON_EXEMPT.getCode().equals(
				resultIncomeTest.getIncomeTestStatus(IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST).getStatus().getCode()));
		this.applyAssertionsUpdateTest(updated, incoming, original, conversionIncomeYear, site);
	}
	public void test12532ProcessIVMFinancialsConversionCloneWithGMT() throws Exception {
		process12532ProcessIVMFinancialsConversionClone("GMT");
	}

	public void test12532ProcessIVMFinancialsConversionClone() throws Exception {
		process12532ProcessIVMFinancialsConversionClone("MT");
	}
	private void process12532ProcessIVMFinancialsConversionClone(String c) throws Exception {
		/*
		 *
		 * Need to update ESR code to explicitly set the Agree to Pay Indicator
		 * to Yes when IVM sends a conversion to one of these statuses: MT Copay
		 * Required or GMT Copay Required.
		 */
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2011);
		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());
	    onFile.getIncomeTest(incomeYear).getIncomeTestStatus().setDeterminedStatus(
	    		this.getLookupService().getMeansTestStatusByCode(MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode()));
		IncomeTest original = (IncomeTest)onFile.getIncomeTest(incomeYear).clone();
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		Integer conversionIncomeYear = new Integer(2012);
		this.attachIVMConversionTest(incoming, conversionIncomeYear, true, true, c);
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		IncomeTest resultIncomeTest = updated.getIncomeTest(conversionIncomeYear);
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(resultIncomeTest.getSource().getCode()));
		if ("MT".equals(c))
			assertTrue(MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getCode().equals(resultIncomeTest.getStatus().getCode()));
		else if ("GMT".equals(c))
			assertTrue(MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED.getCode().equals(resultIncomeTest.getStatus().getCode()));
		// notice that existing test had MT_STATUS_MT_COPAY_EXEMPT as TDS
		assertTrue(MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode().equals(resultIncomeTest.getDeterminedStatus().getCode()));
		assertTrue(MeansTestStatus.MT_STATUS_NON_EXEMPT.getCode().equals(
				resultIncomeTest.getIncomeTestStatus(IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST).getStatus().getCode()));
		this.applyAssertionsCreateNewTest(updated, incoming, original, conversionIncomeYear, site, false);
	}
	public void test12555GetPreviousPrimaryTest() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer aYear = new Integer(2007);
		Integer bYear = new Integer(2008);
		Integer cYear = new Integer(2009);
		Integer dYear = new Integer(2010);
		Integer eYear = new Integer(2011);
		Integer fYear = new Integer(2012);

		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, aYear, site, false, IncomeTestSource.CODE_HEC.getCode());
	    attachFullFinancialData(onFile, bYear, site, false, IncomeTestSource.CODE_HEC.getCode());
	    attachFullFinancialData(onFile, cYear, site, false, IncomeTestSource.CODE_HEC.getCode());
	    attachFullFinancialData(onFile, dYear, site, false, IncomeTestSource.CODE_HEC.getCode());
	    attachFullFinancialData(onFile, eYear, site, false, IncomeTestSource.CODE_HEC.getCode());
	    attachFullFinancialData(onFile, fYear, site, false, IncomeTestSource.CODE_HEC.getCode());

	    FinancialInputParameter param = new FinancialInputParameter();
		Integer conversionIncomeYear = bYear;
	    IncomeTest resultTest = param.getPreviousPrimaryTest(conversionIncomeYear, onFile);
	    assertTrue(resultTest.getIncomeYear().equals(aYear));
		conversionIncomeYear = cYear;
	    resultTest = param.getPreviousPrimaryTest(conversionIncomeYear, onFile);
	    assertTrue(resultTest.getIncomeYear().equals(bYear));
		conversionIncomeYear = fYear;
	    resultTest = param.getPreviousPrimaryTest(conversionIncomeYear, onFile);
	    assertTrue(resultTest.getIncomeYear().equals(eYear));

	}

	public void test12447ProcessIVMFinancialsConversionClone() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2011);
		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());
	    onFile.getIncomeTest(incomeYear).getIncomeTestStatus().setDeterminedStatus(
	    		this.getLookupService().getMeansTestStatusByCode(MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode()));
		IncomeTest original = (IncomeTest)onFile.getIncomeTest(incomeYear).clone();
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		Integer conversionIncomeYear = new Integer(2012);
		this.attachIVMConversionTest(incoming, conversionIncomeYear, true, true, "MT");
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		IncomeTest resultIncomeTest = updated.getIncomeTest(conversionIncomeYear);
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(resultIncomeTest.getSource().getCode()));
		assertTrue(MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getCode().equals(resultIncomeTest.getStatus().getCode()));
		// notice that existing test had MT_STATUS_MT_COPAY_EXEMPT as TDS
		assertTrue(MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode().equals(resultIncomeTest.getDeterminedStatus().getCode()));
		assertTrue(MeansTestStatus.MT_STATUS_NON_EXEMPT.getCode().equals(
				resultIncomeTest.getIncomeTestStatus(IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST).getStatus().getCode()));
		this.applyAssertionsCreateNewTest(updated, incoming, original, conversionIncomeYear, site, false);
	}

	public void testProcessIVMFinancialsConversionADRPERSON() throws Exception {
		//convert a test. use person with a test that can be converted. 373971922 377102222 376777416  375124624(no base) 373971922
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("373971922"));
		Person onFile = this.getPersonService().getPerson(personKey);
		Person incoming = savePerson(onFile);
		Integer conversionIncomeYear = new Integer(2012);
		this.attachIVMConversionTest(incoming, conversionIncomeYear, true, true, "MT");
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		IncomeTest test = (IncomeTest)onFile.getIncomeTest(conversionIncomeYear).clone();
		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(updated.getIncomeTest(conversionIncomeYear).getSource().getCode()));
		assertNotNull(updated.getIncomeTest(conversionIncomeYear).getStatus());
		System.out.println("last edit="+updated.getIncomeTest(conversionIncomeYear).getLastEditedDate());
		this.applyAssertionsUpdateTest(onFile, incoming, test, conversionIncomeYear, test.getSiteConductingTest());
	}
	public void testProcessIVMFinancialsConvertAgainADRPERSON() throws Exception {
		//convert a test. use person with a test that can be converted. 373971922 377102222
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("373971922"));
		Person onFile = this.getPersonService().getPerson(personKey);
		Person incoming = savePerson(onFile);
		Integer conversionIncomeYear = new Integer(2009);
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(updated.getIncomeTest(conversionIncomeYear).getSource().getCode()));
		//this.setComplete();
	}
	public void testProcessIVMFinancialsConversion2010NoOnfile() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2012);
		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_VAMC.getCode());
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		IncomeTest original = (IncomeTest)onFile.getIncomeTest(incomeYear).clone();
		Person incoming = savePerson(onFile);
		Integer conversionIncomeYear = new Integer(2010);
		this.attachIVMConversionTest(incoming, conversionIncomeYear, true, true, "MT");
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		Person updated = null;
		try {
		updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		}
		catch (ServiceException e ) {

			System.out.println("e="+e.getMessage());
			return;

		}
		fail("should throw exception");
//		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(updated.getIncomeTest(conversionIncomeYear).getSource().getCode()));
//		this.applyAssertionsCreateNewTest(onFile, incoming, original, conversionIncomeYear, site, false);
	}
	public void testProcessIVMFinancialsConversionNoOnfileNoMt() throws Exception {
		processIVMFinancialsConversionNoOnfileOptionalStatus(false, true);
	}
	public void testProcessIVMFinancialsConversionNoOnfileNoRx() throws Exception {
		processIVMFinancialsConversionNoOnfileOptionalStatus(true, false);
	}
	private void processIVMFinancialsConversionNoOnfileOptionalStatus(boolean hasMt, boolean hasRx ) throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2006);
		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_VAMC.getCode());
	    onFile.getIncomeTest(incomeYear).setEffectiveDate(this.getDate(2007, 1, 1));
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		IncomeTest original = (IncomeTest)onFile.getIncomeTest(incomeYear).clone();
		Person incoming = savePerson(onFile);
		Integer conversionIncomeYear = new Integer(2012);
		this.attachIVMConversionTest(incoming, conversionIncomeYear, hasMt, hasRx, "MT");
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(updated.getIncomeTest(conversionIncomeYear).getSource().getCode()));
		this.applyAssertionsCreateNewTest(onFile, incoming, original, conversionIncomeYear, site, false);
	}

	public void testProcessIVMFinancialsConversionNoOnfile() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2007);
		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_VAMC.getCode());
	    onFile.getIncomeTest(incomeYear).setEffectiveDate(this.getDate(2008, 1, 1));
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		IncomeTest modified = (IncomeTest)onFile.getIncomeTest(incomeYear);
		modified.setLastEditedDate(new Date());
		assertNotNull(modified.getLastEditedDate());
		IncomeTest original = (IncomeTest)onFile.getIncomeTest(incomeYear).clone();
		assertNotNull(original.getLastEditedDate());
		Person incoming = savePerson(onFile);
		Integer conversionIncomeYear = new Integer(2012);
		this.attachIVMConversionTest(incoming, conversionIncomeYear, true, true, "MT");
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(updated.getIncomeTest(conversionIncomeYear).getSource().getCode()));
		this.applyAssertionsCreateNewTest(onFile, incoming, original, conversionIncomeYear, site, false);
	}
	public void testProcessIVMFinancialsConversionOldTest() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer oldIncomeYear = new Integer(2010);
		Integer incomeYear = new Integer(2011);
		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_VAMC.getCode());
	    attachFullFinancialData(onFile, oldIncomeYear, site, false, IncomeTestSource.CODE_VAMC.getCode());
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		IncomeTest original = (IncomeTest)onFile.getIncomeTest(oldIncomeYear).clone();
		Person incoming = savePerson(onFile);
		Integer conversionIncomeYear = oldIncomeYear;
		this.attachIVMConversionTest(incoming, conversionIncomeYear, true, true, "MT");
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(updated.getIncomeTest(conversionIncomeYear).getSource().getCode()));
		this.applyAssertionsUpdateTest(onFile, incoming, original, conversionIncomeYear, site);
	}
	public void testProcessIVMFinancialsConversionAndSave() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer oldIncomeYear = new Integer(2010);
		Integer incomeYear = new Integer(2011);
		VAFacility site = this.getRandomVAFacility();
	    attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_VAMC.getCode());
	    attachFullFinancialData(onFile, oldIncomeYear, site, false, IncomeTestSource.CODE_VAMC.getCode());
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		IncomeTest original = (IncomeTest)onFile.getIncomeTest(oldIncomeYear).clone();
		Person incoming = savePerson(onFile);
		Integer conversionIncomeYear = oldIncomeYear;
		this.attachIVMConversionTest(incoming, conversionIncomeYear, true, true, "MT");
		IVMFinancialInfo ivmFinancialInfo = new IVMFinancialInfo();
		ivmFinancialInfo.setIncomeYear(conversionIncomeYear);
		ivmFinancialInfo.setIvmActionCode("C");
		Person updated = this.getFinancialsService().convertOrReverseESRIncomeTest(incoming, ivmFinancialInfo);
		assertTrue(IncomeTestSource.CODE_IVM.getCode().equals(updated.getIncomeTest(conversionIncomeYear).getSource().getCode()));
		this.applyAssertionsUpdateTest(onFile, incoming, original, conversionIncomeYear, site);

		//this.setComplete();
	}
	public void testMedicaidForCe() throws Exception {
		// This test requires that Person have existing Medicaid with Y (and corresponding verified enrollment)
		// that was changed to No. This test checks that a gap is filled in the
		// CE rules where person did not get second chance even though a qualifying income test
		// was provided and they had previous Medicaid eligibility. See CCR 10517
		//PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("490924"));
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("376778923"));
		Person onFile = this.getPersonService().getPerson(personKey);

		Person incoming = savePerson(onFile);

		Integer incomeYear = new Integer(2010);
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED, incomeYear);
		incomeTest.setGmtThresholdAmount(new BigDecimal(1010));
		incomeTest.setDiscloseFinancialInformation(Boolean.TRUE);
		incomeTest.setThresholdA(new BigDecimal(1000));

		incomeTest.setEffectiveDate(getDate(2011,1,1));
		incomeTest.setTotalIncome(new BigDecimal(1011));
		incomeTest.setAgreesToPayDeductible(Boolean.TRUE);
		incoming.setIncomeTest(incomeYear, incomeTest);

		Person result = calculate(incoming);
		System.out.println("done");
		//   this.getEligibilityEnrollmentService().updateEligibilityData(onFile);
		//setComplete();
	}



	public void testDetermineEnrollment8bIVM() throws Exception {
		process8b(IncomeTestSource.CODE_IVM.getCode());
	}
	public void testDetermineEnrollment8bHEC() throws Exception {
		process8b(IncomeTestSource.CODE_HEC.getCode());
	}

	private void process8b(String source) throws Exception {
		// You have to override the EnrollmentInputParameter so it returns Verified Enrollment
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer year = new Integer(2012);
		this.attachApplication(onFile);

		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED, year);

		incomeTest.setGmtThresholdAmount(new BigDecimal(40000));
		incomeTest.setThresholdA(new BigDecimal(45000));
		onFile.setIncomeTest(year, incomeTest);
		onFile.getIncomeTest(year).setSource(this.getLookupService().getIncomeTestSourceByCode(source));
		onFile.getIncomeTest(year).setAgreesToPayDeductible(Boolean.TRUE);
		onFile.getIncomeTest(year).setDiscloseFinancialInformation(Boolean.TRUE);
		onFile.setFinancialStatement(year, this.createFinancialStatement());
		onFile.getFinancialStatement(year).setAsset(
				this.getLookupService().getAssetTypeByCode(AssetType.CODE_OTHER.getCode()), this.createAsset((double)458));
		onFile.getFinancialStatement(year).setDebt(this.createDebt((double)5));
		Income income = (Income) onFile.getFinancialStatement(year).getIncome().values().iterator().next();
		income.setAmount(new BigDecimal(50000));
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		onFile.getIncomeTest(year).setPg8RelaxationIndicator(Boolean.TRUE);
		this.attachServiceConnectionAward(onFile, new Integer(0));

		Person incoming = savePerson(onFile);
		this.getEnrollmentRuleService().calculateEE(onFile, true, true);
		assertTrue(onFile.getIncomeTest(year).getPg8RelaxationIndicator().booleanValue());
		assertTrue(EnrollmentPriorityGroup.GROUP_8.getCode().equals(onFile.getEnrollmentDetermination().getPriorityGroup().getCode()));
		assertTrue(EnrollmentPrioritySubGroup.SUBGROUP_B.getCode().equals(onFile.getEnrollmentDetermination().getPrioritySubGroup().getCode()));
	}
	public void testDetermineEnrollment8dIVM() throws Exception {
		process8d(IncomeTestSource.CODE_IVM.getCode());
	}
	public void testDetermineEnrollment8dHEC() throws Exception {
		process8d(IncomeTestSource.CODE_HEC.getCode());
	}
	private void process8d(String source) throws Exception {
		// You have to override the EnrollmentInputParameter so it returns Verified Enrollment
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer year = new Integer(2012);
		this.attachApplication(onFile);

		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED, year);

		incomeTest.setGmtThresholdAmount(new BigDecimal(45000));
		incomeTest.setThresholdA(new BigDecimal(45000));
		onFile.setIncomeTest(year, incomeTest);
		onFile.getIncomeTest(year).setSource(this.getLookupService().getIncomeTestSourceByCode(source));
		onFile.getIncomeTest(year).setAgreesToPayDeductible(Boolean.TRUE);
		onFile.getIncomeTest(year).setDiscloseFinancialInformation(Boolean.TRUE);
		onFile.setFinancialStatement(year, this.createFinancialStatement());
		onFile.getFinancialStatement(year).setAsset(
				this.getLookupService().getAssetTypeByCode(AssetType.CODE_OTHER.getCode()), this.createAsset((double)458));
		onFile.getFinancialStatement(year).setDebt(this.createDebt((double)5));
		Income income = (Income) onFile.getFinancialStatement(year).getIncome().values().iterator().next();
		income.setAmount(new BigDecimal(145000));
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		onFile.getIncomeTest(year).setPg8RelaxationIndicator(Boolean.TRUE);
		Person incoming = savePerson(onFile);
		this.getEnrollmentRuleService().calculateEE(onFile, true, true);
		assertTrue(onFile.getIncomeTest(year).getPg8RelaxationIndicator().booleanValue());
		assertTrue(EnrollmentPriorityGroup.GROUP_8.getCode().equals(onFile.getEnrollmentDetermination().getPriorityGroup().getCode()));
		assertTrue(EnrollmentPrioritySubGroup.SUBGROUP_D.getCode().equals(onFile.getEnrollmentDetermination().getPrioritySubGroup().getCode()));
	}

	public void testDetermineEnrollmentP8() throws Exception {
		// You have to override the EnrollmentInputParameter so it returns Verified Enrollment
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer year = new Integer(2012);
		this.attachApplication(onFile);
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED, year);
		incomeTest.setGmtThresholdAmount(new BigDecimal(46000));
		incomeTest.setThresholdA(new BigDecimal(45000));
		onFile.setIncomeTest(year, incomeTest);
		onFile.getIncomeTest(year).setSource(this.getLookupService().getIncomeTestSourceByCode(IncomeTestSource.CODE_HEC.getCode()));
		onFile.getIncomeTest(year).setAgreesToPayDeductible(Boolean.TRUE);
		onFile.getIncomeTest(year).setDiscloseFinancialInformation(Boolean.TRUE);
		onFile.setFinancialStatement(year, this.createFinancialStatement());
		onFile.getFinancialStatement(year).setAsset(
				this.getLookupService().getAssetTypeByCode(AssetType.CODE_OTHER.getCode()), this.createAsset((double)458));
		onFile.getFinancialStatement(year).setDebt(this.createDebt((double)5));
		Income income = (Income) onFile.getFinancialStatement(year).getIncome().values().iterator().next();
		income.setAmount(new BigDecimal(46100));
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		this.getEnrollmentRuleService().calculateEE(onFile, true, true);
		assertTrue(EnrollmentPriorityGroup.GROUP_8.getCode().equals(onFile.getEnrollmentDetermination().getPriorityGroup().getCode()));
		assertTrue(EnrollmentPrioritySubGroup.SUBGROUP_D.getCode().equals(onFile.getEnrollmentDetermination().getPrioritySubGroup().getCode()));
	}


	public void testMergeIncomeTests() throws Exception {
		Integer year = new Integer(2012);
		IncomeTestType type = getLookupService().getIncomeTestTypeByCode(IncomeTestType.CODE_MEANS_TEST.getCode());
		Person incomingPerson = buildSimplePerson();
		IncomeTest incoming = new IncomeTest();
		incoming.setPg8RelaxationIndicator(Boolean.TRUE);
		incoming.setIncomeYear(year);
		incoming.setType(type);
		incoming.setComments("incoming Comments");
		IncomeTestStatus status = new IncomeTestStatus();
		status.setStatus(getLookupService().getMeansTestStatusByCode(MeansTestStatus.MT_STATUS_EXEMPT.getCode()));
		status.setType(type);
		incoming.addIncomeTestStatus(status);
		System.out.println("incoming: " + incoming);
		incomingPerson.setIncomeTest(year, incoming);

		Person onFilePerson = buildSimplePerson();
		IncomeTest onFile = new IncomeTest();
		onFile.setIncomeYear(year);
		onFile.setType(type);
		onFile.setSiteConductingTest(this.getLookupService().getVaFacilityByCode(VAFacility.CODE_ALBUQUERQUE.getCode()));
		onFile.setComments("onFile Comments");
		System.out.println("onFile: " + onFile);
		onFilePerson.setIncomeTest(year, onFile);


		Person mergedPerson = this.getMergeRuleService().mergePerson(incomingPerson, onFilePerson, true);
		assertNotNull(mergedPerson.getIncomeTest(year).getPg8RelaxationIndicator());
		assertTrue(mergedPerson.getIncomeTest(year).getPg8RelaxationIndicator().booleanValue());
	}
	public void testUpdateInsurance() throws Exception {
		Person onFile = this.buildSimplePerson();
		// Create a policy for a veteran
		Medicare policy = (Medicare)this.createMedicareInsurance();
		InsuredRelationship relationship =
			this.getLookupService().getInsuredRelationshipByCode( InsuredRelationship.CODE_VETERAN.getName() );

		InsuranceSubscriber subscriber = new InsuranceSubscriber();
		subscriber.setRelationship( relationship );

		policy.setSubscriber( subscriber );
		policy.setReportSource( this.getRandomReportSource() );
		policy.setEnrolledInPartB( Boolean.TRUE );
		policy.setMedicareClaimNumber( "111111" );

		onFile.addInsurance( policy );
		this.attachVerifiedEnrollment(onFile);


		// Create a working person
		Person incoming = (Person)savePerson(onFile);
		this.createIVMMigrationEntry(incoming, new Integer(2012), MessageStatus.COMPLETE, false);
		policy = (Medicare)incoming.getInsurances().iterator().next();
		policy.setMedicareClaimNumber( "222222" );

		try {
			assertEquals( "111111", ((Medicare)onFile.getInsurances().iterator().next()).getMedicareClaimNumber() );
			this.getInsuranceService().updateInsurance( incoming );

//			onFile = this.getPersonService().getPerson( incoming.getPersonEntityKey() );
//			assertEquals( "222222", ((Medicare)onFile.getInsurances().iterator().next()).getMedicareClaimNumber() );
		}
		catch( ValidationServiceException e ) {
			if( logger.isDebugEnabled() ) {
				logger.debug( "Got an un-expected exception ", e );
			}
		}
	}

	public void testEmploymentChangeEmpty() throws Exception {

		Employment one = new Employment();
		Employment two = new Employment();
		two.setEmployerName("");
		boolean f = StringUtils.isEmpty(two.getEmployerName());

		if (StringUtils.isEmpty(one.getEmployerName()) ) {
			assertTrue(one.matchesDomainValues(two));
		}
	}

	public void testIncomeTestChanges() throws Exception {

		IncomeTest one = new IncomeTest();
		IncomeTest two = new IncomeTest();
		two.setDeductibleExpenses(new BigDecimal(4));
		assertTrue(one.matchesDomainConcept(two));
//		one.setDeductibleExpenses(new BigDecimal(4));
//		assertTrue(one.matchesDomainValues(two));
	}

	public void testEmploymentChange() throws Exception {

		Employment one = new Employment();
		Employment two = new Employment();
		Person onFile = this.buildSimplePerson();
		onFile.setEmployment(one);
		Person incoming = savePerson(onFile);
		two = incoming.getEmployment();

		two.setModifiedOn(new Date());

		// Shows that modified date has no influence
		assertTrue(one.matchesDomainValues(two));

		two.setEmployerPhone("444");
		assertFalse(one.matchesDomainValues(two));
		one.setEmployerPhone("444");
		assertTrue(one.matchesDomainValues(two));

		two.setEmployerAddress(new Address());
		assertFalse(one.matchesDomainValues(two));
		one.setEmployerAddress(new Address());
		assertTrue(one.matchesDomainValues(two));

		two.setEmployerName("444");
		assertFalse(one.matchesDomainValues(two));
		one.setEmployerName("444");
		assertTrue(one.matchesDomainValues(two));

		two.setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_FULL_TIME.getCode()));
		assertFalse(one.matchesDomainValues(two));
		one.setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_FULL_TIME.getCode()));
		assertTrue(one.matchesDomainValues(two));
		two.setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_NOT_EMPLOYED.getCode()));
		assertFalse(one.matchesDomainValues(two));
		one.setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_NOT_EMPLOYED.getCode()));
		assertTrue(one.matchesDomainValues(two));

		two.setOccupation("444");
		assertFalse(one.matchesDomainValues(two));
		one.setOccupation("444");
		assertTrue(one.matchesDomainValues(two));

		two.setRetirementDate(ImpreciseDateUtils.createImpreciseDate(2007,11,1));
		assertFalse(one.matchesDomainValues(two));
		one.setRetirementDate(ImpreciseDateUtils.createImpreciseDate(2007,11,1));
		assertTrue(one.matchesDomainValues(two));
	}
public void testEmploymentChangePerson() throws Exception {

		Employment one = new Employment();
		Employment two = new Employment();
		Person onFile = this.buildSimplePerson();
		onFile.setEmployment(one);
		one.setEmployerPhone("444");
		one.setEmployerAddress(new Address());
		one.setEmployerName("444");
		one.setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_FULL_TIME.getCode()));

		one.setOccupation("444");
		one.setRetirementDate(ImpreciseDateUtils.createImpreciseDate(2007,11,1));

		Person incoming = savePerson(onFile);
		this.getMergeRuleService().mergeEmployment(incoming, onFile);
		two = incoming.getEmployment();
		two.setSpouse(new Spouse());

		two.setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_FULL_TIME.getCode()));

		assertTrue(one.matchesDomainValues(two));


//		two.setEmployerPhone("444");
//		two.setEmployerAddress(new Address());
//		two.setRetirementDate(ImpreciseDateUtils.createImpreciseDate(2007,11,1));
//		two.setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_NOT_EMPLOYED.getCode()));
//		two.setEmployerName("444");
//		two.setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_FULL_TIME.getCode()));
//		two.setOccupation("444");
//		// Shows that modified date has no influence
//		assertTrue(one.matchesDomainValues(two));

	}
public void testEmploymentChangeConcept() throws Exception {

	Employment one = new Employment();
	Employment two = new Employment();
	Person onFile = this.buildSimplePerson();
	onFile.setEmployment(one);
	one.setEmployerPhone("444");
	one.setEmployerAddress(new Address());
	one.setEmployerName("444");
	one.setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_FULL_TIME.getCode()));

	one.setOccupation("");
	one.setRetirementDate(ImpreciseDateUtils.createImpreciseDate(2007,11,1));

	Person incoming = savePerson(onFile);
	this.getMergeRuleService().mergeEmployment(incoming, onFile);
	two = incoming.getEmployment();
	two.setSpouse(new Spouse());

	two.setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_FULL_TIME.getCode()));

	assertTrue(one.matchesDomainConcept(two));


//	two.setEmployerPhone("444");
//	two.setEmployerAddress(new Address());
//	two.setRetirementDate(ImpreciseDateUtils.createImpreciseDate(2007,11,1));
//	two.setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_NOT_EMPLOYED.getCode()));
//	two.setEmployerName("444");
//	two.setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_FULL_TIME.getCode()));
//	two.setOccupation("444");
//	// Shows that modified date has no influence
//	assertTrue(one.matchesDomainValues(two));

}
	public void testPersonChangeMap() throws Exception {
		Person person = this.buildSimplePerson();
		person.setChangeEvent("CLAIM", "NUMBER");
		System.out.println("person value="+person.getChangeEvents().get("CLAIM"));
	}

	public void testIVMColumns() throws Exception {
		Person onFile = this.buildSimplePerson();

		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED, new Integer(2012));
		incomeTest.setWorkflowCaseStatus(this.getLookupService().getWkfCaseStatusTypeByCode(
				WkfCaseStatusType.ASSIGNED.getCode()));
		incomeTest.setIvmConversionDate(new Date());
		onFile.setIncomeTest(new Integer(2012), incomeTest);

		Person incoming = this.savePerson(onFile);
		this.setComplete();
	}
	public void testPG8Column() throws Exception {
		Person onFile = this.buildSimplePerson();

		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED, new Integer(2012));
		incomeTest.setPg8RelaxationIndicator(Boolean.TRUE);
		onFile.setIncomeTest(new Integer(2012), incomeTest);

		Person incoming = this.savePerson(onFile);
		//this.setComplete();
	}
	//376759481  373971922
	public void testPG8ColumnGet() throws Exception {
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("376759481"));
		Person onFile = this.getPersonService().getPerson(personKey);
		assertTrue(onFile.getIncomeTest(new Integer(2012)).getPg8RelaxationIndicator());
	}
	/**
	 * IVM SELECTION ALGORITHM
	 * IF SSN Verification Status = Verified AND Date of
	 * Death Not Populated AND
	 * (Primary Income Test for the Income Year or thelatest primary income test not expired as of VFA start date) AND
	 * [(Means Test Status = MT Copay Exempt) AND
	 * (Test Determined Status = MT Copay Exempt) AND
	 * (Hardship Effective Date = Null)] AND
	 * (Eligible for Medicaid = No or Null) AND
	 * (The Primary Eligibility Code = NSC OR (The Primary Eligibility Code = SC Less than 50% AND SC% = 0 or Null AND Total Check
	 * Amount = Null or 0.))
	 *
	 * @throws Exception
	 */
	public void testUINewIYWithExistMigrationForDifferentIY() throws Exception {
		testUINewIYWithExistMigration(new Integer(2010));
	}

	public void testUINewIYWithExistMigrationForSameIY() throws Exception {
		testUINewIYWithExistMigration(new Integer(2011));

	}
	private void testUINewIYWithExistMigration(Integer incomeYear) throws Exception {
		Person onFile = this.buildSimplePerson();
		onFile.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		updatePersonToMeetIVMSelectionCriteria(onFile, true);
		onFile.getEnrollmentDetermination().setPrimaryEligiblity(null);
		this.attachEligibilityVerification(onFile, EligibilityVerificationSource.CODE_VBA.getCode());
		this.setEligibilityStatusToPendingVerification(onFile);
		Person incoming = savePerson(onFile);
		this.createIVMMigrationEntry(incoming, incomeYear, MessageStatus.COMPLETE, false);
		this.updatePersonToMeetIVMSelectionCriteria(incoming, true);
		this.setEligibilityStatusToVerified(incoming);
		Person updated = this.getEligibilityEnrollmentService().updateEligibilityData(incoming);
	}
//	public void testUIDemographics() throws Exception {
//		Person onFile = this.buildSimplePerson();
//		onFile.addSsn(
//				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
//		updatePersonToMeetIVMSelectionCriteria(onFile);
//		this.attachEligibilityVerification(onFile, EligibilityVerificationSource.CODE_VBA.getCode());
//		this.setEligibilityStatusToVerified(onFile);
//		PreferredFacility fac = new PreferredFacility();
//		fac.setFacility(this.getLookupService().getVaFacilityByCode("722"));
//		fac.setSourceDesignation(this.getLookupService().getSourceDesignationByCode(SourceDesignation.CODE_ESR.getCode()));
//	    onFile.addPreferredFacility(fac);
//
//		Person incoming = savePerson(onFile);
//		incoming.setClaimFolderNumber("34343");
//		this.createIVMMigrationEntry(incoming, new Integer(2012), MessageStatus.COMPLETE);
//
//		Person updated = this.getDemographicService().updateDemographicInformation(incoming);
//	}
	public void testUIDemographics() throws Exception {
		Person onFile = this.buildSimplePerson();
		onFile.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		updatePersonToMeetIVMSelectionCriteria(onFile, true);
		this.attachEligibilityVerification(onFile, EligibilityVerificationSource.CODE_VBA.getCode());
		this.setEligibilityStatusToVerified(onFile);
		PreferredFacility fac = new PreferredFacility();
		fac.setFacility(this.getLookupService().getVaFacilityByCode("722"));
		fac.setSourceDesignation(this.getLookupService().getSourceDesignationByCode(SourceDesignation.CODE_ESR.getCode()));
		fac.setAssignmentDate(new Date());
	    onFile.addPreferredFacility(fac);
	    Employment em = new Employment();
	    em.setEmployerPhone("4444");
	    em.setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_FULL_TIME.getCode()));
	    onFile.setEmployment(em);
		Person incoming = savePerson(onFile);
		incoming.getEmployment().setEmployerName("");
		incoming.getEmployment().setEmployerPhone("55555");
		incoming.getEmployment().setOccupation("job");
		incoming.getEmployment().setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_PART_TIME.getCode()));
		incoming.setClaimFolderNumber("34343");
		this.createIVMMigrationEntry(incoming, new Integer(2012), MessageStatus.COMPLETE, false);

		Person updated = this.getDemographicService().updateDemographicInformation(incoming);

	}
	public void testUIDemographicsNOIVMENTRIES() throws Exception {
		Person onFile = this.buildSimplePerson();
		onFile.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		updatePersonToMeetIVMSelectionCriteria(onFile, true);
		this.attachEligibilityVerification(onFile, EligibilityVerificationSource.CODE_VBA.getCode());
		this.setEligibilityStatusToVerified(onFile);
		PreferredFacility fac = new PreferredFacility();
		fac.setFacility(this.getLookupService().getVaFacilityByCode("722"));
		fac.setSourceDesignation(this.getLookupService().getSourceDesignationByCode(SourceDesignation.CODE_ESR.getCode()));
		fac.setAssignmentDate(new Date());
	    onFile.addPreferredFacility(fac);
	    Employment em = new Employment();
	    em.setEmployerPhone("4444");
	    em.setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_FULL_TIME.getCode()));
	    onFile.setEmployment(em);
		Person incoming = savePerson(onFile);
		incoming.getEmployment().setEmployerName("");
		incoming.getEmployment().setEmployerPhone("55555");
		incoming.getEmployment().setOccupation("job");
		incoming.getEmployment().setEmploymentStatus(this.getLookupService().getEmploymentStatusByCode(EmploymentStatus.CODE_PART_TIME.getCode()));
		incoming.setClaimFolderNumber("34343");

		Person updated = this.getDemographicService().updateDemographicInformation(incoming);

	}
	public void testUIDemographicsEmailChange() throws Exception {
		Person onFile = this.buildSimplePerson();
		onFile.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		updatePersonToMeetIVMSelectionCriteria(onFile, true);
		ServiceConnectionAward sc = new ServiceConnectionAward();
		sc.setServiceConnectedIndicator(Boolean.FALSE);
		onFile.setServiceConnectionAward(sc);
		//this.attachEligibilityVerification(onFile, EligibilityVerificationSource.CODE_VBA.getCode());
		//this.setEligibilityStatusToVerified(onFile);
		PreferredFacility fac = new PreferredFacility();
		fac.setFacility(this.getLookupService().getVaFacilityByCode("722"));
		fac.setSourceDesignation(this.getLookupService().getSourceDesignationByCode(SourceDesignation.CODE_ESR.getCode()));
		fac.setAssignmentDate(new Date());
	    onFile.addPreferredFacility(fac);
	    onFile.addAddress(createAddress(this.getAddressType( AddressType.CODE_PERMANENT_ADDRESS)));
		Person incoming = savePerson(onFile);
		Email email = this.createEmail();
		email.setSourceOfChange(this.getLookupService().getEmailSourceOfChangeByCode(EmailSourceOfChange.CODE_HEC.getCode()));
		incoming.addEmail(email);
		this.createIVMMigrationEntry(incoming, new Integer(2012), MessageStatus.COMPLETE, false);

		Person updated = this.getDemographicService().updateContactInformation(incoming);

		this.assertTrue(updated.getEmails().size() > 0);
	}
	public void testUIDemographicsEmailChangeNoMT() throws Exception {
		Person onFile = this.buildSimplePerson();
		this.attachVerifiedEnrollment(onFile);
		onFile.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.VERIFIED.getCode())));
		this.setServiceConnectedPercentage(new Integer(40),onFile);
		this.setEligibilityStatusToVerified(onFile);
		PreferredFacility fac = new PreferredFacility();
		fac.setFacility(this.getLookupService().getVaFacilityByCode("722"));
		fac.setSourceDesignation(this.getLookupService().getSourceDesignationByCode(SourceDesignation.CODE_ESR.getCode()));
		fac.setAssignmentDate(new Date());
	    onFile.addPreferredFacility(fac);
	    onFile.addAddress(createAddress(this.getAddressType( AddressType.CODE_PERMANENT_ADDRESS)));
		Person incoming = savePerson(onFile);

		Email email = this.createEmail();
		email.setSourceOfChange(this.getLookupService().getEmailSourceOfChangeByCode(EmailSourceOfChange.CODE_HEC.getCode()));
		incoming.addEmail(email);
		this.createIVMMigrationEntry(incoming, new Integer(2012), MessageStatus.COMPLETE, false);
		this.createIVMMigrationEntry(incoming, new Integer(2011), MessageStatus.COMPLETE, false);
		Person updated = this.getDemographicService().updateContactInformation(incoming);

		this.assertTrue(updated.getEmails().size() > 0);
	}

	public void testUIDemographicsAddressChange() throws Exception {
		Person onFile = this.buildSimplePerson();
		this.attachVerifiedEnrollment(onFile);
		onFile.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.VERIFIED.getCode())));
		this.setServiceConnectedPercentage(new Integer(40),onFile);
		this.setEligibilityStatusToVerified(onFile);
		PreferredFacility fac = new PreferredFacility();
		fac.setFacility(this.getLookupService().getVaFacilityByCode("722"));
		fac.setSourceDesignation(this.getLookupService().getSourceDesignationByCode(SourceDesignation.CODE_ESR.getCode()));
		fac.setAssignmentDate(new Date());
	    onFile.addPreferredFacility(fac);
	    onFile.addAddress(createAddress(this.getAddressType( AddressType.CODE_PERMANENT_ADDRESS)));
		Person incoming = savePerson(onFile);
        incoming.getPermanentAddress().setLine1("different");

		this.createIVMMigrationEntry(incoming, new Integer(2012), MessageStatus.COMPLETE, false);
		this.createIVMMigrationEntry(incoming, new Integer(2011), MessageStatus.COMPLETE, false);
		Person updated = this.getDemographicService().updateContactInformation(incoming);
	}
	public void testUIDemographicsAddressChangeToBadReason() throws Exception {
		Person onFile = this.buildSimplePerson();
		this.attachVerifiedEnrollment(onFile);
		onFile.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.VERIFIED.getCode())));
		this.setServiceConnectedPercentage(new Integer(40),onFile);
		this.setEligibilityStatusToVerified(onFile);
		PreferredFacility fac = new PreferredFacility();
		fac.setFacility(this.getLookupService().getVaFacilityByCode("722"));
		fac.setSourceDesignation(this.getLookupService().getSourceDesignationByCode(SourceDesignation.CODE_ESR.getCode()));
		fac.setAssignmentDate(new Date());
	    onFile.addPreferredFacility(fac);
	    onFile.addAddress(createAddress(this.getAddressType( AddressType.CODE_PERMANENT_ADDRESS)));
		Person incoming = savePerson(onFile);
        BadAddressReason badAddrReason = getLookupService().getBadAddressReasonByCode(BadAddressReason.CODE_HOMELESS.getName());
        incoming.getPermanentAddress().setBadAddressReason(badAddrReason);
        incoming.getPermanentAddress().setCity("Reston");

		this.createIVMMigrationEntry(incoming, new Integer(2012), MessageStatus.COMPLETE, false);
		this.createIVMMigrationEntry(incoming, new Integer(2011), MessageStatus.COMPLETE, false);
		Person updated = this.getDemographicService().updateContactInformation(incoming);
	}
	public void testUIDemographicsAddressChangeToConfidentialAddress() throws Exception {
		Person onFile = this.buildSimplePerson();
		this.attachVerifiedEnrollment(onFile);
		onFile.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.VERIFIED.getCode())));
		this.setServiceConnectedPercentage(new Integer(40),onFile);
		this.setEligibilityStatusToVerified(onFile);
		PreferredFacility fac = new PreferredFacility();
		fac.setFacility(this.getLookupService().getVaFacilityByCode("722"));
		fac.setSourceDesignation(this.getLookupService().getSourceDesignationByCode(SourceDesignation.CODE_ESR.getCode()));
		fac.setAssignmentDate(new Date());
	    onFile.addPreferredFacility(fac);
	    onFile.addAddress(createAddress(this.getAddressType( AddressType.CODE_PERMANENT_ADDRESS)));
		Person incoming = savePerson(onFile);
		incoming.addAddress(createAddress(this.getAddressType( AddressType.CODE_CONFIDENTIAL_ADDRESS)));
		this.createIVMMigrationEntry(incoming, new Integer(2012), MessageStatus.COMPLETE, false);
		this.createIVMMigrationEntry(incoming, new Integer(2011), MessageStatus.COMPLETE, false);
		Person updated = this.getDemographicService().updateContactInformation(incoming);
	}
	public void testIVMFromUINotMeetIVMCriteriaWithComplete() throws Exception {
		//This tests this last section of logic in advice
        //IF the Veteran does not meet IVM Selection Criteria for Current IVM active IY
        // and/or next IY THEN
		//   The most recent IY, for which the Veteran has been previously
		//   transferred without an EDB Load Failure Reason,
		//   if the Veteran has been previously transferred, will be sent as
		//   an ES to IVM Update.
		//ENDIF
		testIVMFromUINotMeetIVMCriteria(MessageStatus.COMPLETE);
	}
	public void testIVMFromUINotMeetIVMCriteriaWithAwaitingTx() throws Exception {
		//This tests this last section of logic in advice
        //IF the Veteran does not meet IVM Selection Criteria for Current IVM active IY
        // and/or next IY THEN
		//   The most recent IY, for which the Veteran has been previously
		//   transferred without an EDB Load Failure Reason,
		//   if the Veteran has been previously transferred, will be sent as
		//   an ES to IVM Update.
		//ENDIF
		testIVMFromUINotMeetIVMCriteria(MessageStatus.AWAITING_TRANSMISSION);
	}
	private void testIVMFromUINotMeetIVMCriteria(MessageStatus.Code status) throws Exception {
		//This tests this last section of logic in advice
        //IF the Veteran does not meet IVM Selection Criteria for Current IVM active IY
        // and/or next IY THEN
		//   The most recent IY, for which the Veteran has been previously
		//   transferred without an EDB Load Failure Reason,
		//   if the Veteran has been previously transferred, will be sent as
		//   an ES to IVM Update.
		//ENDIF

		Person onFile = this.buildSimplePerson();
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED, new Integer(2010));
		onFile.setIncomeTest(new Integer(2010), incomeTest);
		onFile.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		updatePersonToMeetIVMSelectionCriteria(onFile, true);
		this.attachEligibilityVerification(onFile, EligibilityVerificationSource.CODE_VBA.getCode());
		this.setEligibilityStatusToPendingVerification(onFile);
		Person incoming = savePerson(onFile);
		// Put earlier record with COMPLETE status,  which will be the most recent IY
		// The 2011 test will not meet IVM selection (because I set SC%=100) and its status will vary per test.
		this.createIVMMigrationEntry(incoming, new Integer(2010), MessageStatus.COMPLETE, false);
		this.createIVMMigrationEntry(incoming, new Integer(2011), status, false);
		this.attachServiceConnectionAward(incoming, new Integer(100));
		this.setEligibilityStatusToVerified(incoming);
		Person updated = this.getEligibilityEnrollmentService().updateEligibilityData(incoming);
	}
	public void testIVMFromUIDeletedTest() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED, new Integer(2011));
		incomeTest.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest.setThresholdA(new BigDecimal(9));
		onFile.setIncomeTest(new Integer(2011), incomeTest);
		onFile.getIncomeTest(new Integer(2011)).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		onFile.setFinancialStatement(new Integer(2011), this.createFinancialStatement());
		onFile.getFinancialStatement(new Integer(2011)).setAsset(
				this.getLookupService().getAssetTypeByCode(AssetType.CODE_OTHER.getCode()), this.createAsset((double)45458));
		onFile.getFinancialStatement(new Integer(2011)).setDebt(this.createDebt((double)5));

		IncomeTest incomeTest2012 = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED, new Integer(2012));
		incomeTest2012.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest2012.setThresholdA(new BigDecimal(9));
		onFile.setIncomeTest(new Integer(2012), incomeTest2012);
		onFile.getIncomeTest(new Integer(2012)).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		onFile.setFinancialStatement(new Integer(2012), this.createFinancialStatement());
		onFile.getFinancialStatement(new Integer(2012)).setAsset(
				this.getLookupService().getAssetTypeByCode(AssetType.CODE_OTHER.getCode()), this.createAsset((double)45458));
		onFile.getFinancialStatement(new Integer(2012)).setDebt(this.createDebt((double)5));


		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		this.createIVMMigrationEntry(incoming, new Integer(2011), MessageStatus.COMPLETE, false);
		this.createIVMMigrationEntry(incoming, new Integer(2012), MessageStatus.COMPLETE, false);
		IncomeTest hold = incoming.getIncomeTest(new Integer(2011));
		incoming.removeAllIncomeTests();
		incoming.setIncomeTest(new Integer(2011), hold);
		Person updated = this.getFinancialsService().updateFinancialAssessment(	new Integer(2012), (Person) incoming);
	}

	public void test12540UpdateDeleteFlag() throws Exception {
		IVMMigration ivmData = null; // this.getIvmDMService().findIVMMigration("");
		if (ivmData != null) {
			ivmData.isStampped();
		}

		/*
		.getPersonEntityKey() != null)
			{
				ivmCandidateInfo.setVpid(this.getPersonService().getVPIDByPersonId(ivmData.getPersonEntityKey()).getVPID());
				ivmCandidateInfo.setIncomeYear(ivmData.getIncomeYear());
				ivmCandidateInfo.setTransactionId(ivmData.getEntityKey().getKeyValueAsString());
				this.getIvmDMService().saveIVMMigration(ivmData, MessageStatus.AWAITING_ACKNOWLEDGEMENT);
			}

			eeIVMCandidateInfo[i] = ivmCandidateInfo;
			i++;
		}
		*/
	}

	public void test12540FinancialsSummaryFactoryImplChanges() throws Exception {
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("373971922"));
		Person onFile = this.getPersonService().getPerson(personKey);
		createIVMMigrationEntry(onFile, new Integer(2012), MessageStatus.COMPLETE, true);
		EESummary eeSummary = getExternalSummaryFactory().buildEESummary(onFile, new Integer(2012), "IVMData");
		assertTrue("DELETE".equals(eeSummary.getFinancialsInfo().getIncomeTest().getComments()));
		assertNotNull(eeSummary.getFinancialsInfo().getIncomeTest().getIncomeYear());
	}

	public void test12540DeletedTest() throws Exception {
		Integer yearToDelete = new Integer(2012);
		Integer yearToKeep = new Integer(2011);
		Person onFile = buildSimplePerson(); // bare-bones person
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED, yearToKeep);
		incomeTest.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest.setThresholdA(new BigDecimal(9));
		onFile.setIncomeTest(yearToKeep, incomeTest);
		onFile.getIncomeTest(yearToKeep).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		onFile.setFinancialStatement(yearToKeep, this.createFinancialStatement());
		onFile.getFinancialStatement(yearToKeep).setAsset(
				this.getLookupService().getAssetTypeByCode(AssetType.CODE_OTHER.getCode()), this.createAsset((double)45458));
		onFile.getFinancialStatement(yearToKeep).setDebt(this.createDebt((double)5));

		IncomeTest incomeTest2012 = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED, yearToDelete);
		incomeTest2012.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest2012.setThresholdA(new BigDecimal(9));
		onFile.setIncomeTest(yearToDelete, incomeTest2012);
		onFile.getIncomeTest(yearToDelete).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		onFile.setFinancialStatement(yearToDelete, this.createFinancialStatement());
		onFile.getFinancialStatement(yearToDelete).setAsset(
				this.getLookupService().getAssetTypeByCode(AssetType.CODE_OTHER.getCode()), this.createAsset((double)45458));
		onFile.getFinancialStatement(yearToDelete).setDebt(this.createDebt((double)5));


		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		this.createIVMMigrationEntry(incoming, yearToKeep, MessageStatus.COMPLETE, false);
		// simulate a pending item
		this.createIVMMigrationEntry(incoming, yearToDelete, MessageStatus.PENDING, false);
		IncomeTest hold = incoming.getIncomeTest(yearToKeep);
		incoming.removeAllIncomeTests();
		incoming.setIncomeTest(yearToKeep, hold);
		Person updated = this.getFinancialsService().updateFinancialAssessment(yearToDelete, (Person) incoming);

		IncomeTest resultTest = updated.getIncomeTest(yearToKeep);
		IncomeTest deletedTest = updated.getIncomeTest(yearToDelete);
		assertNull(deletedTest);
		assertNotNull(resultTest);
	}
	public void test12540DeletedTestEntryExists() throws Exception {
		Integer yearToDelete = new Integer(2012);
		Integer yearToKeep = new Integer(2011);
		Person onFile = buildSimplePerson(); // bare-bones person
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED, yearToKeep);
		incomeTest.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest.setThresholdA(new BigDecimal(9));
		onFile.setIncomeTest(yearToKeep, incomeTest);
		onFile.getIncomeTest(yearToKeep).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		onFile.setFinancialStatement(yearToKeep, this.createFinancialStatement());
		onFile.getFinancialStatement(yearToKeep).setAsset(
				this.getLookupService().getAssetTypeByCode(AssetType.CODE_OTHER.getCode()), this.createAsset((double)45458));
		onFile.getFinancialStatement(yearToKeep).setDebt(this.createDebt((double)5));

		IncomeTest incomeTest2012 = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED, yearToDelete);
		incomeTest2012.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest2012.setThresholdA(new BigDecimal(9));
		onFile.setIncomeTest(yearToDelete, incomeTest2012);
		onFile.getIncomeTest(yearToDelete).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		onFile.setFinancialStatement(yearToDelete, this.createFinancialStatement());
		onFile.getFinancialStatement(yearToDelete).setAsset(
				this.getLookupService().getAssetTypeByCode(AssetType.CODE_OTHER.getCode()), this.createAsset((double)45458));
		onFile.getFinancialStatement(yearToDelete).setDebt(this.createDebt((double)5));


		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		this.createIVMMigrationEntry(incoming, yearToKeep, MessageStatus.COMPLETE, true);
		// simulate a pending item
		this.createIVMMigrationEntry(incoming, yearToDelete, MessageStatus.PENDING, false);
		IncomeTest hold = incoming.getIncomeTest(yearToKeep);
		incoming.removeAllIncomeTests();
		incoming.setIncomeTest(yearToKeep, hold);
		Person updated = this.getFinancialsService().updateFinancialAssessment(yearToDelete, (Person) incoming);

		IncomeTest resultTest = updated.getIncomeTest(yearToKeep);
		IncomeTest deletedTest = updated.getIncomeTest(yearToDelete);
		assertNull(deletedTest);
		assertNotNull(resultTest);
	}
	public void testIVMFromEEWithNoTestForIY() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		this.setServiceConnectedPercentage(new Integer(40), onFile);
		Person incoming = savePerson(onFile);
		this.createIVMMigrationEntry(incoming, new Integer(2011), MessageStatus.COMPLETE, false);
		Person updated = this.getEligibilityEnrollmentService().updateEligibilityData(incoming);

	}
	public void testIVMSort() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Person incoming = savePerson(onFile);
		Set temp = new HashSet();

		ArrayList dd = new ArrayList(temp);

		PersonSubmittedAdvice advice = this.buildMockPersonSubmittedAdvice();
		Set data = new HashSet();
		data.add(this.createIVMMigrationEntry(incoming, new Integer(2003), MessageStatus.COMPLETE, false));
		data.add(this.createIVMMigrationEntry(incoming, new Integer(2011), MessageStatus.COMPLETE, false));
		data.add(this.createIVMMigrationEntry(incoming, new Integer(2012), MessageStatus.COMPLETE, false));
		data.add(this.createIVMMigrationEntry(incoming, new Integer(2010), MessageStatus.COMPLETE, false));
		data.add(this.createIVMMigrationEntry(incoming, new Integer(2004), MessageStatus.COMPLETE, false));
		List d = advice.sortIVMMigrationsByIY(data);
		Iterator iter = d.iterator();
		while (iter.hasNext()) {
			IVMMigration migration = (IVMMigration)iter.next();
			System.out.println("iy="+migration.getIncomeYear().toString());
		}
		System.out.println("max iy="+((IVMMigration)d.get(0)).getIncomeYear().toString());

		Integer year = advice.getMostRecentIVMMigratedIY(data);
		assertTrue(year.compareTo(new Integer(2012)) == 0);
	}
	public void testIVMGetMostRecentIY() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Person incoming = savePerson(onFile);
		PersonSubmittedAdvice advice = this.buildMockPersonSubmittedAdvice();
		Set data = new HashSet();
		data.add(this.createIVMMigrationEntry(incoming, new Integer(2003), MessageStatus.COMPLETE, false));
		data.add(this.createIVMMigrationEntry(incoming, new Integer(2011), MessageStatus.COMPLETE, false));
		data.add(this.createIVMMigrationEntry(incoming, new Integer(2012), MessageStatus.AWAITING_TRANSMISSION, false));
		data.add(this.createIVMMigrationEntry(incoming, new Integer(2010), MessageStatus.COMPLETE, false));
		data.add(this.createIVMMigrationEntry(incoming, new Integer(2004), MessageStatus.COMPLETE, false));

		Integer year = advice.getMostRecentIVMMigratedIY(data);
		assertTrue(year.compareTo(new Integer(2011)) == 0);
		System.out.println("max iy="+year.toString());
	}
	public void testIVMGetMostRecentLegacyIY() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Person incoming = savePerson(onFile);
		PersonSubmittedAdvice advice = this.buildMockPersonSubmittedAdvice();
		Set data = new HashSet();
		data.add(this.createIVMMigrationEntryHecLegacy(incoming, new Integer(2003)));
		data.add(this.createIVMMigrationEntryHecLegacy(incoming, new Integer(2011)));
		data.add(this.createIVMMigrationEntryHecLegacy(incoming, new Integer(2012)));
		data.add(this.createIVMMigrationEntryHecLegacy(incoming, new Integer(2010)));
		data.add(this.createIVMMigrationEntryHecLegacy(incoming, new Integer(2004)));

		Integer year = advice.getLatestMigratedIYForLegacyRecord(data);
		assertTrue(year.compareTo(new Integer(2012)) == 0);
		System.out.println("max legacy iy="+year.toString());
	}
	public void testIVMFromUI_ExistingDeletedTestEntry() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED, new Integer(2011));
		incomeTest.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest.setThresholdA(new BigDecimal(9));
		onFile.setIncomeTest(new Integer(2011), incomeTest);
		onFile.getIncomeTest(new Integer(2011)).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		onFile.setFinancialStatement(new Integer(2011), this.createFinancialStatement());
		onFile.getFinancialStatement(new Integer(2011)).setAsset(
				this.getLookupService().getAssetTypeByCode(AssetType.CODE_OTHER.getCode()), this.createAsset((double)45458));
		onFile.getFinancialStatement(new Integer(2011)).setDebt(this.createDebt((double)5));

		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		this.createIVMMigrationEntry(incoming, new Integer(2011), MessageStatus.COMPLETE, false);
		this.createIVMMigrationEntry(incoming, new Integer(2011), MessageStatus.AWAITING_TRANSMISSION, false);
		this.createIVMMigrationEntry(incoming, new Integer(2012), MessageStatus.COMPLETE, false);
		IncomeTest hold = incoming.getIncomeTest(new Integer(2011));
		incoming.removeAllIncomeTests();
		incoming.setIncomeTest(new Integer(2011), hold);
		Person updated = this.getFinancialsService().updateFinancialAssessment(	new Integer(2011), (Person) incoming);
	}
	public void testIVMQueryGetMostRecent() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		Person incoming = savePerson(onFile);
		this.createIVMMigrationEntry(incoming, new Integer(2011), MessageStatus.COMPLETE, false);
		Integer y = this.getIvmDMService().getMostRecentIVMMigratedYear(incoming.getPersonEntityKey());
		assertNotNull(y);
	}
	public void testUpdateFinancialsEnrollStatusMTReq() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person

		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED, new Integer(2011));
		incomeTest.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest.setThresholdA(new BigDecimal(9));
		onFile.setIncomeTest(new Integer(2011), incomeTest);
		onFile.getIncomeTest(new Integer(2011)).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		onFile.setFinancialStatement(new Integer(2011), this.createFinancialStatement());
		onFile.getFinancialStatement(new Integer(2011)).setAsset(
				this.getLookupService().getAssetTypeByCode(AssetType.CODE_OTHER.getCode()), this.createAsset((double)45458));
		onFile.getFinancialStatement(new Integer(2011)).setDebt(this.createDebt((double)5));
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		this.createIVMMigrationEntry(incoming, new Integer(2010), MessageStatus.COMPLETE, false);
		incoming.removeAllFinancialStatements();
		incoming.removeAllIncomeTests();
		Person updated = this.getFinancialsService().updateFinancialAssessment(
				new Integer(2011), (Person) incoming.clone());
		// Check PersonSubmittedAdvice using breakpoint. Should see Enroll Status cause
		// trigger.
	}
	public void testUpdateDependentFinancials() throws Exception {
		//CodeCR12232
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2012);
		VAFacility site = this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getCode());
		this.attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		EntityKey key = ((DependentFinancials)incoming.getFinancialStatement(
				incomeYear).getDependentFinancials().iterator().next()).getEntityKey();

		incoming.getFinancialStatement(
		incomeYear).getDependentFinancialsByEntityKey(key).setAttendedSchool(Boolean.TRUE);



		Person updated = this.getFinancialsService().updateDependentFinancials(
				incomeYear,(DependentFinancials)incoming.getFinancialStatement(
						incomeYear).getDependentFinancials().iterator().next() ,incoming);
		assertTrue(updated.getFinancialStatement(incomeYear).getDependentFinancialsByEntityKey(key).getAttendedSchool());
	}
	public void testUpdateFinancialAssessmentDependentSchool() throws Exception {
		//CodeCR12232
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2012);
		VAFacility site = this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getCode());
		this.attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		EntityKey key = ((DependentFinancials)incoming.getFinancialStatement(
				incomeYear).getDependentFinancials().iterator().next()).getEntityKey();

		incoming.getFinancialStatement(
		incomeYear).getDependentFinancialsByEntityKey(key).setAttendedSchool(Boolean.TRUE);
		Person updated = this.getFinancialsService().updateFinancialAssessment(incomeYear,incoming);
		assertTrue(updated.getFinancialStatement(incomeYear).getDependentFinancialsByEntityKey(key).getAttendedSchool());
	}
	public void testUpdateFinancialAssessmentDependentGender() throws Exception {
		//CodeCR12232
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2012);
		VAFacility site = this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getCode());
		this.attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		EntityKey key = ((DependentFinancials)incoming.getFinancialStatement(
				incomeYear).getDependentFinancials().iterator().next()).getEntityKey();
		incoming.getFinancialStatement(incomeYear).getDependentFinancialsByEntityKey(
				key).getReportedOn().setGender(this.getLookupService().getGenderByCode(Gender.AMBIGUOUS.getCode()));
		Person updated = this.getFinancialsService().updateFinancialAssessment(incomeYear,incoming);
		assertTrue(updated.getFinancialStatement(incomeYear).getDependentFinancialsByEntityKey(
				key).getReportedOn().getGender().getCode().equals(Gender.AMBIGUOUS.getCode()));
	}

	public void testUpdateFinancialAssessmentEducation() throws Exception {
		//CodeCR12232
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2012);
		VAFacility site = this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getCode());
		this.attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
//		DAOOperations ops = (DAOOperations)applicationContext.getBean("genericDAO");
		Person incoming = savePerson(onFile);
		Person temp = this.getFinancialInfoRuleService().manageFinancialAssessment(
				incomeYear, site,incoming, onFile, null);
		FinancialStatement res1 =temp.getFinancialStatement(incomeYear);
		System.out.println("count expenses="+res1.getExpenses().size());
		System.out.println("expense="+res1.getExpense(ExpenseType.EXPENSE_TYPE_EDUCATIONAL_EXPENSES_BY_DEPENDENT));
		////////////////////////////////////////
		Person temp2 = (Person)temp.clone();
		BigDecimal hold = temp2.getIncomeTest(incomeYear).getDeductibleExpenses();
		ExpenseType type = getLookupService().getExpenseTypeByCode(
				ExpenseType.EXPENSE_TYPE_EDUCATIONAL_EXPENSES_BY_DEPENDENT.getCode());
		Expense expense = new Expense(new BigDecimal(200));
		FinancialStatement statement =temp2.getFinancialStatement(incomeYear);
		statement.addExpense(type, expense);
		Person updated = this.getFinancialInfoRuleService().manageFinancialAssessment(
				incomeYear, site,temp2, temp, null);
		FinancialStatement res =updated.getFinancialStatement(incomeYear);
		System.out.println("count expenses="+res.getExpenses().size());
		System.out.println("expense="+res.getExpense(ExpenseType.EXPENSE_TYPE_EDUCATIONAL_EXPENSES_BY_DEPENDENT));
		IncomeTest tst = updated.getIncomeTest(incomeYear);
		System.out.println("total expenses="+tst.getDeductibleExpenses());
		//assertTrue(updated.getIncomeTest(incomeYear).getDeductibleExpenses().compareTo(hold) == 0);
		/////////////////////////////////////////
		Person temp3 = (Person)temp2.clone();
		type = getLookupService().getExpenseTypeByCode(
				ExpenseType.EXPENSE_TYPE_COLLEGE_AND_VOCATION.getCode());
		expense = new Expense(new BigDecimal(200));
		statement =temp3.getFinancialStatement(incomeYear);
		statement.addExpense(type, expense);
		updated = this.getFinancialInfoRuleService().manageFinancialAssessment(
				incomeYear, site,temp3, temp2, null);
		res = updated.getFinancialStatement(incomeYear);
		System.out.println("count expenses="+res.getExpenses().size());
		System.out.println("expense="+res.getExpense(ExpenseType.EXPENSE_TYPE_COLLEGE_AND_VOCATION));
		tst = updated.getIncomeTest(incomeYear);
		System.out.println("total expenses="+tst.getDeductibleExpenses());
	}
	public void testUpdateDependentFinancialsRelationship() throws Exception {
		//CodeCR12232
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2012);
		VAFacility site = this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getCode());
		this.attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		EntityKey key = ((DependentFinancials)incoming.getFinancialStatement(
				incomeYear).getDependentFinancials().iterator().next()).getEntityKey();
		incoming.getFinancialStatement(
		incomeYear).getDependentFinancialsByEntityKey(key).getReportedOn().setRelationship(
				this.getLookupService().getRelationshipByCode(Relationship.CODE_FATHER.getCode()));
		Person updated = this.getFinancialsService().updateDependentFinancials(
				incomeYear,(DependentFinancials)incoming.getFinancialStatement(
						incomeYear).getDependentFinancials().iterator().next() ,incoming);
	}
	public void testUpdateFinancialAssessmentIncapable() throws Exception {
		//CodeCR12232
		Person onFile = buildSimplePerson(); // bare-bones person
		Integer incomeYear = new Integer(2012);
		VAFacility site = this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getCode());
		this.attachFullFinancialData(onFile, incomeYear, site, false, IncomeTestSource.CODE_HEC.getCode());
		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		EntityKey key = ((DependentFinancials)incoming.getFinancialStatement(
				incomeYear).getDependentFinancials().iterator().next()).getEntityKey();
		incoming.getFinancialStatement(
		incomeYear).getDependentFinancialsByEntityKey(key).setIncapableOfSelfSupport(Boolean.TRUE);
		Person updated = this.getFinancialsService().updateFinancialAssessment(incomeYear, incoming);
		assertTrue(updated.getFinancialStatement(incomeYear).getDependentFinancialsByEntityKey(key).getIncapableOfSelfSupport());
	}


	public void testUpdateFinancialsMeanTestGMTCopayReq() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person

		this.attachVerifiedEnrollment(onFile);
		this.setEligibilityStatusToVerified(onFile);
		this.addPermanentAddress(onFile, Calendar.getInstance().getTime(),null);
		Person incoming = savePerson(onFile);
		this.createIVMMigrationEntry(incoming, new Integer(2004), MessageStatus.COMPLETE, false);
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED, new Integer(2011));
		incomeTest.setEffectiveDate(getDate(2013,1,1));
		incomeTest.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest.setThresholdA(new BigDecimal(9));
		incoming.setIncomeTest(new Integer(2011), incomeTest);
		incoming.getIncomeTest(new Integer(2011)).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		incoming.setFinancialStatement(new Integer(2011), this.createFinancialStatement());
		incoming.getFinancialStatement(new Integer(2011)).setAsset(
				this.getLookupService().getAssetTypeByCode(AssetType.CODE_OTHER.getCode()), this.createAsset((double)45458));
		incoming.getFinancialStatement(new Integer(2011)).setDebt(this.createDebt((double)5));

		Person updated = this.getFinancialsService().updateFinancialAssessment(
				new Integer(2011), incoming);
		// Check PersonSubmittedAdvice using breakpoint. Should see Enroll Status cause
		// trigger.
	}
	public void testUpdateFinancialsPG2() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person

		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED, new Integer(2011));
		incomeTest.setGmtThresholdAmount(new BigDecimal(9));
		incomeTest.setThresholdA(new BigDecimal(9));
		onFile.setIncomeTest(new Integer(2011), incomeTest);

		onFile.getIncomeTest(new Integer(2011)).setSource(this.getLookupService().getIncomeTestSourceByCode(
				IncomeTestSource.CODE_HEC.getCode()));
		onFile.setFinancialStatement(new Integer(2011), this.createFinancialStatement());
		onFile.getFinancialStatement(new Integer(2011)).setAsset(
				this.getLookupService().getAssetTypeByCode(AssetType.CODE_OTHER.getCode()), this.createAsset((double)45458));
		onFile.getFinancialStatement(new Integer(2011)).setDebt(this.createDebt((double)5));
		this.attachVerifiedEnrollment(onFile);
		this.attachServiceConnectionAward(onFile, new Integer(35));
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		this.createIVMMigrationEntry(incoming, new Integer(2004), MessageStatus.COMPLETE, false);
		//incoming.getFinancialStatement(new Integer(2005)).setDebt(this.createDebt((double)45));
		incoming.removeAllFinancialStatements();
		incoming.removeAllIncomeTests();
		Person updated = this.getFinancialsService().updateFinancialAssessment(
				new Integer(2011), (Person) incoming.clone());


	}
	public void testUpdateEEtoPG2() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		this.attachVerifiedEnrollment(onFile);
		this.attachServiceConnectionAward(onFile, new Integer(35));
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		incoming.getEligibilityVerification().setVerificationMethod("test");
		this.createIVMMigrationEntry(incoming, new Integer(2011), MessageStatus.COMPLETE, false);
		Person updated = this.getEligibilityEnrollmentService().updateEligibilityData(incoming);
	}

	public void testUpdateEEtoPG2NEW() throws Exception {
		Person onFile = buildSimplePerson(); // bare-bones person
		this.attachVerifiedEnrollment(onFile);
		this.attachServiceConnectionAward(onFile, new Integer(35));
		this.setEligibilityStatusToVerified(onFile);
		Person incoming = savePerson(onFile);
		incoming.getEligibilityVerification().setVerificationMethod("test");
		Person updated = this.getEligibilityEnrollmentService().updateEligibilityData(incoming);
	}

	public void testIVMUpdateFromUINonIncomeChange() throws Exception {
		Person onFile = this.buildSimplePerson();
		onFile.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		updatePersonToMeetIVMSelectionCriteria(onFile, true);
		this.attachEligibilityVerification(onFile, EligibilityVerificationSource.CODE_VBA.getCode());
		this.setEligibilityStatusToPendingVerification(onFile);
		Person incoming = savePerson(onFile);
		this.updatePersonToMeetIVMSelectionCriteria(incoming, true);
		this.setEligibilityStatusToVerified(incoming);
		Person updated = this.getEligibilityEnrollmentService().updateEligibilityData(incoming);
		//this.setComplete();
	}
	public void testIVMUpdateFromUIWithNoChange() throws Exception {
		Person onFile = this.buildSimplePerson();
		onFile.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		onFile.setServiceConnectionAward(new ServiceConnectionAward());
		onFile.getServiceConnectionAward().setServiceConnectedIndicator(Boolean.FALSE);
		updatePersonToMeetIVMSelectionCriteria(onFile, true);
		this.attachEligibilityVerification(onFile, EligibilityVerificationSource.CODE_VBA.getCode());
		onFile.getEligibilityVerification().setEligibilityStatus(
				this.getLookupService().getEligibilityStatusByCode(EligibilityStatus.CODE_VERIFIED.getCode()));
		onFile.getEligibilityVerification().setAacIndicator(
				this.getLookupService().getAACIndicatorByCode(AACIndicator.CODE_DATA_ACCEPTED.getCode()));
		Person incoming = savePerson(onFile);
		Person updated = this.getEligibilityEnrollmentService().updateEligibilityData(incoming);
		//this.setComplete();
	}
	public void testIVMUpdateFromUIExisting() throws Exception {
		Person onFile = this.buildSimplePerson();
		onFile.addSsn(createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		updatePersonToMeetIVMSelectionCriteria(onFile, true);
		onFile.getEnrollmentDetermination().setPrimaryEligiblity(null);
		this.attachEligibilityVerification(onFile, EligibilityVerificationSource.CODE_VBA.getCode());
		this.setEligibilityStatusToPendingVerification(onFile);
		Person incoming = savePerson(onFile);
		this.createIVMMigrationEntry(incoming, new Integer(2011), MessageStatus.COMPLETE, false);
		this.updatePersonToMeetIVMSelectionCriteria(incoming, true);
		this.setEligibilityStatusToVerified(incoming);
		Person updated = this.getEligibilityEnrollmentService()
				.updateEligibilityData(incoming);
//		this.setComplete();
	}
	public void testIVMNoOldPerson() throws Exception {
		Person onFile = this.buildSimplePerson();
		onFile.addSsn(createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		updatePersonToMeetIVMSelectionCriteria(onFile, true);
		onFile.getEnrollmentDetermination().setPrimaryEligiblity(null);
		this.attachEligibilityVerification(onFile, EligibilityVerificationSource.CODE_VBA.getCode());
		this.setEligibilityStatusToPendingVerification(onFile);
//		this.createIVMMigrationEntry(onFileincoming, new Integer(2011), MessageStatus.COMPLETE);
//		this.updatePersonToMeetIVMSelectionCriteria(incoming);
//		this.setEligibilityStatusToVerified(incoming);
		Person updated = this.getEligibilityEnrollmentService().updateEligibilityData(onFile);
//		this.setComplete();
	}

	private Integer getLatestMigratedYear(PersonEntityKey person) throws ServiceException {
		Serializable param = new BigDecimal(person.getKeyValueAsString());
		try {
			List list = this.getGenericDAO().findByNamedQueryAndNamedParam(QUERY_GET_LATEST_MIGRATED_YEAR_BY_PERSON,
					PERSON_ID_PARAM_NAME, param);
			return list.isEmpty() ? null : (Integer) list.get(0);
		} catch (DAOException e) {
			throw new ServiceException("Failed to get lastest migrated year for person " + param, e);
		}
	}

	private IVMMigration createIVMMigrationEntry(Person person, Integer incomeYear, MessageStatus.Code status, boolean delete) throws ServiceException {
		IVMMigration ivmMigration = new IVMMigration();
		ivmMigration.setPersonEntityKey(
				CommonEntityKeyFactory.createPersonIdEntityKey(person.getPersonEntityKey().getKeyValueAsString()));
		ivmMigration.setIncomeYear(incomeYear);
		ivmMigration.setMigrationDate(new Date());
		ivmMigration.setRemigrate(false);
		if (delete)
			ivmMigration.setStampped(true);

		this.getIvmDMService().saveIVMMigration(ivmMigration, status);
		return ivmMigration;
	}
	private IVMMigration createIVMMigrationEntryHecLegacy(Person person, Integer incomeYear) throws ServiceException {
		IVMMigration ivmMigration = new IVMMigration();
		ivmMigration.setPersonEntityKey(
				CommonEntityKeyFactory.createPersonIdEntityKey(person.getPersonEntityKey().getKeyValueAsString()));
		ivmMigration.setIncomeYear(incomeYear);
		ivmMigration.setMigrationDate(new Date());
		ivmMigration.setRemigrate(false);

		this.getIvmDMService().saveIVMMigration(ivmMigration);
		return ivmMigration;
	}
	public void testZ07HasIVMOnfileSameIYAddressChange() throws Exception {
		Person onFile = buildSimplePerson();
		Integer year = new Integer(2012);

		this.attachIVMConversionTest(onFile, year, true, true, "MT");
		this.setEligibilityStatusToVerified(onFile);
		onFile.getEligibilityVerification().setAacIndicator(
				this.getLookupService().getAACIndicatorByCode(
						AACIndicator.CODE_DATA_ACCEPTED.getName()));
		addPermanentAddress(onFile, Calendar.getInstance().getTime(), null);
		Person incoming = this.savePerson(onFile);

		VAFacility va = this.getLookupService().getVaFacilityByStationNumber(
				VAFacility.CODE_HEC.getName());
		incoming.removeAllIncomeTests();
		attachIVMConversionTest(incoming, year, true, true, "MT");
		incoming.getEligibilityVerification().setVerificationMethod("fff");

		VerificationInfo vi = new VerificationInfo("x", MessageType.CODE_ORUZ07_TO_ESR.getCode(),
				"x");
		VAFacility site = va;
		vi.setSiteNumber(site.getCode());
		Person updated = this.getMessagingService().processZ07(incoming, site, vi);
	}
	public void testZ07AddressChangeConfidential() throws Exception {

		Person onFile = this.buildSimplePerson();
		// call to mock delegate
		onFile.setIdentityTraits(this.getPsDelegateService().getIdentityTraitsWithCompositeCall(onFile.getVPIDEntityKey()));
		Integer year = new Integer(2012);
		ServiceConnectionAward sc = new ServiceConnectionAward();
		this.attachVerifiedEnrollment(onFile);
		sc.setServiceConnectedIndicator(Boolean.FALSE);
		onFile.setServiceConnectionAward(sc);
        this.attachMeansTestWithMtCopayExempt(onFile);
		this.addSpecificAddressType(AddressType.CODE_CONFIDENTIAL_ADDRESS.getName(), onFile,
				new Date(), null);
		onFile.addAddress(createAddress("Atlanta", "Clairmont Dr", "GA", "30305",
					new Date(), AddressType.CODE_CONFIDENTIAL_ADDRESS.getName()));
		onFile.getConfidentialAddress().setActive(true);
		this.setEligibilityStatusToVerified(onFile);
		onFile.getEligibilityVerification().setAacIndicator(
				this.getLookupService().getAACIndicatorByCode(
						AACIndicator.CODE_DATA_ACCEPTED.getName()));
		addPermanentAddress(onFile, Calendar.getInstance().getTime(), null);
		Person incoming = this.savePerson(onFile);
		incoming.getConfidentialAddress().setLine1("line1 different");
		VAFacility va = this.getLookupService().getVaFacilityByStationNumber(
				VAFacility.CODE_HEC.getName());

		VerificationInfo vi = new VerificationInfo("x", MessageType.CODE_ORUZ07_TO_ESR.getCode(),
				"x");
		VAFacility site = va;
		vi.setSiteNumber(site.getCode());
		Person updated = this.getMessagingService().processZ07(incoming, site, vi);
	//	assertNotNull(updated.getConfidentialAddress());
	}
	public void testIncomingIVMFromZ07HasNoIVMOnfileSameIncomeYear() throws Exception {
		Person onFile = buildSimplePerson();
		Integer year = new Integer(2012);
		this.setEligibilityStatusToVerified(onFile);
		onFile.getEligibilityVerification().setAacIndicator(
				this.getLookupService().getAACIndicatorByCode(
						AACIndicator.CODE_DATA_ACCEPTED.getName()));
		Person incoming = this.savePerson(onFile);

		VAFacility va = this.getLookupService().getVaFacilityByStationNumber(
				VAFacility.CODE_HEC.getName());
		incoming.removeAllIncomeTests();
		attachIVMConversionTest(incoming, year, true, true, "MT");
		incoming.getEligibilityVerification().setVerificationMethod("fff");
		addPermanentAddress(incoming, Calendar.getInstance().getTime(), null);
		VerificationInfo vi = new VerificationInfo("x", MessageType.CODE_ORUZ07_TO_ESR.getCode(),
				"x");
		VAFacility site = va;
		vi.setSiteNumber(site.getCode());
		Person updated = this.getMessagingService().processZ07(incoming, site, vi);
	}

	public void testIVMSelectionProcessZ07() throws Exception {
		Person onFile = buildSimplePerson();
		// this.attachDeathRecord(onFile);
		this.setEligibilityStatusToPendingVerification(onFile);
		onFile.getEligibilityVerification().setAacIndicator(
				this.getLookupService().getAACIndicatorByCode(
						AACIndicator.CODE_DATA_ACCEPTED.getName()));
		// this.attachVerifiedEnrollment(onFile);
		// this.setEnrollmentStatus(EnrollmentStatus.CODE_PENDING_ELIGIBILITY_STATUS_IS_UNVERIFIED.getCode(),
		// onFile);
		this.attachServiceConnectionAward(onFile, new Integer(80));
		this.attachMilitaryService(onFile);
		MilitaryServiceEpisode mse = new MilitaryServiceEpisode();
		mse.setServiceBranch(this.getRandomServiceBranch());
		mse.setDischargeType(this.getLookupService().getDischargeTypeByCode(DischargeType.CODE_HONORABLE.getCode()));
		mse.setStartDate(ImpreciseDateUtils.createImpreciseDate(2008, 1, 1));
		mse.setEndDate(ImpreciseDateUtils.createImpreciseDate(2009, 1, 1));
		mse.setServiceNumber("12345");
		MilitaryServiceSiteRecord m = this.createMilitaryServiceSireRecord();
		m.setSite(this.getLookupService().getVaFacilityByStationNumber(VAFacility.CODE_HEC.getName()));
		m.addMilitaryServiceEpisode(mse);
		onFile.getMilitaryService().addMilitaryServiceSiteRecord(m);
		CombatEpisode ce = new CombatEpisode();
		ce.setConflictLocation(this.getLookupService().getConflictByCode(ConflictLocation.CODE_UNKNOWN_OEF_OIF.getCode()));
		ce.setStartDate(ImpreciseDateUtils.createImpreciseDate(2002,2,1));
		ce.setEndDate(ImpreciseDateUtils.createImpreciseDate(2007,11,1));
		onFile.getMilitaryService().addCombatEpisode(ce);
		Person incoming = this.savePerson(onFile);

		VAFacility va = this.getRandomVAFacility();
		IncomeTest incomeTest = this.createIncomeTest(IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED, new Integer(2011));
		incomeTest.setSource(this.getLookupService().getIncomeTestSourceByCode(IncomeTestSource.CODE_VAMC.getCode()));
		incomeTest.setSiteConductingTest(va);
		incoming.setIncomeTest(new Integer(2011), incomeTest);

		this.setEligibilityStatusToVerified(incoming);
		incoming.getEligibilityVerification().setVerificationFacility(
				this.getRandomVAFacility());
		this.setServiceConnectedPercentage(new Integer(0), incoming);
		this.addPermanentAddress(incoming, Calendar.getInstance().getTime(),
				null);
		VerificationInfo vi = new VerificationInfo("x",
				MessageType.CODE_ORUZ07_TO_ESR.getCode(), "x");
		Iterator iter = incoming.getServiceConnectionAward()
		.getRatedDisabilities().iterator();
		while (iter.hasNext()) {
			RatedDisability rd = (RatedDisability) iter.next();
			rd.setPercentage(new Integer(0));
		}
		vi.setSiteNumber(incoming.getEligibilityVerification()
				.getVerificationFacility().getCode());
		Person updated = this.getMessagingService().processZ07(incoming,
				this.getRandomVAFacility(), vi);
		//this.setComplete();
		// assertTrue(updated.getEligibilityVerification().getEligibilityStatus()
		// .getCode().equals(EligibilityStatus.CODE_VERIFIED.getName()));
		// assertEquals(0,
		// updated.getServiceConnectionAward().getServiceConnectedPercentage().intValue());
	}
	
	public void testIVMSelectionPOSITIVEProcessZ07() throws Exception {
		Person onFile = buildSimplePerson();
		onFile.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.VERIFIED.getCode())));

		this.attachEligibilityVerification(onFile, EligibilityVerificationSource.CODE_VBA.getCode());

		onFile.getEligibilityVerification().setAacIndicator(
				this.getLookupService().getAACIndicatorByCode(
						AACIndicator.CODE_DATA_ACCEPTED.getName()));
		updatePersonToMeetIVMSelectionCriteria(onFile, true);
		VAFacility va = 		onFile.getIncomeTest(new Integer(2012)).getSiteConductingTest();
		onFile.getIncomeTest(new Integer(2012)).setHardship(this.createHardship("test"));
		onFile.getIncomeTest(new Integer(2012)).getHardship().setSiteGrantingHardship(va);
		Person incoming = this.savePerson(onFile);
		// Comment out below to simulate no existing ivm_migrate record
		this.createIVMMigrationEntry(incoming, new Integer(2011), MessageStatus.COMPLETE, false);
		this.addPermanentAddress(incoming, Calendar.getInstance().getTime(),
				null);
		incoming.getIncomeTest(new Integer(2012)).setHardship(null);
		VerificationInfo vi = new VerificationInfo("x",
				MessageType.CODE_ORUZ07_TO_ESR.getCode(), "x");

		assertNotNull(onFile.getIncomeTest(new Integer(2012)).getHardship());
		Person updated = this.getMessagingService().processZ07(incoming,va, vi);
		assertNull(updated.getIncomeTest(new Integer(2012)).getHardship());
	}
	public void testIVMSelectionEditToExistingProcessZ07() throws Exception {
		/*
		 * I wanted to try a simple edit of MT coming from Vista
		 *
		 * 1. This veteran has a 2011 MT Copay Reqd test that was done by site
		 * 442 (Chey3). I manually set his SSN verification status to VERIFIED.
		 *
		 * 2. In Chey3, I edited that test to make him MT Copay Exempt
		 *
		 * 3. Z07 uploaded >>> veteran has MT Copay Exempt in ESR >>> no
		 * IVM_MIGRATE record created
		 *
		 *
		 */
		VAFacility va =		this.getLookupService().getVaFacilityByStationNumber("442");
		Person onFile = buildSimplePerson();
		onFile.addSsn(
				createSSNWithVerificationStatus(
						this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.VERIFIED.getCode())));
		IncomeTest incomeTest = this.createIncomeTest(IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED, new Integer(2012));

		onFile.setIncomeTest(new Integer(2012), incomeTest);
 		onFile.getIncomeTest(new Integer(2012)).setSiteConductingTest(va);
		incomeTest.setSource(
				this.getLookupService().getIncomeTestSourceByCode(IncomeTestSource.CODE_VAMC.getCode()));
		incomeTest.setSiteConductingTest(va);

		updatePersonToMeetIVMSelectionCriteriaExceptIncomeTest(onFile);

		this.attachEligibilityVerification(onFile, EligibilityVerificationSource.CODE_VBA.getCode());

		// ALREADY VERIFIED
		onFile.getEligibilityVerification().setAacIndicator(
				this.getLookupService().getAACIndicatorByCode(
						AACIndicator.CODE_DATA_ACCEPTED.getName()));

		Person incoming = this.savePerson(onFile);



		this.addPermanentAddress(incoming, Calendar.getInstance().getTime(),
				null);
		incoming.getIncomeTest(new Integer(2012)).setMeansTestStatus(
				this.getLookupService().getMeansTestStatusByCode(MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode()));
		incoming.getIncomeTest(new Integer(2012)).getIncomeTestStatus().setDeterminedStatus(
				this.getLookupService().getMeansTestStatusByCode(MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode()));
		VerificationInfo vi = new VerificationInfo("x",	MessageType.CODE_ORUZ07_TO_ESR.getCode(), "x");

		Person updated = this.getMessagingService().processZ07(incoming,va, vi);
		assertNull(updated.getIncomeTest(new Integer(2012)).getHardship());
		//this.setComplete();
	}

	public void testIVMSelectionCriteriaWithNSC() throws Exception {
		PersonSubmittedAdvice advice = this.buildMockPersonSubmittedAdvice();
		Person old = this.buildSimplePerson();
		old.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		Person updated = this.savePerson(old);
		Integer incomeYear = updatePersonToMeetIVMSelectionCriteria(updated, true);
		boolean flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertTrue("expected true", flag);
	}
	private Integer updatePersonToMeetIVMSelectionCriteria(Person updated, boolean attachIncomeTest) throws Exception {
		this.attachVerifiedEnrollment(updated);
		Eligibility elig = new Eligibility();
		elig.setType(this.getLookupService().getEligibilityTypeByCode(EligibilityType.NSC.getCode()));
		updated.getEnrollmentDetermination().setPrimaryEligiblity(elig);
		if (attachIncomeTest) {
			IncomeTest incomeTest = this.createIncomeTest(IncomeTestType.CODE_MEANS_TEST,
					MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT, new Integer(2012));
			incomeTest.getIncomeTestStatus().setDeterminedStatus(this.getLookupService().getMeansTestStatusByCode(
					MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode()));
			incomeTest.setPrimaryIncomeTest(Boolean.TRUE);
			updated.setIncomeTest(new Integer(2012), incomeTest);
		}

		updated.getOfficialSsn().setSsaVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.VERIFIED.getCode()));
		return new Integer(2012);
	}
	private Integer updatePersonToMeetIVMSelectionCriteriaExceptIncomeTest(Person updated) throws Exception {
		this.attachVerifiedEnrollment(updated);
		Eligibility elig = new Eligibility();
		elig.setType(this.getLookupService().getEligibilityTypeByCode(EligibilityType.NSC.getCode()));
		updated.getEnrollmentDetermination().setPrimaryEligiblity(elig);
		updated.getOfficialSsn().setSsaVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.VERIFIED.getCode()));
		return new Integer(2012);
	}
	public void testIVMSelectionCriteriaWithSC0NONCOMP() throws Exception {
		PersonSubmittedAdvice advice = this.buildMockPersonSubmittedAdvice();
		Person old = this.buildSimplePerson();
		old.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		Person updated = this.savePerson(old);
		Integer incomeYear = updatePersonToMeetIVMSelectionCriteria(updated, true);

		this.attachServiceConnectionAward(updated, new Integer(0));
		Eligibility elig = new Eligibility();
		elig.setType(this.getLookupService().getEligibilityTypeByCode(EligibilityType.SC_LESS_THAN_50_PERCENT.getCode()));
		updated.getEnrollmentDetermination().setPrimaryEligiblity(elig);
		this.attachMonetaryBenefitAward(updated);
		updated.getMonetaryBenefitAward().setCheckAmount(new BigDecimal(0));

		boolean flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertTrue("expected true", flag);

	}
	public void testIVMSelectionCriteriaWithNegSC0NONCOMP() throws Exception {
		PersonSubmittedAdvice advice = this.buildMockPersonSubmittedAdvice();

		Person old = this.buildSimplePerson();
		old.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		Person updated = this.savePerson(old);
		Integer incomeYear = updatePersonToMeetIVMSelectionCriteria(updated, true);

		this.attachServiceConnectionAward(updated, new Integer(0));
		Eligibility elig = new Eligibility();
		elig.setType(this.getLookupService().getEligibilityTypeByCode(EligibilityType.SC_LESS_THAN_50_PERCENT.getCode()));
		updated.getEnrollmentDetermination().setPrimaryEligiblity(elig);
		this.attachMonetaryBenefitAward(updated);
		// Setting check > 0 should cause it to evaluate to FALSE
		updated.getMonetaryBenefitAward().setCheckAmount(new BigDecimal(1));

		boolean flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertFalse("expected false", flag);
	}
	private PersonSubmittedAdvice buildMockPersonSubmittedAdvice() {
		PersonSubmittedAdvice advice = new PersonSubmittedAdvice();
		advice.setPersonHelperService(this.getPersonHelperService());
		advice.setIvmDMService(this.getIvmDMService());
		return advice;
	}
	public void testIVMSelectionCriteriaMTStatus() throws Exception {
		PersonSubmittedAdvice advice = this.buildMockPersonSubmittedAdvice();
		Person old = this.buildSimplePerson();
		/**
		 * These statuses can cause person to be ivm candidate:
		 * Means Test Status = MT Copay Exempt or GMT Copay Required, or
		 * Pending Adjudication or MT Copay Required
		 */
		old.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		Person updated = this.savePerson(old);
		Integer incomeYear = updatePersonToMeetIVMSelectionCriteria(updated, true);
		updated.getEnrollmentDetermination().setPriorityGroup(
				this.getLookupService().getEnrollmentPriorityGroupByCode(EnrollmentPriorityGroup.GROUP_1.getCode()));

		updated.getIncomeTest(incomeYear).getIncomeTestStatus().setStatus(
				this.getLookupService().getMeansTestStatusByCode(
				MeansTestStatus.MT_STATUS_NO_LONGER_REQUIRED.getCode()));
		boolean flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertFalse("expected false", flag);

		updated.getIncomeTest(incomeYear).getIncomeTestStatus().setStatus(
				this.getLookupService().getMeansTestStatusByCode(
				MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT.getCode()));
		flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertTrue("expected true", flag);


		updated.getIncomeTest(incomeYear).getIncomeTestStatus().setStatus(
				this.getLookupService().getMeansTestStatusByCode(
				MeansTestStatus.MT_STATUS_GMT_COPAY_REQUIRED.getCode()));
		flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertTrue("expected true", flag);

		updated.getIncomeTest(incomeYear).getIncomeTestStatus().setStatus(
				this.getLookupService().getMeansTestStatusByCode(
				MeansTestStatus.MT_STATUS_PENDING_ADJUDICATION.getCode()));
		flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertTrue("expected true", flag);

		updated.getIncomeTest(incomeYear).getIncomeTestStatus().setStatus(
				this.getLookupService().getMeansTestStatusByCode(
				MeansTestStatus.MT_STATUS_MT_COPAY_REQUIRED.getCode()));
		flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertTrue("expected true", flag);
	}
	public void testIVMSelectionCriteriaPendingMTRequired() throws Exception {
		PersonSubmittedAdvice advice = this.buildMockPersonSubmittedAdvice();
		Person old = this.buildSimplePerson();
		old.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		Person updated = this.savePerson(old);
		Integer incomeYear = updatePersonToMeetIVMSelectionCriteria(updated, false);// no income test

		updated.getEnrollmentDetermination().setPriorityGroup(null);
		boolean flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertFalse("expected false", flag);
		updated.getEnrollmentDetermination().setEnrollmentStatus(
				this.getLookupService().getEnrollmentStatusByCode(
						EnrollmentStatus.CODE_PENDING_MEANS_TEST_REQUIRED.getCode()));
		flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertFalse("expected false", flag);
		IncomeTest incomeTest = this.createIncomeTest(
				IncomeTestType.CODE_MEANS_TEST,
				MeansTestStatus.MT_STATUS_MT_COPAY_EXEMPT, incomeYear);
		updated.setIncomeTest(incomeTest.getIncomeYear(), incomeTest);
		flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertTrue("expected true", flag);
		incomeTest.setSource(
				this.getLookupService().getIncomeTestSourceByCode(IncomeTestSource.CODE_IVM.getCode()));
		flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertFalse("expected false", flag);
	}

	public void testIVMSelectionCriteriaPriorityGroup() throws Exception {
		PersonSubmittedAdvice advice = this.buildMockPersonSubmittedAdvice();
		Person old = this.buildSimplePerson();

		old.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		Person updated = this.savePerson(old);
		Integer incomeYear = updatePersonToMeetIVMSelectionCriteria(updated, false); // no income test

		updated.getEnrollmentDetermination().setPriorityGroup(
				this.getLookupService().getEnrollmentPriorityGroupByCode(EnrollmentPriorityGroup.GROUP_1.getCode()));
		boolean flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertFalse("expected false", flag);

		updated.getEnrollmentDetermination().setPriorityGroup(
				this.getLookupService().getEnrollmentPriorityGroupByCode(EnrollmentPriorityGroup.GROUP_2.getCode()));
		flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertTrue("expected true", flag);

		updated.getEnrollmentDetermination().setPriorityGroup(
				this.getLookupService().getEnrollmentPriorityGroupByCode(EnrollmentPriorityGroup.GROUP_3.getCode()));
		flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertTrue("expected true", flag);

		updated.getEnrollmentDetermination().setPriorityGroup(
				this.getLookupService().getEnrollmentPriorityGroupByCode(EnrollmentPriorityGroup.GROUP_5.getCode()));
		flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertTrue("expected true", flag);

		updated.getEnrollmentDetermination().setPriorityGroup(
				this.getLookupService().getEnrollmentPriorityGroupByCode(EnrollmentPriorityGroup.GROUP_6.getCode()));
		flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertTrue("expected true", flag);

		updated.getEnrollmentDetermination().setPriorityGroup(
				this.getLookupService().getEnrollmentPriorityGroupByCode(EnrollmentPriorityGroup.GROUP_7.getCode()));
		flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertTrue("expected true", flag);

		updated.getEnrollmentDetermination().setPriorityGroup(
				this.getLookupService().getEnrollmentPriorityGroupByCode(EnrollmentPriorityGroup.GROUP_8.getCode()));
		flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertTrue("expected true", flag);

		updated.getEnrollmentDetermination().setPriorityGroup(null);
		flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertFalse("expected false", flag);

	}
	public void testIVMSelectionCriteriaFutureTest() throws Exception {
		PersonSubmittedAdvice advice = this.buildMockPersonSubmittedAdvice();
		Person old = this.buildSimplePerson();
		old.addSsn(
				createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		Person updated = this.savePerson(old);
		Integer incomeYear = updatePersonToMeetIVMSelectionCriteria(updated, true);

		updated.getIncomeTest(incomeYear).setFutureTest(Boolean.TRUE);

		boolean flag = advice.satisfiesIVMSelectionCriteria(updated, incomeYear, updated.getIdentityTraits());
		assertFalse("expected false", flag);
	}
	private SSN createSSNWithVerificationStatus(SSAVerificationStatus status) throws Exception {
		SSN ssn = new SSN();
		String str = Long.toString(System.currentTimeMillis());
		String text = str.substring(str.length() - 9);
		ssn.setSsnText(text);
		ssn.setType(this.getLookupService().getSSNTypeByCode(SSNType.CODE_ACTIVE.getCode()));
		ssn.setSsaVerificationStatus(status);
		return ssn;
	}
	public void testSelectionCriteriaSQLQuery() throws Exception {
		// FOR ESR 3.11, I expect this query is NOT necessary. We will apply
		// criteria one time when data changes.
		String queryName = "ivmDMQuery_checkSelectionCriteria";
		String[] paramNames = {"personId", "incomeYear"};
		Object[] paramValues = {new BigDecimal(373960894), new Integer(2010)};
		List list = getDAO().findByNamedQueryAndNamedParam(queryName, paramNames, paramValues);
		System.out.println(list.get(0));
	}

	public void testGetIVMMigrationsByPersonAndIncomeYear() throws Exception {
		String queryName = "ivmDMQuery_GetIVMMigrationByPersonAndIncomeYear";
		String[] paramNames = {"personId", "incomeYear"};
		Object[] paramValues = {new BigDecimal(373960894), new Integer(2010)};
		List list = getDAO().findByNamedQueryAndNamedParam(queryName, paramNames, paramValues);
		System.out.println(list.get(0));
	}
//3468029
	public void testGetIVMLegacyDataForAdvice() throws Exception {
		//377102222  373971922
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("3468029"));
		Integer s = this.getIvmDMService().getLatestHECLegacyYear(personKey);
		assertTrue(s > 0);

		Set w = this.getIvmDMService().findIVMMigrationsWithCompleteOrPendingStatus(personKey);
		assertTrue(w.size() > 0);
		Iterator iter = w.iterator();
		while (iter.hasNext()) {
			IVMMigration m = (IVMMigration)iter.next();
			System.out.println("ivm year="+m.getIncomeYear());
		}
	}

	public void testGetIVMDataForAdvice() throws Exception {
		//377102222  373971922
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("373971922"));
		Set s = this.getIvmDMService().findIVMMigrationsWithCompleteOrPendingStatus(personKey);
		assertTrue(s.size() > 0);
		Iterator iter = s.iterator();
		while (iter.hasNext()) {
			IVMMigration m = (IVMMigration)iter.next();
			System.out.println("ivm status="+m.getStatus().getDescription());
		}
	}
	public void testGetIVMCandidates() throws Exception {
		Set s = this.getIvmDMService().findIVMMigrationData(this.getDate(2012, 1, 1));
		assertTrue(s.size() > 0);
		System.out.println("count="+s.size());
	}
	public void testGetIVMCandidatesZero() throws Exception {
		Set s = this.getIvmDMService().findIVMMigrationData(this.getDate(2012, 11, 1));
		assertTrue(s.size() == 0);
	}
	public void testGetCurrentIVMIncomeYear() throws Exception {
		int year = this.getIvmDMService().getCurrentActiveIVMIncomeYear();
		assertTrue(year == 2011);
	}
	public void testGetNextIVMIncomeYear() throws Exception {
		int year = this.getIvmDMService().getNextVMIncomeYear();
		assertTrue(year == 2013);
		int yearActive = this.getIvmDMService().getCurrentActiveIVMIncomeYear();
		assertTrue(yearActive == 2012);
	}
	public void testGetMostRecentMigratedIncomeYear() throws Exception {
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("373973138"));
		Integer year = this.getIvmDMService().getMostRecentIVMMigratedYear(personKey);
		assertNotNull(year);

		IVMMigration m = this.getIvmDMService().findIVMMigration(personKey, year);
		assertNotNull(m);

	}
	public void testLatestHECIncomeYear() throws Exception {
		// CRR 12072
		// Expect A NON-null response from legacy record. A non-legacy would also work,
		// but it would never reach this query
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("4960074"));
		Integer year = this.getIvmDMService().getLatestHECLegacyYear(personKey);
		assertNotNull(year);

		IVMMigration m = this.getIvmDMService().findIVMMigration(personKey, year);
		assertNotNull(m);
	}
	public void testMostRecentHECIncomeYear() throws Exception {
		// CRR 12072
		// Expect a null response from a legacy record
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("4960074"));
		Integer year = this.getIvmDMService().getMostRecentIVMMigratedYear(personKey);
		assertNull(year);
	}
	public void testUpdateFromUIExistingHECLegacy() throws Exception {
		// CCR 12072
		Person onFile = this.buildSimplePerson();
		onFile.addSsn(createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		this.attachVerifiedEnrollment(onFile);
		onFile.getEnrollmentDetermination().setPrimaryEligiblity(null);
		onFile.getEnrollmentDetermination().setPriorityGroup(null);
		onFile.getEnrollmentDetermination().setPrioritySubGroup(null);
		onFile.getEnrollmentDetermination().setEffectiveDate(null);
		onFile.getEnrollmentDetermination().setEnrollmentStatus(
				this.getLookupService().getEnrollmentStatusByCode(EnrollmentStatus.CODE_PENDING_ELIGIBILITY_STATUS_IS_UNVERIFIED.getCode()));
		this.attachEligibilityVerification(onFile, EligibilityVerificationSource.CODE_VBA.getCode());
		this.setEligibilityStatusToPendingVerification(onFile);

		Person incoming = savePerson(onFile);
		this.createIVMMigrationEntryHecLegacy(incoming, new Integer(2011));
		this.setEligibilityStatusToVerified(incoming);
		Person updated = this.getEligibilityEnrollmentService().updateEligibilityData(incoming);
	}
	public void testUpdateFromUIExistingHECLegacyWithNewRecord() throws Exception {
		// CCR 12072
		Person onFile = this.buildSimplePerson();
		onFile.addSsn(createSSNWithVerificationStatus(this.getLookupService().getSSAVerificationStatusByCode(SSAVerificationStatus.IN_PROCESS.getCode())));
		this.attachVerifiedEnrollment(onFile);
		onFile.getEnrollmentDetermination().setPrimaryEligiblity(null);
		this.attachEligibilityVerification(onFile, EligibilityVerificationSource.CODE_VBA.getCode());
		this.setEligibilityStatusToPendingVerification(onFile);
		Person incoming = savePerson(onFile);
		this.createIVMMigrationEntry(incoming, new Integer(2011),MessageStatus.COMPLETE, false);
		this.createIVMMigrationEntryHecLegacy(incoming, new Integer(2011));
		this.setEligibilityStatusToVerified(incoming);
		Person updated = this.getEligibilityEnrollmentService().updateEligibilityData(incoming);
	}
	public void testFindMigratedRecordByPersonIncomeYearStatus() throws Exception {
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("373971922"));
		IVMMigration m = this.getIvmDMService().findIVMMigration(personKey,
				new Integer(2011),MessageStatus.AWAITING_TRANSMISSION);
		assertNotNull(m);
	}
//	public void testHasPreviousQualifiedRecord() throws Exception {
//		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("373973138"));
//		boolean flag = this.getIvmDMService().hasIVMMigrationWithCompleteOrAwaitingTxAck(personKey);
//		assertTrue(flag);
//	}
	public void testGetIVMCandidate() throws Exception {
		PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("373971922"));
		IVMMigration s = this.getIvmDMService().findIVMMigration(personKey, new Integer(2011));
		assertNotNull(s);
	}
	private FinancialInputParameter buildFinancialInputParameter(FinancialInputData data) throws ServiceException {
		FinancialInputParameter fip = new FinancialInputParameter();
		fip.setRuleDataAware(data);
		fip.setLookupService(getLookupService());
		fip.setHelperService(getPersonHelperService());
		fip.setMergeRuleService(this.getMergeRuleService());
		fip.setFinancialsHelperService(new FinancialsHelperServiceImpl());
		fip.setFinancialsServiceName("financialsService");
		fip.setApplicationContext(this.applicationContext);
		fip.setVeteranExpenseTypes(EXPENSE_TYPES_VETERAN);
		fip.setChildExpenseTypes(EXPENSE_TYPES_DEPENDENT);
		fip.setChildRelationships(DEPENDENT_RELATIONSHIPS);
		fip.setTimestampManagerName("common.timestampManager");
		return fip;
	}

	protected FinancialStatement buildFinancialStatementData(Integer incomeYear, Person person)
	throws Exception {
		FinancialStatement stmt = person.getFinancialStatement(incomeYear);
		if (stmt == null) {
			stmt = createFinancialStatement();
			setFinancialInfo(stmt, 5000, 0, 0, 1000);
			createAsset(stmt, 50, AssetType.CODE_CASH);
			createAsset(stmt, 1000, AssetType.CODE_REAL_ESTATE);
			createAsset(stmt, 1000, AssetType.CODE_OTHER);
			setExpense(stmt, 200, ExpenseType.EXPENSE_TYPE_FUNERAL_AND_BURIAL);
			setExpense(stmt, 400, ExpenseType.EXPENSE_TYPE_NON_REIMBURSED_MEDICAL);
			setExpense(stmt, 400, ExpenseType.EXPENSE_TYPE_ADJUSTED_MEDICAL);
			person.setFinancialStatement(incomeYear, stmt);
		}
		Calendar startDate = Calendar.getInstance();
		startDate.set(Calendar.YEAR, incomeYear.intValue() - 1);
		Spouse spouse = createSpouse();
		spouse.setStartDate(new ImpreciseDate(startDate));

		SpouseFinancials sf = createSpouseFinancials(spouse);
		sf.setLivedWithPatient(Boolean.TRUE);
		setFinancialInfo(sf, 2000, 500, 500, 100);
		createAsset(sf, 5000, AssetType.CODE_OTHER);
		stmt.setMarriedLastCalendarYear(Boolean.TRUE);
		stmt.removeActiveSpouseFinancials();
		stmt.addSpouseFinancials(sf);

		DependentFinancials df1 = createDependentFinancials(incomeYear, Relationship.CODE_DAUGHTER);
		df1.setLivedWithPatient(Boolean.TRUE);
		stmt.addDependentFinancials(df1);

		Dependent dependent2 = createDependent();
		DependentFinancials df2 = createDependentFinancials(dependent2);
		dependent2.setRelationship(getLookupService().getRelationshipByCode(Relationship.CODE_SON.getName()));
		dependent2.setStartDate(new ImpreciseDate(startDate));
		df2.setLivedWithPatient(Boolean.TRUE);
		df2.setHasIncome(Boolean.TRUE);
		df2.setIncomeAvailableToPatient(Boolean.TRUE);
		df2.setContributedToSupport(Boolean.FALSE);
		setFinancialInfo(df2, 20000, 1200, 2050, 1000);
		createIncome(df2, 2000, IncomeType.INCOME_TYPE_TOTAL_INCOME_FROM_EMPLOYMENT);
		stmt.addDependentFinancials(df2);

		return stmt;
	}
	private DependentFinancials createDependentFinancials(Integer incomeYear, Relationship.Code relationship)
	throws Exception, UnknownLookupTypeException, UnknownLookupCodeException {
		Calendar startDate = Calendar.getInstance();
		startDate.set(Calendar.YEAR, incomeYear.intValue() - 1);

		Dependent dependent1 = createDependent();
		DependentFinancials df1 = createDependentFinancials(dependent1);
		dependent1.setRelationship(getLookupService().getRelationshipByCode(relationship.getName()));
		dependent1.setStartDate(new ImpreciseDate(startDate));
		df1.setLivedWithPatient(Boolean.TRUE);
		df1.setHasIncome(Boolean.TRUE);
		df1.setIncomeAvailableToPatient(Boolean.TRUE);
		setFinancialInfo(df1, 10000, 1500, 1750, 750);
		createIncome(df1, 5000, IncomeType.INCOME_TYPE_TOTAL_INCOME_FROM_EMPLOYMENT);
		setExpense(df1, 500, ExpenseType.EXPENSE_TYPE_EDUCATIONAL_EXPENSES_BY_DEPENDENT);
		return df1;
	}
	protected void setFinancialInfo(FinancialInformation finInfo, double incomeAmount, double expenseAmount,
			double assetAmount, double debtAmount) throws Exception {
		Asset asset = (Asset) finInfo.getAssets().values().iterator().next();
		asset.setAmount(new BigDecimal(assetAmount));
		Income income = (Income) finInfo.getIncome().values().iterator().next();
		income.setAmount(new BigDecimal(incomeAmount));
		Expense expense = (Expense) finInfo.getExpenses().values().iterator().next();
		expense.setAmount(new BigDecimal(expenseAmount));
		Debt debt = finInfo.getDebt();
		debt.setAmount(new BigDecimal(debtAmount));
	}

	public void testGetIVMMigrationWithPendingTransmissionStatus() throws Exception {
		this.getIvmDMService().findIVMMigrationData(this.getDate(2012, 1,1));

	}
	public void testIVMMigrationStatus() throws Exception {
		IVMMigration m = new IVMMigration();
		m.setStatus(this.getLookupService().getMessageStatusByCode(MessageStatus.COMPLETE));

	}
	public IVMDMService getIvmDMService() {
		return ivmDMService;
	}
	public void setIvmDMService(IVMDMService ivmDMService) {
		this.ivmDMService = ivmDMService;
	}
	public DAOOperations getGenericDAO() throws ServiceException{
		if(genericDAO == null) {
			genericDAO = (DAOOperations)applicationContext.getBean("genericDAO");
		}
		return this.genericDAO;
	}

}
