//#############################################################################
//#                                                                           #
//#  Copyright (C) <2014>  <IMS MAXIMS>                                       #
//#                                                                           #
//#  This program is free software: you can redistribute it and/or modify     #
//#  it under the terms of the GNU Affero General Public License as           #
//#  published by the Free Software Foundation, either version 3 of the       #
//#  License, or (at your option) any later version.                          # 
//#                                                                           #
//#  This program is distributed in the hope that it will be useful,          #
//#  but WITHOUT ANY WARRANTY; without even the implied warranty of           #
//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            #
//#  GNU Affero General Public License for more details.                      #
//#                                                                           #
//#  You should have received a copy of the GNU Affero General Public License #
//#  along with this program.  If not, see <http://www.gnu.org/licenses/>.    #
//#                                                                           #
//#############################################################################
//#EOH
// This code was generated by Marius Mihalec using IMS Development Environment (version 1.52 build 2508.29436)
// Copyright (C) 1995-2006 IMS MAXIMS plc. All rights reserved.

package ims.assessment.domain.impl;

import ims.assessment.configuration.domain.objects.AssessmentQuestion;
import ims.assessment.configuration.domain.objects.AssessmentQuestionGroup;
import ims.assessment.configuration.domain.objects.FindingStageQuestions;
import ims.assessment.configuration.domain.objects.GraphicAssessment;
import ims.assessment.configuration.domain.objects.GraphicAssessmentFinding;
import ims.assessment.configuration.domain.objects.GraphicAssessmentFindingQuestion;
import ims.assessment.configuration.domain.objects.GraphicAssessmentQuestion;
import ims.assessment.configuration.domain.objects.GraphicAssessmentStage;
import ims.assessment.configuration.domain.objects.UserAssessment;
import ims.assessment.configuration.vo.GraphicAssessmentRefVo;
import ims.assessment.configuration.vo.UserAssessmentRefVo;
import ims.assessment.domain.base.impl.BaseDynamicAssessmentsImpl;
import ims.assessment.instantiation.domain.objects.PatientAnswerDetails;
import ims.assessment.instantiation.domain.objects.PatientAssessment;
import ims.assessment.instantiation.domain.objects.PatientAssessmentAnswer;
import ims.assessment.instantiation.domain.objects.PatientAssessmentData;
import ims.assessment.instantiation.domain.objects.PatientAssessmentGroup;
import ims.assessment.instantiation.domain.objects.PatientAssessmentQuestion;
import ims.assessment.instantiation.domain.objects.PatientGraphicAssessment;
import ims.assessment.instantiation.domain.objects.PatientGraphicAssessmentFinding;
import ims.assessment.instantiation.domain.objects.PatientGraphicAssessmentFindingQuestionAnswer;
import ims.assessment.instantiation.domain.objects.PatientGraphicAssessmentQuestionAnswer;
import ims.assessment.instantiation.domain.objects.PatientGraphicalAssessmentStage;
import ims.assessment.instantiation.vo.PatientAssessmentRefVo;
import ims.assessment.vo.Answer_DetailsVo;
import ims.assessment.vo.Answer_DetailsVoCollection;
import ims.assessment.vo.Answer_OptionVo;
import ims.assessment.vo.Answer_OptionVoCollection;
import ims.assessment.vo.Assessment_QuestionGroupVo;
import ims.assessment.vo.Assessment_QuestionGroupVoCollection;
import ims.assessment.vo.Assessment_QuestionVo;
import ims.assessment.vo.Assessment_QuestionVoCollection;
import ims.assessment.vo.Finding_StageQuestionsVo;
import ims.assessment.vo.Finding_StageQuestionsVoCollection;
import ims.assessment.vo.Graphic_AssessmentFindingQuestionVo;
import ims.assessment.vo.Graphic_AssessmentFindingQuestionVoCollection;
import ims.assessment.vo.Graphic_AssessmentFindingVo;
import ims.assessment.vo.Graphic_AssessmentFindingVoCollection;
import ims.assessment.vo.Graphic_AssessmentQuestionVo;
import ims.assessment.vo.Graphic_AssessmentQuestionVoCollection;
import ims.assessment.vo.Graphic_AssessmentStageVo;
import ims.assessment.vo.Graphic_AssessmentVo;
import ims.assessment.vo.Patient_AssessmentAnswerVo;
import ims.assessment.vo.Patient_AssessmentAnswerVoCollection;
import ims.assessment.vo.Patient_AssessmentDataVo;
import ims.assessment.vo.Patient_AssessmentGroupVo;
import ims.assessment.vo.Patient_AssessmentGroupVoCollection;
import ims.assessment.vo.Patient_AssessmentListVo;
import ims.assessment.vo.Patient_AssessmentListVoCollection;
import ims.assessment.vo.Patient_AssessmentQuestionVo;
import ims.assessment.vo.Patient_AssessmentQuestionVoCollection;
import ims.assessment.vo.Patient_AssessmentVo;
import ims.assessment.vo.Patient_GraphicAssessmentFindingQuestionAnswerVo;
import ims.assessment.vo.Patient_GraphicAssessmentFindingQuestionAnswerVoCollection;
import ims.assessment.vo.Patient_GraphicAssessmentFindingVo;
import ims.assessment.vo.Patient_GraphicAssessmentFindingVoCollection;
import ims.assessment.vo.Patient_GraphicAssessmentQuestionAnswerVo;
import ims.assessment.vo.Patient_GraphicAssessmentQuestionAnswerVoCollection;
import ims.assessment.vo.Patient_GraphicAssessmentVo;
import ims.assessment.vo.Patient_GraphicAssessmentVoCollection;
import ims.assessment.vo.Patient_GraphicalAssessmentStageVo;
import ims.assessment.vo.Patient_GraphicalAssessmentStageVoCollection;
import ims.assessment.vo.Question_AnswerTypeVo;
import ims.assessment.vo.Question_AnswerTypeVoCollection;
import ims.assessment.vo.Question_InformationVo;
import ims.assessment.vo.UserAssessmentVo;
import ims.assessment.vo.UserAssessmentWithServiceCollVo;
import ims.assessment.vo.User_AssessmentVo;
import ims.assessment.vo.domain.AssessmentQuestionRoleVoAssembler;
import ims.assessment.vo.domain.AssessmentRoleVoAssembler;
import ims.assessment.vo.domain.Patient_AssessmentListVoAssembler;
import ims.assessment.vo.domain.Patient_AssessmentVoAssembler;
import ims.assessment.vo.domain.UserAssessmentVoAssembler;
import ims.assessment.vo.domain.UserAssessmentWithServiceCollVoAssembler;
import ims.core.admin.domain.objects.CareContext;
import ims.core.admin.domain.objects.ClinicalContact;
import ims.core.admin.domain.objects.EpisodeOfCare;
import ims.core.admin.domain.objects.TemplateBo;
import ims.core.admin.vo.CareContextRefVo;
import ims.core.admin.vo.CareSpellRefVo;
import ims.core.admin.vo.ClinicalContactRefVo;
import ims.core.admin.vo.EpisodeOfCareRefVo;
import ims.core.admin.vo.TemplateBoRefVo;
import ims.core.clinical.domain.objects.AnswerOption;
import ims.core.clinical.domain.objects.QuestionAnswerType;
import ims.core.clinical.domain.objects.QuestionInformation;
import ims.core.documents.domain.objects.PatientDocument;
import ims.core.documents.vo.PatientDocumentRefVo;
import ims.core.helper.DrawingControlReportHelper;
import ims.core.patient.domain.objects.Patient;
import ims.core.patient.vo.PatientRefVo;
import ims.core.resource.people.vo.HcpRefVo;
import ims.core.vo.CareContextShortVo;
import ims.core.vo.ClinicalContactShortVo;
import ims.core.vo.EpisodeofCareShortVo;
import ims.core.vo.HcpLiteVo;
import ims.core.vo.PatientDocumentLiteVo;
import ims.core.vo.PatientDocumentVo;
import ims.core.vo.PatientShort;
import ims.core.vo.TemplateBoLiteVo;
import ims.core.vo.domain.AuthoringInformationVoAssembler;
import ims.core.vo.domain.CareContextShortVoAssembler;
import ims.core.vo.domain.ClinicalContactShortVoAssembler;
import ims.core.vo.domain.DrawingGraphicFindingVoAssembler;
import ims.core.vo.domain.DrawingGraphicImageVoAssembler;
import ims.core.vo.domain.EpisodeofCareShortVoAssembler;
import ims.core.vo.domain.HcpLiteVoAssembler;
import ims.core.vo.domain.PatientDocumentLiteVoAssembler;
import ims.core.vo.domain.PatientDocumentVoAssembler;
import ims.core.vo.domain.PatientShortAssembler;
import ims.core.vo.domain.TemplateBoLiteVoAssembler;
import ims.core.vo.lookups.LookupHelper;
import ims.core.vo.lookups.UserDefinedAssessmentType;
import ims.domain.DomainFactory;
import ims.domain.DomainObject;
import ims.domain.exceptions.DomainRuntimeException;
import ims.domain.exceptions.StaleObjectException;
import ims.framework.exceptions.CodingRuntimeException;
import ims.framework.utils.Date;
import ims.framework.utils.DateTime;
import ims.framework.utils.PartialDate;
import ims.framework.utils.Time;
import ims.vo.ValueObjectRef;

import java.util.ArrayList;
import java.util.List;

public class DynamicAssessmentsImpl extends BaseDynamicAssessmentsImpl
{
	private static final long serialVersionUID = 1L;

	public User_AssessmentVo getStructuredAssessment(UserAssessmentRefVo assessmentRef)
	{		
		if(assessmentRef == null || assessmentRef.getID_UserAssessment() == null)
			throw new CodingRuntimeException("Invalid user assessment");
		
		//return User_AssessmentVoAssembler.create((UserAssessment)getDomainFactory().getDomainObject(assessmentRef));
		return assembleUserAssessment((UserAssessment)getDomainFactory().getDomainObject(assessmentRef));	//WDEV-12215
	}
	public Graphic_AssessmentVo getGraphicalAssessment(GraphicAssessmentRefVo assessmentRef)
	{
		if(assessmentRef == null || assessmentRef.getID_GraphicAssessment() == null)
			throw new CodingRuntimeException("Invalid graphical assessment");
		
		//return Graphic_AssessmentVoAssembler.create((GraphicAssessment)getDomainFactory().getDomainObject(assessmentRef));
		return assembleGraphicAssessment((GraphicAssessment)getDomainFactory().getDomainObject(assessmentRef));	//WDEV-12215
	}
	public Patient_AssessmentVo getPatientAssessment(ClinicalContactRefVo clinicalContact, UserAssessmentRefVo userAssessment)
	{
		if(clinicalContact == null || clinicalContact.getID_ClinicalContact() == null)
			throw new CodingRuntimeException("Invalid clinical contact");
		if(userAssessment == null || userAssessment.getID_UserAssessment() == null)
			throw new CodingRuntimeException("Invalid user assessment");
		
		DomainFactory factory = getDomainFactory();		
		StringBuffer hql = new StringBuffer();
		String query = " from PatientAssessment a ";
		ArrayList<String> markers= new ArrayList<String>();
		ArrayList<Object> values = new ArrayList<Object>();
		String andStr = " ";

		hql.append(andStr + " a.clinicalContact.id = :cc");
		markers.add("cc");
		values.add(clinicalContact.getID_ClinicalContact());
		andStr = " and ";
		
		hql.append(andStr + " a.assessmentData.userAssessment.id = :ua");
		markers.add("ua");
		values.add(userAssessment.getID_UserAssessment());
		
		if (markers.size() > 0) 
			query += " where ";
		query += hql.toString();	
		
		List result = factory.find(query, markers, values);
		if(result == null || result.size() > 1)
			throw new RuntimeException("More than one patient assessment found");
		else if (result.size() == 0)
			return null;
		
		return Patient_AssessmentVoAssembler.create((PatientAssessment)result.get(0));
	}
	
	public Patient_AssessmentVo getPatientAssessment(ClinicalContactRefVo clinicalContact, GraphicAssessmentRefVo graphicalAssessment)
	{
		if(clinicalContact == null || clinicalContact.getID_ClinicalContact() == null)
			throw new CodingRuntimeException("Invalid clinical contact");
		if(graphicalAssessment == null || graphicalAssessment.getID_GraphicAssessment() == null)
			throw new CodingRuntimeException("Invalid graphical assessment");
		
		DomainFactory factory = getDomainFactory();		
		StringBuffer hql = new StringBuffer();
		String query = " from PatientAssessment a ";
		ArrayList<String> markers= new ArrayList<String>();
		ArrayList<Object> values = new ArrayList<Object>();
		String andStr = " ";

		hql.append(andStr + " a.clinicalContact.id = :cc");
		markers.add("cc");
		values.add(clinicalContact.getID_ClinicalContact());
		andStr = " and ";
		
		hql.append(andStr + " a.assessmentData.graphic.id = :ga");
		markers.add("ga");
		values.add(graphicalAssessment.getID_GraphicAssessment());
		
		if (markers.size() > 0) 
			query += " where ";
		query += hql.toString();	
		
		List result = factory.find(query, markers, values);
		if(result == null || result.size() > 1)
			throw new RuntimeException("More than one patient assessment found");
		else if (result.size() == 0)
			return null;
		
		return Patient_AssessmentVoAssembler.create((PatientAssessment)result.get(0));
	}
	
	public Patient_AssessmentVo savePatientAssessment(Patient_AssessmentVo patientAssessment) throws ims.domain.exceptions.StaleObjectException
	{
		if(patientAssessment == null)
			throw new CodingRuntimeException("Invalid patient assessment");
		if(!patientAssessment.isValidated())
			throw new CodingRuntimeException("User assessment not validated");
		
		DomainFactory factory = getDomainFactory();
		
		//ONLY ONE ASSESSMENT PER CLINICAL CONTACT
		if (!patientAssessment.getID_PatientAssessmentIsNotNull() && patientAssessment.getClinicalContactIsNotNull())
		{
			StringBuilder query = new  StringBuilder("select pa.id from PatientAssessment as pa left join pa.assessmentData as ad where " +
					"(pa.clinicalContact.id = :ClinicalContact_id and pa.isRIE is null");
			
			String[] paramNames = new String[2];
			Object[] paramValues = new Object[2];
			
			paramNames[0] = "ClinicalContact_id";
			paramValues[0] = patientAssessment.getClinicalContact().getID_ClinicalContact();
			
			if (patientAssessment.getAssessmentData().getGraphicIsNotNull())
			{
				query.append(" and ad.graphic.id = :GraphicAssessment_id)"); 
				paramNames[1] = "GraphicAssessment_id";
				paramValues[1] = patientAssessment.getAssessmentData().getGraphic().getID_GraphicAssessment();
			}
			else
			if (patientAssessment.getAssessmentData().getUserAssessmentIsNotNull())
			{
				query.append(" and ad.userAssessment.id = :UserAssessment_id)");
				paramNames[1] = "UserAssessment_id";
				paramValues[1] = patientAssessment.getAssessmentData().getUserAssessment().getID_UserAssessment();
			}
			else 
				throw new DomainRuntimeException("Invalid Patient Assessment. It doesn't contain either a graphical assessment or a user assessment");
			
			int count = factory.count(query.toString(), paramNames, paramValues);
			if (count > 0)
				throw new StaleObjectException(null,"An assessment of this type has been created by another user");
		}
		//END ONLY ONE ASSESSMENT PER CLINICAL CONTACT
		
		PatientAssessment domainObject = Patient_AssessmentVoAssembler.extractPatientAssessment(factory, patientAssessment);
		
		//save every PatientGraphicAssessment as a rendered MHT - used by reports only
		DrawingControlReportHelper helper = new DrawingControlReportHelper();
		if(patientAssessment.getAssessmentDataIsNotNull() && patientAssessment.getAssessmentData().getGraphicFindingsIsNotNull())
		{
			for (int i = 0; i < patientAssessment.getAssessmentData().getGraphicFindings().size(); i++)
			{
				PatientGraphicAssessment pga = (PatientGraphicAssessment) domainObject.getAssessmentData().getGraphicFindings().get(i);
				pga.setRenderedMHT(helper.CreateDrawingControlSeed(patientAssessment.getAssessmentData().getGraphicFindings().get(i), 800, 400));
			}
		}
		
		factory.save(domainObject);
		
		//return Patient_AssessmentVoAssembler.create(domainObject);
		return assemblePatientAssessment(domainObject);
	}
	
	public Patient_AssessmentListVoCollection listPatientAssessments(PatientRefVo patient, EpisodeOfCareRefVo episodeOfCare, CareContextRefVo careContext, ClinicalContactRefVo clinicalContact, UserAssessmentRefVo userAssessment, Date fromDate, Date toDate)
	{
		//wdev-11721
		if(patient == null || patient.getID_Patient() == null)
			throw new CodingRuntimeException("Can not get PatientAssessment on null Patient Id.");
		
		if(userAssessment == null || userAssessment.getID_UserAssessment() == null)
			throw new CodingRuntimeException("Invalid user assessment");
		
		DomainFactory factory = getDomainFactory();		
		StringBuffer hql = new StringBuffer();
		String query = " from PatientAssessment a ";
		ArrayList<String> markers= new ArrayList<String>();
		ArrayList<Object> values = new ArrayList<Object>();
		String andStr = " ";

		//wdev-13558
		if(clinicalContact != null && clinicalContact.getID_ClinicalContactIsNotNull())
		{
    		hql.append(andStr + " a.clinicalContact.id = :clc");
    		markers.add("clc");
    		values.add(clinicalContact.getID_ClinicalContact());
    		andStr = " and ";
		}
		//wdev-11721 - starts here
		else if(careContext != null && careContext.getID_CareContext() != null)
		{
    		hql.append(andStr + " a.careContext.id = :cc");
    		markers.add("cc");
    		values.add(careContext.getID_CareContext());
    		andStr = " and ";
		}	
		else if(episodeOfCare != null && episodeOfCare.getID_EpisodeOfCare() != null)
		{
    		hql.append(andStr + " a.episodeOfCare.id = :ec");
    		markers.add("ec");
    		values.add(episodeOfCare.getID_EpisodeOfCare());
    		andStr = " and ";
		}	
		else if(patient != null && patient.getID_Patient() != null)
		{
    		hql.append(andStr + " a.patient.id = :patId");
    		markers.add("patId");
    		values.add(patient.getID_Patient());
    		andStr = " and ";
		}
		//wdev-11721 - ends here
		
		hql.append(andStr + " a.assessmentData.userAssessment.id = :ua");
		markers.add("ua");
		values.add(userAssessment.getID_UserAssessment());
		
		if (fromDate != null)
		{
			if (toDate == null)
				toDate = new Date();
			
			hql.append(andStr);
			hql.append(" a.authoringInformation.authoringDateTime between :FROM_DATE and :TO_DATE ");
			
			markers.add("FROM_DATE"); markers.add("TO_DATE");
			
			values.add(fromDate.getDate());
			
			java.util.Date toDateJavaUtil = toDate.getDate();
			toDateJavaUtil.setHours(23);
			toDateJavaUtil.setMinutes(59);
			toDateJavaUtil.setSeconds(59);
			values.add(toDateJavaUtil);
		}
		else if (toDate != null)
		{
			hql.append(andStr);
			hql.append(" a.authoringInformation.authoringDateTime <= :TO_DATE ");
			
			markers.add("TO_DATE");
			
			java.util.Date toDateJava = toDate.getDate();
			
			toDateJava.setHours(23);
			toDateJava.setMinutes(59);
			toDateJava.setSeconds(59);
			
			values.add(toDateJava);
		}
		
		
		if (markers.size() > 0) 
			query += " where ";
		query += hql.toString();	
		
		query += " order by a.authoringInformation.authoringDateTime desc";
		
		return Patient_AssessmentListVoAssembler.createPatient_AssessmentListVoCollectionFromPatientAssessment(factory.find(query, markers, values));
	}
	
	public Patient_AssessmentListVoCollection listPatientAssessments(EpisodeOfCareRefVo episodeOfCare, UserAssessmentRefVo userAssessment)
	{
		if(episodeOfCare == null || episodeOfCare.getID_EpisodeOfCare() == null)
			throw new CodingRuntimeException("Invalid episode of care");
		if(userAssessment == null || userAssessment.getID_UserAssessment() == null)
			throw new CodingRuntimeException("Invalid user assessment");
		
		DomainFactory factory = getDomainFactory();		
		StringBuffer hql = new StringBuffer();
		String query = " from PatientAssessment a ";
		ArrayList<String> markers= new ArrayList<String>();
		ArrayList<Object> values = new ArrayList<Object>();
		String andStr = " ";

		//WDEV-11526
		hql.append(andStr + " a.episodeOfCare.id = :ec");
		markers.add("ec");
		values.add(episodeOfCare.getID_EpisodeOfCare());
		andStr = " and ";
		
		hql.append(andStr + " a.assessmentData.userAssessment.id = :ua");
		markers.add("ua");
		values.add(userAssessment.getID_UserAssessment());
		
		if (markers.size() > 0) 
			query += " where ";
		query += hql.toString();	
		
		query += " order by a.authoringInformation.authoringDateTime desc";
		
		return Patient_AssessmentListVoAssembler.createPatient_AssessmentListVoCollectionFromPatientAssessment(factory.find(query, markers, values));
	}
	
	public Patient_AssessmentListVoCollection listPatientAssessments(PatientRefVo patient, EpisodeOfCareRefVo episodeOfCare, CareContextRefVo careContext, ClinicalContactRefVo clinicalContact,GraphicAssessmentRefVo graphicalAssessment, Date fromDate, Date toDate)
	{
		//wdev-11721
		if(patient == null || patient.getID_Patient() == null)
			throw new CodingRuntimeException("Can not get PatientAssessment on null Patient Id.");
		
		if(graphicalAssessment == null || graphicalAssessment.getID_GraphicAssessment() == null)
			throw new CodingRuntimeException("Invalid graphic assessment");
		
		DomainFactory factory = getDomainFactory();		
		StringBuffer hql = new StringBuffer();
		String query = " from PatientAssessment a ";
		ArrayList<String> markers= new ArrayList<String>();
		ArrayList<Object> values = new ArrayList<Object>();
		String andStr = " ";

		//wdev-13558
		if(clinicalContact != null && clinicalContact.getID_ClinicalContactIsNotNull())
		{
    		hql.append(andStr + " a.clinicalContact.id = :clc");
    		markers.add("clc");
    		values.add(clinicalContact.getID_ClinicalContact());
    		andStr = " and ";
		}
		//wdev-11721 - starts here
		else if(careContext != null && careContext.getID_CareContextIsNotNull())
		{
    		hql.append(andStr + " a.careContext.id = :cc");
    		markers.add("cc");
    		values.add(careContext.getID_CareContext());
    		andStr = " and ";
		}
		else if(episodeOfCare != null && episodeOfCare.getID_EpisodeOfCareIsNotNull())
		{
    		hql.append(andStr + " a.episodeOfCare.id = :ec");
    		markers.add("ec");
    		values.add(episodeOfCare.getID_EpisodeOfCare());
    		andStr = " and ";
		}
		else if(patient != null && patient.getID_PatientIsNotNull())
		{
    		hql.append(andStr + " a.patient.id = :patId");
    		markers.add("patId");
    		values.add(patient.getID_Patient());
    		andStr = " and ";
		}
		//wdev-11721 - ends here
		
		if (fromDate != null)
		{
			if (toDate == null)
				toDate = new Date();
			
			hql.append(andStr);
			hql.append(" a.authoringInformation.authoringDateTime between :FROM_DATE and :TO_DATE ");
			
			markers.add("FROM_DATE"); markers.add("TO_DATE");
			
			values.add(fromDate.getDate());
			
			java.util.Date toDateJavaUtil = toDate.getDate();
			toDateJavaUtil.setHours(23);
			toDateJavaUtil.setMinutes(59);
			toDateJavaUtil.setSeconds(59);
			values.add(toDateJavaUtil);
			
			andStr = " and ";
		}
		else if (toDate != null)
		{
			hql.append(andStr);
			hql.append(" a.authoringInformation.authoringDateTime <= :TO_DATE ");
			
			markers.add("TO_DATE");
			
			java.util.Date toDateJava = toDate.getDate();
			
			toDateJava.setHours(23);
			toDateJava.setMinutes(59);
			toDateJava.setSeconds(59);
			
			values.add(toDateJava);
			
			andStr = " and ";
		}

		hql.append(andStr + " a.assessmentData.graphic.id = :ga");
		markers.add("ga");
		values.add(graphicalAssessment.getID_GraphicAssessment());
		
		if (markers.size() > 0) 
			query += " where ";
		query += hql.toString();	
		
		query += " order by a.authoringInformation.authoringDateTime desc";
		
		return Patient_AssessmentListVoAssembler.createPatient_AssessmentListVoCollectionFromPatientAssessment(factory.find(query, markers, values));
	}
	public Patient_AssessmentListVoCollection listPatientAssessments(EpisodeOfCareRefVo episodeOfCare, GraphicAssessmentRefVo graphicalAssessment)
	{
		if(episodeOfCare == null || episodeOfCare.getID_EpisodeOfCare() == null)
			throw new CodingRuntimeException("Invalid episode of care");
		if(graphicalAssessment == null || graphicalAssessment.getID_GraphicAssessment() == null)
			throw new CodingRuntimeException("Invalid graphic assessment");
		
		DomainFactory factory = getDomainFactory();		
		StringBuffer hql = new StringBuffer();
		String query = " from PatientAssessment a ";
		ArrayList<String> markers= new ArrayList<String>();
		ArrayList<Object> values = new ArrayList<Object>();
		String andStr = " ";

		//WDEV-11526
		hql.append(andStr + " a.episodeOfCare.id = :ec");
		markers.add("ec");
		values.add(episodeOfCare.getID_EpisodeOfCare());
		andStr = " and ";
		
		hql.append(andStr + " a.assessmentData.graphic.id = :ga");
		markers.add("ga");
		values.add(graphicalAssessment.getID_GraphicAssessment());
		
		if (markers.size() > 0) 
			query += " where ";
		query += hql.toString();	
		
		query += " order by a.authoringInformation.authoringDateTime desc";
		
		return Patient_AssessmentListVoAssembler.createPatient_AssessmentListVoCollectionFromPatientAssessment(factory.find(query, markers, values));
	}
	public ims.assessment.vo.Patient_AssessmentVo getPatientAssessment(PatientAssessmentRefVo patientAssessment)
	{
		if(patientAssessment == null || patientAssessment.getID_PatientAssessment() == null)
			throw new CodingRuntimeException("Invalid patient assessment");
		
		//return Patient_AssessmentVoAssembler.create((PatientAssessment)getDomainFactory().getDomainObject(patientAssessment));	
		PatientAssessment doPatientAssessment = (PatientAssessment) getDomainFactory().getDomainObject(PatientAssessment.class, patientAssessment.getID_PatientAssessment());
		
		Patient_AssessmentVo patAssessment = assemblePatientAssessment(doPatientAssessment);
		
		return patAssessment;
	}
	/**
	 * WDEV-16324
	 * getPatientAssessment record for the given assessmentReference - returning
	 */
	public ims.assessment.vo.Patient_AssessmentListVo getPatientAssessmentList(PatientAssessmentRefVo patientAssessment)
	{
		if(patientAssessment == null || patientAssessment.getID_PatientAssessment() == null)
			throw new CodingRuntimeException("Invalid patient assessment");
		
		//return Patient_AssessmentVoAssembler.create((PatientAssessment)getDomainFactory().getDomainObject(patientAssessment));	
		PatientAssessment doPatientAssessment = (PatientAssessment) getDomainFactory().getDomainObject(PatientAssessment.class, patientAssessment.getID_PatientAssessment());
		
		Patient_AssessmentListVo patAssessment = Patient_AssessmentListVoAssembler.create(doPatientAssessment);
		
		return patAssessment;
	}

	@SuppressWarnings("unchecked")
	public Patient_AssessmentListVo getLastStructuredAssessment(UserDefinedAssessmentType type, CareContextRefVo careContext)
	{
		List list = getDomainFactory().find("from PatientAssessment as p1_1 where p1_1.assessmentData.userAssessment.assessmentType.id = :TYPE and p1_1.careContext.id = :CARE_CONTEXT order by p1_1.authoringInformation.authoringDateTime desc", new String[] {"TYPE", "CARE_CONTEXT"}, new Object[] {new Integer(type.getID()), careContext.getID_CareContext()});
		
		//Get only the first record (to optimise the work of the assembler)
		if(list != null && list.size() > 1)
		{
			Object firstItem = list.get(0);
			list.removeAll(list);
			list.add(firstItem);
		}
		
		Patient_AssessmentListVoCollection voColl = Patient_AssessmentListVoAssembler.createPatient_AssessmentListVoCollectionFromPatientAssessment(list);
		if(voColl != null && voColl.size() > 0)
			return voColl.get(0);
			
		return null;
	}
	public CareContextShortVo getCareContextShort(CareContextRefVo voCareContextRef)
	{
		if (voCareContextRef == null)
			return null;

		CareContext doCareContext = (CareContext) getDomainFactory().getDomainObject(CareContext.class, voCareContextRef.getID_CareContext());
		return CareContextShortVoAssembler.create(doCareContext);
	}
	
	public ClinicalContactShortVo getClinicalContactShort(ClinicalContactRefVo clinicacalContactRefVo)
	{
		if (clinicacalContactRefVo == null)
			return null;

		ClinicalContact doClinicalContact = (ClinicalContact) getDomainFactory().getDomainObject(ClinicalContact.class, clinicacalContactRefVo.getID_ClinicalContact());
		return ClinicalContactShortVoAssembler.create(doClinicalContact);

	}
	public String getLinkedReportName(ims.vo.ValueObjectRef refVo)
	{
		if (refVo == null)
			return null;

		if(refVo instanceof UserAssessmentRefVo)
		{
			List list = getDomainFactory().find("select u1_1.associatedReport.name from UserAssessment as u1_1 where (u1_1.id = :ID)", new String[] {"ID"}, new Object[] {new Integer(refVo.getBoId())});
			
			if(list != null && list.size() > 0)
			{
				return (String) list.get(0);
			}
			
			return null;			
		}
		else if(refVo instanceof GraphicAssessmentRefVo)
		{
			return null;
		}
		
		return null;
	}
	
	public HcpLiteVo getHcpById(HcpRefVo hcpRefVo)
	{
		if(hcpRefVo == null)
			throw new CodingRuntimeException("null hcpRefVo passed to getHcpById() !");

		DomainFactory factory = getDomainFactory();
		
		ims.core.resource.people.domain.objects.Hcp boHcp = (ims.core.resource.people.domain.objects.Hcp)factory.getDomainObject(ims.core.resource.people.domain.objects.Hcp.class, hcpRefVo.getID_Hcp());
		
		return HcpLiteVoAssembler.create(boHcp);
	}
	
	public PatientAssessmentRefVo getPreviousPatientAssessment(ValueObjectRef contextType, UserAssessmentRefVo userAssessment) 
	{
		if(userAssessment == null || userAssessment.getID_UserAssessment() == null)
			throw new CodingRuntimeException("Invalid user assessment");
		
		if(contextType == null)
			throw new CodingRuntimeException("Invalid context type");
		
		DomainFactory factory = getDomainFactory();	
		ArrayList<String> markers= new ArrayList<String>();
		ArrayList<Object> values = new ArrayList<Object>();
		
		String query = "from PatientAssessment a where a.assessmentData.userAssessment.id = :ua";
		
		markers.add("ua");
		values.add(userAssessment.getID_UserAssessment());
		
		if(contextType instanceof CareContextRefVo)
		{
			query += " and a.careContext.id = :cc";
			markers.add("cc");
			values.add(((CareContextRefVo)contextType).getID_CareContext());
		}
		else if(contextType instanceof EpisodeOfCareRefVo)
		{
			//WDEV-11526
			query += " and a.episodeOfCare.id = :ec";
			markers.add("ec");
			values.add(((EpisodeOfCareRefVo)contextType).getID_EpisodeOfCare());
		}
		else if(contextType instanceof CareSpellRefVo)
		{
			//WDEV-11526
			query += " and a.episodeOfCare.careSpell.id = :cs";
			markers.add("cs");
			values.add(((CareSpellRefVo)contextType).getID_CareSpell());
		}
		else if(contextType instanceof PatientRefVo)
		{
			//WDEV-11721
			query += " and a.patient.id = :pat";
			markers.add("pat");
			values.add(((PatientRefVo)contextType).getID_Patient());
		}
		else
			throw new CodingRuntimeException("Invalid context type");
		
		query += " and a.isRIE is null and a.completedDateTime is not null order by a.completedDateTime desc";
		
		DomainObject previousAssessment = factory.findFirst(query, markers, values);
		
		if(previousAssessment instanceof PatientAssessment)
			return new PatientAssessmentRefVo(previousAssessment.getId(), previousAssessment.getVersion());
			
		return null;
	}
	
	public EpisodeofCareShortVo getEpisodeOfCare(EpisodeOfCareRefVo episodeOfCareRef) 
	{
		if(episodeOfCareRef == null || !episodeOfCareRef.getID_EpisodeOfCareIsNotNull())
			return null;		//WDEV-11721
		
		return EpisodeofCareShortVoAssembler.create((EpisodeOfCare) getDomainFactory().getDomainObject(EpisodeOfCare.class, episodeOfCareRef.getID_EpisodeOfCare()));
	}
	
	public PatientShort getPatient(PatientRefVo patient)
	{
		if(patient == null || !patient.getID_PatientIsNotNull())
			throw new CodingRuntimeException("Can not Patient on null Id.");
		
		return PatientShortAssembler.create((Patient) getDomainFactory().getDomainObject(Patient.class, patient.getID_Patient()));
	}
	
	//WDEV-11721 - starts here
	public Patient_AssessmentListVoCollection listPatientAssessments(CareContextRefVo careContext, UserAssessmentRefVo userAssessment)
	{
		if(careContext == null || careContext.getID_CareContext() == null)
			throw new CodingRuntimeException("Invalid care context");
		if(userAssessment == null || userAssessment.getID_UserAssessment() == null)
			throw new CodingRuntimeException("Invalid user assessment");
		
		DomainFactory factory = getDomainFactory();		
		StringBuffer hql = new StringBuffer();
		String query = " from PatientAssessment a ";
		ArrayList<String> markers= new ArrayList<String>();
		ArrayList<Object> values = new ArrayList<Object>();
		String andStr = " ";

		hql.append(andStr + " a.careContext.id = :cc");
		markers.add("cc");
		values.add(careContext.getID_CareContext());
		andStr = " and ";
		
		hql.append(andStr + " a.assessmentData.userAssessment.id = :ua");
		markers.add("ua");
		values.add(userAssessment.getID_UserAssessment());
		
		if (markers.size() > 0) 
			query += " where ";
		query += hql.toString();	
		
		query += " order by a.authoringInformation.authoringDateTime desc";
		
		return Patient_AssessmentListVoAssembler.createPatient_AssessmentListVoCollectionFromPatientAssessment(factory.find(query, markers, values));
	}
	
	public Patient_AssessmentListVoCollection listPatientAssessments(CareContextRefVo careContext, GraphicAssessmentRefVo graphicalAssessment)
	{
		if(careContext == null || careContext.getID_CareContext() == null)
			throw new CodingRuntimeException("Invalid care context");
		if(graphicalAssessment == null || graphicalAssessment.getID_GraphicAssessment() == null)
			throw new CodingRuntimeException("Invalid graphic assessment");
		
		DomainFactory factory = getDomainFactory();		
		StringBuffer hql = new StringBuffer();
		String query = " from PatientAssessment a ";
		ArrayList<String> markers= new ArrayList<String>();
		ArrayList<Object> values = new ArrayList<Object>();
		String andStr = " ";

		hql.append(andStr + " a.careContext.id = :cc");
		markers.add("cc");
		values.add(careContext.getID_CareContext());
		andStr = " and ";
		
		hql.append(andStr + " a.assessmentData.graphic.id = :ga");
		markers.add("ga");
		values.add(graphicalAssessment.getID_GraphicAssessment());
		
		if (markers.size() > 0) 
			query += " where ";
		query += hql.toString();	
		
		query += " order by a.authoringInformation.authoringDateTime desc";
		
		return Patient_AssessmentListVoAssembler.createPatient_AssessmentListVoCollectionFromPatientAssessment(factory.find(query, markers, values));
	}
	//WDEV-11721 - ends here


	/**
	 * Function used to save a PatientDocument record and update PatientAssessment record (marked as have been printed)
	 */
	public Boolean savePatientDocument(PatientDocumentVo patientDocument, Patient_AssessmentVo patientAssessment) throws StaleObjectException
	{
		if (patientDocument == null)
			throw new DomainRuntimeException("Invalid PatientDocument record");
		if (!patientDocument.isValidated())
			throw new DomainRuntimeException("PatientDocument record not validated");
		if(patientAssessment == null)
			throw new DomainRuntimeException("Invalid patient assessment");
		if(!patientAssessment.isValidated())
			throw new DomainRuntimeException("User assessment not validated");
		
		DomainFactory factory = getDomainFactory();

		// Save PatientDocumet record
		PatientDocument domainPatientDocument = PatientDocumentVoAssembler.extractPatientDocument(factory, patientDocument);
		factory.save(domainPatientDocument);
		
		// Save PatientAssessment record
		PatientAssessment domainObject = Patient_AssessmentVoAssembler.extractPatientAssessment(factory, patientAssessment);
		
		//wdev-15972
		if( domainObject != null && domainPatientDocument != null )
			domainObject.setAssociatedDocument(domainPatientDocument);
		
		//---------
		factory.save(domainObject);
		
		return true;
	}

	/**
	 * Function used to do a preemptive check before attempting to print document
	 */
	public Boolean isSaved(PatientAssessmentRefVo patientAssessment)
	{
		if (patientAssessment == null || !patientAssessment.getID_PatientAssessmentIsNotNull())
			throw new DomainRuntimeException("Can not check invalid record");
		
		String query = "select ass.isAssessmentDocumentSaved from PatientAssessment as ass where ass.id = " + patientAssessment.getID_PatientAssessment().toString();
		
		List result = getDomainFactory().find(query);
		
		if (result.iterator().hasNext())
		{
			if (Boolean.TRUE.equals((Boolean) result.iterator().next()))
				return true;
		}

		return false;
	}

	public TemplateBoLiteVo getTemplate(TemplateBoRefVo template)
	{
		if (template == null || !template.getID_TemplateBoIsNotNull())
			throw new DomainRuntimeException("Invalid template record");
		
		return TemplateBoLiteVoAssembler.create((TemplateBo) getDomainFactory().getDomainObject(TemplateBo.class, template.getID_TemplateBo()));
	}
	
	//WDEV-12215 - starts here
	private Patient_AssessmentVo assemblePatientAssessment(PatientAssessment doPatientAssessment) 
	{
		if(doPatientAssessment == null)
			return null;
		
		Patient_AssessmentVo patientAssessment = new Patient_AssessmentVo(doPatientAssessment.getId(), doPatientAssessment.getVersion());
		patientAssessment.setIsRIE(doPatientAssessment.getIsRIE());
		patientAssessment.setStatus(doPatientAssessment.getStatus() != null ? LookupHelper.getPatientAssessmentStatusReasonInstance(getLookupService(), doPatientAssessment.getStatus().getId()) : null);
		patientAssessment.setAuthoringInformation(AuthoringInformationVoAssembler.create(doPatientAssessment.getAuthoringInformation()));
		patientAssessment.setCompletedHCP(HcpLiteVoAssembler.create(doPatientAssessment.getCompletedHCP()));
		patientAssessment.setCompletedDateTime(doPatientAssessment.getCompletedDateTime() != null ? new DateTime(doPatientAssessment.getCompletedDateTime()) : null);
		patientAssessment.setPatient(doPatientAssessment.getPatient() != null ? new PatientRefVo(doPatientAssessment.getPatient().getId(), doPatientAssessment.getPatient().getVersion()) : null);
		patientAssessment.setEpisodeOfCare(doPatientAssessment.getEpisodeOfCare() != null ? new EpisodeOfCareRefVo(doPatientAssessment.getEpisodeOfCare().getId(), doPatientAssessment.getEpisodeOfCare().getVersion()) : null);
		patientAssessment.setCareContext(doPatientAssessment.getCareContext() != null ? new CareContextRefVo(doPatientAssessment.getCareContext().getId(), doPatientAssessment.getCareContext().getVersion()) : null);
		patientAssessment.setClinicalContact(doPatientAssessment.getClinicalContact() != null ? new ClinicalContactRefVo(doPatientAssessment.getClinicalContact().getId(), doPatientAssessment.getClinicalContact().getVersion()) : null);
		patientAssessment.setScore(doPatientAssessment.getScore());
		patientAssessment.setIsAssessmentDocumentSaved(doPatientAssessment.isIsAssessmentDocumentSaved());
		patientAssessment.setAssessmentData(assemblePatientAssessmentData(doPatientAssessment.getAssessmentData()));
		//wdev-15972
		patientAssessment.setAssociatedDocument(doPatientAssessment.getAssociatedDocument() != null ? new PatientDocumentRefVo(doPatientAssessment.getAssociatedDocument().getId(),doPatientAssessment.getAssociatedDocument().getVersion()):null);
		//----------
				
		return patientAssessment;
	}
	
	private Patient_AssessmentDataVo assemblePatientAssessmentData(PatientAssessmentData doPatientAssessmentData) 
	{
		if(doPatientAssessmentData == null)
			return null;
		
		Patient_AssessmentDataVo patientAssessmentData = new Patient_AssessmentDataVo(doPatientAssessmentData.getId(), doPatientAssessmentData.getVersion());
		patientAssessmentData.setIsRIE(doPatientAssessmentData.getIsRIE());
		patientAssessmentData.setGroupQuestionWidth(doPatientAssessmentData.getGroupQuestionWidth());
		patientAssessmentData.setGraphic(assembleGraphicAssessment(doPatientAssessmentData.getGraphic()));
		patientAssessmentData.setUserAssessment(assembleUserAssessment(doPatientAssessmentData.getUserAssessment()));
		
		if(doPatientAssessmentData.getAnswerGroups()!= null)
		{
			patientAssessmentData.setAnswerGroups(new Patient_AssessmentGroupVoCollection());
			
			for (int i = 0; i < doPatientAssessmentData.getAnswerGroups().size(); i++)
			{
				Object next = doPatientAssessmentData.getAnswerGroups().get(i);
				if(next instanceof PatientAssessmentGroup)
				{
					patientAssessmentData.getAnswerGroups().add(assemblePatientAssessmentGroup((PatientAssessmentGroup) next));
				}				
			}
		}
		
		if(doPatientAssessmentData.getGraphicFindings() != null)
		{
			patientAssessmentData.setGraphicFindings(new Patient_GraphicAssessmentVoCollection());
			
			for (int i = 0; i < doPatientAssessmentData.getGraphicFindings().size(); i++)
			{
				Object next = doPatientAssessmentData.getGraphicFindings().get(i);
				if(next instanceof PatientGraphicAssessment)
				{
					patientAssessmentData.getGraphicFindings().add(assemblePatientGraphicAssessment((PatientGraphicAssessment) next));
				}
			}
		}
		
		if(doPatientAssessmentData.getGraphicQuestion() != null)
		{
			patientAssessmentData.setGraphicQuestion(new Patient_GraphicAssessmentQuestionAnswerVoCollection());
			
			for (int i = 0; i < doPatientAssessmentData.getGraphicQuestion().size(); i++)
			{
				Object next = doPatientAssessmentData.getGraphicQuestion().get(i);
				if(next instanceof PatientGraphicAssessmentQuestionAnswer)
				{
					patientAssessmentData.getGraphicQuestion().add(assemblePatientGraphicAssessmentQuestionAnswer((PatientGraphicAssessmentQuestionAnswer) next));
				}
			}	
		}
		
		return patientAssessmentData;
	}
	
	private Patient_GraphicAssessmentQuestionAnswerVo assemblePatientGraphicAssessmentQuestionAnswer(PatientGraphicAssessmentQuestionAnswer doPatientGraphicAssessmentQuestionAnswer) 
	{
		if(doPatientGraphicAssessmentQuestionAnswer == null)
			return null;
		
		Patient_GraphicAssessmentQuestionAnswerVo patientGraphicAssessmentQuestionAnswer = new Patient_GraphicAssessmentQuestionAnswerVo(doPatientGraphicAssessmentQuestionAnswer.getId(), doPatientGraphicAssessmentQuestionAnswer.getVersion());
		
		patientGraphicAssessmentQuestionAnswer.setIsRIE(doPatientGraphicAssessmentQuestionAnswer.getIsRIE());
		patientGraphicAssessmentQuestionAnswer.setIsAnswered(doPatientGraphicAssessmentQuestionAnswer.isIsAnswered());
		patientGraphicAssessmentQuestionAnswer.setIsMandatory(doPatientGraphicAssessmentQuestionAnswer.isIsMandatory());
		patientGraphicAssessmentQuestionAnswer.setGraphicQuestion(assembleGraphicAssessmentQuestion(doPatientGraphicAssessmentQuestionAnswer.getGraphicQuestion()));
		
		if(doPatientGraphicAssessmentQuestionAnswer.getPatientAnswers() != null)
		{
			patientGraphicAssessmentQuestionAnswer.setPatientAnswers(new Patient_AssessmentAnswerVoCollection());
			
			for (int i = 0; i < doPatientGraphicAssessmentQuestionAnswer.getPatientAnswers().size(); i++)
			{
				Object next = doPatientGraphicAssessmentQuestionAnswer.getPatientAnswers().get(i);
				if(next instanceof PatientAssessmentAnswer)
				{
					patientGraphicAssessmentQuestionAnswer.getPatientAnswers().add(assemblePatientAssessmentAnswer((PatientAssessmentAnswer) next));
				}
			}
		}
		
		return patientGraphicAssessmentQuestionAnswer;
	}
	
	private Patient_GraphicAssessmentVo assemblePatientGraphicAssessment(PatientGraphicAssessment doPatientGraphicAssessment) 
	{
		if(doPatientGraphicAssessment == null)
			return null;
		
		Patient_GraphicAssessmentVo patientGraphicAssessment = new Patient_GraphicAssessmentVo(doPatientGraphicAssessment.getId(), doPatientGraphicAssessment.getVersion());
		
		patientGraphicAssessment.setIsRIE(doPatientGraphicAssessment.getIsRIE());
		patientGraphicAssessment.setGraphicImage(DrawingGraphicImageVoAssembler.create(doPatientGraphicAssessment.getGraphicImage()));
		
		if(doPatientGraphicAssessment.getPatientGraphicFinding() != null)
		{
			patientGraphicAssessment.setPatientGraphicFinding(new Patient_GraphicAssessmentFindingVoCollection());
			
			for (Object next : doPatientGraphicAssessment.getPatientGraphicFinding())
			{
				if(next instanceof PatientGraphicAssessmentFinding)
				{
					patientGraphicAssessment.getPatientGraphicFinding().add(assemblePatientGraphicAssessmentFinding((PatientGraphicAssessmentFinding) next));
				}
			}
		}
			
		return patientGraphicAssessment;
	}
	
	private Patient_GraphicAssessmentFindingVo assemblePatientGraphicAssessmentFinding(PatientGraphicAssessmentFinding doPatientGraphicAssessmentFinding) 
	{
		if(doPatientGraphicAssessmentFinding == null)
			return null;
		
		Patient_GraphicAssessmentFindingVo patientGraphicAssessmentFinding = new Patient_GraphicAssessmentFindingVo(doPatientGraphicAssessmentFinding.getId(), doPatientGraphicAssessmentFinding.getVersion());
		
		patientGraphicAssessmentFinding.setIsRIE(doPatientGraphicAssessmentFinding.getIsRIE());
		patientGraphicAssessmentFinding.setAreaName(doPatientGraphicAssessmentFinding.getAreaName());
		patientGraphicAssessmentFinding.setGraphicFinding(DrawingGraphicFindingVoAssembler.create(doPatientGraphicAssessmentFinding.getGraphicFinding()));
		patientGraphicAssessmentFinding.setAreaDrawn(doPatientGraphicAssessmentFinding.getAreaDrawn());
		patientGraphicAssessmentFinding.setAuthoringInformation(AuthoringInformationVoAssembler.create(doPatientGraphicAssessmentFinding.getAuthoringInformation()));
		patientGraphicAssessmentFinding.setAreaDetails(doPatientGraphicAssessmentFinding.getAreaDetails());
		
		if(doPatientGraphicAssessmentFinding.getStage() != null)
		{
			patientGraphicAssessmentFinding.setStage(new Patient_GraphicalAssessmentStageVoCollection());
			
			for(Object next : doPatientGraphicAssessmentFinding.getStage())
			{
				if(next instanceof PatientGraphicalAssessmentStage)
				{
					patientGraphicAssessmentFinding.getStage().add(assemblePatientGraphicalAssessmentStage((PatientGraphicalAssessmentStage) next));
				}
			}
		}
		
		return patientGraphicAssessmentFinding;
	}
	
	private Patient_GraphicalAssessmentStageVo assemblePatientGraphicalAssessmentStage(PatientGraphicalAssessmentStage doPatientGraphicalAssessmentStage) 
	{
		if(doPatientGraphicalAssessmentStage == null)
			return null;
		
		Patient_GraphicalAssessmentStageVo patientGraphicalAssessmentStage = new Patient_GraphicalAssessmentStageVo(doPatientGraphicalAssessmentStage.getId(), doPatientGraphicalAssessmentStage.getVersion());
		
		patientGraphicalAssessmentStage.setIsRIE(doPatientGraphicalAssessmentStage.getIsRIE());
		patientGraphicalAssessmentStage.setStage(assembleFindingStageQuestions(doPatientGraphicalAssessmentStage.getStage()));
		
		if(doPatientGraphicalAssessmentStage.getFindingQuestion() != null)
		{
			patientGraphicalAssessmentStage.setFindingQuestion(new Patient_GraphicAssessmentFindingQuestionAnswerVoCollection());
			
			for (Object next : doPatientGraphicalAssessmentStage.getFindingQuestion())
			{
				if(next instanceof PatientGraphicAssessmentFindingQuestionAnswer)
				{
					patientGraphicalAssessmentStage.getFindingQuestion().add(assemblePatientGraphicAssessmentFindingQuestionAnswer((PatientGraphicAssessmentFindingQuestionAnswer) next));
				}
			}	
		}
		
		return patientGraphicalAssessmentStage;
	}
	
	private Patient_GraphicAssessmentFindingQuestionAnswerVo assemblePatientGraphicAssessmentFindingQuestionAnswer(PatientGraphicAssessmentFindingQuestionAnswer doPatientGraphicAssessmentFindingQuestionAnswer) 
	{
		if(doPatientGraphicAssessmentFindingQuestionAnswer == null)
			return null;
		
		Patient_GraphicAssessmentFindingQuestionAnswerVo patientGraphicAssessmentFindingQuestionAnswer = new Patient_GraphicAssessmentFindingQuestionAnswerVo(doPatientGraphicAssessmentFindingQuestionAnswer.getId(), doPatientGraphicAssessmentFindingQuestionAnswer.getVersion());
		
		patientGraphicAssessmentFindingQuestionAnswer.setIsRIE(doPatientGraphicAssessmentFindingQuestionAnswer.getIsRIE());
		patientGraphicAssessmentFindingQuestionAnswer.setIsAnswered(doPatientGraphicAssessmentFindingQuestionAnswer.isIsAnswered());
		patientGraphicAssessmentFindingQuestionAnswer.setIsMandatory(doPatientGraphicAssessmentFindingQuestionAnswer.isIsMandatory());
		patientGraphicAssessmentFindingQuestionAnswer.setGraphicFindingQuestion(assembleGraphicAssessmentFindingQuestion(doPatientGraphicAssessmentFindingQuestionAnswer.getGraphicFindingQuestion()));
		
		if(doPatientGraphicAssessmentFindingQuestionAnswer.getPatientAnswers() != null)
		{
			patientGraphicAssessmentFindingQuestionAnswer.setPatientAnswers(new Patient_AssessmentAnswerVoCollection());
			
			for (Object next : doPatientGraphicAssessmentFindingQuestionAnswer.getPatientAnswers())
			{
				if(next instanceof PatientAssessmentAnswer)
				{
					patientGraphicAssessmentFindingQuestionAnswer.getPatientAnswers().add(assemblePatientAssessmentAnswer((PatientAssessmentAnswer) next));
				}
			}
		}
		
		return patientGraphicAssessmentFindingQuestionAnswer;
	}
	
	private Patient_AssessmentGroupVo assemblePatientAssessmentGroup(PatientAssessmentGroup doPatientAssessmentGroup) 
	{
		if(doPatientAssessmentGroup == null)
			return null;
		
		Patient_AssessmentGroupVo patientAssessmentGroup = new Patient_AssessmentGroupVo(doPatientAssessmentGroup.getId(), doPatientAssessmentGroup.getVersion());
		
		patientAssessmentGroup.setIsRIE(doPatientAssessmentGroup.getIsRIE());
		patientAssessmentGroup.setAssessmentQuestionGroup(assembleAssessmentQuestionGroup(doPatientAssessmentGroup.getAssessmentQuestionGroup()));
		patientAssessmentGroup.setCurrentScore(doPatientAssessmentGroup.getCurrentScore());
		
		if(doPatientAssessmentGroup.getAssessmentAnswers() != null)
		{
			patientAssessmentGroup.setAssessmentAnswers(new Patient_AssessmentQuestionVoCollection());
			
			for (Object next : doPatientAssessmentGroup.getAssessmentAnswers())
			{
				if(next instanceof PatientAssessmentQuestion)
				{
					patientAssessmentGroup.getAssessmentAnswers().add(assemblePatientAssessmentQuestion((PatientAssessmentQuestion) next));
				}
			}
		}
		
		return patientAssessmentGroup;
	}
	
	private Patient_AssessmentQuestionVo assemblePatientAssessmentQuestion(PatientAssessmentQuestion doPatientAssessmentQuestion) 
	{
		if(doPatientAssessmentQuestion == null)
			return null;
		
		Patient_AssessmentQuestionVo patientAssessmentQuestion = new Patient_AssessmentQuestionVo(doPatientAssessmentQuestion.getId(), doPatientAssessmentQuestion.getVersion());
		
		patientAssessmentQuestion.setIsRIE(doPatientAssessmentQuestion.getIsRIE());
		patientAssessmentQuestion.setIsAnswered(doPatientAssessmentQuestion.getIsAnswered() != null ? ims.assessment.vo.lookups.LookupHelper.getAnswerStatusInstance(getLookupService(), doPatientAssessmentQuestion.getIsAnswered().getId()) : null);
		patientAssessmentQuestion.setAssessmentQuestion(assembleAssessmentQuestion(doPatientAssessmentQuestion.getAssessmentQuestion()));
		patientAssessmentQuestion.setIsMandatory(doPatientAssessmentQuestion.isIsMandatory());
		patientAssessmentQuestion.setAllowsMultipleAnswers(doPatientAssessmentQuestion.isAllowsMultipleAnswers());
		patientAssessmentQuestion.setSequence(doPatientAssessmentQuestion.getSequence());
		
		if(doPatientAssessmentQuestion.getPatientAnswers() != null)
		{
			patientAssessmentQuestion.setPatientAnswers(new Patient_AssessmentAnswerVoCollection());
			
			for (Object next : doPatientAssessmentQuestion.getPatientAnswers())
			{
				if(next instanceof PatientAssessmentAnswer)
				{
					patientAssessmentQuestion.getPatientAnswers().add(assemblePatientAssessmentAnswer((PatientAssessmentAnswer) next));
				}
			}
		}
		
		return patientAssessmentQuestion;
	}
	
	private Patient_AssessmentAnswerVo assemblePatientAssessmentAnswer(PatientAssessmentAnswer doPatientAssessmentAnswer) 
	{
		if(doPatientAssessmentAnswer == null)
			return null;
		
		Patient_AssessmentAnswerVo patientAssessmentAnswer = new Patient_AssessmentAnswerVo(doPatientAssessmentAnswer.getId(), doPatientAssessmentAnswer.getVersion());
		
		patientAssessmentAnswer.setIsRIE(doPatientAssessmentAnswer.getIsRIE());
		patientAssessmentAnswer.setAuthoringInfo(AuthoringInformationVoAssembler.create(doPatientAssessmentAnswer.getAuthoringInfo()));
		
		if(doPatientAssessmentAnswer.getAnswerDetails() != null)
		{
			patientAssessmentAnswer.setAnswerDetails(new Answer_DetailsVoCollection());
			
			for (Object next : doPatientAssessmentAnswer.getAnswerDetails())
			{
				if(next instanceof PatientAnswerDetails)
				{
					patientAssessmentAnswer.getAnswerDetails().add(assemblePatientAnswerDetails((PatientAnswerDetails) next));
				}
			}
		}
			
		return patientAssessmentAnswer;
	}
	
	private Answer_DetailsVo assemblePatientAnswerDetails(PatientAnswerDetails doPatientAnswerDetails) 
	{
		if(doPatientAnswerDetails == null)
			return null;
		
		Answer_DetailsVo answerDetails = new Answer_DetailsVo(doPatientAnswerDetails.getId(), doPatientAnswerDetails.getVersion());
		answerDetails.setIsRIE(doPatientAnswerDetails.getIsRIE());
		answerDetails.setAnswerType(assembleQuestionAnswerType(doPatientAnswerDetails.getAnswerType()));
		answerDetails.setAnswerWidth(doPatientAnswerDetails.getAnswerWidth());
		answerDetails.setMaxMultiselectAllowed(doPatientAnswerDetails.getMaxMultiselectAllowed());
		answerDetails.setBoolValueAnswer(doPatientAnswerDetails.isBoolValueAnswer());
		answerDetails.setPicklist(assembleAnswerOption(doPatientAnswerDetails.getPicklist()));
		answerDetails.setCalculatedScore(doPatientAnswerDetails.getCalculatedScore());
		answerDetails.setDateAnswer(doPatientAnswerDetails.getDateAnswer() != null ? new Date(doPatientAnswerDetails.getDateAnswer()) : null);
		answerDetails.setTimeAnswer(doPatientAnswerDetails.getTimeAnswer() != null ? new Time(doPatientAnswerDetails.getTimeAnswer()) : null);
		answerDetails.setStringAnswer(doPatientAnswerDetails.getStringAnswer());
		answerDetails.setIntegerAnswer(doPatientAnswerDetails.getIntegerAnswer());
		answerDetails.setDecimalAnswer(doPatientAnswerDetails.getDecimalAnswer());
		answerDetails.setPartialDate(doPatientAnswerDetails.getPartialDate() != null ? new PartialDate(doPatientAnswerDetails.getPartialDate()) : null);
		
		if(doPatientAnswerDetails.getMultiSelectAnswers() != null)
		{
			answerDetails.setMultiSelectAnswers(new Answer_OptionVoCollection());
			
			for (Object next : doPatientAnswerDetails.getMultiSelectAnswers())
			{
				if(next instanceof AnswerOption)
				{
					answerDetails.getMultiSelectAnswers().add(assembleAnswerOption((AnswerOption) next));
				}
			}	
		}
		
		return answerDetails;
	}
	
	private User_AssessmentVo assembleUserAssessment(UserAssessment doUserAssessment) 
	{
		if(doUserAssessment == null)
			return null;
		
		User_AssessmentVo userAssessment = new User_AssessmentVo(doUserAssessment.getId(), doUserAssessment.getVersion());
		
		userAssessment.setIsRIE(doUserAssessment.getIsRIE());
		userAssessment.setName(doUserAssessment.getName());
		userAssessment.setDescription(doUserAssessment.getDescription());
		userAssessment.setGroupQuestionWidth(doUserAssessment.getGroupQuestionWidth());
		userAssessment.setHelpURL(doUserAssessment.getHelpURL());
		userAssessment.setIsFlatView(doUserAssessment.isIsFlatView());
		userAssessment.setIsMultipleGroup(doUserAssessment.isIsMultipleGroup());
		userAssessment.setHeaderText(doUserAssessment.getHeaderText());
		userAssessment.setFooterText(doUserAssessment.getFooterText());
		userAssessment.setMaxHeaderHeight(doUserAssessment.getMaxHeaderHeight());
		userAssessment.setMaxFooterHeight(doUserAssessment.getMaxFooterHeight());
		userAssessment.setAssessmentType(doUserAssessment.getAssessmentType() != null ? LookupHelper.getUserDefinedAssessmentTypeInstance(getLookupService(), doUserAssessment.getAssessmentType().getId()) : null);
		userAssessment.setScoringMethod(doUserAssessment.getScoringMethod() != null ? LookupHelper.getUserAssessmentScoringMethodInstance(getLookupService(), doUserAssessment.getScoringMethod().getId()) : null);
		userAssessment.setAssociatedReport(doUserAssessment.getAssociatedReport() != null ? new TemplateBoRefVo(doUserAssessment.getAssociatedReport().getId(), doUserAssessment.getAssociatedReport().getVersion()) : null);
		userAssessment.setStorePrintedAssessment(doUserAssessment.isStorePrintedAssessment());
		userAssessment.setCanCopyLast(doUserAssessment.isCanCopyLast());
		userAssessment.setCopyLastFromContext(doUserAssessment.getCopyLastFromContext() != null ? ims.assessment.vo.lookups.LookupHelper.getCopyLastAssessmentContextTypeInstance(getLookupService(), doUserAssessment.getCopyLastFromContext().getId()) : null);
		userAssessment.setCategory(doUserAssessment.getCategory() != null ? LookupHelper.getUserAssessmentCategoryInstance(getLookupService(), doUserAssessment.getCategory().getId()) : null);
		
		if(doUserAssessment.getQuestionGroups() != null)
		{
			userAssessment.setQuestionGroups(new Assessment_QuestionGroupVoCollection());
			
			for (Object next : doUserAssessment.getQuestionGroups())
			{
				if(next instanceof AssessmentQuestionGroup)
				{
					userAssessment.getQuestionGroups().add(assembleAssessmentQuestionGroup((AssessmentQuestionGroup) next));
				}
			}
		}
		
		userAssessment.setAssessmentRoles(AssessmentRoleVoAssembler.createAssessmentRoleVoCollectionFromAssessmentRole(doUserAssessment.getAssessmentRoles())); //WDEV-3709
		
		return userAssessment;
	}
	
	private Assessment_QuestionGroupVo assembleAssessmentQuestionGroup(AssessmentQuestionGroup doAssessmentQuestionGroup) 
	{
		if(doAssessmentQuestionGroup == null)
			return null;
		
		Assessment_QuestionGroupVo assessmentGroup = new Assessment_QuestionGroupVo(doAssessmentQuestionGroup.getId(), doAssessmentQuestionGroup.getVersion());
		
		assessmentGroup.setIsRIE(doAssessmentQuestionGroup.getIsRIE());
		assessmentGroup.setName(doAssessmentQuestionGroup.getName());
		assessmentGroup.setActiveStatus(doAssessmentQuestionGroup.getActiveStatus() != null ? LookupHelper.getPreActiveActiveInactiveStatusInstance(getLookupService(), doAssessmentQuestionGroup.getActiveStatus().getId()) : null);
		assessmentGroup.setDescription(doAssessmentQuestionGroup.getDescription());
		assessmentGroup.setLegendText(doAssessmentQuestionGroup.getLegendText());
		
		if(doAssessmentQuestionGroup.getQuestions() != null)
		{
			assessmentGroup.setQuestions(new Assessment_QuestionVoCollection());
			
			for (Object next : doAssessmentQuestionGroup.getQuestions())
			{
				if(next instanceof AssessmentQuestion)
				{
					assessmentGroup.getQuestions().add(assembleAssessmentQuestion((AssessmentQuestion) next));
				}
			}
		}
		
		return assessmentGroup;
	}

	private Assessment_QuestionVo assembleAssessmentQuestion(AssessmentQuestion doAssessmentQuestion) 
	{
		if(doAssessmentQuestion == null)
			return null;
		
		Assessment_QuestionVo assessmentQuestion = new Assessment_QuestionVo(doAssessmentQuestion.getId(), doAssessmentQuestion.getVersion());
		
		assessmentQuestion.setIsRIE(doAssessmentQuestion.getIsRIE());
		assessmentQuestion.setLegendText(doAssessmentQuestion.getLegendText());
		assessmentQuestion.setQuestion(assembleQuestionInformation(doAssessmentQuestion.getQuestion()));
		assessmentQuestion.setIsMandatory(doAssessmentQuestion.isIsMandatory());
		assessmentQuestion.setActiveStatus(doAssessmentQuestion.getActiveStatus() != null ? LookupHelper.getPreActiveActiveInactiveStatusInstance(getLookupService(), doAssessmentQuestion.getActiveStatus().getId()) : null);
		assessmentQuestion.setAllowsMultipleAnswers(doAssessmentQuestion.isAllowsMultipleAnswers());
		assessmentQuestion.setSequence(doAssessmentQuestion.getSequence());
		assessmentQuestion.setAssessmentAnswerRole(AssessmentQuestionRoleVoAssembler.createAssessmentQuestionRoleVoCollectionFromAssessmentQuestionRole(doAssessmentQuestion.getAssessmentAnswerRole()));	//	WDEV-3709
		
		return assessmentQuestion;
	}
	
	private Question_InformationVo assembleQuestionInformation(QuestionInformation doQuestionInformation) 
	{
		if(doQuestionInformation == null)
			return null;
		
		Question_InformationVo questionInformation = new Question_InformationVo(doQuestionInformation.getId(), doQuestionInformation.getVersion());
		questionInformation.setIsRIE(doQuestionInformation.getIsRIE());
		questionInformation.setText(doQuestionInformation.getText());
		questionInformation.setShortText(doQuestionInformation.getShortText());
		questionInformation.setIsQuestion(doQuestionInformation.isIsQuestion());
		questionInformation.setStatus(doQuestionInformation.getStatus() != null ? LookupHelper.getPreActiveActiveInactiveStatusInstance(getLookupService(), doQuestionInformation.getStatus().getId()) : null);
		questionInformation.setGenderSpecific(ims.admin.vo.lookups.LookupHelper.getGenderSpecificInstance(getLookupService(), doQuestionInformation.getGenderSpecific().getId()));
		questionInformation.setAgeRangeMin(doQuestionInformation.getAgeRangeMin());
		questionInformation.setAgeRangeMax(doQuestionInformation.getAgeRangeMax());
		questionInformation.setLegendText(doQuestionInformation.getLegendText());
		
		if(doQuestionInformation.getAnswerTypes() != null)
		{
			questionInformation.setAnswerTypes(new Question_AnswerTypeVoCollection());
			
			for (Object next : doQuestionInformation.getAnswerTypes())
			{
				if(next instanceof QuestionAnswerType)
				{
					questionInformation.getAnswerTypes().add(assembleQuestionAnswerType((QuestionAnswerType) next));
				}
			}
		}
		
		return questionInformation;
	}
	
	private Question_AnswerTypeVo assembleQuestionAnswerType(QuestionAnswerType doQuestionAnswerType) 
	{
		if(doQuestionAnswerType == null)
			return null;
		
		Question_AnswerTypeVo questionAnswerType = new Question_AnswerTypeVo(doQuestionAnswerType.getId(), doQuestionAnswerType.getVersion());
		
		questionAnswerType.setIsRIE(doQuestionAnswerType.getIsRIE());
		questionAnswerType.setAnswerType(doQuestionAnswerType.getAnswerType() != null ? LookupHelper.getQuestionAnswerTypeInstance(getLookupService(), doQuestionAnswerType.getAnswerType().getId()) : null);
		questionAnswerType.setActiveStatus(doQuestionAnswerType.isActiveStatus());
		questionAnswerType.setAnswerWidth(doQuestionAnswerType.getAnswerWidth());
		questionAnswerType.setSeparatorText(doQuestionAnswerType.getSeparatorText());
		questionAnswerType.setMaxMultiselectAllowed(doQuestionAnswerType.getMaxMultiselectAllowed());
		questionAnswerType.setIsMandatory(doQuestionAnswerType.isIsMandatory());
		questionAnswerType.setMandatoryValMessage(doQuestionAnswerType.getMandatoryValMessage());
		
		if(doQuestionAnswerType.getOptions() != null)
		{
			questionAnswerType.setOptions(new Answer_OptionVoCollection());
			
			for (Object next : doQuestionAnswerType.getOptions())
			{
				if(next instanceof AnswerOption)
				{
					questionAnswerType.getOptions().add(assembleAnswerOption((AnswerOption) next));
				}
			}		
		}
		
		return questionAnswerType;
	}
	private Answer_OptionVo assembleAnswerOption(AnswerOption doAnswerOption) 
	{
		if(doAnswerOption == null)
			return null;
		
		Answer_OptionVo answerOption = new Answer_OptionVo(doAnswerOption.getId(), doAnswerOption.getVersion());
		answerOption.setIsRIE(doAnswerOption.getIsRIE());
		answerOption.setOptionText(doAnswerOption.getOptionText());
		answerOption.setOptionDescription(doAnswerOption.getOptionDescription());
		answerOption.setColour(doAnswerOption.getColour());
		answerOption.setScore(doAnswerOption.getScore());
		
		return answerOption;
	}
	
	private Graphic_AssessmentVo assembleGraphicAssessment(GraphicAssessment doGraphicAssessment) 
	{
		if(doGraphicAssessment == null)
			return null;
		
		Graphic_AssessmentVo graphicAssessment = new Graphic_AssessmentVo(doGraphicAssessment.getId(), doGraphicAssessment.getVersion());
		
		graphicAssessment.setIsRIE(doGraphicAssessment.getIsRIE());
		graphicAssessment.setName(doGraphicAssessment.getName());
		graphicAssessment.setAssessmentType(doGraphicAssessment.getAssessmentType() != null ? LookupHelper.getUserDefinedAssessmentTypeInstance(getLookupService(), doGraphicAssessment.getAssessmentType().getId()) : null);
		graphicAssessment.setActiveStatus(doGraphicAssessment.getActiveStatus() != null ? LookupHelper.getPreActiveActiveInactiveStatusInstance(getLookupService(), doGraphicAssessment.getActiveStatus().getId()) : null);
		graphicAssessment.setStorePrintedReport(doGraphicAssessment.isStorePrintedReport());
		graphicAssessment.setHelpUrl(doGraphicAssessment.getHelpUrl());
		
		// WDEV-13730
		if (doGraphicAssessment.getAssociatedReportForPrinting() != null)
		{
			graphicAssessment.setAssociatedReportForPrinting(new TemplateBoRefVo(doGraphicAssessment.getAssociatedReportForPrinting().getId(), doGraphicAssessment.getAssociatedReportForPrinting().getVersion()));
		}
		else
		{
			graphicAssessment.setAssociatedReportForPrinting(null);
		}
		
		graphicAssessment.setImages(DrawingGraphicImageVoAssembler.createDrawingGraphicImageVoCollectionFromDrawingGraphicImage(doGraphicAssessment.getImages()));
		
		if(doGraphicAssessment.getAssociatedQuestions() != null)
		{
			graphicAssessment.setAssociatedQuestions(new Graphic_AssessmentQuestionVoCollection());
			
			for (Object next : doGraphicAssessment.getAssociatedQuestions())
			{
				if(next instanceof GraphicAssessmentQuestion)
				{
					graphicAssessment.getAssociatedQuestions().add(assembleGraphicAssessmentQuestion((GraphicAssessmentQuestion) next));
				}
			}
		}
		
		if(doGraphicAssessment.getFindingsAndQuestions() != null)
		{
			graphicAssessment.setFindingsAndQuestions(new Graphic_AssessmentFindingVoCollection());
			
			for (Object next : doGraphicAssessment.getFindingsAndQuestions())
			{
				if(next instanceof GraphicAssessmentFinding)
				{
					graphicAssessment.getFindingsAndQuestions().add(assembleGraphicAssessmentFinding((GraphicAssessmentFinding) next));
				}
			}
		}
		
		return graphicAssessment;
	}
	
	private Graphic_AssessmentFindingVo assembleGraphicAssessmentFinding(GraphicAssessmentFinding doGraphicAssessmentFinding) 
	{
		if(doGraphicAssessmentFinding == null)
			return null;
		
		Graphic_AssessmentFindingVo graphicAssessmentFinding = new Graphic_AssessmentFindingVo(doGraphicAssessmentFinding.getId(), doGraphicAssessmentFinding.getVersion());
		
		graphicAssessmentFinding.setIsRIE(doGraphicAssessmentFinding.getIsRIE());
		graphicAssessmentFinding.setSequence(doGraphicAssessmentFinding.getSequence());
		graphicAssessmentFinding.setFinding(DrawingGraphicFindingVoAssembler.create(doGraphicAssessmentFinding.getFinding()));
		
		if(doGraphicAssessmentFinding.getFindingStage() != null)
		{
			graphicAssessmentFinding.setFindingStage(new Finding_StageQuestionsVoCollection());
			
			for (Object next : doGraphicAssessmentFinding.getFindingStage())
			{
				if(next instanceof FindingStageQuestions)
				{
					graphicAssessmentFinding.getFindingStage().add(assembleFindingStageQuestions((FindingStageQuestions) next));
				}
			}	
		}	
		
		return graphicAssessmentFinding;
	}
	
	private Finding_StageQuestionsVo assembleFindingStageQuestions(FindingStageQuestions doFindingStageQuestions) 
	{
		if(doFindingStageQuestions == null)
			return null;
		
		Finding_StageQuestionsVo findingStageQuestions = new Finding_StageQuestionsVo(doFindingStageQuestions.getId(), doFindingStageQuestions.getVersion());
		
		findingStageQuestions.setIsRIE(doFindingStageQuestions.getIsRIE());
		findingStageQuestions.setAssessmentStage(assembleGraphicAssessmentStage(doFindingStageQuestions.getAssessmentStage()));
		
		if(doFindingStageQuestions.getAssociatedQuestions() != null)
		{
			findingStageQuestions.setAssociatedQuestions(new Graphic_AssessmentFindingQuestionVoCollection());
			
			for (Object next : doFindingStageQuestions.getAssociatedQuestions())
			{
				if(next instanceof GraphicAssessmentFindingQuestion)
				{
					findingStageQuestions.getAssociatedQuestions().add(assembleGraphicAssessmentFindingQuestion((GraphicAssessmentFindingQuestion) next));
				}
			}
		}
		
		return findingStageQuestions;
	}
	
	private Graphic_AssessmentFindingQuestionVo assembleGraphicAssessmentFindingQuestion(GraphicAssessmentFindingQuestion doGraphicAssessmentFindingQuestion) 
	{
		if(doGraphicAssessmentFindingQuestion == null)
			return null;
		
		Graphic_AssessmentFindingQuestionVo graphicAssessmentFindingQuestion = new Graphic_AssessmentFindingQuestionVo(doGraphicAssessmentFindingQuestion.getId(), doGraphicAssessmentFindingQuestion.getVersion());
		
		graphicAssessmentFindingQuestion.setIsRIE(doGraphicAssessmentFindingQuestion.getIsRIE());
		graphicAssessmentFindingQuestion.setQuestion(assembleQuestionInformation(doGraphicAssessmentFindingQuestion.getQuestion()));
		graphicAssessmentFindingQuestion.setActiveStatus(doGraphicAssessmentFindingQuestion.getActiveStatus() != null ? LookupHelper.getPreActiveActiveInactiveStatusInstance(getLookupService(), doGraphicAssessmentFindingQuestion.getActiveStatus().getId()) : null);
		graphicAssessmentFindingQuestion.setIsMandatory(doGraphicAssessmentFindingQuestion.isIsMandatory());
		graphicAssessmentFindingQuestion.setSequence(doGraphicAssessmentFindingQuestion.getSequence());
		graphicAssessmentFindingQuestion.setAllowsMultipleAnswers(doGraphicAssessmentFindingQuestion.isAllowsMultipleAnswers());
			
		return graphicAssessmentFindingQuestion;
	}
	
	private Graphic_AssessmentStageVo assembleGraphicAssessmentStage(GraphicAssessmentStage doGraphicAssessmentStage) 
	{
		if(doGraphicAssessmentStage == null)
			return null;
		
		Graphic_AssessmentStageVo graphicAssessmentStage = new Graphic_AssessmentStageVo(doGraphicAssessmentStage.getId(), doGraphicAssessmentStage.getVersion());
		
		graphicAssessmentStage.setIsRIE(doGraphicAssessmentStage.getIsRIE());
		graphicAssessmentStage.setIsAnnotated(doGraphicAssessmentStage.isIsAnnotated());
		graphicAssessmentStage.setStageName(doGraphicAssessmentStage.getStageName());
		graphicAssessmentStage.setIsActive(doGraphicAssessmentStage.isIsActive());
		
		return graphicAssessmentStage;
	}
	
	private Graphic_AssessmentQuestionVo assembleGraphicAssessmentQuestion(GraphicAssessmentQuestion doGraphicAssessmentQuestion) 
	{
		if(doGraphicAssessmentQuestion == null)
			return null;
		
		Graphic_AssessmentQuestionVo graphicAssessmentQuestion = new Graphic_AssessmentQuestionVo(doGraphicAssessmentQuestion.getId(), doGraphicAssessmentQuestion.getVersion());
		
		graphicAssessmentQuestion.setIsRIE(doGraphicAssessmentQuestion.getIsRIE());
		graphicAssessmentQuestion.setIsMandatory(doGraphicAssessmentQuestion.isIsMandatory());
		graphicAssessmentQuestion.setActiveStatus(doGraphicAssessmentQuestion.getActiveStatus() != null ? LookupHelper.getPreActiveActiveInactiveStatusInstance(getLookupService(), doGraphicAssessmentQuestion.getActiveStatus().getId()) : null);
		graphicAssessmentQuestion.setQuestion(assembleQuestionInformation(doGraphicAssessmentQuestion.getQuestion()));
		graphicAssessmentQuestion.setSequence(doGraphicAssessmentQuestion.getSequence());
		graphicAssessmentQuestion.setAllowsMultipleAnswers(doGraphicAssessmentQuestion.isAllowsMultipleAnswers());
		
		return graphicAssessmentQuestion;
	}
	//WDEV-12215 - ends here


	/**
	 * WDEV-13704
	 * Function used to retrieve Report and Template
	 */
	public String[] getReportAndTemplate(TemplateBoRefVo template)
	{
		String[] result = null;

		if (template == null || !template.getID_TemplateBoIsNotNull())
			return null;

		@SuppressWarnings("rawtypes")
		List list = getDomainFactory().find("select rep.reportXml, tmpl.templateXml from TemplateBo as tmpl left join tmpl.report as rep where tmpl.id = :ID", "ID", template.getID_TemplateBo());

		if (list.iterator().hasNext())
		{
			Object[] obj = (Object[]) list.iterator().next();

			result = new String[] { (String) obj[0], (String) obj[1] };
		}

		return result;
	}
	//wdev-14028
	public UserAssessmentWithServiceCollVo getUserAssessment(UserAssessmentRefVo assessRef) 
	{
		if(assessRef == null)
			return null;
		UserAssessment domainUserAsses = (UserAssessment) getDomainFactory().getDomainObject(UserAssessment.class, assessRef.getID_UserAssessment());
		return UserAssessmentWithServiceCollVoAssembler.create(domainUserAsses);
	}
	
	//wdev-15972
	public PatientDocumentLiteVo getPatientDocumentLiteVo(PatientDocumentRefVo patDocRef) 
	{
		if( patDocRef == null )
			return null;
		
		PatientDocument doPatientDocument = (PatientDocument)getDomainFactory().getDomainObject(PatientDocument.class, patDocRef.getID_PatientDocument());
		return PatientDocumentLiteVoAssembler.create(doPatientDocument);
		
	}

}
