// Generated by: hibernate/SpringHibernateDaoImpl.vsl in andromda-spring-cartridge.
// license-header java merge-point
/**
 * This is only generated once! It will never be overwritten.
 * You can (and have to!) safely modify it by hand.
 */
package org.phoenixctms.ctsms.domain;

import java.awt.Dimension;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Subqueries;
import org.phoenixctms.ctsms.enumeration.DBModule;
import org.phoenixctms.ctsms.enumeration.FileModule;
import org.phoenixctms.ctsms.enumeration.PaymentMethod;
import org.phoenixctms.ctsms.enumeration.VariablePeriod;
import org.phoenixctms.ctsms.query.CategoryCriterion;
import org.phoenixctms.ctsms.query.CategoryCriterion.EmptyPrefixModes;
import org.phoenixctms.ctsms.query.CriteriaUtil;
import org.phoenixctms.ctsms.query.QueryUtil;
import org.phoenixctms.ctsms.query.SubCriteriaMap;
import org.phoenixctms.ctsms.security.CipherText;
import org.phoenixctms.ctsms.security.CryptoUtil;
import org.phoenixctms.ctsms.security.reencrypt.DataReEncrypter;
import org.phoenixctms.ctsms.security.reencrypt.FieldReEncrypter;
import org.phoenixctms.ctsms.security.reencrypt.ReEncrypter;
import org.phoenixctms.ctsms.util.CommonUtil;
import org.phoenixctms.ctsms.util.CoreUtil;
import org.phoenixctms.ctsms.util.DefaultSettings;
import org.phoenixctms.ctsms.util.SettingCodes;
import org.phoenixctms.ctsms.util.Settings;
import org.phoenixctms.ctsms.util.Settings.Bundle;
import org.phoenixctms.ctsms.vo.CriteriaInstantVO;
import org.phoenixctms.ctsms.vo.DepartmentVO;
import org.phoenixctms.ctsms.vo.PSFVO;
import org.phoenixctms.ctsms.vo.PrivacyConsentStatusTypeVO;
import org.phoenixctms.ctsms.vo.ProbandCategoryVO;
import org.phoenixctms.ctsms.vo.ProbandImageInVO;
import org.phoenixctms.ctsms.vo.ProbandImageOutVO;
import org.phoenixctms.ctsms.vo.ProbandInVO;
import org.phoenixctms.ctsms.vo.ProbandOutVO;
import org.phoenixctms.ctsms.vo.StaffOutVO;
import org.phoenixctms.ctsms.vo.UserOutVO;
import org.phoenixctms.ctsms.vocycle.ProbandReflexionGraph;

/**
 * @see Proband
 */
public class ProbandDaoImpl
		extends ProbandDaoBase {

	private final static Collection<ReEncrypter<Proband>> RE_ENCRYPTERS = new ArrayList<ReEncrypter<Proband>>();
	static {
		RE_ENCRYPTERS.add(new DataReEncrypter<Proband>() {

			@Override
			protected byte[] getIv(Proband item) {
				return item.getPersonParticulars().getPrefixedTitle1Iv();
			}

			@Override
			protected byte[] getEncrypted(Proband item) {
				return item.getPersonParticulars().getEncryptedPrefixedTitle1();
			}

			@Override
			protected void setIv(Proband item, byte[] iv) {
				item.getPersonParticulars().setPrefixedTitle1Iv(iv);
			}

			@Override
			protected void setEncrypted(Proband item, byte[] cipherText) {
				item.getPersonParticulars().setEncryptedPrefixedTitle1(cipherText);
			}

			@Override
			protected boolean isSkip(Proband item) {
				return !(item.isPerson() && item.getPersonParticulars() != null);
			}
		});
		RE_ENCRYPTERS.add(new DataReEncrypter<Proband>() {

			@Override
			protected byte[] getIv(Proband item) {
				return item.getPersonParticulars().getPrefixedTitle2Iv();
			}

			@Override
			protected byte[] getEncrypted(Proband item) {
				return item.getPersonParticulars().getEncryptedPrefixedTitle2();
			}

			@Override
			protected void setIv(Proband item, byte[] iv) {
				item.getPersonParticulars().setPrefixedTitle2Iv(iv);
			}

			@Override
			protected void setEncrypted(Proband item, byte[] cipherText) {
				item.getPersonParticulars().setEncryptedPrefixedTitle2(cipherText);
			}

			@Override
			protected boolean isSkip(Proband item) {
				return !(item.isPerson() && item.getPersonParticulars() != null);
			}
		});
		RE_ENCRYPTERS.add(new DataReEncrypter<Proband>() {

			@Override
			protected byte[] getIv(Proband item) {
				return item.getPersonParticulars().getPrefixedTitle3Iv();
			}

			@Override
			protected byte[] getEncrypted(Proband item) {
				return item.getPersonParticulars().getEncryptedPrefixedTitle3();
			}

			@Override
			protected void setIv(Proband item, byte[] iv) {
				item.getPersonParticulars().setPrefixedTitle3Iv(iv);
			}

			@Override
			protected void setEncrypted(Proband item, byte[] cipherText) {
				item.getPersonParticulars().setEncryptedPrefixedTitle3(cipherText);
			}

			@Override
			protected boolean isSkip(Proband item) {
				return !(item.isPerson() && item.getPersonParticulars() != null);
			}
		});
		RE_ENCRYPTERS.add(new FieldReEncrypter<Proband>() {

			@Override
			protected byte[] getIv(Proband item) {
				return item.getPersonParticulars().getFirstNameIv();
			}

			@Override
			protected byte[] getEncrypted(Proband item) {
				return item.getPersonParticulars().getEncryptedFirstName();
			}

			@Override
			protected void setIv(Proband item, byte[] iv) {
				item.getPersonParticulars().setFirstNameIv(iv);
			}

			@Override
			protected void setEncrypted(Proband item, byte[] cipherText) {
				item.getPersonParticulars().setEncryptedFirstName(cipherText);
			}

			@Override
			protected void setHash(Proband item, byte[] hash) {
				item.getPersonParticulars().setFirstNameHash(hash);
			}

			@Override
			protected boolean isSkip(Proband item) {
				return !(item.isPerson() && item.getPersonParticulars() != null);
			}
		});
		RE_ENCRYPTERS.add(new FieldReEncrypter<Proband>() {

			@Override
			protected byte[] getIv(Proband item) {
				return item.getPersonParticulars().getLastNameIv();
			}

			@Override
			protected byte[] getEncrypted(Proband item) {
				return item.getPersonParticulars().getEncryptedLastName();
			}

			@Override
			protected void setIv(Proband item, byte[] iv) {
				item.getPersonParticulars().setLastNameIv(iv);
			}

			@Override
			protected void setEncrypted(Proband item, byte[] cipherText) {
				item.getPersonParticulars().setEncryptedLastName(cipherText);
			}

			@Override
			protected void setHash(Proband item, byte[] hash) {
				item.getPersonParticulars().setLastNameHash(hash);
			}

			@Override
			protected boolean isSkip(Proband item) {
				return !(item.isPerson() && item.getPersonParticulars() != null);
			}
		});
		RE_ENCRYPTERS.add(new DataReEncrypter<Proband>() {

			@Override
			protected byte[] getIv(Proband item) {
				return item.getPersonParticulars().getPostpositionedTitle1Iv();
			}

			@Override
			protected byte[] getEncrypted(Proband item) {
				return item.getPersonParticulars().getEncryptedPostpositionedTitle1();
			}

			@Override
			protected void setIv(Proband item, byte[] iv) {
				item.getPersonParticulars().setPostpositionedTitle1Iv(iv);
			}

			@Override
			protected void setEncrypted(Proband item, byte[] cipherText) {
				item.getPersonParticulars().setEncryptedPostpositionedTitle1(cipherText);
			}

			@Override
			protected boolean isSkip(Proband item) {
				return !(item.isPerson() && item.getPersonParticulars() != null);
			}
		});
		RE_ENCRYPTERS.add(new DataReEncrypter<Proband>() {

			@Override
			protected byte[] getIv(Proband item) {
				return item.getPersonParticulars().getPostpositionedTitle2Iv();
			}

			@Override
			protected byte[] getEncrypted(Proband item) {
				return item.getPersonParticulars().getEncryptedPostpositionedTitle2();
			}

			@Override
			protected void setIv(Proband item, byte[] iv) {
				item.getPersonParticulars().setPostpositionedTitle2Iv(iv);
			}

			@Override
			protected void setEncrypted(Proband item, byte[] cipherText) {
				item.getPersonParticulars().setEncryptedPostpositionedTitle2(cipherText);
			}

			@Override
			protected boolean isSkip(Proband item) {
				return !(item.isPerson() && item.getPersonParticulars() != null);
			}
		});
		RE_ENCRYPTERS.add(new DataReEncrypter<Proband>() {

			@Override
			protected byte[] getIv(Proband item) {
				return item.getPersonParticulars().getPostpositionedTitle3Iv();
			}

			@Override
			protected byte[] getEncrypted(Proband item) {
				return item.getPersonParticulars().getEncryptedPostpositionedTitle3();
			}

			@Override
			protected void setIv(Proband item, byte[] iv) {
				item.getPersonParticulars().setPostpositionedTitle3Iv(iv);
			}

			@Override
			protected void setEncrypted(Proband item, byte[] cipherText) {
				item.getPersonParticulars().setEncryptedPostpositionedTitle3(cipherText);
			}

			@Override
			protected boolean isSkip(Proband item) {
				return !(item.isPerson() && item.getPersonParticulars() != null);
			}
		});
		RE_ENCRYPTERS.add(new FieldReEncrypter<Proband>() {

			@Override
			protected byte[] getIv(Proband item) {
				return item.getPersonParticulars().getDateOfBirthIv();
			}

			@Override
			protected byte[] getEncrypted(Proband item) {
				return item.getPersonParticulars().getEncryptedDateOfBirth();
			}

			@Override
			protected void setIv(Proband item, byte[] iv) {
				item.getPersonParticulars().setDateOfBirthIv(iv);
			}

			@Override
			protected void setEncrypted(Proband item, byte[] cipherText) {
				item.getPersonParticulars().setEncryptedDateOfBirth(cipherText);
			}

			@Override
			protected void setHash(Proband item, byte[] hash) {
				item.getPersonParticulars().setDateOfBirthHash(hash);
			}

			@Override
			protected boolean isSkip(Proband item) {
				return !(item.isPerson() && item.getPersonParticulars() != null);
			}
		});
		RE_ENCRYPTERS.add(new FieldReEncrypter<Proband>() {

			@Override
			protected byte[] getIv(Proband item) {
				return item.getPersonParticulars().getCitizenshipIv();
			}

			@Override
			protected byte[] getEncrypted(Proband item) {
				return item.getPersonParticulars().getEncryptedCitizenship();
			}

			@Override
			protected void setIv(Proband item, byte[] iv) {
				item.getPersonParticulars().setCitizenshipIv(iv);
			}

			@Override
			protected void setEncrypted(Proband item, byte[] cipherText) {
				item.getPersonParticulars().setEncryptedCitizenship(cipherText);
			}

			@Override
			protected void setHash(Proband item, byte[] hash) {
				item.getPersonParticulars().setCitizenshipHash(hash);
			}

			@Override
			protected boolean isSkip(Proband item) {
				return !(item.isPerson() && item.getPersonParticulars() != null);
			}
		});
		RE_ENCRYPTERS.add(new FieldReEncrypter<Proband>() {

			@Override
			protected byte[] getIv(Proband item) {
				return item.getPersonParticulars().getCommentIv();
			}

			@Override
			protected byte[] getEncrypted(Proband item) {
				return item.getPersonParticulars().getEncryptedComment();
			}

			@Override
			protected void setIv(Proband item, byte[] iv) {
				item.getPersonParticulars().setCommentIv(iv);
			}

			@Override
			protected void setEncrypted(Proband item, byte[] cipherText) {
				item.getPersonParticulars().setEncryptedComment(cipherText);
			}

			@Override
			protected void setHash(Proband item, byte[] hash) {
				item.getPersonParticulars().setCommentHash(hash);
			}

			@Override
			protected boolean isSkip(Proband item) {
				return !(item.isPerson() && item.getPersonParticulars() != null);
			}
		});
		RE_ENCRYPTERS.add(new DataReEncrypter<Proband>() {

			@Override
			protected byte[] getIv(Proband item) {
				return item.getPersonParticulars().getDataIv();
			}

			@Override
			protected byte[] getEncrypted(Proband item) {
				return item.getPersonParticulars().getEncryptedData();
			}

			@Override
			protected void setIv(Proband item, byte[] iv) {
				item.getPersonParticulars().setDataIv(iv);
			}

			@Override
			protected void setEncrypted(Proband item, byte[] cipherText) {
				item.getPersonParticulars().setEncryptedData(cipherText);
			}

			@Override
			protected boolean isSkip(Proband item) {
				return !(item.isPerson() && item.getPersonParticulars() != null && getEncrypted(item) != null);
			}
		});
		RE_ENCRYPTERS.add(new FieldReEncrypter<Proband>() {

			@Override
			protected byte[] getIv(Proband item) {
				return item.getPersonParticulars().getFileNameIv();
			}

			@Override
			protected byte[] getEncrypted(Proband item) {
				return item.getPersonParticulars().getEncryptedFileName();
			}

			@Override
			protected void setIv(Proband item, byte[] iv) {
				item.getPersonParticulars().setFileNameIv(iv);
			}

			@Override
			protected void setEncrypted(Proband item, byte[] cipherText) {
				item.getPersonParticulars().setEncryptedFileName(cipherText);
			}

			@Override
			protected void setHash(Proband item, byte[] hash) {
				item.getPersonParticulars().setFileNameHash(hash);
			}

			@Override
			protected boolean isSkip(Proband item) {
				return !(item.isPerson() && item.getPersonParticulars() != null && getEncrypted(item) != null);
			}
		});
	}

	@Override
	protected Collection<ReEncrypter<Proband>> getReEncrypters() {
		return RE_ENCRYPTERS;
	}

	@Override
	protected long handleGetCountByAlias(boolean person, String aliasPattern) throws Exception {
		org.hibernate.Criteria probandCriteria = createProbandCriteria(null);
		org.hibernate.Criteria particularsCriteria;
		if (person) {
			particularsCriteria = probandCriteria.createCriteria("personParticulars");
		} else {
			particularsCriteria = probandCriteria.createCriteria("animalParticulars");
		}
		particularsCriteria.add(Restrictions.like("alias", aliasPattern, MatchMode.EXACT));
		return (Long) probandCriteria.setProjection(Projections.rowCount()).uniqueResult();
	}

	@Override
	protected Proband handleFindByMaxAlias(boolean person, String aliasPattern) throws Exception {
		org.hibernate.Criteria probandCriteria = createProbandCriteria(null);
		org.hibernate.Criteria particularsCriteria;
		if (person) {
			particularsCriteria = probandCriteria.createCriteria("personParticulars", "particulars");
		} else {
			particularsCriteria = probandCriteria.createCriteria("animalParticulars", "particulars");
		}
		particularsCriteria.add(Restrictions.like("alias", aliasPattern, MatchMode.EXACT));
		probandCriteria.addOrder(Order.desc("particulars.alias"));
		probandCriteria.setMaxResults(1);
		return (Proband) probandCriteria.uniqueResult();
	}

	private org.hibernate.Criteria createProbandCriteria(String alias) {
		org.hibernate.Criteria probandCriteria;
		if (alias != null && alias.length() > 0) {
			probandCriteria = this.getSession().createCriteria(Proband.class, alias);
		} else {
			probandCriteria = this.getSession().createCriteria(Proband.class);
		}
		return probandCriteria;
	}

	@Override
	protected Collection<Proband> handleFindByCriteria(
			CriteriaInstantVO criteria, PSFVO psf) throws Exception {
		Query query = QueryUtil.createSearchQuery(
				criteria,
				DBModule.PROBAND_DB,
				psf,
				this.getSessionFactory(),
				this.getCriterionTieDao(),
				this.getCriterionPropertyDao(),
				this.getCriterionRestrictionDao());
		return query.list();
	}

	@Override
	protected Collection<Proband> handleFindByInquiryValuesTrial(Long departmentId, Long trialId, Boolean active, Boolean activeSignup, PSFVO psf) throws Exception {
		org.hibernate.Criteria probandCriteria = createProbandCriteria(null);
		SubCriteriaMap criteriaMap = new SubCriteriaMap(Proband.class, probandCriteria);
		if (departmentId != null) {
			criteriaMap.createCriteria("department").add(Restrictions.idEq(departmentId.longValue()));
		}
		org.hibernate.Criteria inquiryCriteria = criteriaMap.createCriteria("inquiryValues.inquiry");
		inquiryCriteria.add(Restrictions.eq("trial.id", trialId.longValue()));
		if (active != null) {
			inquiryCriteria.add(Restrictions.eq("active", active.booleanValue()));
		}
		if (activeSignup != null) {
			inquiryCriteria.add(Restrictions.eq("activeSignup", activeSignup.booleanValue()));
		}
		return CriteriaUtil.listDistinctRootPSFVO(criteriaMap, psf, this);
	}

	@Override
	protected Collection<Proband> handleFindByIdDepartment(Long probandId,
			Long departmentId, PSFVO psf) throws Exception {
		org.hibernate.Criteria probandCriteria = createProbandCriteria(null);
		SubCriteriaMap criteriaMap = new SubCriteriaMap(Proband.class, probandCriteria);
		CriteriaUtil.applyIdDepartmentCriterion(probandCriteria, probandId, departmentId);
		CriteriaUtil.applyPSFVO(criteriaMap, psf);
		return probandCriteria.list();
	}

	@Override
	protected Collection<Proband> handleFindByMoneyTransferNoParticipation(Long trialId,
			PaymentMethod method, String costType, Boolean paid, boolean total,
			Boolean person, PSFVO psf)
			throws Exception {
		org.hibernate.Criteria probandCriteria = createProbandCriteria("proband0");
		if (person != null) {
			probandCriteria.add(Restrictions.eq("person", person.booleanValue()));
		}
		SubCriteriaMap criteriaMap = new SubCriteriaMap(Proband.class, probandCriteria);
		Criteria moneyTransferCriteria = criteriaMap.createCriteria("moneyTransfers");
		moneyTransferCriteria.add(Restrictions.eq("trial.id", trialId.longValue()));
		if (method != null) {
			moneyTransferCriteria.add(Restrictions.eq("method", method));
		}
		if (paid != null) {
			moneyTransferCriteria.add(Restrictions.eq("paid", paid.booleanValue()));
		}
		CategoryCriterion.apply(moneyTransferCriteria, new CategoryCriterion(costType, "costType", MatchMode.EXACT, EmptyPrefixModes.ALL_ROWS));
		DetachedCriteria subQuery = DetachedCriteria.forClass(ProbandListEntryImpl.class, "probandListEntry"); // IMPL!!!!
		subQuery.setProjection(Projections.rowCount());
		subQuery.add(Restrictions.eqProperty("proband.id", "proband0.id"));
		subQuery.add(Restrictions.eq("trial.id", trialId.longValue()));
		if (!total) {
			subQuery.createCriteria("lastStatus", CriteriaSpecification.INNER_JOIN).createCriteria("status", CriteriaSpecification.INNER_JOIN)
					.add(Restrictions.eq("count", true));
		}
		probandCriteria.add(Subqueries.eq(0l, subQuery));
		return CriteriaUtil.listDistinctRootPSFVO(criteriaMap, psf, this);
	}

	@Override
	protected Collection<Staff> handleFindByPhysician(Long staffId, PSFVO psf) throws Exception {
		org.hibernate.Criteria probandCriteria = createProbandCriteria(null);
		SubCriteriaMap criteriaMap = new SubCriteriaMap(Proband.class, probandCriteria);
		if (staffId != null) {
			probandCriteria.add(Restrictions.eq("physician.id", staffId.longValue()));
		}
		CriteriaUtil.applyPSFVO(criteriaMap, psf);
		return probandCriteria.list();
	}

	@Override
	protected Collection<Proband> handleFindToBeAutoDeleted(Date today, Long departmentId, Long categoryId, VariablePeriod reminderPeriod, Long reminderPeriodDays, Boolean delete,
			boolean includeAlreadyPassed,
			PSFVO psf)
			throws Exception {
		org.hibernate.Criteria probandCriteria = createProbandCriteria(null);
		SubCriteriaMap criteriaMap = new SubCriteriaMap(Proband.class, probandCriteria);
		if (departmentId != null) {
			probandCriteria.add(Restrictions.eq("department.id", departmentId.longValue()));
		}
		org.hibernate.Criteria categoryCriteria = criteriaMap.createCriteria("category");
		if (categoryId != null) {
			categoryCriteria.add(Restrictions.eq("id", categoryId.longValue()));
		}
		categoryCriteria.add(Restrictions.eq("privacyConsentControl", true)); // performance only...
		if (delete != null) {
			categoryCriteria.add(Restrictions.eq("delete", delete.booleanValue()));
		}
		criteriaMap.createCriteria("privacyConsentStatus").add(Restrictions.eq("autoDelete", true)); // performance only...
		if (psf != null) {
			PSFVO sorterFilter = new PSFVO();
			sorterFilter.setFilters(psf.getFilters());
			sorterFilter.setSortField(psf.getSortField());
			sorterFilter.setSortOrder(psf.getSortOrder());
			CriteriaUtil.applyPSFVO(criteriaMap, sorterFilter);
		}
		ArrayList<Proband> resultSet = CriteriaUtil.listExpirations(probandCriteria, today, null, includeAlreadyPassed, null, null, reminderPeriod, reminderPeriodDays);
		return CriteriaUtil.applyPVO(resultSet, psf, false); // no dupes by default
	}

	@Override
	protected long handleGetChildrenCount(Long probandId) throws Exception {
		org.hibernate.Criteria probandCriteria = createProbandCriteria(null);
		probandCriteria.add(Restrictions.idEq(probandId.longValue()));
		org.hibernate.Criteria parentsCriteria = probandCriteria.createCriteria("parents", CriteriaSpecification.INNER_JOIN);
		return (Long) parentsCriteria.setProjection(Projections.rowCount()).uniqueResult();
	}

	@Override
	protected long handleGetCountByCriteria(CriteriaInstantVO criteria, PSFVO psf) throws Exception {
		return QueryUtil.getSearchQueryResultCount(
				criteria,
				DBModule.PROBAND_DB,
				psf,
				this.getSessionFactory(),
				this.getCriterionTieDao(),
				this.getCriterionPropertyDao(),
				this.getCriterionRestrictionDao());
	}

	@Override
	protected long handleGetParentsCount(Long probandId) throws Exception {
		org.hibernate.Criteria probandCriteria = createProbandCriteria(null);
		probandCriteria.add(Restrictions.idEq(probandId.longValue()));
		org.hibernate.Criteria childrenCriteria = probandCriteria.createCriteria("children", CriteriaSpecification.INNER_JOIN);
		return (Long) childrenCriteria.setProjection(Projections.rowCount()).uniqueResult();
	}

	/**
	 * Retrieves the entity object that is associated with the specified value object
	 * from the object store. If no such entity object exists in the object store,
	 * a new, blank entity is created
	 */
	private Proband loadProbandFromProbandImageInVO(ProbandImageInVO probandImageInVO) {
		Long id = probandImageInVO.getId();
		Proband proband = null;
		if (id != null) {
			proband = this.load(id);
		}
		if (proband == null) {
			proband = Proband.Factory.newInstance();
		}
		return proband;
	}

	/**
	 * Retrieves the entity object that is associated with the specified value object
	 * from the object store. If no such entity object exists in the object store,
	 * a new, blank entity is created
	 */
	private Proband loadProbandFromProbandImageOutVO(ProbandImageOutVO probandImageOutVO) {
		throw new UnsupportedOperationException("org.phoenixctms.ctsms.domain.loadProbandFromProbandImageOutVO(ProbandImageOutVO) not yet implemented.");
	}

	/**
	 * Retrieves the entity object that is associated with the specified value object
	 * from the object store. If no such entity object exists in the object store,
	 * a new, blank entity is created
	 */
	private Proband loadProbandFromProbandInVO(ProbandInVO probandInVO) {
		Proband proband = null;
		Long id = probandInVO.getId();
		if (id != null) {
			proband = this.load(id);
		}
		if (proband == null) {
			proband = Proband.Factory.newInstance();
		}
		return proband;
	}

	/**
	 * Retrieves the entity object that is associated with the specified value object
	 * from the object store. If no such entity object exists in the object store,
	 * a new, blank entity is created
	 */
	private Proband loadProbandFromProbandOutVO(ProbandOutVO probandOutVO) {
		Proband proband = this.load(probandOutVO.getId());
		if (proband == null) {
			proband = Proband.Factory.newInstance();
		}
		return proband;
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public Proband probandImageInVOToEntity(ProbandImageInVO probandImageInVO) {
		Proband entity = this.loadProbandFromProbandImageInVO(probandImageInVO);
		this.probandImageInVOToEntity(probandImageInVO, entity, true);
		return entity;
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public void probandImageInVOToEntity(
			ProbandImageInVO source,
			Proband target,
			boolean copyIfNull) {
		super.probandImageInVOToEntity(source, target, copyIfNull);
		ProbandContactParticulars personParticulars = null;
		if (target.isPerson()) {
			personParticulars = target.getPersonParticulars();
			if (personParticulars == null) {
				personParticulars = ProbandContactParticulars.Factory.newInstance();
				target.setPersonParticulars(personParticulars);
			}
		} else if (copyIfNull) {
			target.setPersonParticulars(null);
		}
		if (personParticulars != null) {
			try {
				if (copyIfNull || source.getFileName() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getFileName());
					personParticulars.setFileNameIv(cipherText.getIv());
					personParticulars.setEncryptedFileName(cipherText.getCipherText());
				}
				if (copyIfNull || source.getFileTimestamp() != null) {
					personParticulars.setFileTimestamp((source.getFileTimestamp() == null ? null : new Timestamp(source.getFileTimestamp().getTime())));
				}
				if (source.getDatas() != null && source.getDatas().length > 0) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getDatas());
					personParticulars.setDataIv(cipherText.getIv());
					personParticulars.setEncryptedData(cipherText.getCipherText());
					personParticulars.setFileSize((long) source.getDatas().length);
					personParticulars.setContentType(this.getMimeTypeDao().findByMimeTypeModule(source.getMimeType(), FileModule.PROBAND_IMAGE).iterator().next());
					Dimension imageDimension = CoreUtil.getImageDimension(source.getDatas());
					if (imageDimension != null) {
						personParticulars.setWidth((long) imageDimension.width);
						personParticulars.setHeight((long) imageDimension.height);
					}
				} else if (copyIfNull) {
					CipherText cipherText = CryptoUtil.encryptValue(null);
					personParticulars.setDataIv(cipherText.getIv());
					personParticulars.setEncryptedData(cipherText.getCipherText());
					personParticulars.setFileSize(0l);
					personParticulars.setContentType(null);
					personParticulars.setWidth(null);
					personParticulars.setHeight(null);
				}
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		AnimalContactParticulars animalParticulars = null;
		if (!target.isPerson()) {
			animalParticulars = target.getAnimalParticulars();
			if (animalParticulars == null) {
				animalParticulars = AnimalContactParticulars.Factory.newInstance();
				target.setAnimalParticulars(animalParticulars);
			}
		} else if (copyIfNull) {
			target.setAnimalParticulars(null);
		}
		if (animalParticulars != null) {
			if (copyIfNull || source.getFileName() != null) {
				animalParticulars.setFileName(source.getFileName());
			}
			if (copyIfNull || source.getFileTimestamp() != null) {
				animalParticulars.setFileTimestamp((source.getFileTimestamp() == null ? null : new Timestamp(source.getFileTimestamp().getTime())));
			}
			if (source.getDatas() != null && source.getDatas().length > 0) {
				animalParticulars.setData(source.getDatas());
				animalParticulars.setFileSize((long) source.getDatas().length);
				animalParticulars.setContentType(this.getMimeTypeDao().findByMimeTypeModule(source.getMimeType(), FileModule.PROBAND_IMAGE).iterator().next());
				Dimension imageDimension = CoreUtil.getImageDimension(source.getDatas());
				if (imageDimension != null) {
					animalParticulars.setWidth((long) imageDimension.width);
					animalParticulars.setHeight((long) imageDimension.height);
				}
			} else if (copyIfNull) {
				animalParticulars.setData(null);
				animalParticulars.setFileSize(0l);
				animalParticulars.setContentType(null);
				animalParticulars.setWidth(null);
				animalParticulars.setHeight(null);
			}
		}
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public Proband probandImageOutVOToEntity(ProbandImageOutVO probandImageOutVO) {
		Proband entity = this.loadProbandFromProbandImageOutVO(probandImageOutVO);
		this.probandImageOutVOToEntity(probandImageOutVO, entity, true);
		return entity;
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public void probandImageOutVOToEntity(
			ProbandImageOutVO source,
			Proband target,
			boolean copyIfNull) {
		super.probandImageOutVOToEntity(source, target, copyIfNull);
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public Proband probandInVOToEntity(ProbandInVO probandInVO) {
		Proband entity = this.loadProbandFromProbandInVO(probandInVO);
		this.probandInVOToEntity(probandInVO, entity, true);
		return entity;
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public void probandInVOToEntity(
			ProbandInVO source,
			Proband target,
			boolean copyIfNull) {
		super.probandInVOToEntity(source, target, copyIfNull);
		Long departmentId = source.getDepartmentId();
		Long physicianId = source.getPhysicianId();
		Long categoryId = source.getCategoryId();
		if (departmentId != null) {
			target.setDepartment(this.getDepartmentDao().load(departmentId));
		} else if (copyIfNull) {
			target.setDepartment(null);
		}
		if (categoryId != null) {
			target.setCategory(this.getProbandCategoryDao().load(categoryId));
		} else if (copyIfNull) {
			target.setCategory(null);
		}
		if (physicianId != null) {
			Staff physician = this.getStaffDao().load(physicianId);
			target.setPhysician(physician);
			physician.addPatients(target);
		} else if (copyIfNull) {
			Staff physician = target.getPhysician();
			target.setPhysician(null);
			if (physician != null) {
				physician.removePatients(target);
			}
		}
		if (copyIfNull || source.getChildIds().size() > 0) {
			Iterator<Proband> it = target.getChildren().iterator();
			while (it.hasNext()) {
				it.next().removeParents(target);
			}
			target.setChildren(toProbandSet(source.getChildIds()));
		}
		ProbandContactParticulars personParticulars = target.getPersonParticulars();
		if (source.isPerson()) {
			if (personParticulars == null) {
				personParticulars = ProbandContactParticulars.Factory.newInstance();
				target.setPersonParticulars(personParticulars);
			}
		} else if (copyIfNull) {
			target.setPersonParticulars(null);
		}
		if (personParticulars != null) {
			try {
				CipherText cipherText = CryptoUtil.encryptValue(null);
				personParticulars.setFileNameIv(cipherText.getIv());
				personParticulars.setEncryptedFileName(cipherText.getCipherText());
				cipherText = CryptoUtil.encryptValue(null);
				personParticulars.setDataIv(cipherText.getIv());
				personParticulars.setEncryptedData(cipherText.getCipherText());
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
			if (copyIfNull || source.getGender() != null) {
				personParticulars.setGender(source.getGender());
			}
			if (source.getDateOfBirth() != null) {
				personParticulars.setYearOfBirth(new Long(CommonUtil.getYearOfBirth(source.getDateOfBirth())));
			} else if (copyIfNull) {
				personParticulars.setYearOfBirth(null);
			}
			if (source.getLastName() != null) {
				int probandLastNameIndexLength = Settings.getInt(SettingCodes.PROBAND_LAST_NAME_INDEX_LENGTH, Bundle.SETTINGS, DefaultSettings.PROBAND_LAST_NAME_INDEX_LENGTH);
				personParticulars.setLastNameIndex(source.getLastName().substring(0, probandLastNameIndexLength < 0 ? 0 : probandLastNameIndexLength));
			} else if (copyIfNull) {
				personParticulars.setLastNameIndex(null);
			}
			if (copyIfNull || source.getAlias() != null) {
				personParticulars.setAlias(source.getAlias());
			}
			try {
				if (copyIfNull || source.getPrefixedTitle1() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getPrefixedTitle1());
					personParticulars.setPrefixedTitle1Iv(cipherText.getIv());
					personParticulars.setEncryptedPrefixedTitle1(cipherText.getCipherText());
				}
				if (copyIfNull || source.getPrefixedTitle2() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getPrefixedTitle2());
					personParticulars.setPrefixedTitle2Iv(cipherText.getIv());
					personParticulars.setEncryptedPrefixedTitle2(cipherText.getCipherText());
				}
				if (copyIfNull || source.getPrefixedTitle3() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getPrefixedTitle3());
					personParticulars.setPrefixedTitle3Iv(cipherText.getIv());
					personParticulars.setEncryptedPrefixedTitle3(cipherText.getCipherText());
				}
				if (copyIfNull || source.getFirstName() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getFirstName());
					personParticulars.setFirstNameIv(cipherText.getIv());
					personParticulars.setEncryptedFirstName(cipherText.getCipherText());
					personParticulars.setFirstNameHash(CryptoUtil.hashForSearch(source.getFirstName()));
				}
				if (copyIfNull || source.getLastName() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getLastName());
					personParticulars.setLastNameIv(cipherText.getIv());
					personParticulars.setEncryptedLastName(cipherText.getCipherText());
					personParticulars.setLastNameHash(CryptoUtil.hashForSearch(source.getLastName()));
				}
				if (copyIfNull || source.getPostpositionedTitle1() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getPostpositionedTitle1());
					personParticulars.setPostpositionedTitle1Iv(cipherText.getIv());
					personParticulars.setEncryptedPostpositionedTitle1(cipherText.getCipherText());
				}
				if (copyIfNull || source.getPostpositionedTitle2() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getPostpositionedTitle2());
					personParticulars.setPostpositionedTitle2Iv(cipherText.getIv());
					personParticulars.setEncryptedPostpositionedTitle2(cipherText.getCipherText());
				}
				if (copyIfNull || source.getPostpositionedTitle3() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getPostpositionedTitle3());
					personParticulars.setPostpositionedTitle3Iv(cipherText.getIv());
					personParticulars.setEncryptedPostpositionedTitle3(cipherText.getCipherText());
				}
				if (copyIfNull || source.getDateOfBirth() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getDateOfBirth());
					personParticulars.setDateOfBirthIv(cipherText.getIv());
					personParticulars.setEncryptedDateOfBirth(cipherText.getCipherText());
					personParticulars.setDateOfBirthHash(CryptoUtil.hashForSearch(source.getDateOfBirth()));
				}
				if (copyIfNull || source.getCitizenship() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getCitizenship());
					personParticulars.setCitizenshipIv(cipherText.getIv());
					personParticulars.setEncryptedCitizenship(cipherText.getCipherText());
					personParticulars.setCitizenshipHash(CryptoUtil.hashForSearch(source.getCitizenship()));
				}
				if (copyIfNull || source.getComment() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getComment());
					personParticulars.setCommentIv(cipherText.getIv());
					personParticulars.setEncryptedComment(cipherText.getCipherText());
					personParticulars.setCommentHash(CryptoUtil.hashForSearch(source.getComment()));
				}
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		AnimalContactParticulars animalParticulars = target.getAnimalParticulars();
		if (!source.isPerson()) {
			if (animalParticulars == null) {
				animalParticulars = AnimalContactParticulars.Factory.newInstance();
				target.setAnimalParticulars(animalParticulars);
			}
		} else if (copyIfNull) {
			target.setAnimalParticulars(null);
		}
		if (animalParticulars != null) {
			if (copyIfNull || source.getAnimalName() != null) {
				animalParticulars.setAnimalName(source.getAnimalName());
			}
			if (copyIfNull || source.getDateOfBirth() != null) {
				animalParticulars.setDateOfBirth(source.getDateOfBirth());
			}
			if (copyIfNull || source.getGender() != null) {
				animalParticulars.setGender(source.getGender());
			}
			if (copyIfNull || source.getComment() != null) {
				animalParticulars.setComment(source.getComment());
			}
			if (copyIfNull || source.getAlias() != null) {
				animalParticulars.setAlias(source.getAlias());
			}
		}
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public Proband probandOutVOToEntity(ProbandOutVO probandOutVO) {
		throw new UnsupportedOperationException("out value object to recursive entity not supported");
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public void probandOutVOToEntity(
			ProbandOutVO source,
			Proband target,
			boolean copyIfNull) {
		super.probandOutVOToEntity(source, target, copyIfNull);
		DepartmentVO departmentVO = source.getDepartment();
		ProbandCategoryVO categoryVO = source.getCategory();
		StaffOutVO physicianVO = source.getPhysician();
		UserOutVO modifiedUserVO = source.getModifiedUser();
		PrivacyConsentStatusTypeVO privacyConsentStatusVO = source.getPrivacyConsentStatus();
		if (departmentVO != null) {
			target.setDepartment(this.getDepartmentDao().departmentVOToEntity(departmentVO));
		} else if (copyIfNull) {
			target.setDepartment(null);
		}
		if (categoryVO != null) {
			target.setCategory(this.getProbandCategoryDao().probandCategoryVOToEntity(categoryVO));
		} else if (copyIfNull) {
			target.setCategory(null);
		}
		if (modifiedUserVO != null) {
			target.setModifiedUser(this.getUserDao().userOutVOToEntity(modifiedUserVO));
		} else if (copyIfNull) {
			target.setModifiedUser(null);
		}
		if (privacyConsentStatusVO != null) {
			target.setPrivacyConsentStatus(this.getPrivacyConsentStatusTypeDao().privacyConsentStatusTypeVOToEntity(privacyConsentStatusVO));
		} else if (copyIfNull) {
			target.setPrivacyConsentStatus(null);
		}
		if (physicianVO != null) {
			Staff physician = this.getStaffDao().staffOutVOToEntity(physicianVO);
			target.setPhysician(physician);
			physician.addPatients(target);
		} else if (copyIfNull) {
			Staff physician = target.getPhysician();
			target.setPhysician(null);
			if (physician != null) {
				physician.removePatients(target);
			}
		}
		ProbandContactParticulars personParticulars = null;
		if (source.isPerson()) {
			personParticulars = target.getPersonParticulars();
			if (personParticulars == null) {
				personParticulars = ProbandContactParticulars.Factory.newInstance();
				target.setPersonParticulars(personParticulars);
			}
		} else if (copyIfNull) {
			target.setPersonParticulars(null);
		}
		if (personParticulars != null) {
			if (copyIfNull || source.getGender() != null) {
				personParticulars.setGender(source.getGender().getSex());
			}
			if (source.getDateOfBirth() != null) {
				personParticulars.setYearOfBirth(new Long(CommonUtil.getYearOfBirth(source.getDateOfBirth())));
			} else if (copyIfNull) {
				personParticulars.setYearOfBirth(null);
			}
			if (source.getLastName() != null) {
				int probandLastNameIndexLength = Settings.getInt(SettingCodes.PROBAND_LAST_NAME_INDEX_LENGTH, Bundle.SETTINGS, DefaultSettings.PROBAND_LAST_NAME_INDEX_LENGTH);
				personParticulars.setLastNameIndex(source.getLastName().substring(0, probandLastNameIndexLength < 0 ? 0 : probandLastNameIndexLength));
			} else if (copyIfNull) {
				personParticulars.setLastNameIndex(null);
			}
			if (copyIfNull || source.getAlias() != null) {
				personParticulars.setAlias(source.getAlias());
			}
			try {
				if (copyIfNull || source.getPrefixedTitle1() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getPrefixedTitle1());
					personParticulars.setPrefixedTitle1Iv(cipherText.getIv());
					personParticulars.setEncryptedPrefixedTitle1(cipherText.getCipherText());
				}
				if (copyIfNull || source.getPrefixedTitle2() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getPrefixedTitle2());
					personParticulars.setPrefixedTitle2Iv(cipherText.getIv());
					personParticulars.setEncryptedPrefixedTitle2(cipherText.getCipherText());
				}
				if (copyIfNull || source.getPrefixedTitle3() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getPrefixedTitle3());
					personParticulars.setPrefixedTitle3Iv(cipherText.getIv());
					personParticulars.setEncryptedPrefixedTitle3(cipherText.getCipherText());
				}
				if (copyIfNull || source.getFirstName() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getFirstName());
					personParticulars.setFirstNameIv(cipherText.getIv());
					personParticulars.setEncryptedFirstName(cipherText.getCipherText());
					personParticulars.setFirstNameHash(CryptoUtil.hashForSearch(source.getFirstName()));
				}
				if (copyIfNull || source.getLastName() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getLastName());
					personParticulars.setLastNameIv(cipherText.getIv());
					personParticulars.setEncryptedLastName(cipherText.getCipherText());
					personParticulars.setLastNameHash(CryptoUtil.hashForSearch(source.getLastName()));
				}
				if (copyIfNull || source.getPostpositionedTitle1() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getPostpositionedTitle1());
					personParticulars.setPostpositionedTitle1Iv(cipherText.getIv());
					personParticulars.setEncryptedPostpositionedTitle1(cipherText.getCipherText());
				}
				if (copyIfNull || source.getPostpositionedTitle2() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getPostpositionedTitle2());
					personParticulars.setPostpositionedTitle2Iv(cipherText.getIv());
					personParticulars.setEncryptedPostpositionedTitle2(cipherText.getCipherText());
				}
				if (copyIfNull || source.getPostpositionedTitle3() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getPostpositionedTitle3());
					personParticulars.setPostpositionedTitle3Iv(cipherText.getIv());
					personParticulars.setEncryptedPostpositionedTitle3(cipherText.getCipherText());
				}
				if (copyIfNull || source.getDateOfBirth() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getDateOfBirth());
					personParticulars.setDateOfBirthIv(cipherText.getIv());
					personParticulars.setEncryptedDateOfBirth(cipherText.getCipherText());
					personParticulars.setDateOfBirthHash(CryptoUtil.hashForSearch(source.getDateOfBirth()));
				}
				if (copyIfNull || source.getCitizenship() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getCitizenship());
					personParticulars.setCitizenshipIv(cipherText.getIv());
					personParticulars.setEncryptedCitizenship(cipherText.getCipherText());
					personParticulars.setCitizenshipHash(CryptoUtil.hashForSearch(source.getCitizenship()));
				}
				if (copyIfNull || source.getComment() != null) {
					CipherText cipherText = CryptoUtil.encryptValue(source.getComment());
					personParticulars.setCommentIv(cipherText.getIv());
					personParticulars.setEncryptedComment(cipherText.getCipherText());
					personParticulars.setCommentHash(CryptoUtil.hashForSearch(source.getComment()));
				}
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		AnimalContactParticulars animalParticulars = null;
		if (!source.isPerson()) {
			animalParticulars = target.getAnimalParticulars();
			if (animalParticulars == null) {
				animalParticulars = AnimalContactParticulars.Factory.newInstance();
				target.setAnimalParticulars(animalParticulars);
			}
		} else if (copyIfNull) {
			target.setAnimalParticulars(null);
		}
		if (animalParticulars != null) {
			if (copyIfNull || source.getAnimalName() != null) {
				animalParticulars.setAnimalName(source.getAnimalName());
			}
			if (copyIfNull || source.getDateOfBirth() != null) {
				animalParticulars.setDateOfBirth(source.getDateOfBirth());
			}
			if (copyIfNull || source.getGender() != null) {
				animalParticulars.setGender(source.getGender().getSex());
			}
			if (copyIfNull || source.getComment() != null) {
				animalParticulars.setComment(source.getComment());
			}
			if (copyIfNull || source.getAlias() != null) {
				animalParticulars.setAlias(source.getAlias());
			}
		}
	}

	private ArrayList<Long> toProbandIdCollection(Collection<Proband> probands) { // lazyload persistentset prevention
		ArrayList<Long> result = new ArrayList<Long>(probands.size());
		Iterator<Proband> it = probands.iterator();
		while (it.hasNext()) {
			result.add(it.next().getId());
		}
		Collections.sort(result); // InVO ID sorting
		return result;
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public ProbandImageInVO toProbandImageInVO(final Proband entity) {
		return super.toProbandImageInVO(entity);
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public void toProbandImageInVO(
			Proband source,
			ProbandImageInVO target) {
		super.toProbandImageInVO(source, target);
		if (source.isPerson()) {
			ProbandContactParticulars personParticulars = source.getPersonParticulars();
			if (personParticulars != null) {
				MimeType contentType = personParticulars.getContentType();
				target.setFileTimestamp(personParticulars.getFileTimestamp());
				if (contentType != null) {
					target.setMimeType(contentType.getMimeType());
				}
				try {
					target.setFileName((String) CryptoUtil.decryptValue(personParticulars.getFileNameIv(), personParticulars.getEncryptedFileName()));
					target.setDatas((byte[]) CryptoUtil.decryptValue(personParticulars.getDataIv(), personParticulars.getEncryptedData()));
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		} else {
			AnimalContactParticulars animalParticulars = source.getAnimalParticulars();
			if (animalParticulars != null) {
				MimeType contentType = animalParticulars.getContentType();
				target.setFileName(animalParticulars.getFileName());
				target.setFileTimestamp(animalParticulars.getFileTimestamp());
				target.setDatas(animalParticulars.getData());
				if (contentType != null) {
					target.setMimeType(contentType.getMimeType());
				}
			}
		}
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public ProbandImageOutVO toProbandImageOutVO(final Proband entity) {
		return super.toProbandImageOutVO(entity);
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public void toProbandImageOutVO(
			Proband source,
			ProbandImageOutVO target) {
		super.toProbandImageOutVO(source, target);
		User modifiedUser = source.getModifiedUser();
		if (modifiedUser != null) {
			target.setModifiedUser(this.getUserDao().toUserOutVO(modifiedUser));
		}
		if (source.isPerson()) {
			ProbandContactParticulars personParticulars = source.getPersonParticulars();
			if (personParticulars != null) {
				MimeType contentType = personParticulars.getContentType();
				target.setFileSize(personParticulars.getFileSize());
				target.setFileTimestamp(personParticulars.getFileTimestamp());
				target.setHeight(personParticulars.getHeight());
				target.setWidth(personParticulars.getWidth());
				target.setHasImage(personParticulars.getFileSize() != null && personParticulars.getFileSize() > 0l);
				if (contentType != null) {
					target.setContentType(this.getMimeTypeDao().toMimeTypeVO(contentType));
				}
				try {
					if (!CoreUtil.isPassDecryption()) {
						throw new Exception();
					}
					target.setFileName((String) CryptoUtil.decryptValue(personParticulars.getFileNameIv(), personParticulars.getEncryptedFileName()));
					target.setDatas((byte[]) CryptoUtil.decryptValue(personParticulars.getDataIv(), personParticulars.getEncryptedData()));
					target.setDecrypted(true);
				} catch (Exception e) {
					target.setFileName(null);
					target.setDatas(null);
					target.setDecrypted(false);
				}
			} else {
				target.setDecrypted(true);
			}
		} else {
			AnimalContactParticulars animalParticulars = source.getAnimalParticulars();
			if (animalParticulars != null) {
				MimeType contentType = animalParticulars.getContentType();
				target.setFileName(animalParticulars.getFileName());
				target.setFileSize(animalParticulars.getFileSize());
				target.setFileTimestamp(animalParticulars.getFileTimestamp());
				target.setHeight(animalParticulars.getHeight());
				target.setWidth(animalParticulars.getWidth());
				target.setHasImage(animalParticulars.getFileSize() != null && animalParticulars.getFileSize() > 0l);
				if (contentType != null) {
					target.setContentType(this.getMimeTypeDao().toMimeTypeVO(contentType));
				}
				target.setDatas(animalParticulars.getData());
				target.setDecrypted(true);
			} else {
				target.setDecrypted(true);
			}
		}
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public ProbandInVO toProbandInVO(final Proband entity) {
		return super.toProbandInVO(entity);
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public void toProbandInVO(
			Proband source,
			ProbandInVO target) {
		super.toProbandInVO(source, target);
		Department department = source.getDepartment();
		Staff physician = source.getPhysician();
		ProbandCategory category = source.getCategory();
		if (department != null) {
			target.setDepartmentId(department.getId());
		}
		if (category != null) {
			target.setCategoryId(category.getId());
		}
		if (physician != null) {
			target.setPhysicianId(physician.getId());
		}
		target.setChildIds(toProbandIdCollection(source.getChildren()));
		if (source.isPerson()) {
			ProbandContactParticulars personParticulars = source.getPersonParticulars();
			if (personParticulars != null) {
				target.setGender(personParticulars.getGender());
				target.setAlias(personParticulars.getAlias());
				try {
					target.setPrefixedTitle1((String) CryptoUtil.decryptValue(personParticulars.getPrefixedTitle1Iv(), personParticulars.getEncryptedPrefixedTitle1()));
					target.setPrefixedTitle2((String) CryptoUtil.decryptValue(personParticulars.getPrefixedTitle2Iv(), personParticulars.getEncryptedPrefixedTitle2()));
					target.setPrefixedTitle3((String) CryptoUtil.decryptValue(personParticulars.getPrefixedTitle3Iv(), personParticulars.getEncryptedPrefixedTitle3()));
					target.setFirstName((String) CryptoUtil.decryptValue(personParticulars.getFirstNameIv(), personParticulars.getEncryptedFirstName()));
					target.setLastName((String) CryptoUtil.decryptValue(personParticulars.getLastNameIv(), personParticulars.getEncryptedLastName()));
					target.setPostpositionedTitle1((String) CryptoUtil.decryptValue(personParticulars.getPostpositionedTitle1Iv(),
							personParticulars.getEncryptedPostpositionedTitle1()));
					target.setPostpositionedTitle2((String) CryptoUtil.decryptValue(personParticulars.getPostpositionedTitle2Iv(),
							personParticulars.getEncryptedPostpositionedTitle2()));
					target.setPostpositionedTitle3((String) CryptoUtil.decryptValue(personParticulars.getPostpositionedTitle3Iv(),
							personParticulars.getEncryptedPostpositionedTitle3()));
					target.setDateOfBirth((Date) CryptoUtil.decryptValue(personParticulars.getDateOfBirthIv(), personParticulars.getEncryptedDateOfBirth()));
					target.setCitizenship((String) CryptoUtil.decryptValue(personParticulars.getCitizenshipIv(), personParticulars.getEncryptedCitizenship()));
					target.setComment((String) CryptoUtil.decryptValue(personParticulars.getCommentIv(), personParticulars.getEncryptedComment()));
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		} else {
			AnimalContactParticulars animalParticulars = source.getAnimalParticulars();
			if (animalParticulars != null) {
				target.setAnimalName(animalParticulars.getAnimalName());
				target.setAlias(animalParticulars.getAlias());
				target.setDateOfBirth(animalParticulars.getDateOfBirth());
				target.setGender(animalParticulars.getGender());
				target.setComment(animalParticulars.getComment());
			}
		}
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public ProbandOutVO toProbandOutVO(final Proband entity) {
		return super.toProbandOutVO(entity);
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public void toProbandOutVO(
			Proband source,
			ProbandOutVO target) {
		(new ProbandReflexionGraph(this, this.getProbandCategoryDao(), this.getDepartmentDao(), this.getStaffDao(), this.getPrivacyConsentStatusTypeDao(), this.getUserDao()))
				.toVOHelper(source, target, new HashMap<Class, HashMap<Long, Object>>());
	}

	@Override
	public void toProbandOutVO(
			Proband source,
			ProbandOutVO target, Integer... maxInstances) {
		(new ProbandReflexionGraph(this, this.getProbandCategoryDao(), this.getDepartmentDao(), this.getStaffDao(), this.getPrivacyConsentStatusTypeDao(), this.getUserDao(),
				maxInstances)).toVOHelper(source, target, new HashMap<Class, HashMap<Long, Object>>());
	}

	private HashSet<Proband> toProbandSet(Collection<Long> probandIds) { // lazyload persistentset prevention
		HashSet<Proband> result = new HashSet<Proband>(probandIds.size());
		Iterator<Long> it = probandIds.iterator();
		while (it.hasNext()) {
			result.add(this.load(it.next()));
		}
		return result;
	}
}