

package gov.va.med.cds.client.functional;


import gov.va.med.cds.clinicaldata.DomainEntryPoint;
import gov.va.med.cds.testharness.vhim400.RequestIdAppendingElementModifier;
import gov.va.med.cds.testharness.vhim400.SchemaBasedElementModifier;
import gov.va.med.cds.testharness.vhim400.TemplateIdHelper;
import gov.va.med.cds.testharness.vhim400.builders.BaseDatatypesBuilder;
import gov.va.med.cds.testharness.vhim400.builders.ClinicalDataBuilderInterface;
import gov.va.med.cds.testharness.vhim400.builders.ClinicalDomainBuilderFactoryInterface;
import gov.va.med.cds.testharness.vhim400.builders.FilterBuilder;
import gov.va.med.cds.testharness.vhim400.builders.OutpatientMedicationPromiseBuilder;
import gov.va.med.cds.testharness.vhim400.builders.PathwaysDataBuilder;
import gov.va.med.cds.testharness.vhim400.builders.SensitivePatientDataAccessBuilder;
import gov.va.med.cds.testharness.vhim400.builders.SensitivePatientDataAccessBuilderFactory;

import java.io.IOException;
import java.io.StringReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.XMLGregorianCalendar;

import org.apache.commons.collections4.map.MultiValueMap;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXModifier;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;


@SuppressWarnings( "unchecked" )
public class DataGenerator
{
    private static final String DATE_FORMAT_PATTERN = "yyyy-MM-dd";
    private static final String COMMENT_8K_SIZE = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz";
    private ClinicalDataBuilderInterface clinicalDataBuilder = null;


    public void setClinicalDataBuilder( ClinicalDataBuilderInterface clinicalDataBuilder )
    {
        this.clinicalDataBuilder = clinicalDataBuilder;
    }


    public ClinicalDataBuilderInterface getClinicalDataBuilder( )
    {
        return clinicalDataBuilder;
    }


    public String createAllergyAssessmentXml( String requestId, String templateId, String patientIdentity )
    {
        Element patient = null;
        if ( patientIdentity == null )
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "allergyAssessmentTest" );
        }
        else
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "allergyAssessmentTest", patientIdentity );
        }

        Document vdmClinicalDataInsert = clinicalDataBuilder.createClinicalData( templateId, 1, patient );
        return vdmClinicalDataInsert.asXML();
    }


    public String modifyTemplateMetaDataOfCRUADResultXml( String templateId, String xml )
        throws Exception
    {

        Document modifiedDoc = modifyTemplateMetaDataOfCRUADResultDocument( templateId, xml );
        return modifiedDoc.asXML();
    }


    public Document modifyTemplateMetaDataOfCRUADResultDocument( String templateId, String xml )
        throws Exception
    {

        SAXModifier modifier = new SAXModifier();

        SchemaBasedElementModifier elementModifier = new SchemaBasedElementModifier();

        elementModifier.setTemplateId( templateId );

        modifier.addModifier( "/ClinicalData", elementModifier );

        return modifier.modify( new StringReader( xml ) );
    }


    public String setClinicalDataObservationTime( String xml, String entryPoint )
        throws Exception
    {
        Document clinicalDataDocument = DocumentHelper.parseText( xml );
        List<Node> nodes = clinicalDataDocument.selectNodes( "/ClinicalData/patient/*/observationTime/literal" );

        for ( Node obsTimeLiteral : nodes )
        {
            obsTimeLiteral.setText( null );
        }

        return clinicalDataDocument.asXML();

    }


    /*******************************************************************************************************************
     * After automating the functional tests using VDM builders; the Expected Results generation needed to be automated
     * as well. The Expected Result is generated using CREATE XML used for the write request. To create the Expected
     * Result for a scenario where 2 consecutive writes happen; the entry points from the multiple write requests need
     * to be merged
     * 
     * @param entryPoint is the domain of the CREATE and READ request
     * @param createXML is the CREATE request XML
     * @param createXMLWithNoObervationEvent is the subsequent CREATE request XML
     */
    public String mergeExpectedResult( String entryPoint, String createXML, String createXMLWithNoObervationEvent )
        throws Exception
    {
        Document mergedDocument = DocumentHelper.createDocument();
        Document createDocument = DocumentHelper.parseText( createXML );
        Document createDocumentWithNoObservationEvent = DocumentHelper.parseText( createXMLWithNoObervationEvent );

        Element mergedRootElement = ( Element )createDocument.getRootElement().detach();
        mergedDocument.setRootElement( mergedRootElement );
        Element mergedPatient = ( Element )mergedDocument.selectSingleNode( "/ClinicalData/patient" );

        // select the observation event nodes based on an appropriate xpath express
        List<Node> nodes = createDocumentWithNoObservationEvent.selectNodes( buildObservationXpathFromEntryPoint( entryPoint ) );
        for ( Node node : nodes )
        {
            node.detach();
            mergedPatient.add( node );
        }

        return mergedDocument.asXML();

    }


    private String buildObservationXpathFromEntryPoint( String entryPoint )
    {
        String xpathFormat = "ClinicalData/patient/%s";

        if ( TemplateIdHelper.VITALSIGNS_READ_TEMPLATE_ID.equals( entryPoint ) )
        {
            return String.format( xpathFormat, "vitalSignObservationEvents" );
        }

        else if ( TemplateIdHelper.ALLERGY_ASSESSMENT_READ_TEMPLATE_ID.equals( entryPoint ) )
        {
            return String.format( xpathFormat, "allergyAssessments" );
        }

        else if ( TemplateIdHelper.PHARMACY_READ_TEMPLATE_ID.equals( entryPoint ) )
        {
            return String.format( xpathFormat, "outpatientMedicationPromises" );
        }

        else if ( TemplateIdHelper.INTOLERANCE_CONDITION_READ_TEMPLATE_ID.equals( entryPoint )
                        || TemplateIdHelper.INTOLERANCE_CONDITION_REDUCED_READ_TEMPLATE_ID.equals( entryPoint ) )
        {
            return String.format( xpathFormat, "intoleranceConditions" );
        }

        throw new IllegalArgumentException( String.format( "Invalid entry point: %s. Please provide a valid entry point.", entryPoint ) );
    }


    /*******************************************************************************************************************
     * 
     * The Record Identifiers between 2 XML files are set to the same value. The Record Identifier needs to be the same
     * between two requests for the two requests to be related.
     * 
     * @param entryPoint is the domain of the request XML
     * @param createXML is the request whose Record Identifier needs to be related to all other subsequent requests
     * @param createXMLWithDifferentRecordIdentifier is the request whose Record Identifier will get reset to the 1st
     *            request
     * @return the request XML whose Record Identifier has been reset
     */
    public String makeRecordIdentifierIdentical( String entryPoint, String createXML, String createXMLWithDifferentRecordIdentifier )
        throws Exception
    {

        Document createDocument = DocumentHelper.parseText( createXML );
        Document createDocumentWithDifferentRecordIdentifier = DocumentHelper.parseText( createXMLWithDifferentRecordIdentifier );

        Element recordIdentifierFrom = ( Element )createDocument.selectSingleNode( "/ClinicalData/patient/*/recordIdentifier" );
        Element recordIdentifierTo = ( Element )createDocumentWithDifferentRecordIdentifier
                        .selectSingleNode( "/ClinicalData/patient/*/recordIdentifier" );

        copyRecordIdentifier( recordIdentifierFrom, recordIdentifierTo );

        return createDocumentWithDifferentRecordIdentifier.asXML();
    }


    private void copyRecordIdentifier( Element recordIdentifierFrom, Element recordIdentifierTo )
    {
        recordIdentifierTo.element( "identity" ).setText( recordIdentifierFrom.elementText( "identity" ) );
        recordIdentifierTo.element( "namespaceId" ).setText( recordIdentifierFrom.elementText( "namespaceId" ) );
        recordIdentifierTo.element( "universalId" ).setText( recordIdentifierFrom.elementText( "universalId" ) );
        recordIdentifierTo.element( "universalIdType" ).setText( recordIdentifierFrom.elementText( "universalIdType" ) );
    }


    public String[] createIntoleranceConditionXmlWithTemplateIdentifier( String requestId, String templateId, String templateIdentifierForReadResult )
        throws Exception
    {
        Element patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "intoleranceConditionTest" );
        Document clinicalDataInsertDocument = clinicalDataBuilder.createClinicalData( templateId, 1, patient );
        updateRequestId( clinicalDataInsertDocument, requestId );
        String clinicalDataInsertXml = clinicalDataInsertDocument.asXML();
        return new String[] { clinicalDataInsertXml, createExpectedReadResultXML( requestId, clinicalDataInsertXml, templateIdentifierForReadResult ) };
    }


    public String createIntoleranceConditionXml( String templateId, String requestId, String patientIdentity )
        throws Exception
    {
        Element patient = null;
        if ( patientIdentity == null )
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "intoleranceConditionTest" );
        }
        else
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "intoleranceConditionTest", patientIdentity );
        }

        Document clinicalDataInsertDocument = clinicalDataBuilder.createClinicalData( templateId, 1, patient );
        updateRequestId( clinicalDataInsertDocument, requestId );
        return clinicalDataInsertDocument.asXML();
    }


    public String createDODIntoleranceConditionXml( String templateId, String requestId, String patientIdentity )
        throws Exception
    {
        Element patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "patient", patientIdentity, "200CH", "USDOD" );

        Document clinicalDataInsertDocument = clinicalDataBuilder.createClinicalData( templateId, 1, patient );
        updateRequestId( clinicalDataInsertDocument, requestId );
        return clinicalDataInsertDocument.asXML();
    }


    public String createAllergyAssessmentCreateXml( String templateId, String requestId, String patientIdentity )
        throws Exception
    {
        Element patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "patient", patientIdentity, "200CH", "USDOD" );

        Document clinicalDataInsertDocument = clinicalDataBuilder.createClinicalData( templateId, 1, patient );
        updateRequestId( clinicalDataInsertDocument, requestId );
        return clinicalDataInsertDocument.asXML();
    }


    public String[] createAllergies( String assessmentTemplateId, String intoleranceConditionTemplateId, String requestId, String patientIdentifier )
    {

        Element patient = null;
        if ( patientIdentifier == null )
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "allergiesTest" );
        }
        else
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "allergiesTest", patientIdentifier );
        }

        Document assessementInsertDocument = clinicalDataBuilder.createClinicalData( assessmentTemplateId, 1, patient );
        updateRequestId( assessementInsertDocument, requestId );

        Document intoleranceConditionInsertDocument = clinicalDataBuilder.createClinicalData( intoleranceConditionTemplateId, 1, patient );
        updateRequestId( intoleranceConditionInsertDocument, requestId );

        return new String[] { assessementInsertDocument.asXML(), intoleranceConditionInsertDocument.asXML() };
    }


    public String mergeCreateRequests( String crateRequest1, String createRequest2, String entryPoint )
        throws Exception
    {
        Document mergedDocument = DocumentHelper.createDocument();
        Document createDocument1 = DocumentHelper.parseText( crateRequest1 );
        Document createDocument2 = DocumentHelper.parseText( createRequest2 );

        Element mergedRootElement = ( Element )createDocument1.getRootElement().detach();
        mergedDocument.setRootElement( mergedRootElement );
        Element mergedPatient = ( Element )mergedDocument.selectSingleNode( "/ClinicalData/patient" );

        // select the observation event nodes based on an appropriate xpath express
        List<Node> nodes = createDocument2.selectNodes( "ClinicalData/patient/" + entryPoint );
        for ( Node node : nodes )
        {
            node.detach();
            mergedPatient.add( node );
        }

        return mergedDocument.asXML();
    }


    private void updateRequestId( Document clinicalData, String requestId )
    {
        updateElement( clinicalData, FilterBuilder.REQUEST_ID_XPATH, requestId );
    }


    private void updateElement( Document clinicalData, String nodePath, String nodeValue )
    {
        Element element = ( Element )clinicalData.selectSingleNode( nodePath );
        if ( element != null )
        {
            element.setText( nodeValue );
        }
    }


    public String createIntoleranceConditionWithDateRangeXml( String observationDate )
    {
        Document clinicalDataInsertDocument = clinicalDataBuilder.createClinicalData( TemplateIdHelper.INTOLERANCE_CONDITION_CREATE_TEMPLATE_ID, 1,
                        "allergyDateTest" );
        List<Node> nodes = clinicalDataInsertDocument.selectNodes( "/ClinicalData/patient/*/observationTime/literal" );
        for ( Node n : nodes )
        {
            n.setText( observationDate );
        }
        return clinicalDataInsertDocument.asXML();
    }


    public String createIntoleranceConditionWithCommentEventXml( String templateId, String requestId )
        throws IOException
    {
        Element patientId = BaseDatatypesBuilder.createHL72PersonIdentifier( "intoleranceConditionTest" );

        Document clinicalDataInsertDocument = clinicalDataBuilder.createClinicalData( templateId, 1, patientId );
        updateRequestId( clinicalDataInsertDocument, requestId );

        List commentNodes = clinicalDataInsertDocument.selectNodes( "//comments" );
        for ( Iterator iterator = commentNodes.iterator(); iterator.hasNext(); )
        {
            Node node = ( Node )iterator.next();
            node.setText( COMMENT_8K_SIZE );
        }

        return clinicalDataInsertDocument.asXML();
    }


    public String[] createIntoleranceConditionAndPharmacyForRDI( String intoleranceConditionTemplateId, String pharmacyTemplateId, String requestId,
                    String patientIdentifier )
    {
        Element patient = null;
        if ( patientIdentifier == null )
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "RDI_IC_RX_TEST" );
        }
        else
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "RDI_IC_RX_TEST", patientIdentifier );
        }

        String ic_gmrAllergyAgent_codingSystem_xPath = "ClinicalData/patient/intoleranceConditions/gmrAllergyAgent/codingSystem";
        String ic_status_Xpath = "ClinicalData/patient/intoleranceConditions/status";
        String rx_medicationCode_codingSystem_xPath = "ClinicalData/patient/outpatientMedicationPromises/pharmacyRequest/orderedMedication/medicationCode/codingSystem";

        Document intoleranceConditionInsertDocument = clinicalDataBuilder.createClinicalData( intoleranceConditionTemplateId, 1, patient );
        updateElement( intoleranceConditionInsertDocument, FilterBuilder.REQUEST_ID_XPATH, requestId );
        updateElement( intoleranceConditionInsertDocument, ic_gmrAllergyAgent_codingSystem_xPath, "99VHA_ERT" );
        updateElement( intoleranceConditionInsertDocument, ic_status_Xpath, "F" );

        Document pharmacyInsertDocument = clinicalDataBuilder.createClinicalData( pharmacyTemplateId, 1, patient );
        updateElement( pharmacyInsertDocument, FilterBuilder.REQUEST_ID_XPATH, requestId );
        updateElement( pharmacyInsertDocument, rx_medicationCode_codingSystem_xPath, "99VHA_ERT" );

        return new String[] { intoleranceConditionInsertDocument.asXML(), pharmacyInsertDocument.asXML() };
    }


    public String createClinicalDocumentEventXml( String templateId, String requestId )
        throws Exception
    {
        Element patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "TIUTest" );
        Document clinicalDataInsertDocument = clinicalDataBuilder.createClinicalData( templateId, 1, patient );
        updateRequestId( clinicalDataInsertDocument, requestId );
        return clinicalDataInsertDocument.asXML();
    }


    public String createQuestionnaireResult( String templateId, String clientName )
    {
        Element patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "DBQTest" );
        Document clinicalDataInsertDocument = clinicalDataBuilder.createClinicalData( templateId, 1, patient );
        clinicalDataBuilder.addAuditInfo( clinicalDataInsertDocument.getRootElement(), clientName );

        return clinicalDataInsertDocument.asXML();
    }


    private Element insertElementAtLocation( Element elementTobeInserted, Element parentElement, int index )
    {
        org.jdom2.Element jdom22ElementTobeInserted = convertDom4jElementTOjdom22Element( elementTobeInserted );
        org.jdom2.Element jdom22ParentElement = convertDom4jElementTOjdom22Element( parentElement );
        jdom22ParentElement.addContent( index, jdom22ElementTobeInserted );
        return convertjdom22ElementTODom4jElement( jdom22ParentElement );
    }


    private org.jdom2.Element convertDom4jElementTOjdom22Element( Element element )
    {
        org.jdom2.Element jdom22Element = null;
        SAXBuilder sb = new SAXBuilder();
        try
        {
            StringReader sr = new StringReader( element.asXML() );
            org.jdom2.Document doc = sb.build( sr );
            jdom22Element = doc.detachRootElement();
        }
        catch ( Exception e )
        {
            throw new RuntimeException( e.getMessage(), e );
        }
        return jdom22Element;
    }


    private Element convertjdom22ElementTODom4jElement( org.jdom2.Element jdom22Element )
    {
        XMLOutputter outputter = new XMLOutputter( Format.getCompactFormat() );
        String xmlString = outputter.outputString( jdom22Element );
        Document dom4jDoc = null;
        try
        {
            dom4jDoc = DocumentHelper.parseText( xmlString );
        }
        catch ( DocumentException e )
        {
            throw new RuntimeException( e.getMessage(), e );
        }
        return dom4jDoc.getRootElement();
    }


    /*******************************************************************************************************************
     * Create expected Read Result XMl for a given CREATE XML
     */
    public String createExpectedReadResultXML( String requestId, String createXml, String readTemplateId )
        throws Exception
    {
        SAXModifier modifier = new SAXModifier();
        SchemaBasedElementModifier elementModifier = new SchemaBasedElementModifier();
        elementModifier.setTemplateId( readTemplateId );
        elementModifier.addElementModifier( new RequestIdAppendingElementModifier() );
        modifier.addModifier( "/ClinicalData", elementModifier );
        return modifier.modify( new StringReader( createXml ) ).asXML();
    }


    public String createVitalObservationEventXml( String requestId, String templateId, String patientIdentifier )
    {
        Element patient = null;
        if ( patientIdentifier == null )
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "vitalSignTest" );
        }
        else
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "vitalSignTest", patientIdentifier );
        }

        Document clinicalDataInsertDocument = clinicalDataBuilder.createClinicalData( templateId, 1, patient );

        updateRequestId( clinicalDataInsertDocument, requestId );
        List<Node> nodes = clinicalDataInsertDocument.selectNodes( "/ClinicalData/patient/*/vitalSignObservationEvents" );
        for ( Node n : nodes )
        {
            n.getParent().setText( "20080401170000" );
        }

        return clinicalDataInsertDocument.asXML();
    }


    public String createDODOutpatientMedicationPromiseXml( String templateId, String requestId, String patientIdentity )
        throws Exception
    {
        Element patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "patient", patientIdentity, "200CH", "USDOD" );

        Document clinicalDataInsertDocument = clinicalDataBuilder.createClinicalData( templateId, 1, patient );
        updateRequestId( clinicalDataInsertDocument, requestId );
        return clinicalDataInsertDocument.asXML();
    }


    public String createOutpatientMedicationPromiseXml( String templateId, String aRequestId, String patientIdentifier )
    {
        Element patient = null;
        if ( patientIdentifier == null )
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "outpatientPharmacyTest" );
        }
        else
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "outpatientPharmacyTest", patientIdentifier );
        }
        Document clinicalDataInsertDocument = clinicalDataBuilder.createClinicalData( templateId, 1, patient );

        //        if ( !templateId.equals( "PharmacyCreateOrUpdate40060" ) )
        updateRequestId( clinicalDataInsertDocument, aRequestId );

        return clinicalDataInsertDocument.asXML();
    }


    public String createOutpatientMedicationPromiseXml( String templateId, String aRequestId, String patientId, String patientAssigningFacility )
    {
        Element patient = BaseDatatypesBuilder.createHL72PersonIdentifier( patientId, patientAssigningFacility );
        Document vdmClinicalDataInsert = clinicalDataBuilder.createClinicalData( templateId, 1, patient );
        updateRequestId( vdmClinicalDataInsert, aRequestId );
        return vdmClinicalDataInsert.asXML();
    }


    public String createDuplicateDODOutpatientMedicationPromiseXml( String templateId, String requestId, String patientIdentity )
        throws Exception
    {
        Element patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "patient", patientIdentity, "200CH", "USDOD" );

        Document clinicalDataInsertDocument = clinicalDataBuilder.createClinicalData( templateId, 1, patient );
        updateRequestId( clinicalDataInsertDocument, requestId );
        setKeysForDuplicateRecord( clinicalDataInsertDocument, "ID_1436913928720" );
        return clinicalDataInsertDocument.asXML();
    }


    private void setKeysForDuplicateRecord( Document clinicalData, String requestId )
    {
        updateElement( clinicalData, "//recordIdentifier/identity", "ID_143717055352810000" );
        updateElement( clinicalData, "//recordUpdateTime/literal", "20150717160233-0600" );
        updateElement( clinicalData, "//recordIdentifier/universalId", "UID_143717055352810000" );
        updateElement( clinicalData, "//recordIdentifier/universalIdType", "universalIdType" );
        updateElement( clinicalData, "//recordIdentifier/namespaceId", "992" );
    }


    public String createOutpatientMedicationPromiseWithSpecificDispensesXml( String aRequestId )
    {
        Element patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "outpatientPharmacyTest" );
        Document vdmClinicalDataInsert = clinicalDataBuilder.createClinicalData( TemplateIdHelper.PHARMACY_CREATE_TEMPLATE_ID, 1, patient );

        updateRequestId( vdmClinicalDataInsert, aRequestId );

        detachDispenseNodes( vdmClinicalDataInsert );

        Element outpatientMedicationPromisesNode = ( Element )vdmClinicalDataInsert
                        .selectSingleNode( "/ClinicalData/patient/outpatientMedicationPromises" );
        outpatientMedicationPromisesNode.detach();

        Element patientNode = ( Element )vdmClinicalDataInsert.selectSingleNode( "/ClinicalData/patient" );

        OutpatientMedicationPromiseBuilder pharmacyBuilder = new OutpatientMedicationPromiseBuilder();
        List<Element> dispenseElements = pharmacyBuilder.makeDispensesElementsForPharmacy( "All", 3 );
        int i = 0;
        for ( Element e : dispenseElements )
        {
            Element modifiedParent = insertElementAtLocation( e, outpatientMedicationPromisesNode, 25 + i );
            outpatientMedicationPromisesNode = modifiedParent;
            i++ ;
        }
        patientNode.add( outpatientMedicationPromisesNode );
        return patientNode.getDocument().asXML();
    }


    private void detachDispenseNodes( Document vdmClinicalDataInsert )
    {
        detachNodes( vdmClinicalDataInsert.selectNodes( "/ClinicalData/patient/outpatientMedicationPromises/originalDispense" ) );
        detachNodes( vdmClinicalDataInsert.selectNodes( "/ClinicalData/patient/outpatientMedicationPromises/refillDispense" ) );
        detachNodes( vdmClinicalDataInsert.selectNodes( "/ClinicalData/patient/outpatientMedicationPromises/partialDispense" ) );
    }


    public void detachNodes( List<Node> nodesToDetach )
    {
        if ( nodesToDetach != null )
        {
            for ( Node nodeToDetach : nodesToDetach )
            {
                nodeToDetach.detach();
            }
        }
    }


    public String createOutpatientMedicationPromiseWithExpiryCancelDatesXml( String aRequestId, int cancelYear, int expirationYear )
    {
        Element patientId = BaseDatatypesBuilder.createHL72PersonIdentifier( "outpatientPharmacyTest" );
        Document vdmClinicalDataInsert = clinicalDataBuilder.createClinicalData( TemplateIdHelper.PHARMACY_CREATE_TEMPLATE_ID, 1, patientId );
        updateRequestId( vdmClinicalDataInsert, aRequestId );

        Element patientNode = ( Element )vdmClinicalDataInsert.selectSingleNode( "/ClinicalData/patient" );

        detachNodeFromDocument( vdmClinicalDataInsert, "/ClinicalData/patient/outpatientMedicationPromises/expirationDate" );
        detachNodeFromDocument( vdmClinicalDataInsert, "/ClinicalData/patient/outpatientMedicationPromises/cancel" );

        Element outpatientMedicationPromisesNode = ( Element )vdmClinicalDataInsert
                        .selectSingleNode( "/ClinicalData/patient/outpatientMedicationPromises" );
        outpatientMedicationPromisesNode.detach();

        OutpatientMedicationPromiseBuilder vdmPharmacyBuilder = new OutpatientMedicationPromiseBuilder();
        Element expiryDateElement = vdmPharmacyBuilder.makeExpiryDateElementForPharmacy( expirationYear );
        outpatientMedicationPromisesNode = insertElementAtLocation( expiryDateElement, outpatientMedicationPromisesNode, 8 );

        Element cancelElement = vdmPharmacyBuilder.makeCancelDateElementForPharmacy( cancelYear );
        outpatientMedicationPromisesNode = insertElementAtLocation( cancelElement, outpatientMedicationPromisesNode, 30 );

        patientNode.add( outpatientMedicationPromisesNode );
        return patientNode.getDocument().asXML();

    }


    private void detachNodeFromDocument( Document vdmClinicalDataInsert, String xPathForNodeToDetach )
    {
        Node nodeToDetach = vdmClinicalDataInsert.selectSingleNode( xPathForNodeToDetach );
        if ( nodeToDetach != null )
            nodeToDetach.detach();
    }


    public String createOutpatientMedicationPromiseWithCommentsXml( String aRequestId )
        throws IOException
    {
        Element patientId = BaseDatatypesBuilder.createHL72PersonIdentifier( "outpatientPharmacyTest" );
        Document vdmClinicalDataInsert = clinicalDataBuilder.createClinicalData( TemplateIdHelper.PHARMACY_CREATE_TEMPLATE_ID, 1, patientId );
        updateRequestId( vdmClinicalDataInsert, aRequestId );

        Element patientNode = ( Element )vdmClinicalDataInsert.selectSingleNode( "/ClinicalData/patient" );

        List<Node> ptInstructionsNodes = vdmClinicalDataInsert
                        .selectNodes( "/ClinicalData/patient/outpatientMedicationPromises/expandedPatientInstructions" );
        int i = 1;
        for ( Node ptInstructionsNode : ptInstructionsNodes )
        {
            ptInstructionsNode.setText( COMMENT_8K_SIZE + i );
            i++ ;
        }

        detachNodeFromDocument( vdmClinicalDataInsert, "/ClinicalData/patient/outpatientMedicationPromises/originalDispense/currentProvider" );
        detachNodeFromDocument( vdmClinicalDataInsert, "/ClinicalData/patient/outpatientMedicationPromises/originalDispense/currentProviderComments" );

        Element originalDispenseElement = ( Element )vdmClinicalDataInsert
                        .selectSingleNode( "/ClinicalData/patient/outpatientMedicationPromises/originalDispense" );
        originalDispenseElement.detach();

        Element outpatientMedicationPromisesElement = ( Element )vdmClinicalDataInsert
                        .selectSingleNode( "/ClinicalData/patient/outpatientMedicationPromises" );
        outpatientMedicationPromisesElement.detach();

        OutpatientMedicationPromiseBuilder vdmPharmacyBuilder = new OutpatientMedicationPromiseBuilder();
        Element currentProviderElement = vdmPharmacyBuilder.makeCurrentProviderForPharmacy();
        Element currentProviderCommentElement = vdmPharmacyBuilder.makeCurrentProviderCommentsForPharmacy( COMMENT_8K_SIZE );

        originalDispenseElement = insertElementAtLocation( currentProviderElement, originalDispenseElement, 5 );
        originalDispenseElement = insertElementAtLocation( currentProviderCommentElement, originalDispenseElement, 6 );

        outpatientMedicationPromisesElement = insertElementAtLocation( originalDispenseElement, outpatientMedicationPromisesElement, 25 );

        patientNode.add( outpatientMedicationPromisesElement );
        return patientNode.getDocument().asXML();

    }


    /**
     * Creates a VDM OutPatientMedicationPromise with expanded patient comments and provider comments of size 8k by
     * calling directly the RxVdmBuilder with non-null identity and marshalls it into xml. Uses vdmclinicaldatabuiler
     * call chain for the inital creation of Rx and later calls the Rx vdmbuilder to add more dispenses; thus
     * vdmclinicaldatabuilder flow is not affected.
     */
    public String createOutpatientMedicationPromiseWithNullCurrentProvider( String aRequestId )
        throws IOException
    {
        Element patientId = BaseDatatypesBuilder.createHL72PersonIdentifier( "outpatientPharmacyTest" );
        Document vdmClinicalDataInsert = clinicalDataBuilder.createClinicalData( TemplateIdHelper.PHARMACY_CREATE_TEMPLATE_ID, 1, patientId );
        updateRequestId( vdmClinicalDataInsert, aRequestId );

        Element patientNode = ( Element )vdmClinicalDataInsert.selectSingleNode( "/ClinicalData/patient" );

        List<Node> ptInstructionsNodes = vdmClinicalDataInsert
                        .selectNodes( "/ClinicalData/patient/outpatientMedicationPromises/expandedPatientInstructions" );
        int i = 1;
        for ( Node ptInstructionsNode : ptInstructionsNodes )
        {
            ptInstructionsNode.setText( COMMENT_8K_SIZE + i );
            i++ ;
        }

        detachNodeFromDocument( vdmClinicalDataInsert, "/ClinicalData/patient/outpatientMedicationPromises/originalDispense/currentProvider" );
        detachNodeFromDocument( vdmClinicalDataInsert, "/ClinicalData/patient/outpatientMedicationPromises/originalDispense/currentProviderComments" );

        Element originalDispenseElement = ( Element )vdmClinicalDataInsert
                        .selectSingleNode( "/ClinicalData/patient/outpatientMedicationPromises/originalDispense" );
        originalDispenseElement.detach();

        Element outpatientMedicationPromisesElement = ( Element )vdmClinicalDataInsert
                        .selectSingleNode( "/ClinicalData/patient/outpatientMedicationPromises" );
        outpatientMedicationPromisesElement.detach();

        OutpatientMedicationPromiseBuilder vdmPharmacyBuilder = new OutpatientMedicationPromiseBuilder();
        //Element currentProviderElement = vdmPharmacyBuilder.makeCurrentProviderForPharmacy();
        Element currentProviderCommentElement = vdmPharmacyBuilder.makeCurrentProviderCommentsForPharmacy( COMMENT_8K_SIZE );

        originalDispenseElement = insertElementAtLocation( currentProviderCommentElement, originalDispenseElement, 5 );

        outpatientMedicationPromisesElement = insertElementAtLocation( originalDispenseElement, outpatientMedicationPromisesElement, 25 );

        patientNode.add( outpatientMedicationPromisesElement );
        return patientNode.getDocument().asXML();

    }


    /**
     * Create Lab Xml using data builders
     * @param aRequestId
     * @param templateId
     * @param patientIdentifier TODO
     * @return xml
     */
    public String createLabEventXml( String aRequestId, String templateId, String patientIdentifier )
    {
        Element patient = null;
        if ( patientIdentifier == null )
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "labTest" );
        }
        else
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "labTest", patientIdentifier );
        }

        Document vdmClinicalDataInsert = clinicalDataBuilder.createClinicalData( templateId, 1, patient );
        Element requestedNationalId = ( Element )vdmClinicalDataInsert.selectSingleNode( "ClinicalData/requestedNationalId" );
        if ( requestedNationalId != null )
        {
            requestedNationalId.setText( "1234567890" );
        }
        updateRequestId( vdmClinicalDataInsert, aRequestId );
        return vdmClinicalDataInsert.asXML();
    }


    /*******************************************************************************************************************
     * createXpathFilterForMultiDomainQuery is used exclusively to create multi domain filters.
     * 
     * @param createXML is a variable argument parameter; the first set arguments are create XMLS followed by XPath
     *            query for each corresponding create XML
     * @return a filter with one or more domains
     */
    public String createXpathFilterForMultiDomainQuery( String filterId, String... createXML )
    {
        // TODO: Figure out what this is supposed to be doing. I really have no clue.
        return null;

        // List<PersonIdentifier> patientIdentifierList = new ArrayList<PersonIdentifier>( createXML.length / 2 );
        // List<EntryFilter> entryFilterList = new ArrayList<EntryFilter>( createXML.length / 2 );
        //
        // for ( int counter = 0; counter < createXML.length / 2; counter++ )
        // {
        // ClinicalData responseClinicalData = ( ClinicalData )marshallerUnmarshaller400.unmarshallToVdm(
        // createXML[counter] );
        // ClinicalDataPatient patient = ( ClinicalDataPatient )responseClinicalData.getPatient().get( 0 );
        //
        // PersonIdentifier personIdentifier = new PersonIdentifier();
        //
        // if ( patient.getIntoleranceConditions().size() > 0 )
        // {
        // IntoleranceCondition intoleranceCondition = ( IntoleranceCondition )patient.getIntoleranceConditions().get( 0
        // );
        //
        // personIdentifier.setIdentity( intoleranceCondition.getPatient().getIdentifier().getIdentity() );
        // personIdentifier.setAssigningAuthority(
        // intoleranceCondition.getPatient().getIdentifier().getAssigningAuthority() );
        // personIdentifier.setAssigningFacility(
        // intoleranceCondition.getPatient().getIdentifier().getAssigningFacility() );
        // }
        // else
        // {
        // OutpatientMedicationPromise outpatientMedicationPromise = ( OutpatientMedicationPromise
        // )patient.getOutpatientMedicationPromises()
        // .get( 0 );
        //
        // personIdentifier.setIdentity( outpatientMedicationPromise.getPatient().getIdentifier().getIdentity() );
        // personIdentifier.setAssigningAuthority(
        // outpatientMedicationPromise.getPatient().getIdentifier().getAssigningAuthority() );
        // personIdentifier.setAssigningFacility(
        // outpatientMedicationPromise.getPatient().getIdentifier().getAssigningFacility() );
        // }
        //
        // patientIdentifierList.add( personIdentifier );
        //
        // }
        //
        // for ( int counter = ( createXML.length / 2 ); counter <= createXML.length - 1; counter++ )
        // {
        // EntryFilter entryFilter = new EntryFilter();
        //
        // if ( createXML[counter].contains( "intoleranceConditions" ) )
        // {
        // entryFilter.setDomainEntryPoint( "IntoleranceCondition" );
        // entryFilter.setQueryName( "IC-Standardized" );
        // }
        // else if ( createXML[counter].contains( "outpatientMedicationPromises" ) )
        // {
        // entryFilter.setDomainEntryPoint( "OutpatientMedicationPromise" );
        // entryFilter.setQueryName( "OMP-Standardized" );
        // }
        //
        // XpathQuery xpathQuery = new XpathQuery();
        // xpathQuery.setXpath( createXML[counter] );
        // entryFilter.setXpathQuery( xpathQuery );
        // entryFilter.setStartDate( null );
        // entryFilter.setEndDate( null );
        //
        // entryFilterList.add( entryFilter );
        // }
        //
        // return createFilter( patientIdentifierList, entryFilterList, filterId );
    }


    public String createFilterFromAllergyAssessment( String xml, String filterId, Map entryFilterMap )
    {
        Document document = FilterBuilder.convertString2Document( xml );
        Element patientIdentifier = document.getRootElement().element( "patient" ).element( "allergyAssessments" ).element( "patient" )
                        .element( "identifier" );
        String assigningFacility = patientIdentifier.element( "assigningFacility" ).getText();
        String assigningAuthority = patientIdentifier.element( "assigningAuthority" ).getText();
        String identity = patientIdentifier.element( "identity" ).getText();

        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createPatient( "patients", assigningAuthority, assigningFacility, identity ) );

        // Use defaults for entryFilter or values from the map.
        String startDate = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.START_DATE_KEY ) ) : null;
        String endDate = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.END_DATE_KEY ) ) : null;
        String xpath = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.X_PATH_KEY ) != null ? ( String )entryFilterMap
                        .get( FilterBuilder.X_PATH_KEY ) : FilterBuilder.NO_XPATH ) : FilterBuilder.NO_XPATH;
        String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                        .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
        element.add( FilterBuilder.createEntryFilter( "entryPointFilter", "AllergyAssessment", startDate, endDate, xpath, queryName, null ) );

        element.addAttribute( "vhimVersion", "Vhim_4_00" );
        return element.asXML();
    }


    public String createFilterFromIntoleranceConditions( String xml, String filterId, Map entryFilterMap )
    {
        String xpath = FilterBuilder.NO_XPATH;

        Document document = FilterBuilder.convertString2Document( xml );
        Element patientIdentifier = document.getRootElement().element( "patient" ).element( "intoleranceConditions" ).element( "patient" )
                        .element( "identifier" );
        String assigningFacility = patientIdentifier.element( "assigningFacility" ).getText();
        String assigningAuthority = patientIdentifier.element( "assigningAuthority" ).getText();
        String identity = patientIdentifier.element( "identity" ).getText();

        if ( filterId.equals( TemplateIdHelper.VW_IC_SINGLE_PATIENT_FILTER ) )
        {
            xpath = FilterBuilder.IC_XPATH;
        }

        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );

        if ( filterId.equals( TemplateIdHelper.CHDR_ALLERGY_SINGLE_PATIENT_FILTER ) )
        {
            element.add( FilterBuilder.createCHDRPatient( "patients", identity, "USDOD", "200HD" ) );
        }
        else
        {
            element.add( FilterBuilder.createPatient( "patients", assigningAuthority, assigningFacility, identity ) );
        }

        // Use defaults for entryFilter or values from the map.
        String startDate = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.START_DATE_KEY ) ) : null;
        String endDate = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.END_DATE_KEY ) ) : null;
        xpath = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.X_PATH_KEY ) != null ? ( String )entryFilterMap
                        .get( FilterBuilder.X_PATH_KEY ) : xpath ) : xpath;
        String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                        .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";

        element.add( FilterBuilder.createEntryFilter( "entryPointFilter", "IntoleranceCondition", startDate, endDate, xpath, queryName, null ) );
        element.addAttribute( "vhimVersion", "Vhim_4_00" );

        return element.asXML();
    }


    public String createFilterFromAllergies( String xml, String filterId )
    {
        Document document = FilterBuilder.convertString2Document( xml );
        Element patientIdentifier = document.getRootElement().element( "patient" ).element( "allergyAssessments" ).element( "patient" )
                        .element( "identifier" );
        String identity = patientIdentifier.element( "identity" ).getText();

        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );

        if ( filterId.equals( TemplateIdHelper.ALLERGY_SINGLE_PATIENT_ALL_DATA_FILTER ) )
        {
            element.add( FilterBuilder.createPatientWithNationalId( "patients", identity, null ) );
        }
        else if ( filterId.equals( TemplateIdHelper.CHDR_ALLERGY_SINGLE_PATIENT_FILTER ) )
        {
            element.add( FilterBuilder.createCHDRPatient( "patients", identity, "USDOD", "200HD" ) );
        }

        element.add( FilterBuilder.createEntryFilter( "entryPointFilter", "AllergyAssessment", null, null, FilterBuilder.NO_XPATH, "id_1", null ) );
        element.add( FilterBuilder.createEntryFilter( "entryPointFilter", "IntoleranceCondition", null, null, FilterBuilder.NO_XPATH, "id_2", null ) );
        element.addAttribute( "vhimVersion", "Vhim_4_00" );
        return element.asXML();
    }


    public String createVwAllergySinglePatientFilter( String xml, String filterId )
    {
        Document document = FilterBuilder.convertString2Document( xml );
        Element patientIdentifier = document.getRootElement().element( "patient" ).element( "allergyAssessments" ).element( "patient" )
                        .element( "identifier" );
        String assigningFacility = patientIdentifier.element( "assigningFacility" ).getText();
        String assigningAuthority = patientIdentifier.element( "assigningAuthority" ).getText();
        String identity = patientIdentifier.element( "identity" ).getText();

        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createPatient( "patients", assigningAuthority, assigningFacility, identity ) );
        element.add( FilterBuilder.createEntryFilter( "entryPointFilter", "AllergyAssessment", null, null, FilterBuilder.ASSESSMENT_XPATH, "ID_1",
                        null ) );
        element.add( FilterBuilder.createEntryFilter( "entryPointFilter", "IntoleranceCondition", null, null, FilterBuilder.IC_XPATH, "ID_2", null ) );
        element.addAttribute( "vhimVersion", "Vhim_4_00" );

        return element.asXML();
    }


    public String createFilterFromOutpatientMedicationPromise( String xml, String filterId, Map entryFilterMap )
    {
        Document document = FilterBuilder.convertString2Document( xml );
        Element patientIdentifier = document.getRootElement().element( "patient" ).element( "outpatientMedicationPromises" ).element( "patient" )
                        .element( "identifier" );
        String assigningFacility = patientIdentifier.element( "assigningFacility" ).getText();
        String assigningAuthority = patientIdentifier.element( "assigningAuthority" ).getText();
        String identity = patientIdentifier.element( "identity" ).getText();

        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createPatient( "patients", assigningAuthority, assigningFacility, identity ) );

        if ( filterId.equals( TemplateIdHelper.RX_SINGLE_PATIENT_ALL_DATA_FILTER ) )
        {
            // Use defaults for entryFilter or values from the map.
            String startDate = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.START_DATE_KEY ) ) : null;
            String endDate = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.END_DATE_KEY ) ) : null;
            String xpath = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.X_PATH_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.X_PATH_KEY ) : FilterBuilder.NO_XPATH ) : FilterBuilder.NO_XPATH;
            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
            element.add( FilterBuilder.createEntryFilter( "entryPointFilter", "OutpatientMedicationPromise", startDate, endDate, queryName, xpath,
                            null ) );
        }
        else if ( filterId.equals( TemplateIdHelper.RX_SINGLE_PATIENT_SINGLE_RECORD_FILTER ) )
        {
            Element recordIdentifier = document.getRootElement().element( "patient" ).element( "outpatientMedicationPromises" )
                            .element( "recordIdentifier" );
            String recordIdentity = recordIdentifier.element( "identity" ).getText();
            String recordNamespaceId = recordIdentifier.element( "namespaceId" ).getText();
            String recordUniversalId = recordIdentifier.element( "universalId" ).getText();

            element.add( FilterBuilder.createEntryFilterWithRecordIdentifiers( "entryPointFilter", "OutpatientMedicationPromise", recordIdentity,
                            recordNamespaceId, recordUniversalId, "ID_1" ) );
        }

        element.addAttribute( "vhimVersion", "Vhim_4_00" );

        return element.asXML();
    }


    public String createChdrPharmacySinglePatientFilter( String xml, String filterId )
    {
        Document document = FilterBuilder.convertString2Document( xml );
        Element patientIdentifier = document.getRootElement().element( "patient" ).element( "outpatientMedicationPromises" ).element( "patient" )
                        .element( "identifier" );
        String identity = patientIdentifier.element( "identity" ).getText();

        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createCHDRPatient( "patients", identity, "USDOD", "200HD" ) );
        element.add( FilterBuilder.createEntryFilter( "entryPointFilter", "OutpatientMedicationPromise", null, null, FilterBuilder.NO_XPATH,
                        "CHDR_RX_QUERY", null ) );
        element.addAttribute( "vhimVersion", "Vhim_4_00" );
        return element.asXML();
    }


    public String createRdiIntoleranceConditionPharmacySinglePatientFilter( String xml, String filterId )
    {
        Document document = FilterBuilder.convertString2Document( xml );
        Element patientIdentifier = document.getRootElement().element( "patient" ).element( "intoleranceConditions" ).element( "patient" )
                        .element( "identifier" );
        String assigningFacility = patientIdentifier.element( "assigningFacility" ).getText();
        String assigningAuthority = patientIdentifier.element( "assigningAuthority" ).getText();
        String identity = patientIdentifier.element( "identity" ).getText();

        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createPatient( "patients", assigningAuthority, assigningFacility, identity ) );
        element.add( FilterBuilder.createEntryFilter( "entryPointFilter", "IntoleranceCondition", null, null, FilterBuilder.RDI_IC_XPATH, "ID_1",
                        null ) );
        element.add( FilterBuilder.createEntryFilter( "entryPointFilter", "OutpatientMedicationPromise", null, null, FilterBuilder.RDI_RX_XPATH,
                        "ID_2", null ) );
        element.addAttribute( "vhimVersion", "Vhim_4_00" );

        return element.asXML();
    }


    public String createTiuSinglePatientDetailedDataFilter( String filterId, String patientIdentity, String assigningFacility,
                    String assigningAuthority, String recordIdentity, String recordNamespaceId, String recordUniversalId )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createPatient( "patients", assigningAuthority, assigningFacility, patientIdentity ) );

        element.add( FilterBuilder.createEntryFilterWithRecordIdentifiers( "entryPointFilter", "ClinicalDocumentEvent", recordIdentity,
                        recordNamespaceId, recordUniversalId, "ID_1" ) );

        element.addAttribute( "vhimVersion", "Vhim_4_00" );
        return element.asXML();
    }


    public String createTiuSinglePatientDetailedDataFilter( String filterId, List<Map<String, String>> resolvedPatients, String recordIdentity,
                    String recordNamespaceId, String recordUniversalId, String recordUniversalIdType )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        element.add( FilterBuilder.createEntryFilterWithRecordIdentifiers( "entryPointFilter", "ClinicalDocumentEvent", recordIdentity,
                        recordNamespaceId, recordUniversalId, recordUniversalIdType, "ID_1" ) );

        element.addAttribute( "vhimVersion", "Vhim_4_00" );
        return element.asXML();
    }


    public String createTiuSinglePatientListDataFilter( List<Map<String, String>> resolvedPatients, String filterId, String documentClassValue,
                    String[] documentTypeValues, String startDate, String endDate )
    {
        //Document document = FilterBuilder.convertString2Document( xml );
        //Element patientIdentifier = document.getRootElement().element( "patient" ).element( "clinicalDocumentEvents" ).element( "patient" ).element("identifier" );
        //String assigningFacility = "521"; //patientIdentifier.element( "assigningFacility" ).getText();
        //String assigningAuthority = patientIdentifier.element( "assigningAuthority" ).getText();
        //String identity = "260"; patientIdentifier.element( "identity" ).getText();

        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );
        element.add( FilterBuilder.createEntryFilterWithAdditionalParameters( "entryPointFilter", "ClinicalDocumentEvent", startDate, endDate,
                        documentClassValue, documentTypeValues, "ID_1", "/referenceDate/literal descending" ) );

        element.addAttribute( "vhimVersion", "Vhim_4_00" );
        return element.asXML();
    }


    public String createTiuSinglePatientListDataFilter( Map<String, String> patientIdentityAndAssigningFacilityMap, String assigningAuthority,
                    String filterId, String documentClassValue, String[] documentTypeValues )
    {
        //Document document = FilterBuilder.convertString2Document( xml );
        //Element patientIdentifier = document.getRootElement().element( "patient" ).element( "clinicalDocumentEvents" ).element( "patient" ).element("identifier" );
        //String assigningFacility = "521"; //patientIdentifier.element( "assigningFacility" ).getText();
        //String assigningAuthority = patientIdentifier.element( "assigningAuthority" ).getText();
        //String identity = "260"; patientIdentifier.element( "identity" ).getText();

        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createPatient( "patients", assigningAuthority, patientIdentityAndAssigningFacilityMap ) );
        element.add( FilterBuilder.createEntryFilterWithAdditionalParameters( "entryPointFilter", "ClinicalDocumentEvent", null, null,
                        documentClassValue, documentTypeValues, "ID_1", "/referenceDate/literal descending" ) );

        element.addAttribute( "vhimVersion", "Vhim_4_00" );
        return element.asXML();
    }


    public String createSinglePatientFilter( String aFilterId, List<Map<String, String>> entryPointFilter, List<Map<String, String>> aResolvedPatients )
    {
        return FilterBuilder.buildFilterWithResolvedIdentfiers( aFilterId, entryPointFilter, aResolvedPatients,
                        DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );
    }


    public String createNonVAMedsSinglePatientDataFilter( String filterId, List<Map<String, String>> entryPointFilter,
                    List<Map<String, String>> resolvedPatients, String statusValue )
    {
        return FilterBuilder.buildNonVaMedFilterWithResolvedIdentfiers( filterId, entryPointFilter, resolvedPatients, statusValue,
                        DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );
    }


    public String createAppointmentSinglePatientDataFilter( String filterId, String clientName, String clientRequestInitiationTime,
                    List<Map<String, String>> entryPointFilter, List<Map<String, String>> resolvedPatients, String statusValue )
    {
        return FilterBuilder.buildAppointmentFilterWithResolvedIdentfiers( filterId, clientName, clientRequestInitiationTime, entryPointFilter,
                        resolvedPatients, statusValue );
    }

    public String createClinicalRemindersSinglePatientDataFilter( String filterId,  List<Map<String, String>> entryPointFilterMaps, List<Map<String, String>>  resolvedPatients,
                    String clientRequestInitiationTime, String status, String token  )
    {
        return FilterBuilder.buildClinicalRemindersFilterElementWithResolvedIdentfiers( filterId, entryPointFilterMaps, resolvedPatients,
                        null, null, clientRequestInitiationTime, status, token ).asXML();
    }
                    
    public String createROISinglePatientDataFilter( String filterId, String clientName, String clientRequestInitiationTime,
                    List<Map<String, String>> entryPointFilter, List<Map<String, String>> resolvedPatients )
    {
        //resusing builder of similar doman
        return FilterBuilder.buildAppointmentFilterWithResolvedIdentfiers( filterId, clientName, clientRequestInitiationTime, entryPointFilter,
                        resolvedPatients, null );
    }


    public String buildProblemListFilterElementWithResolvedIdentfiers( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String startDate, String endDate, Map<String, String> optionalParamsMap )
    {
        return FilterBuilder.buildProblemListFilterElementWithResolvedIdentfiers( filterId, entryPointFilterMaps, resolvedPatients, startDate,
                        endDate, optionalParamsMap, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );
    }


    public String createOutpatientMedicationPromiseEntryFilterWithAdditionalQueryParameters(
                    Map<String, String> assigningFacilityAndPatientIdentityMap, String entryPoint, String assigningAuthority, String filterId,
                    String identity, String namespaceId, String universalId, String universalIdType, String queryTimeoutSeconds )

    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createPatient( "patients", assigningAuthority, assigningFacilityAndPatientIdentityMap ) );

        element.add( FilterBuilder.createOutpatientMedicationPromiseEntryFilterWithAdditionalQueryParameters( "entryPointFilter", entryPoint,
                        identity, namespaceId, universalId, universalIdType, "ID_1", queryTimeoutSeconds ) );

        element.addAttribute( "vhimVersion", "Vhim_4_00" );
        return element.asXML();

    }


    public String buildRequestsNExamsFilterElementWithResolvedIdentfiers( String filterId, String clientName, String clientRequestInitiationTime,
                    List<Map<String, String>> entryPointFilterMaps, List<Map<String, String>> resolvedPatients, String startDate, String endDate,
                    Map<String, String> optionalParamsMap )
    {
        return FilterBuilder.buildRequestsNExamsFilterElementWithResolvedIdentfiers( filterId, clientName, clientRequestInitiationTime,
                        entryPointFilterMaps, resolvedPatients, optionalParamsMap );
    }


    public String create3xOutpatientMedicationPromiseSinglePatientDataFilter( String filterId, List<Map<String, String>> entryPointFilter,
                    List<Map<String, String>> resolvedPatients )
    {
        return FilterBuilder.build3xOutpatientMedicationPromiseFilterWithResolvedIdentfiers( filterId, entryPointFilter, resolvedPatients,
                        DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );
    }


    public String createXpathFilterFromAllergyAssessment( String xml, String filterId )
    {
        // TODO: Figure out what this is supposed to be doing. No clue yet.
        return null;

        // String xpath = null;
        //
        // ClinicalData responseClinicalData = ( ClinicalData )marshallerUnmarshaller400.unmarshallToVdm( xml );
        // ClinicalDataPatient patient = ( ClinicalDataPatient )responseClinicalData.getPatient().get( 0 );
        //
        // AllergyAssessment allergyAssessment = ( AllergyAssessment )patient.getAllergyAssessments().get( 0 );
        //
        // if ( allergyAssessment.getRecordIdentifier().getUniversalId() != null )
        // {
        // xpath = "allergyAssessments[recordIdentifier/universalId='" +
        // allergyAssessment.getRecordIdentifier().getUniversalId() + "']";
        // }
        // else
        // {
        // xpath = "allergyAssessments[recordIdentifier/identity='" +
        // allergyAssessment.getRecordIdentifier().getIdentity() + "']";
        // }
        //
        // return createXpathFilter( allergyAssessment.getPatient().getIdentifier(), "AllergyAssessmentQuery", xpath,
        // gov.va.med.cds.cdm.clinicaldata.DomainEntryPoint.AllergyAssessment.toString(), null, null, filterId );
    }


    public String createXpathFilterFromIntoleranceCondition( String xml, String filterId, String queryNameByDomain )
    {
        String xpath = null;
        return xpath;
        // String queryName = null;
        //
        // ClinicalData responseClinicalData = ( ClinicalData )marshallerUnmarshaller400.unmarshallToVdm( xml );
        // ClinicalDataPatient patient = ( ClinicalDataPatient )responseClinicalData.getPatient().get( 0 );
        //
        // IntoleranceCondition intoleranceCondition = ( IntoleranceCondition )patient.getIntoleranceConditions().get( 0
        // );
        // if ( !filterId.equals( "VW_ALLERGY_SINGLE_PATIENT_FILTER" ) )
        // {
        // if ( intoleranceCondition.getRecordIdentifier().getUniversalId() != null )
        // {
        // xpath = "intoleranceConditions[recordIdentifier/universalId='" +
        // intoleranceCondition.getRecordIdentifier().getUniversalId() + "']";
        // }
        // else
        // {
        // xpath = "intoleranceConditions[recordIdentifier/identity='" +
        // intoleranceCondition.getRecordIdentifier().getIdentity() + "']";
        // }
        // }
        // else if ( filterId.equals( "VW_ALLERGY_SINGLE_PATIENT_FILTER" ) )
        // {
        // xpath = "intoleranceConditions[status != 'E']";
        // }
        //
        // // RDI, VW and RPT each have different query filter name
        // if ( queryNameByDomain.equals( "RDI" ) )
        // {
        // queryName = "RDIREADQuery";
        // }
        // else if ( queryNameByDomain.equals( "VW" ) )
        // {
        // queryName = "VWREADQuery";
        // }
        // else if ( queryNameByDomain.equals( "RPT" ) )
        // {
        // queryName = "ActiveReportQuery";
        // }
        // // TODO: xPathQuery name is messed, what is the significance of the name here
        // else if ( queryNameByDomain.equals( "AIC" ) )
        // {
        // queryName = "AICondition";
        // }
        // else if ( queryNameByDomain.equals( "IC-Standardized" ) )
        // {
        // queryName = "IC-Standardized";
        // }
        // else if ( queryNameByDomain.equals( "VTLS-Standardized" ) )
        // {
        // queryName = "VTLS-Standardized";
        // }
        //
        // // All Interolerance Condition
        //
        // return createXpathFilter( intoleranceCondition.getPatient().getIdentifier(), queryName, xpath,
        // gov.va.med.cds.cdm.clinicaldata.DomainEntryPoint.IntoleranceCondition.toString(), null, null, filterId );
    }


    public String createXpathFilterFromVitalObservationEvent( String xml, String filterId )
        throws DatatypeConfigurationException,
            ParseException
    {
        String filter = null;

        // TODO: Need to figure out what goes in here.

        return filter;

        // Date startDate = null;
        // Date endDate = null;
        //
        // String filter = null;
        //
        // ClinicalData responseClinicalData = ( ClinicalData )marshallerUnmarshaller400.unmarshallToVdm( xml );
        // ClinicalDataPatient patient = ( ClinicalDataPatient )responseClinicalData.getPatient().get( 0 );
        //
        // VitalSignObservationEvent vitalSignObservationEvent = ( VitalSignObservationEvent
        // )patient.getVitalSignObservationEvents().get( 0 );
        //
        // if ( !filterId.equals( "VW_VITAL_SINGLE_PATIENT_FILTER" ) )
        // {
        // if ( vitalSignObservationEvent.getRecordIdentifier().getUniversalId() != null )
        // {
        // xpath = "vitalSignObservationEvents[recordIdentifier/universalId='"
        // + vitalSignObservationEvent.getRecordIdentifier().getUniversalId() + "']";
        // }
        // else
        // {
        // xpath = "vitalSignObservationEvents[recordIdentifier/identity='" +
        // vitalSignObservationEvent.getRecordIdentifier().getIdentity()
        // + "']";
        // }
        // filter = createXpathFilter( vitalSignObservationEvent.getPatient().getIdentifier(),
        // "VitalSignObservationEventQuery", xpath,
        // gov.va.med.cds.cdm.clinicaldata.DomainEntryPoint.VitalSignObservationEvent.toString(), null, null, filterId
        // );
        //
        // }
        // else if ( filterId.equals( "VW_VITAL_SINGLE_PATIENT_FILTER" ) )
        // {
        //
        // xpath = "vitalSignObservationEvents[status != 'E']";
        // DateFormat df = new SimpleDateFormat( "dd/MM/yyyy" );
        //
        // startDate = df.parse( "15/04/2006" );
        // endDate = df.parse( "15/04/2010" );
        //
        // filter = createEntryPointWithDates( vitalSignObservationEvent.getPatient().getIdentifier(),
        // "VitalSignObservationEventQuery", xpath,
        // gov.va.med.cds.cdm.clinicaldata.DomainEntryPoint.VitalSignObservationEvent.toString(),
        // convertDateToXMLGregorianCalendar( startDate ), convertDateToXMLGregorianCalendar( endDate ), filterId );
        // }
        //
        // return filter;
    }


    public String createXpathFilterFromLabObservationEvent( String xml, String filterId )
    {

        String filter = null;

        // TODO: figure out how to build this filter from XML.

        return filter;

        // ClinicalData responseClinicalData = ( ClinicalData )marshallerUnmarshaller400.unmarshallToVdm( xml );
        // ClinicalDataPatient patient = ( ClinicalDataPatient )responseClinicalData.getPatient().get( 0 );
        //
        // LabTestPromise labTestPromise = ( LabTestPromise )patient.getLabTestPromises().get( 0 );
        //
        // String xpath = "labTestPromises[recordIdentifier/universalId='" +
        // labTestPromise.getRecordIdentifier().getUniversalId() + "']";
        //
        // if ( labTestPromise.getRecordIdentifier().getUniversalId() != null )
        // {
        // xpath = "labTestPromises[recordIdentifier/universalId='" +
        // labTestPromise.getRecordIdentifier().getUniversalId() + "']";
        // }
        // else
        // {
        // xpath = "labTestPromises[recordIdentifier/identity='" + labTestPromise.getRecordIdentifier().getIdentity() +
        // "']";
        // }
        //
        // if ( patient.getRequestedNationalId() != null )
        // {
        // return createXpathFilterWithNationalId( patient.getRequestedNationalId(), "LabTestPromiseQuery", xpath,
        // gov.va.med.cds.cdm.clinicaldata.DomainEntryPoint.LabTestPromise.toString(), null, null, filterId );
        // }
        // else
        // {
        // return createXpathFilter( labTestPromise.getPatient().getIdentifier(), "LabTestPromiseQuery", xpath,
        // gov.va.med.cds.cdm.clinicaldata.DomainEntryPoint.LabTestPromise.toString(), null, null, filterId );
        // }

    }


    public String createXpathFilterFromOutpatientMedicationPromise( String xml, String filterId )
    {
        String filter = null;

        // TODO: Figure out how to build the filter.

        return filter;

        // ClinicalData responseClinicalData = ( ClinicalData )marshallerUnmarshaller400.unmarshallToVdm( xml );
        //
        // ClinicalDataPatient patient = ( ClinicalDataPatient )responseClinicalData.getPatient().get( 0 );
        //
        // OutpatientMedicationPromise outpatientMedicationPromise = ( OutpatientMedicationPromise
        // )patient.getOutpatientMedicationPromises().get( 0 );
        //
        // if ( !filterId.equals( "RX_SINGLE_PATIENT_ALL_DATA_FILTER" ) )
        // {
        // if ( outpatientMedicationPromise.getRecordIdentifier().getUniversalId() != null )
        // {
        // xpath = "outpatientMedicationPromises[recordIdentifier/universalId='"
        // + outpatientMedicationPromise.getRecordIdentifier().getUniversalId() + "']";
        // }
        //
        // else
        // {
        // xpath = "outpatientMedicationPromises[recordIdentifier/identity='" +
        // outpatientMedicationPromise.getRecordIdentifier().getIdentity()
        // + "']";
        // }
        // }
        // else if ( filterId.equals( "RX_SINGLE_PATIENT_ALL_DATA_FILTER" ) )
        // {
        // xpath = null;
        // }
        //
        // return createXpathFilter( outpatientMedicationPromise.getPatient().getIdentifier(),
        // "OutpatientMedicationPromiseQuery", xpath,
        // gov.va.med.cds.cdm.clinicaldata.DomainEntryPoint.OutpatientMedicationPromise.toString(), null, null, filterId
        // );
    }


    public String createXpathFilterFromOutpatientMedicationPromise( String xml, Date aStartDate, int aEndDate, String filterId )
        throws DatatypeConfigurationException
    {
        String filter = null;

        // TODO: Figure out how to build the filter.

        return filter;

        // ClinicalData responseClinicalData = ( ClinicalData )marshallerUnmarshaller400.unmarshallToVdm( xml );
        // ClinicalDataPatient patient = ( ClinicalDataPatient )responseClinicalData.getPatient().get( 0 );
        //
        // OutpatientMedicationPromise outpatientMedicationPromise = ( OutpatientMedicationPromise
        // )patient.getOutpatientMedicationPromises().get( 0 );
        //
        // String xpath = "outpatientMedicationPromises[recordIdentifier/universalId='"
        // + outpatientMedicationPromise.getRecordIdentifier().getUniversalId() + "']";
        //
        // XMLGregorianCalendar filterStartDate = convertDateToXMLGregorianCalendar( aStartDate );
        // XMLGregorianCalendar filterEndDate = convertDateToXMLGregorianCalendar( getFilterEndDate( aEndDate ) );
        //
        // return createXpathFilter( outpatientMedicationPromise.getPatient().getIdentifier(),
        // "OutpatientMedicationPromiseQuery", xpath,
        // gov.va.med.cds.cdm.clinicaldata.DomainEntryPoint.OutpatientMedicationPromise.toString(), filterStartDate,
        // filterEndDate,
        // filterId );
    }


    // public static String createXpathFilter( HL72PersonIdentifier aHL72PersonIdentifier, String aQueryName, String
    // aXpath, String aDomainEntryPoint,
    // XMLGregorianCalendar aStartDate, XMLGregorianCalendar aEndDate, String filterId )
    // {
    // PersonIdentifier patientIdentifier = new PersonIdentifier();
    // patientIdentifier.setIdentity( aHL72PersonIdentifier.getIdentity() );
    // patientIdentifier.setAssigningAuthority( aHL72PersonIdentifier.getAssigningAuthority() );
    // patientIdentifier.setAssigningFacility( aHL72PersonIdentifier.getAssigningFacility() );
    // ArrayList<PersonIdentifier> resolvedIds = new ArrayList<PersonIdentifier>( 1 );
    // resolvedIds.add( patientIdentifier );
    //
    // List<EntryFilter> entryFilters = new ArrayList<EntryFilter>( 2 );
    //
    // EntryFilter entryFilter = new EntryFilter();
    // entryFilter.setQueryName( aQueryName );
    // entryFilter.setDomainEntryPoint( aDomainEntryPoint );
    // XpathQuery xpathQuery = new XpathQuery();
    // xpathQuery.setXpath( aXpath );
    // entryFilter.setXpathQuery( xpathQuery );
    // entryFilter.setStartDate( aStartDate );
    // entryFilter.setEndDate( aEndDate );
    // entryFilters.add( entryFilter );
    //
    // if ( filterId.equals( TemplateIdHelper.VW_IC_FILTER_ID ) )
    // {
    // EntryFilter entryFilter1 = new EntryFilter();
    // entryFilter1.setQueryName( aQueryName + "2" );
    // entryFilter1.setDomainEntryPoint( aDomainEntryPoint );
    // XpathQuery xpathQuery1 = new XpathQuery();
    // xpathQuery1.setXpath( aXpath );
    // entryFilter1.setXpathQuery( xpathQuery );
    // entryFilter1.setStartDate( aStartDate );
    // entryFilter1.setEndDate( aEndDate );
    // entryFilters.add( entryFilter1 );
    // }
    //
    // return createFilter( resolvedIds, entryFilters, filterId );
    // }

    // public static String createEntryPointWithDates( HL72PersonIdentifier aHL72PersonIdentifier, String aQueryName,
    // String aXpath,
    // String aDomainEntryPoint, XMLGregorianCalendar aStartDate, XMLGregorianCalendar aEndDate, String filterId )
    // {
    //        
    // PersonIdentifier patientIdentifier = new PersonIdentifier();
    // patientIdentifier.setIdentity( aHL72PersonIdentifier.getIdentity() );
    // patientIdentifier.setAssigningAuthority( aHL72PersonIdentifier.getAssigningAuthority() );
    // patientIdentifier.setAssigningFacility( aHL72PersonIdentifier.getAssigningFacility() );
    // ArrayList<PersonIdentifier> resolvedIds = new ArrayList<PersonIdentifier>( 1 );
    // resolvedIds.add( patientIdentifier );
    //
    // List<EntryFilter> entryFilters = new ArrayList<EntryFilter>( 2 );
    //
    // EntryFilter entryFilter = new EntryFilter();
    // entryFilter.setQueryName( aQueryName );
    // entryFilter.setDomainEntryPoint( aDomainEntryPoint );
    // XpathQuery xpathQuery = new XpathQuery();
    // xpathQuery.setXpath( aXpath );
    // entryFilter.setXpathQuery( xpathQuery );
    // entryFilter.setStartDate( aStartDate );
    // entryFilter.setEndDate( aEndDate );
    // entryFilters.add( entryFilter );
    //
    // return createFilter( resolvedIds, entryFilters, filterId );
    // }

    // public static String createXpathFilterWithNationalId( String nationalId, String aQueryName, String aXpath, String
    // aDomainEntryPoint,
    // XMLGregorianCalendar aStartDate, XMLGregorianCalendar aEndDate, String filterId )
    // {
    // List<EntryFilter> entryFilters = new ArrayList<EntryFilter>( 2 );
    //
    // EntryFilter entryFilter = new EntryFilter();
    // entryFilter.setQueryName( aQueryName );
    // entryFilter.setDomainEntryPoint( aDomainEntryPoint );
    // XpathQuery xpathQuery = new XpathQuery();
    // xpathQuery.setXpath( aXpath );
    // entryFilter.setXpathQuery( xpathQuery );
    // entryFilter.setStartDate( aStartDate );
    // entryFilter.setEndDate( aEndDate );
    // entryFilters.add( entryFilter );
    //
    // return createFilterWithNationalId( nationalId, entryFilters, filterId );
    // }

    /*
     * <filter:filter vhimVersion="String" xsi:schemaLocation="Filter Filter400C5.xsd" xmlns:filter="Filter"
     * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <filterId>String</filterId> <patients>
     * <resolvedIdentifiers> <identity>String</identity> <assigningAuthority>String</assigningAuthority>
     * <assigningFacility>String</assigningFacility> </resolvedIdentifiers> </patients> <entryPointFilter
     * queryName="text"> <domainEntryPoint>String</domainEntryPoint> <startDate>1967-08-13</startDate>
     * <endDate>1967-08-13</endDate> <recordIdentifiers> <identity>String</identity> <namespaceId>VHA</namespaceId>
     * <universalId>String</universalId> <universalIdType>String</universalIdType> </recordIdentifiers> <xpathQuery>
     * <xpath>String</xpath> <parameter type="text" name="text"> <value>String</value> </parameter> </xpathQuery>
     * </entryPointFilter> <correlationFilter queryName="text"> <xpathQuery> <xpath>String</xpath> <parameter
     * type="text" name="text"> <value>String</value> </parameter> </xpathQuery> </correlationFilter> <aggregationFilter
     * queryName="text"> <xpathQuery> <xpath>String</xpath> <parameter type="text" name="text"> <value>String</value>
     * </parameter> </xpathQuery> </aggregationFilter> </filter:filter>
     */
    // public static String createFilter( List<PersonIdentifier> aResolvedIds, List<EntryFilter> aEntryFilters, String
    // filterId )
    // {
    // StringBuffer xmlWorkBuffer = new StringBuffer();
    //
    // xmlWorkBuffer.setLength( 0 );
    //
    // xmlWorkBuffer.append( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" );
    // xmlWorkBuffer
    // .append(
    // "<filter:filter vhimVersion=\"Vhim_4_00\" xmlns:filter=\"Filter\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
    // );
    // xmlWorkBuffer.append( "<filterId>" + filterId + "</filterId>" );
    // xmlWorkBuffer.append( "<patients>" );
    // for ( PersonIdentifier patientIdentifier : aResolvedIds )
    // {
    // xmlWorkBuffer.append( "<resolvedIdentifiers>" );
    // xmlWorkBuffer.append( "<assigningAuthority>" );
    // xmlWorkBuffer.append( patientIdentifier.getAssigningAuthority() );
    // xmlWorkBuffer.append( "</assigningAuthority>" );
    // xmlWorkBuffer.append( "<assigningFacility>" );
    // xmlWorkBuffer.append( patientIdentifier.getAssigningFacility() );
    // xmlWorkBuffer.append( "</assigningFacility>" );
    // xmlWorkBuffer.append( "<identity>" );
    // xmlWorkBuffer.append( patientIdentifier.getIdentity() );
    // xmlWorkBuffer.append( "</identity>" );
    // xmlWorkBuffer.append( "</resolvedIdentifiers> " );
    // }
    // xmlWorkBuffer.append( "</patients>" );
    // return createRestOfFilter( aEntryFilters, filterId, xmlWorkBuffer );
    // }
    // private static String createRestOfFilter( List<EntryFilter> aEntryFilters, String filterId, StringBuffer
    // xmlWorkBuffer )
    // {
    // XMLGregorianCalendar startDate = null;
    // XMLGregorianCalendar endDate = null;
    // for ( EntryFilter entryFilter : aEntryFilters )
    // {
    // xmlWorkBuffer.append( "<entryPointFilter queryName=\"" );
    // xmlWorkBuffer.append( entryFilter.getQueryName() ).append( "\">" );
    // xmlWorkBuffer.append( "<domainEntryPoint>" );
    // xmlWorkBuffer.append( entryFilter.getDomainEntryPoint() );
    // xmlWorkBuffer.append( "</domainEntryPoint>" );
    // startDate = entryFilter.getStartDate();
    // if ( startDate != null )
    // {
    // xmlWorkBuffer.append( "<startDate>" );
    // xmlWorkBuffer.append( formatDate( startDate ) );
    // xmlWorkBuffer.append( "</startDate> " );
    // }
    // endDate = entryFilter.getEndDate();
    // if ( endDate != null )
    // {
    // xmlWorkBuffer.append( "<endDate>" );
    // xmlWorkBuffer.append( formatDate( endDate ) );
    // xmlWorkBuffer.append( "</endDate> " );
    // }
    // if ( entryFilter.getXpathQuery().getXpath() != null )
    // {
    // xmlWorkBuffer.append( "<xpathQuery>" );
    // xmlWorkBuffer.append( "<xpath>" );
    // xmlWorkBuffer.append( entryFilter.getXpathQuery().getXpath() );
    // xmlWorkBuffer.append( "</xpath> </xpathQuery>" );
    // }
    // xmlWorkBuffer.append( "</entryPointFilter>" );
    // }
    //
    // xmlWorkBuffer.append( " </filter:filter>" );
    // return xmlWorkBuffer.toString();
    // }
    /*
     * <filter:filter vhimVersion="String" xsi:schemaLocation="Filter Filter400C5.xsd" xmlns:filter="Filter"
     * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <filterId>String</filterId> <patients>
     * <NationalId>String</NationalId> </patients> <entryPointFilter queryName="text">
     * <domainEntryPoint>String</domainEntryPoint> <startDate>1967-08-13</startDate> <endDate>1967-08-13</endDate>
     * <recordIdentifiers> <identity>String</identity> <namespaceId>VHA</namespaceId> <universalId>String</universalId>
     * <universalIdType>String</universalIdType> </recordIdentifiers> <xpathQuery> <xpath>String</xpath> <parameter
     * type="text" name="text"> <value>String</value> </parameter> </xpathQuery> </entryPointFilter> <correlationFilter
     * queryName="text"> <xpathQuery> <xpath>String</xpath> <parameter type="text" name="text"> <value>String</value>
     * </parameter> </xpathQuery> </correlationFilter> <aggregationFilter queryName="text"> <xpathQuery>
     * <xpath>String</xpath> <parameter type="text" name="text"> <value>String</value> </parameter> </xpathQuery>
     * </aggregationFilter> </filter:filter>
     */
    // public static String createFilterWithNationalId( String aNationalId, List<EntryFilter> aEntryFilters, String
    // filterId )
    // {
    // StringBuffer xmlWorkBuffer = new StringBuffer();
    //
    // xmlWorkBuffer.setLength( 0 );
    //
    // xmlWorkBuffer.append( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" );
    // xmlWorkBuffer
    // .append(
    // "<filter:filter vhimVersion=\"Vhim_4_00\" xmlns:filter=\"Filter\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
    // );
    // xmlWorkBuffer.append( "<filterId>" + filterId + "</filterId>" );
    // xmlWorkBuffer.append( "<patients>" );
    // xmlWorkBuffer.append( "<NationalId>" );
    // xmlWorkBuffer.append( aNationalId );
    // xmlWorkBuffer.append( "</NationalId>" );
    // xmlWorkBuffer.append( "</patients>" );
    //
    // return createRestOfFilter( aEntryFilters, filterId, xmlWorkBuffer );
    // }
    public static String formatDate( XMLGregorianCalendar aDate )
    {
        String value = null;
        if ( aDate != null )
        {
            value = new SimpleDateFormat( DATE_FORMAT_PATTERN ).format( aDate.toGregorianCalendar().getTime() );
        }
        return value;
    }


    /**
     * Used in Spring injection
     * 
     * @param vdmClinicalDataBuilder400
     */
    // public void setVdmClinicalDataBuilder400( VdmClinicalDataBuilder vdmClinicalDataBuilder400 )
    // {
    // this.clinicalDataBuilder = vdmClinicalDataBuilder400;
    // }
    public String createXpathFilterFromIntoleranceConditionDateFilter( String xml, String startDate, String endDate, String filterId )
    {
        String xpathFilter = null;

        // TODO: Figure out how to populate this filter.

        return xpathFilter;

        // ClinicalData responseClinicalData = ( ClinicalData )marshallerUnmarshaller400.unmarshallToVdm( xml );
        // ClinicalDataPatient patient = ( ClinicalDataPatient )responseClinicalData.getPatient().get( 0 );
        //
        // IntoleranceCondition intoleranceCondition = ( IntoleranceCondition )patient.getIntoleranceConditions().get( 0
        // );
        //
        // StringBuffer xmlWorkBuffer = new StringBuffer();
        //
        // xmlWorkBuffer.setLength( 0 );
        // xmlWorkBuffer
        // .append(
        // "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <filter:filter vhimVersion=\"Vhim_4_00\" filterType=\"VDM\" xmlns:filter=\"Filter\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
        // );
        // xmlWorkBuffer.append( "<filterId>" + filterId + "</filterId>" );
        // xmlWorkBuffer.append( "<patients> " );
        // xmlWorkBuffer.append( "<resolvedIdentifiers> <identity>" );
        // xmlWorkBuffer.append( intoleranceCondition.getPatient().getIdentifier().getIdentity() );
        // xmlWorkBuffer.append( "</identity>" );
        // xmlWorkBuffer.append( "<assigningAuthority>" );
        // xmlWorkBuffer.append( intoleranceCondition.getPatient().getIdentifier().getAssigningAuthority() );
        // xmlWorkBuffer.append( "</assigningAuthority>" );
        // xmlWorkBuffer.append( "<assigningFacility>" );
        // xmlWorkBuffer.append( intoleranceCondition.getPatient().getIdentifier().getAssigningFacility() );
        // xmlWorkBuffer.append( "</assigningFacility>" );
        // xmlWorkBuffer.append( "</resolvedIdentifiers> </patients> " );
        // xmlWorkBuffer.append( "<entryPointFilter queryName=\"IC-allergyType\"> <domainEntryPoint>" );
        // xmlWorkBuffer.append( gov.va.med.cds.cdm.clinicaldata.DomainEntryPoint.IntoleranceCondition.toString() );
        // xmlWorkBuffer.append( "</domainEntryPoint> " );
        // xmlWorkBuffer.append( "<startDate>" );
        // xmlWorkBuffer.append( startDate );
        // xmlWorkBuffer.append( "</startDate> " );
        // xmlWorkBuffer.append( "<endDate>" );
        // xmlWorkBuffer.append( endDate );
        // xmlWorkBuffer.append( "</endDate> " );
        // xmlWorkBuffer.append( "<xpathQuery>  " );
        // xmlWorkBuffer.append( "<xpath>" );
        // xmlWorkBuffer.append( "</xpath> " );
        // xmlWorkBuffer.append( "</xpathQuery> </entryPointFilter>  </filter:filter>" );
        //
        // return xmlWorkBuffer.toString();
    }


    // @SuppressWarnings( "unchecked" )
    // public void compareAllergyFilterAndResults( String xml, String startDate, String endDate, boolean positiveTest )
    // {
    // boolean foundIt = false;
    // String observationDate = null;
    // ClinicalData responseClinicalData = ( ClinicalData )marshallerUnmarshaller400.unmarshallToVdm( xml );
    // ClinicalDataPatient patient = ( ClinicalDataPatient )responseClinicalData.getPatient().get( 0 );
    //
    // List<IntoleranceCondition> intoleranceConditions = ( List<IntoleranceCondition>
    // )patient.getIntoleranceConditions();
    //
    // if ( positiveTest )
    // {
    // Assert.assertTrue( intoleranceConditions.size() > 0 );
    // }
    // else
    // {
    // Assert.assertTrue( intoleranceConditions.size() == 0 );
    // }
    //
    // for ( IntoleranceCondition ic : intoleranceConditions )
    // {
    // observationDate = ic.getObservationTime().getLiteral();
    // // Convert non-conforming dates to null
    // observationDate = isNonConformatString( observationDate );
    //
    // if ( observationDate == null || ( observationDate.compareTo( endDate ) < 1 && observationDate.compareTo(
    // startDate ) > -1 ) )
    // {
    // foundIt = true;
    // if ( logger.isDebugEnabled() )
    // {
    // logger.debug( gov.va.med.cds.util.LogMessageUtil.buildMessage( null, null, APPLICATION_NAME, " Date: " +
    // observationDate
    // + " exists between " + startDate + " - " + endDate ) );
    // }
    // }
    // Assert.assertTrue( "An allergy with observation data of " + observationDate + " is NOT between: " + startDate +
    // " - " + endDate, foundIt );
    // }
    //
    // }

    // @SuppressWarnings( "unchecked" )
    // public void ensureAllergyContainsInvalidDate( String xml, String invalidDate )
    // {
    // boolean foundIt = false;
    // String observationDate = null;
    // ClinicalData responseClinicalData = ( ClinicalData )marshallerUnmarshaller400.unmarshallToVdm( xml );
    // ClinicalDataPatient patient = ( ClinicalDataPatient )responseClinicalData.getPatient().get( 0 );
    //
    // List<IntoleranceCondition> intoleranceConditions = ( List<IntoleranceCondition>
    // )patient.getIntoleranceConditions();
    //
    // Assert.assertTrue( intoleranceConditions.size() > 0 );
    //
    // for ( IntoleranceCondition ic : intoleranceConditions )
    // {
    // observationDate = ic.getObservationTime().getLiteral();
    //
    // if ( observationDate.equals( invalidDate ) )
    // {
    // foundIt = true;
    // }
    // }
    //
    // Assert.assertTrue( foundIt );
    // }

    // TODO: Remove
    // /**
    // * This return ensures the user string is conformant to at least the following rules: - All characters must be
    // * numeric for the iso conversion
    // *
    // * @param observationDate
    // * @return String
    // */
    // private String isNonConformatString( String observationDate )
    // {
    // for ( int index = 0; index < observationDate.length(); index++ )
    // {
    // char isoDateCharacter = observationDate.charAt( index );
    // if ( !( isoDateCharacter <= '9' && isoDateCharacter >= '0' ) )
    // {
    // return null;
    // }
    // }
    // observationDate = observationDate.length() > 7 ? observationDate.substring( 0, 8 ) : "00000000";
    // return observationDate;
    // }

    // /*******************************************************************************************************************
    // * Create delete XML, and set values for identity and namespace in record identifier
    // *
    // * @param domain
    // * @param identity
    // * @param namespaceId
    // * @return
    // * @throws IOException
    // */
    // public String customValueDeleteXML( String domain, String identity, String namespaceId )
    // throws IOException
    // {
    // String writeRequest = null;
    // String deleteRequest = null;
    //
    // if ( domain.equals( AbstractDataGeneratorValidatorTest.VITAL_OBSERVATION_EVENT ) )
    // {
    // writeRequest = createVitalObservationEventXml( TemplateIdHelper.UNIQUE_REQUEST_ID );
    //
    // deleteRequest = modifyTemplateMetaDataOfCRUADResultXml( TemplateIdHelper.VITALSIGNS_DELETE_TEMPLATE_ID,
    // writeRequest,
    // AbstractDataGeneratorValidatorTest.VITAL_OBSERVATION_EVENT );
    // }
    // else if ( domain.equals( AbstractDataGeneratorValidatorTest.INTOLERANCE_CONDITION ) )
    // {
    //
    // writeRequest = createIntoleranceConditionWithCommentEventXml( TemplateIdHelper.UNIQUE_REQUEST_ID );
    //
    // deleteRequest = modifyTemplateMetaDataOfCRUADResultXml(
    // TemplateIdHelper.INTOLERANCE_CONDITION_DELETE_TEMPLATE_ID, writeRequest,
    // AbstractDataGeneratorValidatorTest.VITAL_OBSERVATION_EVENT );
    // }
    //
    // ClinicalData clinicalData = ( ClinicalData )marshallerUnmarshaller400.unmarshallToVdm( deleteRequest );
    //
    // gov.va.med.cds.vdm.vhim400.common.ClinicalDataPatient clinicalDataPatient = (
    // gov.va.med.cds.vdm.vhim400.common.ClinicalDataPatient )clinicalData
    // .getPatient().get( 0 );
    //
    // if ( domain.equals( AbstractDataGeneratorValidatorTest.VITAL_OBSERVATION_EVENT ) )
    // {
    // VitalSignObservationEvent vitalSignObservationEvent = ( VitalSignObservationEvent
    // )clinicalDataPatient.getVitalSignObservationEvents()
    // .get( 0 );
    //
    // vitalSignObservationEvent.setRecordVersion( 0 );
    //
    // vitalSignObservationEvent.getRecordIdentifier().setUniversalId( null );
    // vitalSignObservationEvent.getRecordIdentifier().setIdentity( identity );
    // vitalSignObservationEvent.getRecordIdentifier().setUniversalIdType( null );
    // vitalSignObservationEvent.getRecordIdentifier().setNamespaceId( namespaceId );
    // }
    // else if ( domain.equals( AbstractDataGeneratorValidatorTest.INTOLERANCE_CONDITION ) )
    // {
    // IntoleranceCondition intoleranceCondition = ( IntoleranceCondition
    // )clinicalDataPatient.getIntoleranceConditions().get( 0 );
    //
    // intoleranceCondition.setRecordVersion( 0 );
    //
    // intoleranceCondition.getRecordIdentifier().setUniversalId( null );
    // intoleranceCondition.getRecordIdentifier().setIdentity( identity );
    // intoleranceCondition.getRecordIdentifier().setUniversalIdType( null );
    // intoleranceCondition.getRecordIdentifier().setNamespaceId( namespaceId );
    // }
    // return marshalToXml( clinicalData );
    // }

    /**
     * @param entryFilterMap TODO
     * 
     */
    public String createFilterFromLabEvent( String createLabRequest, String filterId, Map entryFilterMap )
    {
        Document document = FilterBuilder.convertString2Document( createLabRequest );
        Element patientIdentifier = document.getRootElement().element( "patient" ).element( "labTestPromises" ).element( "patient" )
                        .element( "identifier" );
        String assigningFacility = patientIdentifier.element( "assigningFacility" ).getText();
        String assigningAuthority = patientIdentifier.element( "assigningAuthority" ).getText();
        String identity = patientIdentifier.element( "identity" ).getText();

        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createPatient( "patients", assigningAuthority, assigningFacility, identity ) );

        String startDate = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.START_DATE_KEY ) ) : null;
        String endDate = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.END_DATE_KEY ) ) : null;
        String xpath = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.X_PATH_KEY ) != null ? ( String )entryFilterMap
                        .get( FilterBuilder.X_PATH_KEY ) : FilterBuilder.NO_XPATH ) : FilterBuilder.NO_XPATH;
        String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                        .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
        element.add( FilterBuilder.createEntryFilter( "entryPointFilter", "LabTestPromise", startDate, endDate, xpath, queryName, null ) );

        element.addAttribute( "vhimVersion", "Vhim_4_00" );
        return element.asXML();
    }


    public String createFilterFromLabEventWithNationalId( String createLabRequest, String filterId, List<Element> excludeIdentifiers )
    {
        Document document = FilterBuilder.convertString2Document( createLabRequest );
        Element patientIdentifier = document.getRootElement().element( "patient" ).element( "labTestPromises" ).element( "patient" )
                        .element( "identifier" );
        String identity = patientIdentifier.element( "identity" ).getText();

        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        String query = "id_1";

        if ( filterId.equals( TemplateIdHelper.LAB_SINGLE_PATIENT_ALL_DATA_FILTER ) )
        {
            element.add( FilterBuilder.createPatientWithNationalId( "patients", identity, excludeIdentifiers ) );
        }
        else if ( filterId.equals( TemplateIdHelper.CHDR_LAB_SINGLE_PATIENT_FILTER ) )
        {

            element.add( FilterBuilder.createCHDRPatient( "patients", identity, "USDOD", "200HD" ) );
            query = "CHDR_LAB_QUERY";
        }

        element.add( FilterBuilder.createEntryFilter( "entryPointFilter", "LabTestPromise", null, null, FilterBuilder.NO_XPATH, query, null ) );
        element.addAttribute( "vhimVersion", "Vhim_4_00" );
        return element.asXML();
    }


    public String createFilterFromVitalObservationEvent( String createVitalsRequest, String filterId, Map entryFilterMap )
    {
        String xpath = FilterBuilder.NO_XPATH;
        Document document = FilterBuilder.convertString2Document( createVitalsRequest );
        Element patientIdentifier = document.getRootElement().element( "patient" ).element( "vitalSignObservationEvents" ).element( "patient" )
                        .element( "identifier" );
        String identity = patientIdentifier.element( "identity" ).getText();
        String assigningFacility = patientIdentifier.element( "assigningFacility" ).getText();
        String assigningAuthority = patientIdentifier.element( "assigningAuthority" ).getText();

        if ( filterId.equals( TemplateIdHelper.VW_VITAL_SINGLE_PATIENT_FILTER ) )
        {
            xpath = FilterBuilder.VITALS_XPATH;
        }

        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createPatient( "patients", assigningAuthority, assigningFacility, identity ) );

        // Use defaults for entryFilter or values from the map.
        String startDate = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.START_DATE_KEY ) ) : null;
        String endDate = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.END_DATE_KEY ) ) : null;
        xpath = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.X_PATH_KEY ) != null ? ( String )entryFilterMap
                        .get( FilterBuilder.X_PATH_KEY ) : xpath ) : xpath;
        String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                        .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
        element.add( FilterBuilder.createEntryFilter( "entryPointFilter", "VitalSignObservationEvent", startDate, endDate, xpath, queryName, null ) );

        element.addAttribute( "vhimVersion", "Vhim_4_00" );
        return element.asXML();
    }


    /**
     * Creates a filter document that includes resolved patient identifiers.
     * 
     * @param filterId - the filter template id/name
     * @param entryPointFilterMaps - <List> of entryPointFilter <Map> objects containing all data for each entryPoint the filter might specify.
     * @param resolvedPatients -  a <List> of arrays that define a resolved patient identifier - the array contains the authority, facility and identity
     * @return - a <String> XML instance of the filter document created
     */
    public String createFilterWithResolvedIdentifiers2x( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients )
    {
        return FilterBuilder.buildFilterWithResolvedIdentfiers2x( filterId, entryPointFilterMaps, resolvedPatients,
                        DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );
    }


    public String createFilterFromVitalObservationEvenWithNationalId( String createVitalsRequest, String filterId, List<Element> excludeIdentifiers )
    {
        String xpath = FilterBuilder.NO_XPATH;
        Document document = FilterBuilder.convertString2Document( createVitalsRequest );
        Element patientIdentifier = document.getRootElement().element( "patient" ).element( "vitalSignObservationEvents" ).element( "patient" )
                        .element( "identifier" );
        String identity = patientIdentifier.element( "identity" ).getText();

        if ( filterId.equals( TemplateIdHelper.VW_VITAL_SINGLE_PATIENT_FILTER ) )
        {
            xpath = FilterBuilder.VITALS_XPATH;
        }

        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createPatientWithNationalId( "patients", identity, excludeIdentifiers ) );
        element.add( FilterBuilder.createEntryFilter( "entryPointFilter", "VitalSignObservationEvent", null, null, xpath, "id_1", null ) );
        element.addAttribute( "vhimVersion", "Vhim_4_00" );
        return element.asXML();
    }


    /**
     * Creates a filter document that includes resolved patient identifiers.
     * 
     * @param filterId - the filter template id/name
     * @param entryPointFilterMaps - <List> of entryPointFilter <Map> objects containing all data for each entryPoint the filter might specify.
     * @param resolvedPatients -  a <List> of arrays that define a resolved patient identifier - the array contains the authority, facility and identity
     * @return - a <String> XML instance of the filter document created
     */
    public String createFilterWithResolvedIdentifiers( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients )
    {
        return FilterBuilder.buildFilterWithResolvedIdentfiers( filterId, entryPointFilterMaps, resolvedPatients,
                        DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );
    }


    public String createFilterWithResolvedIdentifiersWithAdditionalParams( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, Map<String, String> optionalParamsMap, String xpath )
    {
        return FilterBuilder.buildFilterWithAddionalParms( filterId, entryPointFilterMaps, resolvedPatients,
                        DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ), optionalParamsMap, xpath );
    }


    /**
     * Creates a filter document that includes resolved patient identifiers.
     * 
     * @param filterId - the filter template id/name
     * @param entryPointFilterMaps - <List> of entryPointFilter <Map> objects containing all data for each entryPoint the filter might specify.
     * @param resolvedPatients -  a <List> of arrays that define a resolved patient identifier - the array contains the authority, facility and identity
     * @return - a <String> XML instance of the filter document created
     */
    public String createFilterWithResolvedIdentifiersWithQueryTimeout( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients )
    {
        return FilterBuilder.buildFilterElementWithResolvedIdentfiers( filterId, entryPointFilterMaps, resolvedPatients,
                        DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) ).asXML();
    }


    /**
     * Creates a filter document that includes resolved patient identifiers.
     * 
     * @param filterId - the filter template id/name
     * @param entryPointFilterMaps - <List> of entryPointFilter <Map> objects containing all data for each entryPoint the filter might specify.
     * @param resolvedPatients -  a <List> of arrays that define a resolved patient identifier - the array contains the authority, facility and identity
     * @return - a <String> XML instance of the filter document created
     */
    public String createFilterWithEdiPi( String filterId, List<Map<String, String>> entryPointFilterMaps, List<Map<String, String>> patients )
    {
        return FilterBuilder.buildFilterWithEdiPi( filterId, entryPointFilterMaps, patients,
                        DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );
    }


    /**
     * Creates a filter document that includes resolved patient identifiers.
     * 
     * @param filterId - the filter template id/name
     * @param entryPointFilterMaps - <List> of entryPointFilter <Map> objects containing all data for each entryPoint the filter might specify.
     * @param resolvedPatients -  a <List> of arrays that define a resolved patient identifier - the array contains the authority, facility and identity
     * @param specializedEntryFilterElementName  -  a <String> indicating a specialized EntryFitlerName - could be the default or a domain that defines optional parameters
     * @return - a <String> XML instance of the filter document created
     */
    public String createFilterWithEdiPi( String filterId, List<Map<String, String>> entryPointFilterMaps, List<Map<String, String>> patients,
                    String specializedEntryFilterElementName )
    {
        return createFilterWithEdiPi( filterId, entryPointFilterMaps, patients, specializedEntryFilterElementName, null );
    }


    /**
     * Creates a filter document that includes resolved patient identifiers.
     * 
     * @param filterId - the filter template id/name
     * @param entryPointFilterMaps - <List> of entryPointFilter <Map> objects containing all data for each entryPoint the filter might specify.
     * @param resolvedPatients -  a <List> of arrays that define a resolved patient identifier - the array contains the authority, facility and identity
     * @param specializedEntryFilterElementName  -  a <String> indicating a specialized EntryFitlerName - could be the default or a domain that defines optional parameters
     * @param optionalQueryParameters  -  a <Map> indicating a optional paramters and values for additional queries - can be null and unused.
     * @return - a <String> XML instance of the filter document created
     */
    public String createFilterWithEdiPi( String filterId, List<Map<String, String>> entryPointFilterMaps, List<Map<String, String>> patients,
                    String specializedEntryFilterElementName, Map<String, String> optionalQueryParameters )
    {
        if ( specializedEntryFilterElementName == null )
        {
            specializedEntryFilterElementName = "filter:defaultDomainEntryPointFilter";
        }
        return FilterBuilder.buildFilterWithEdiPi( filterId, entryPointFilterMaps, patients,
                        DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ), specializedEntryFilterElementName,
                        optionalQueryParameters );
    }


    /**
     * Method creates a filter with record identifiers for single record (detail) queries, non patient centric
     * 
     */
    public String buildDetailFilterWithRecordIdentifier( String filterId, Map<String, String> entryPointFilterMap, String clientRequestInitiationTime )
    {
        return FilterBuilder.buildDetailFilterWithRecordIdentifier( filterId, entryPointFilterMap, clientRequestInitiationTime );
    }


    /**
     * 
     *                  
     * @param requestId
     * @param templateId
     * @param templateIdSubstitutionKey
     * @param patientIdentifier
     * @param assigningAuthority
     * @param assigningFacility
     * @return
     */
    public String createPatientEnteredXml( String requestId, String templateId, String templateIdSubstitutionKey, String patientIdentifier,
                    String assigningAuthority, String assigningFacility )
    {
        //build substitution key
        Element patient = null;
        if ( patientIdentifier == null )
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "patient" );
        }
        else
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "patient", patientIdentifier, assigningFacility, assigningAuthority );
        }

        Document clinicalDataInsertDocument = clinicalDataBuilder.createClinicalData( templateId, templateIdSubstitutionKey, 1, patient );

        updateRequestId( clinicalDataInsertDocument, requestId );

        return clinicalDataInsertDocument.asXML();
    }
    
    public String createVistaUserFilterforSingleSite( String filterId, List<Map<String, String>> entryPointFilterMaps,String clientRequestInitiationTime, String clientName, 
    		Map<String, String> optionalParamsMap )
    {
    	return FilterBuilder.buildSiteCentricFilterWithOptionalParams(filterId, entryPointFilterMaps, clientRequestInitiationTime, clientName, optionalParamsMap);
    }
    


    /**
     * 
     *                  
     * @param requestId
     * @param templateId
     * @param templateIdSubstitutionKey
     * @param patientIdentifier
     * @param assigningAuthority
     * @param assigningFacility
     * @return
     */
    public String createPatientEnteredXml( String requestId, String templateId, String templateIdSubstitutionKey, String patientIdentifier,
                    String assigningAuthority, String assigningFacility, String skillType )
    {
        //build substitution key
        Element patient = null;
        if ( patientIdentifier == null )
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "patient" );
        }
        else
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "patient", patientIdentifier, assigningFacility, assigningAuthority );
        }

        Document clinicalDataInsertDocument = clinicalDataBuilder.createClinicalData( templateId, templateIdSubstitutionKey, 1, patient, skillType );

        updateRequestId( clinicalDataInsertDocument, requestId );

        return clinicalDataInsertDocument.asXML();
    }


    public String createPatientEnteredXml( String requestId, String templateId, String templateIdSubstitutionKey, String patientIdentifier,
                    String assigningAuthority, String assigningFacility, String goalName, String entryDate )
    {
        //build substitution key
        Element patient = null;
        if ( patientIdentifier == null )
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "patient" );
        }
        else
        {
            patient = BaseDatatypesBuilder.createHL72PersonIdentifier( "patient", patientIdentifier, assigningFacility, assigningAuthority );
        }

        Document clinicalDataInsertDocument = clinicalDataBuilder.createClinicalData( templateId, templateIdSubstitutionKey, 1, patient, goalName,
                        entryDate );

        updateRequestId( clinicalDataInsertDocument, requestId );

        return clinicalDataInsertDocument.asXML();
    }


    /**
     * 
     * @param expectedReadResult
     * @param relativePathToClinicalRecord
     * @param recordIdentifier
     * @return
     * @throws DocumentException
     */
    public String insertCreatedRecordIdentifier( Document expectedReadResult, String relativePathToClinicalRecord, Element recordIdentifier )
        throws DocumentException
    {
        Element expectedClinicalDomainRecord = ( Element )expectedReadResult.getRootElement().selectSingleNode( relativePathToClinicalRecord );

        expectedClinicalDomainRecord.add( recordIdentifier );

        return expectedReadResult.asXML();
    }
    
	public Document createSensitivePatientDataAccessXmlMultipleSites(String pid1, String pid2, String facilityId1, String facilityId2, String duz,
			String menuOption, String clientName) {
		String clientRequestInitiationTime = "2016-06-06T12:01:01Z";
		PathwaysDataBuilder pathwaysDataBuilder = callBuilder();

		MultiValueMap<String, String> dfnDuzMap = new MultiValueMap<String, String>();

		dfnDuzMap.put(pid1, duz);

		dfnDuzMap.put(pid2, duz);

		Document vdmClinicalDataInsert = pathwaysDataBuilder.createClinicalData(
				TemplateIdHelper.SENSITIVE_PATIENT_ACCESS_CREATE1_TEMPLATE_ID, dfnDuzMap, facilityId1, facilityId2,
				menuOption, null, clientName, clientRequestInitiationTime);

		return vdmClinicalDataInsert;
	}
	
	private PathwaysDataBuilder callBuilder() {
		Map<String, DomainEntryPoint> domainEntryPointsMap = new HashMap<String, DomainEntryPoint>();
		domainEntryPointsMap.put(TemplateIdHelper.SENSITIVE_PATIENT_ACCESS_CREATE1_TEMPLATE_ID,
				DomainEntryPoint.PatientDataAccessedEvent);

		PathwaysDataBuilder pathwaysDataBuilder = new PathwaysDataBuilder("patient",
				"patient/patientDataAccessedEvents", "PathwaysResponse400", "logaccessdata", "Logaccessdata",
				"LogaccessData");
		pathwaysDataBuilder.setDomainEntryPointsMap(domainEntryPointsMap);

		Map<String, ClinicalDomainBuilderFactoryInterface> domainEntryPointsWrappersMap = new HashMap<String, ClinicalDomainBuilderFactoryInterface>();
		SensitivePatientDataAccessBuilderFactory factory = new SensitivePatientDataAccessBuilderFactory();
		factory.setSensitivePatientDataAccessBuilder(new SensitivePatientDataAccessBuilder());
		domainEntryPointsWrappersMap.put("PatientDataAccessedEvent", factory);
		pathwaysDataBuilder.setDomainEntryPointsWrappersMap(domainEntryPointsWrappersMap);
		return pathwaysDataBuilder;
	}

}
