package gov.va.med.esr.voa.validator;

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.AssociationType;
import gov.va.med.esr.common.model.lookup.Country;
import gov.va.med.esr.common.model.lookup.EmploymentStatus;
import gov.va.med.esr.common.model.lookup.IncomeType;
import gov.va.med.esr.common.model.lookup.MaritalStatus;
import gov.va.med.esr.common.model.lookup.Relationship;
import gov.va.med.esr.common.model.lookup.SSNType;
import gov.va.med.esr.voa.common.ErrorCode;
import gov.va.med.esr.voa.webservice.AddressInfo;
import gov.va.med.esr.voa.webservice.ApplicationCollection;
import gov.va.med.esr.voa.webservice.ApplicationInfo;
import gov.va.med.esr.voa.webservice.AssetCollection;
import gov.va.med.esr.voa.webservice.AssetInfo;
import gov.va.med.esr.voa.webservice.AssociationInfo;
import gov.va.med.esr.voa.webservice.BaseAddressInfo;
import gov.va.med.esr.voa.webservice.DemographicInfo;
import gov.va.med.esr.voa.webservice.DependentFinancialsCollection;
import gov.va.med.esr.voa.webservice.DependentFinancialsInfo;
import gov.va.med.esr.voa.webservice.DependentInfo;
import gov.va.med.esr.voa.webservice.EeSummary;
import gov.va.med.esr.voa.webservice.EmploymentInfo;
import gov.va.med.esr.voa.webservice.ExpenseCollection;
import gov.va.med.esr.voa.webservice.ExpenseInfo;
import gov.va.med.esr.voa.webservice.FinancialStatementInfo;
import gov.va.med.esr.voa.webservice.FinancialsInfo;
import gov.va.med.esr.voa.webservice.Form;
import gov.va.med.esr.voa.webservice.FormIdentifier;
import gov.va.med.esr.voa.webservice.IncomeCollection;
import gov.va.med.esr.voa.webservice.IncomeInfo;
import gov.va.med.esr.voa.webservice.ObjectFactory;
import gov.va.med.esr.voa.webservice.SpouseFinancialsCollection;
import gov.va.med.esr.voa.webservice.SpouseFinancialsInfo;
import gov.va.med.esr.voa.webservice.SpouseInfo;
import gov.va.med.esr.voa.webservice.SsnCollection;
import gov.va.med.esr.voa.webservice.SsnInfo;

import java.math.BigDecimal;
import java.util.GregorianCalendar;
import java.util.List;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import org.springframework.validation.BindException;

public class FormValidatorTest extends VoaCommonTestCase {

	private AssociationInfoValidator validator;

	private AssociationInfo associationInfo;

	private FormValidator formValidator;

	private Form form;

	@Override
	public void onSetUpInTransaction() throws Exception {
		super.onSetUpInTransaction();
		validator = new AssociationInfoValidator();
		validator.setLookupService(getLookupService());

		formValidator = new FormValidator();
		formValidator.setLookupService(getLookupService());

		ObjectFactory factory = new ObjectFactory();
		form = factory.createForm();
		
		FormIdentifier formIdentifier = factory.createFormIdentifier();
		formIdentifier.setType("100");
		formIdentifier.setValue("1010EZ");
		form.setFormIdentifier(formIdentifier);
		
		associationInfo = factory.createAssociationInfo();

		associationInfo.setFamilyName("test");
		associationInfo.setGivenName("test");
		associationInfo.setPrimaryPhone("2141231234");
		associationInfo.setAlternatePhone("1234567890");
		associationInfo.setRelationship(Relationship.CODE_BROTHER.getCode());

		associationInfo.setContactType(AssociationType.CODE_EMERGENCY_CONTACT
				.getCode());

		BaseAddressInfo baseAddressInfo = factory.createBaseAddressInfo();
		associationInfo.setAddress(baseAddressInfo);

		baseAddressInfo.setLine1("line1");
		baseAddressInfo.setLine2("line2");
		baseAddressInfo.setLine3("line3");
		baseAddressInfo.setCity("Dallas");
		baseAddressInfo.setZipCode("75024");
		baseAddressInfo.setState("TX");
		baseAddressInfo.setCountry("USA");

		ApplicationCollection applicationCollection = factory
				.createApplicationCollection();
		ApplicationInfo applicationInfo = factory.createApplicationInfo();
		applicationCollection.getApplicationInfo().add(applicationInfo);
		form.setApplications(applicationCollection);
		applicationInfo.setBenefitType("1");
		applicationInfo.setAppMethod("1");
		GregorianCalendar calendar = new GregorianCalendar();
		XMLGregorianCalendar xMLGregorianCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar);
		applicationInfo.setAppDate(xMLGregorianCalendar);

		EeSummary eeSummary = factory.createEeSummary();
		form.setSummary(eeSummary);

		DemographicInfo demographicInfo = factory.createDemographicInfo();
		eeSummary.setDemographics(demographicInfo);
		demographicInfo.setMaritalStatus(MaritalStatus.CODE_MARRIED.getCode());
		// HEC center
		demographicInfo.setPreferredFacility("742");
		demographicInfo.setEthnicity("2186-5");

		FinancialStatementInfo financialStatementInfo = factory
				.createFinancialStatementInfo();
		FinancialsInfo financialsInfo = factory.createFinancialsInfo();
		eeSummary.setFinancialsInfo(financialsInfo);
		financialsInfo.setFinancialStatement(financialStatementInfo);

		IncomeCollection vetIncomeCollection = factory.createIncomeCollection();
		financialStatementInfo.setIncomes(vetIncomeCollection);
		IncomeInfo vetIncomeInfo = factory.createIncomeInfo();
		vetIncomeCollection.getIncome().add(vetIncomeInfo);
		vetIncomeInfo.setAmount(new BigDecimal(10000));
		vetIncomeInfo
				.setType(IncomeType.INCOME_TYPE_TOTAL_INCOME_FROM_EMPLOYMENT
						.getCode());
		vetIncomeInfo.setAmount(new BigDecimal(10000));

		AssetCollection vetAssetCollection = factory.createAssetCollection();
		financialStatementInfo.setAssets(vetAssetCollection);
		AssetInfo vatAssetInfo = factory.createAssetInfo();
		vetAssetCollection.getAsset().add(vatAssetInfo);
		vatAssetInfo.setAmount(new BigDecimal(12345));
		vatAssetInfo.setAssetType(AssetType.CODE_REAL_ESTATE.getCode());

		SpouseFinancialsCollection spouseFinancialsCollection = factory
				.createSpouseFinancialsCollection();
		financialStatementInfo
				.setSpouseFinancialsList(spouseFinancialsCollection);

		SpouseFinancialsInfo spouseFinancialsInfo = factory
				.createSpouseFinancialsInfo();
		spouseFinancialsCollection.getSpouseFinancials().add(
				spouseFinancialsInfo);

		SpouseInfo spouseInfo = factory.createSpouseInfo();
		spouseFinancialsInfo.setLivedWithPatient(Boolean.FALSE);
		spouseFinancialsInfo.setSpouse(spouseInfo);

		spouseInfo.setDob("02/12/1966");
		spouseInfo.setFamilyName("sun");
		spouseInfo.setGivenName("test");
		spouseInfo.setGender("male");
		spouseInfo.setMaidenName("maidenName");
		spouseInfo.setMiddleName("middleName");
		spouseInfo.setRelationship("brother");
		SsnInfo ssnInfo = factory.createSsnInfo();
		ssnInfo.setSsnText("123456789");
		ssnInfo.setType(SSNType.CODE_ACTIVE.getCode());
		SsnCollection ssnCollection = factory.createSsnCollection();
		ssnCollection.getSsn().add(ssnInfo);
		spouseInfo.setSsns(ssnCollection);
		spouseInfo.setStartDate("12/12/1988");

		AddressInfo addressInfo = factory.createAddressInfo();
		spouseInfo.setAddress(addressInfo);
		addressInfo.setLine1("Address Line 1");
		addressInfo.setLine2("Address Line 2");
		addressInfo.setLine3("Address Line 3");
		addressInfo.setCity("Plano");
		addressInfo.setState("TX");
		addressInfo.setCountry("USA");
		addressInfo.setZipCode("75024");
		addressInfo.setAddressTypeCode(AddressType.CODE_PERMANENT_ADDRESS
				.getCode());
		addressInfo.setPhoneNumber("2140009999");

		// employment info
		EmploymentInfo employmentInfo = factory.createEmploymentInfo();
		spouseInfo.setEmployment(employmentInfo);
		employmentInfo.setEmploymentStatus(EmploymentStatus.CODE_FULL_TIME
				.getCode());
		employmentInfo.setEmployerName("Boss");
		employmentInfo.setEmployerPhone("2142223333");

		AddressInfo employmentAddress = factory.createAddressInfo();
		employmentInfo.setEmployerAddress(employmentAddress);
		employmentAddress.setLine1("122222 main");
		employmentAddress.setCity("Coppell");
		employmentAddress.setState("TX");
		employmentAddress.setCountry("USA");
		employmentAddress.setZipCode("75001");
		employmentAddress.setPhoneNumber("");
		employmentAddress.setZipPlus4("1234");

		IncomeCollection incomeCollection = factory.createIncomeCollection();
		IncomeInfo incomeInfo = factory.createIncomeInfo();
		incomeCollection.getIncome().add(incomeInfo);
		spouseFinancialsInfo.setIncomes(incomeCollection);

		incomeInfo.setAmount(new BigDecimal(12345));
		incomeInfo.setType(IncomeType.INCOME_TYPE_TOTAL_INCOME_FROM_EMPLOYMENT
				.getCode());

		AssetCollection assetCollection = factory.createAssetCollection();
		spouseFinancialsInfo.setAssets(assetCollection);
		AssetInfo assetInfo = factory.createAssetInfo();
		assetCollection.getAsset().add(assetInfo);

		assetInfo.setAmount(new BigDecimal(1234));
		assetInfo.setAssetType(AssetType.CODE_REAL_ESTATE.getCode());

		DependentFinancialsCollection dependentFinancialsCollection = factory
				.createDependentFinancialsCollection();
		financialStatementInfo
				.setDependentFinancialsList(dependentFinancialsCollection);
		DependentFinancialsInfo dependentFinancialsInfo = factory
				.createDependentFinancialsInfo();
		DependentInfo dependentInfo = factory.createDependentInfo();
		dependentFinancialsInfo.setDependentInfo(dependentInfo);
		dependentFinancialsCollection.getDependentFinancials().add(
				dependentFinancialsInfo);

		dependentInfo.setDob("01/01/1960");
		dependentInfo.setFamilyName("test");
		dependentInfo.setGivenName("test");
		dependentInfo.setMiddleName("test");
		dependentInfo.setRelationship(Relationship.CODE_BROTHER.getCode());
		SsnInfo ssnInfo2 = factory.createSsnInfo();
		ssnInfo2.setSsnText("123456789");
		ssnInfo2.setType(SSNType.CODE_ACTIVE.getCode());
		SsnCollection depSsnCollection = factory.createSsnCollection();
		depSsnCollection.getSsn().add(ssnInfo2);
		spouseInfo.setSsns(depSsnCollection);

		dependentInfo.setSsns(ssnCollection);
		dependentInfo.setStartDate("01/01/2001");
		dependentInfo.setDob("01/01/2001");
		dependentFinancialsInfo.setIncapableOfSelfSupport(Boolean.TRUE);

		ExpenseCollection expenseCollection = factory.createExpenseCollection();
		dependentFinancialsInfo.setExpenses(expenseCollection);
		ExpenseInfo expenseInfo = factory.createExpenseInfo();
		expenseCollection.getExpense().add(expenseInfo);
		expenseInfo.setAmount(new BigDecimal(123));

		IncomeCollection incomeCollection2 = factory.createIncomeCollection();
		IncomeInfo incomeInfo2 = factory.createIncomeInfo();
		incomeInfo2.setAmount(new BigDecimal(12345));
		incomeInfo2.setType(IncomeType.INCOME_TYPE_TOTAL_INCOME_FROM_EMPLOYMENT
				.getCode());
		incomeCollection2.getIncome().add(incomeInfo2);
		dependentFinancialsInfo.setIncomes(incomeCollection2);

		AssetCollection assetCollection2 = factory.createAssetCollection();
		dependentFinancialsInfo.setAssets(assetCollection2);
		dependentFinancialsInfo.setLivedWithPatient(Boolean.TRUE);

		AssetInfo depAssetInfo = factory.createAssetInfo();
		assetCollection2.getAsset().add(depAssetInfo);
		depAssetInfo.setAmount(new BigDecimal(1234));
		depAssetInfo.setAssetType(AssetType.CODE_REAL_ESTATE.getCode());
	}

	@Override
	public void onTearDownInTransaction() {
		validator = null;
		associationInfo = null;
		super.onTearDownInTransaction();
	}

	public void testForm() throws Exception {
		BindException errors = new BindException(form, "form");
		formValidator.validate(form, errors);

		assertFalse(errors.hasErrors());
	}

	public void testVetIncome() throws Exception {
		FinancialStatementInfo financialStatementInfo = form.getSummary()
				.getFinancialsInfo().getFinancialStatement();
		IncomeInfo incomeInfo = financialStatementInfo.getIncomes().getIncome()
				.iterator().next();
		incomeInfo.setAmount(new BigDecimal(-9999));

		BindException errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);

		assertEquals(errors.getErrorCount(), 1);

		boolean hasError0161 = contain(errors, ErrorCode.VOA_0161);

		assertTrue(hasError0161);

		incomeInfo.setAmount(new BigDecimal(9999999 + 1));
		errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);
		hasError0161 = contain(errors, ErrorCode.VOA_0161);

		assertTrue(hasError0161);

		incomeInfo.setAmount(null);
		errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);
		boolean hasError0160 = contain(errors, ErrorCode.VOA_0160);

		assertTrue(hasError0160);
	}

	public void testVetOtherIncome() throws Exception {
		FinancialStatementInfo financialStatementInfo = form.getSummary()
				.getFinancialsInfo().getFinancialStatement();
		IncomeInfo incomeInfo = financialStatementInfo.getIncomes().getIncome()
				.iterator().next();
		incomeInfo.setType(IncomeType.INCOME_TYPE_TOTAL_ALL_OTHER_INCOME
				.getCode());

		incomeInfo.setAmount(null);
		BindException errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);
		boolean hasError0178 = contain(errors, ErrorCode.VOA_0178);

		assertTrue(hasError0178);

		incomeInfo.setAmount(new BigDecimal(-9999));

		errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);

		assertEquals(errors.getErrorCount(), 1);

		boolean hasError0179 = contain(errors, ErrorCode.VOA_0179);

		assertTrue(hasError0179);

		incomeInfo.setAmount(new BigDecimal(9999999 + 1));
		errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);
		hasError0179 = contain(errors, ErrorCode.VOA_0179);

		assertTrue(hasError0179);
	}

	public void testSpouseIncome() throws Exception {
		FinancialStatementInfo financialStatementInfo = form.getSummary()
				.getFinancialsInfo().getFinancialStatement();
		SpouseFinancialsInfo spouseFinancialsInfo = financialStatementInfo
				.getSpouseFinancialsList().getSpouseFinancials().iterator()
				.next();
		IncomeInfo incomeInfo = spouseFinancialsInfo.getIncomes().getIncome()
				.iterator().next();
		incomeInfo.setAmount(new BigDecimal(-9999));

		BindException errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);

		assertEquals(errors.getErrorCount(), 1);

		boolean hasError0164 = contain(errors, ErrorCode.VOA_0164);

		assertTrue(hasError0164);

		incomeInfo.setAmount(new BigDecimal(9999999 + 1));
		errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);
		hasError0164 = contain(errors, ErrorCode.VOA_0164);

		assertTrue(hasError0164);

		incomeInfo.setAmount(null);
		errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);
		boolean hasError0163 = contain(errors, ErrorCode.VOA_0163);

		assertTrue(hasError0163);
	}

	public void testSpouseOtherIncome() throws Exception {
		FinancialStatementInfo financialStatementInfo = form.getSummary()
				.getFinancialsInfo().getFinancialStatement();
		SpouseFinancialsInfo spouseFinancialsInfo = financialStatementInfo
				.getSpouseFinancialsList().getSpouseFinancials().iterator()
				.next();
		IncomeInfo incomeInfo = spouseFinancialsInfo.getIncomes().getIncome()
				.iterator().next();
		incomeInfo.setType(IncomeType.INCOME_TYPE_TOTAL_ALL_OTHER_INCOME
				.getCode());

		incomeInfo.setAmount(null);
		BindException errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);
		boolean hasError0181 = contain(errors, ErrorCode.VOA_0181);

		assertTrue(hasError0181);

		incomeInfo.setAmount(new BigDecimal(-9999));

		errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);

		assertEquals(errors.getErrorCount(), 1);

		boolean hasError0182 = contain(errors, ErrorCode.VOA_0182);

		assertTrue(hasError0182);

		incomeInfo.setAmount(new BigDecimal(9999999 + 1));
		errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);
		hasError0182 = contain(errors, ErrorCode.VOA_0182);

		assertTrue(hasError0182);
	}

	public void testDependentIncome() throws Exception {
		FinancialStatementInfo financialStatementInfo = form.getSummary()
				.getFinancialsInfo().getFinancialStatement();
		DependentFinancialsInfo dependentFinancialsInfo = financialStatementInfo
				.getDependentFinancialsList().getDependentFinancials()
				.iterator().next();
		IncomeInfo incomeInfo = dependentFinancialsInfo.getIncomes()
				.getIncome().iterator().next();
		incomeInfo.setAmount(new BigDecimal(-9999));

		BindException errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);

		assertEquals(errors.getErrorCount(), 1);

		boolean hasError0167 = contain(errors, ErrorCode.VOA_0167);

		assertTrue(hasError0167);

		incomeInfo.setAmount(new BigDecimal(9999999 + 1));
		errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);
		hasError0167 = contain(errors, ErrorCode.VOA_0167);

		assertTrue(hasError0167);

		incomeInfo.setAmount(null);
		errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);
		boolean hasError0166 = contain(errors, ErrorCode.VOA_0166);

		assertTrue(hasError0166);
	}

	public void testDependentOtherIncome() throws Exception {
		FinancialStatementInfo financialStatementInfo = form.getSummary()
				.getFinancialsInfo().getFinancialStatement();
		DependentFinancialsInfo dependentFinancialsInfo = financialStatementInfo
				.getDependentFinancialsList().getDependentFinancials()
				.iterator().next();
		IncomeInfo incomeInfo = dependentFinancialsInfo.getIncomes()
				.getIncome().iterator().next();
		incomeInfo.setType(IncomeType.INCOME_TYPE_TOTAL_ALL_OTHER_INCOME
				.getCode());

		incomeInfo.setAmount(null);
		BindException errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);
		boolean hasError0184 = contain(errors, ErrorCode.VOA_0184);

		assertTrue(hasError0184);

		incomeInfo.setAmount(new BigDecimal(-9999));

		errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);

		assertEquals(errors.getErrorCount(), 1);

		boolean hasError0185 = contain(errors, ErrorCode.VOA_0185);

		assertTrue(hasError0185);

		incomeInfo.setAmount(new BigDecimal(10000000));
		errors = new BindException(incomeInfo, "incomeInfo");
		formValidator.validate(form, errors);
		hasError0185 = contain(errors, ErrorCode.VOA_0185);

		assertTrue(hasError0185);
	}

	public void testVetAsset() throws Exception {
		FinancialStatementInfo financialStatementInfo = form.getSummary()
				.getFinancialsInfo().getFinancialStatement();
		AssetInfo assetInfo = financialStatementInfo.getAssets().getAsset()
				.iterator().next();
		assetInfo.setAssetType(AssetType.CODE_REAL_ESTATE.getCode());

		assetInfo.setAmount(null);
		BindException errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);
		boolean hasError0205 = contain(errors, ErrorCode.VOA_0205);

		assertTrue(hasError0205);

		assetInfo.setAmount(new BigDecimal(-9999));

		errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);

		assertEquals(errors.getErrorCount(), 1);

		boolean hasError0206 = contain(errors, ErrorCode.VOA_0206);

		assertTrue(hasError0206);

		assetInfo.setAmount(new BigDecimal(10000000));
		errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);
		hasError0206 = contain(errors, ErrorCode.VOA_0206);

		assertTrue(hasError0206);
	}

	public void testVetOtherAsset() throws Exception {
		FinancialStatementInfo financialStatementInfo = form.getSummary()
				.getFinancialsInfo().getFinancialStatement();
		AssetInfo assetInfo = financialStatementInfo.getAssets().getAsset()
				.iterator().next();
		assetInfo.setAssetType(AssetType.CODE_OTHER.getCode());

		assetInfo.setAmount(null);
		BindException errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);
		boolean hasError0214 = contain(errors, ErrorCode.VOA_0214);

		assertTrue(hasError0214);

		assetInfo.setAmount(new BigDecimal(-9999));

		errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);

		assertEquals(errors.getErrorCount(), 1);

		boolean hasError0215 = contain(errors, ErrorCode.VOA_0215);

		assertTrue(hasError0215);

		assetInfo.setAmount(new BigDecimal(10000000));
		errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);
		hasError0215 = contain(errors, ErrorCode.VOA_0215);

		assertTrue(hasError0215);
	}

	public void testSpouseAsset() throws Exception {
		FinancialStatementInfo financialStatementInfo = form.getSummary()
				.getFinancialsInfo().getFinancialStatement();
		SpouseFinancialsInfo spouseFinancialsInfo = financialStatementInfo
				.getSpouseFinancialsList().getSpouseFinancials().iterator()
				.next();
		AssetInfo assetInfo = spouseFinancialsInfo.getAssets().getAsset()
				.iterator().next();
		assetInfo.setAssetType(AssetType.CODE_REAL_ESTATE.getCode());

		assetInfo.setAmount(null);
		BindException errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);
		boolean hasError0208 = contain(errors, ErrorCode.VOA_0208);

		assertTrue(hasError0208);

		assetInfo.setAmount(new BigDecimal(-9999));

		errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);

		assertEquals(errors.getErrorCount(), 1);

		boolean hasError0209 = contain(errors, ErrorCode.VOA_0209);

		assertTrue(hasError0209);

		assetInfo.setAmount(new BigDecimal(10000000));
		errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);
		hasError0209 = contain(errors, ErrorCode.VOA_0209);

		assertTrue(hasError0209);
	}

	public void testSpouseOtherAsset() throws Exception {
		FinancialStatementInfo financialStatementInfo = form.getSummary()
				.getFinancialsInfo().getFinancialStatement();
		SpouseFinancialsInfo spouseFinancialsInfo = financialStatementInfo
				.getSpouseFinancialsList().getSpouseFinancials().iterator()
				.next();
		AssetInfo assetInfo = spouseFinancialsInfo.getAssets().getAsset()
				.iterator().next();
		assetInfo.setAssetType(AssetType.CODE_OTHER.getCode());

		assetInfo.setAmount(null);
		BindException errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);
		boolean hasError0217 = contain(errors, ErrorCode.VOA_0217);

		assertTrue(hasError0217);

		assetInfo.setAmount(new BigDecimal(-9999));

		errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);

		assertEquals(errors.getErrorCount(), 1);

		boolean hasError0218 = contain(errors, ErrorCode.VOA_0218);

		assertTrue(hasError0218);

		assetInfo.setAmount(new BigDecimal(10000000));
		errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);
		hasError0218 = contain(errors, ErrorCode.VOA_0218);

		assertTrue(hasError0218);
	}

	public void testDependentAsset() throws Exception {
		FinancialStatementInfo financialStatementInfo = form.getSummary()
				.getFinancialsInfo().getFinancialStatement();
		DependentFinancialsInfo dependentFinancialsInfo = financialStatementInfo
				.getDependentFinancialsList().getDependentFinancials()
				.iterator().next();
		AssetInfo assetInfo = dependentFinancialsInfo.getAssets().getAsset()
				.iterator().next();
		assetInfo.setAssetType(AssetType.CODE_REAL_ESTATE.getCode());

		assetInfo.setAmount(null);
		BindException errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);
		boolean hasError0211 = contain(errors, ErrorCode.VOA_0211);

		assertTrue(hasError0211);

		assetInfo.setAmount(new BigDecimal(-9999));

		errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);

		assertEquals(errors.getErrorCount(), 1);

		boolean hasError0212 = contain(errors, ErrorCode.VOA_0212);

		assertTrue(hasError0212);

		assetInfo.setAmount(new BigDecimal(10000000));
		errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);
		hasError0212 = contain(errors, ErrorCode.VOA_0212);

		assertTrue(hasError0212);
	}

	public void testDependentOtherAsset() throws Exception {
		FinancialStatementInfo financialStatementInfo = form.getSummary()
				.getFinancialsInfo().getFinancialStatement();
		DependentFinancialsInfo dependentFinancialsInfo = financialStatementInfo
				.getDependentFinancialsList().getDependentFinancials()
				.iterator().next();
		AssetInfo assetInfo = dependentFinancialsInfo.getAssets().getAsset()
				.iterator().next();
		assetInfo.setAssetType(AssetType.CODE_OTHER.getCode());

		assetInfo.setAmount(null);
		BindException errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);
		boolean hasError0220 = contain(errors, ErrorCode.VOA_0220);

		assertTrue(hasError0220);

		assetInfo.setAmount(new BigDecimal(-9999));

		errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);

		assertEquals(errors.getErrorCount(), 1);

		boolean hasError0221 = contain(errors, ErrorCode.VOA_0221);

		assertTrue(hasError0221);

		assetInfo.setAmount(new BigDecimal(10000000));
		errors = new BindException(assetInfo, "assetInfo");
		formValidator.validate(form, errors);
		hasError0221 = contain(errors, ErrorCode.VOA_0221);

		assertTrue(hasError0221);
	}

	public void testEmployment() throws Exception {
		BindException errors = new BindException(form, "form");

		FinancialStatementInfo financialStatementInfo = form.getSummary()
				.getFinancialsInfo().getFinancialStatement();
		SpouseFinancialsCollection spouseFinancialsCollection = financialStatementInfo
				.getSpouseFinancialsList();
		List<SpouseFinancialsInfo> spouseFinancialsInfoList = spouseFinancialsCollection
				.getSpouseFinancials();

		for (SpouseFinancialsInfo spouseFinancialsInfo : spouseFinancialsInfoList) {
			SpouseInfo spouseInfo = spouseFinancialsInfo.getSpouse();
			ObjectFactory factory = new ObjectFactory();
			EmploymentInfo employmentInfo = factory.createEmploymentInfo();
			spouseInfo.setEmployment(employmentInfo);
			employmentInfo.setEmploymentStatus(EmploymentStatus.CODE_FULL_TIME
					.getCode());
			employmentInfo
					.setEmployerName("Boss --- long illegal name ----------------- wrong wrong wrong wrong wrong wrong ");
			employmentInfo.setEmployerPhone("2142223333x123456");

			AddressInfo addressInfo = factory.createAddressInfo();
			employmentInfo.setEmployerAddress(addressInfo);
			addressInfo.setLine1("");
			addressInfo.setCity(null);
			addressInfo.setState("PK");
			addressInfo.setCountry("USA");
			addressInfo.setZipCode("20as155");
			addressInfo.setZipPlus4("20as155");
			break;
		}

		formValidator.validate(form, errors);

		boolean hasError0093 = contain(errors, ErrorCode.VOA_0093);
		boolean hasError0094 = contain(errors, ErrorCode.VOA_0094);
		boolean hasError0096 = contain(errors, ErrorCode.VOA_0096);
		boolean hasError0098 = contain(errors, ErrorCode.VOA_0098);
		boolean hasError0100 = contain(errors, ErrorCode.VOA_0100);
		boolean hasError0102 = contain(errors, ErrorCode.VOA_0102);
		boolean hasError0235 = contain(errors, ErrorCode.VOA_0235);

		assertTrue(hasError0093 && hasError0094 && hasError0096 && hasError0098
				&& hasError0100 && hasError0235 && hasError0102);

		errors = new BindException(form, "form");

		for (SpouseFinancialsInfo spouseFinancialsInfo : spouseFinancialsInfoList) {
			SpouseInfo spouseInfo = spouseFinancialsInfo.getSpouse();
			ObjectFactory factory = new ObjectFactory();
			EmploymentInfo employmentInfo = factory.createEmploymentInfo();
			spouseInfo.setEmployment(employmentInfo);
			employmentInfo.setEmploymentStatus(EmploymentStatus.CODE_FULL_TIME
					.getCode());
			employmentInfo
					.setEmployerName("Boss --- long illegal name ----------------- wrong wrong wrong wrong wrong wrong ");
			employmentInfo.setEmployerPhone("2142223333");

			AddressInfo addressInfo = factory.createAddressInfo();
			employmentInfo.setEmployerAddress(addressInfo);
			addressInfo
					.setLine1("long line1 line1 line1 line1 line1 line1 line1 line1 line1 line1 line1 line1 line1 line1 ");
			addressInfo
					.setCity("long long long long long long long long long long long long long long long long city");
			addressInfo.setState(null);
			addressInfo.setCountry(Country.CODE_USA.getCode());
			break;
		}

		formValidator.validate(form, errors);

		boolean hasError0095 = contain(errors, ErrorCode.VOA_0095);
		boolean hasError0097 = contain(errors, ErrorCode.VOA_0097);
		boolean hasError0099 = contain(errors, ErrorCode.VOA_0099);
		assertTrue(hasError0095 && hasError0097 && hasError0099);

		errors = new BindException(form, "form");

		for (SpouseFinancialsInfo spouseFinancialsInfo : spouseFinancialsInfoList) {
			SpouseInfo spouseInfo = spouseFinancialsInfo.getSpouse();
			ObjectFactory factory = new ObjectFactory();
			EmploymentInfo employmentInfo = factory.createEmploymentInfo();
			spouseInfo.setEmployment(employmentInfo);
			employmentInfo.setEmploymentStatus(EmploymentStatus.CODE_FULL_TIME
					.getCode());

			AddressInfo addressInfo = factory.createAddressInfo();
			employmentInfo.setEmployerAddress(addressInfo);
			addressInfo.setLine1("address line 1");
			addressInfo.setCity("Dallas");
			addressInfo.setState("TX");
			addressInfo.setCountry(null);
			break;
		}

		formValidator.validate(form, errors);

		boolean hasError0237 = contain(errors, ErrorCode.VOA_0237);
		assertTrue(hasError0237);

		errors = new BindException(form, "form");
		
		for (SpouseFinancialsInfo spouseFinancialsInfo : spouseFinancialsInfoList) {
			SpouseInfo spouseInfo = spouseFinancialsInfo.getSpouse();
			ObjectFactory factory = new ObjectFactory();
			EmploymentInfo employmentInfo = factory.createEmploymentInfo();
			spouseInfo.setEmployment(employmentInfo);
			employmentInfo.setEmploymentStatus(EmploymentStatus.CODE_FULL_TIME
					.getCode());
			
			AddressInfo addressInfo = factory.createAddressInfo();
			employmentInfo.setEmployerAddress(addressInfo);
			addressInfo.setLine1("address line 1");
			addressInfo.setCity("Dallas");
			addressInfo.setState("TX");
			addressInfo.setCountry("inValidCountry");
			break;
		}
		
		formValidator.validate(form, errors);
		
		boolean hasError0245 = contain(errors, ErrorCode.VOA_0245);
		assertTrue(hasError0245);
	}

	public void testAssociationInfo() throws Exception {
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertFalse(errors.hasErrors());
	}

	public void testDependent() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());

		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertFalse(errors.hasErrors());
	}

	public void testNoFamilyName() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		associationInfo.setFamilyName(null);

		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);
	}

	public void testNoGivenName() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		associationInfo.setGivenName(null);

		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);
	}

	public void testAddreeLine() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		ObjectFactory factory = new ObjectFactory();
		BaseAddressInfo baseAddressInfo = factory.createBaseAddressInfo();
		associationInfo.setAddress(baseAddressInfo);

		baseAddressInfo.setLine1("12344567890123456789012345678901234567890");
		baseAddressInfo.setCity("Dallas");
		baseAddressInfo.setZipCode("75024");
		baseAddressInfo.setState("TX");
		baseAddressInfo.setCountry("USA");

		associationInfo.setAddress(baseAddressInfo);
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);
	}

	public void testCity() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		ObjectFactory factory = new ObjectFactory();
		BaseAddressInfo baseAddressInfo = factory.createBaseAddressInfo();
		associationInfo.setAddress(baseAddressInfo);

		baseAddressInfo.setLine1("12344567890123456789");
		baseAddressInfo.setCity("Dallas - 123456789012345678901234567890");
		baseAddressInfo.setZipCode("75024");
		baseAddressInfo.setState("TX");
		baseAddressInfo.setCountry("USA");

		associationInfo.setAddress(baseAddressInfo);
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);
	}

	public void testPrimPhone() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		associationInfo.setPrimaryPhone("123");
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);
	}

	public void testCellPhone() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		associationInfo.setAlternatePhone("123");
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);
	}

	public void testRelationship() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		associationInfo.setRelationship(Relationship.CODE_BROTHER.getCode());
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 0);
	}

	public void testInvalidRelationship() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		associationInfo.setRelationship("00--00");
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);
	}
	
	public void testAppDate() throws Exception {
		
		form.getFormIdentifier();

		XMLGregorianCalendar existingAppDate = null;
		ApplicationCollection applicationCollection = form.getApplications();
		
		List<ApplicationInfo> applicationInfoList = applicationCollection.getApplicationInfo();

		for (ApplicationInfo applicationInfo : applicationInfoList) {
			existingAppDate = applicationInfo.getAppDate();
			applicationInfo.setAppDate(null);
		}

		BindException errors = new BindException(form, "form");
		formValidator.validate(form, errors);
		
		assertEquals(errors.getErrorCount(), 1);		

		boolean hasError0248 = contain(errors, ErrorCode.VOA_0248);

		assertTrue(hasError0248);
		
		for (ApplicationInfo applicationInfo : applicationInfoList) {
			applicationInfo.setAppDate(existingAppDate);
		}

	}
	
}
