

package gov.va.med.cds.integration.vhim400;


import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import gov.va.med.cds.integration.AbstractEndToEndTest;
import gov.va.med.cds.junit.runners.Suite;
import gov.va.med.cds.junit.runners.SuiteAwareSpringRunner;
import gov.va.med.cds.request.TemplateRequestProcessor;
import gov.va.med.cds.testharness.vhim400.TemplateIdHelper;
import gov.va.med.cds.testharness.vhim400.builders.FilterBuilder;
import gov.va.med.cds.testharness.xml.XmlValidator;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@RunWith( SuiteAwareSpringRunner.class )
public class EndToEndReadAllergiesHdrVistaTest
    extends
        AbstractEndToEndTest
{
    private static final String PATIENT_IDENTITY_HDR = "test_sourceid_10000";
    private static final String ASSIGNING_FACILITY_HDR = "200CH";
    private static final String ASSIGNING_AUTHORITY_HDR = "USDOD";

    private static final String PATIENT_IDENTITY_VISTA = "1";
    private static final String ASSIGNING_FACILITY_VISTA = "580";
    private static final String ASSIGNING_AUTHORITY_VISTA = "USVHA";

    private static final String XPATH_ERRORSECTION = "/clinicaldata:ClinicalData/errorSection";
    private static final String XPATH_ERRORSECTION_ERRORCODE = "/clinicaldata:ClinicalData/errorSection/warnings/errorCode";
    private static final String XPATH_PATIENT = "//patient";
    private static final String XPATH_NATIONAL_ID = "//requestedNationalId";
    private static final String XPATH_IDENTIFIERS = "//requestedResolvedIdentifiers";
    private static final String XPATH_ASSESSMENTS = "//allergyAssessments";
    private static final String XPATH_INTOLERANCE_CONDITIONS = "//intoleranceConditions";

    private static final String ASSESSMENT_DOMAIN_ENTRYPOINT = "AllergyAssessment";
    private static final String INTOLERANCECONDITION_DOMAIN_ENTRYPOINT = "IntoleranceCondition";

    private static final String INTOLERANCECONDITION_QUERY_NAME = "ID_IC";
    private static final String ASSESSMENT_QUERY_NAME = "ID_AA";

    private static final String ASSIGNING_AUTHORITY_ELEMENT_NAME = "assigningAuthority";
    private static final String ASSIGNING_FACILITY_ELEMENT_NAME = "assigningFacility";
    private static final String PATIENT_IDENTITY_ELEMENT_NAME = "identity";

    private static final int expectedHdrAllergyAssessmentAAElements = 6; // 6 from HDR, 0 from Vista
    private static final int expectedHdrAllergyAssessmentICElements = 0; // 0 from HDR, 0 from Vista
    private static final int expectedVistaAllergyAssessmentAAElements = 1; // 1 from Vista, 0 from HDR
    private static final int expectedVistaAllergyAssessmentICElements = 0; // 0 from Vista, 0 from HDR
    private static final int expectedHdrVistaAllergyAssessmentAAElements = 6 + 1; // 6 from HDR, 1 from Vista
    private static final int expectedHdrVistaAllergyAssessmentICElements = 0; // 0 from HDR, 0 from Vista

    private static final int expectedHdrAllergiesAAElements = 6; // 6 from HDR, 0 from Vista
    private static final int expectedHdrAllergiesICElements = 6; // 6 from HDR, 0 from Vista
    private static final int expectedVistaAllergiesAAElements = 1; // 1 from Vista, 0 from HDR
    private static final int expectedVistaAllergiesICElements = 16; // 16 from Vista, 0 from HDR
    private static final int expectedHdrVistaAllergiesAAElements = 6 + 1; // 6 from HDR, 1 from Vista
    private static final int expectedHdrVistaAllergiesICElements = 6 + 16; // 6 from HDR, 16 from Vista

    private static final int expectedHdrIntoleranceConditionAAElements = 0; // 0 from HDR, 0 from Vista
    private static final int expectedHdrIntoleranceConditionICElements = 6; // 6 from HDR, 0 from Vista
    private static final int expectedVistaIntoleranceConditionAAElements = 0; // 0 from Vista, 0 from HDR
    private static final int expectedVistaIntoleranceConditionICElements = 16; // 16 from Vista, 0 from HDR
    private static final int expectedHdrVistaIntoleranceConditionAAElements = 0; // 0 from HDR, 0 from Vista
    private static final int expectedHdrVistaIntoleranceConditionICElements = 6 + 16; // 6 from HDR, 16 from Vista

    protected TemplateRequestProcessor templateRequestProcessor;


    @Before
    @Suite( groups = { "checkintest" } )
    public void beforeEndToEndReadHdrVistaTestClassSetUp( )
        throws Exception
    {
        templateRequestProcessor = ( TemplateRequestProcessor )getRequestProcessor();
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testVistaAllergyAssessmentReadNoKnownAllergies( )
        throws Exception
    {
        //return only assessment data for a known Vista patient - using resolved identifiers
        //this should return an assessment of NO KNOWN ALLERGIES with a populated AUTHOR
        String templateIds[] = { TemplateIdHelper.ALLERGY_ASSESSMENT_READ_TEMPLATE_ID };
        for ( int ii = 0; ii < templateIds.length; ii++ )
        {
            String readTemplateId = templateIds[ii];
            String requestId = TemplateIdHelper.getUniqueIdentifier();
            String filterId = TemplateIdHelper.AA_SINGLE_PATIENT_ALL_DATA_FILTER;

            String[] vistaPatient521 = { ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA, "35" };
            String[][] patientIdentifiers = { vistaPatient521 };
            List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

            Map<String, String> entryPointFilterMap = new HashMap<String, String>();
            entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, ASSESSMENT_DOMAIN_ENTRYPOINT );
            entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, ASSESSMENT_QUERY_NAME );

            List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
            entryPointFilterMaps.add( entryPointFilterMap );

            Document clinicalDataDocument = readAndAssertDomainData( readTemplateId, filterId, requestId, entryPointFilterMaps, resolvedPatients,
                            null, null );

            List<Element> aaElements = clinicalDataDocument.selectNodes( XPATH_ASSESSMENTS );
            assertTrue( aaElements.size() > 0 );
        }
    }


    //@Test
    @Suite( groups = { "checkintest" } )
    public void testHdrVistaAllergyAssessmentRead( )
        throws Exception
    {
        //return only assessment data for a known HDR patient and a known Vista patient - using resolved identifiers
        String templateIds[] = { TemplateIdHelper.ALLERGY_ASSESSMENT_READ_TEMPLATE_ID };
        for ( int ii = 0; ii < templateIds.length; ii++ )
        {
            String readTemplateId = templateIds[ii];
            String requestId = TemplateIdHelper.getUniqueIdentifier();
            String filterId = TemplateIdHelper.AA_SINGLE_PATIENT_ALL_DATA_FILTER;

            String[] vistaPatient521 = { ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA, PATIENT_IDENTITY_VISTA };
            String[] hdrPatient = { ASSIGNING_AUTHORITY_HDR, ASSIGNING_FACILITY_HDR, PATIENT_IDENTITY_HDR };
            String[][] patientIdentifiers = { vistaPatient521, hdrPatient };
            List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

            Map<String, String> entryPointFilterMap = new HashMap<String, String>();
            entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, ASSESSMENT_DOMAIN_ENTRYPOINT );
            entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, ASSESSMENT_QUERY_NAME );

            List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
            entryPointFilterMaps.add( entryPointFilterMap );

            readAndAssertDomainData( readTemplateId, filterId, requestId, entryPointFilterMaps, resolvedPatients, null, null );
        }
    }


    //@Test
    @Suite( groups = { "checkintest" } )
    public void testHdrAllergiesRead( )
        throws Exception
    {
        //return both assessment and intolerance condition data for a known HDR patient - using resolved identifiers
        String templateIds[] = { TemplateIdHelper.ALLERGIES_READ_TEMPLATE_ID };
        for ( int ii = 0; ii < templateIds.length; ii++ )
        {
            String readTemplateId = templateIds[ii];
            String requestId = TemplateIdHelper.getUniqueIdentifier();
            String filterId = TemplateIdHelper.ALLERGY_SINGLE_PATIENT_ALL_DATA_FILTER;

            String[] hdrPatient = { ASSIGNING_AUTHORITY_HDR, ASSIGNING_FACILITY_HDR, PATIENT_IDENTITY_HDR };
            String[][] patientIdentifiers = { hdrPatient };
            List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

            Map<String, String> entryPointICFilterMap = new HashMap<String, String>();
            entryPointICFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, INTOLERANCECONDITION_DOMAIN_ENTRYPOINT );
            entryPointICFilterMap.put( FilterBuilder.QUERY_NAME_KEY, INTOLERANCECONDITION_QUERY_NAME );

            Map<String, String> entryPointAAFilterMap = new HashMap<String, String>();
            entryPointAAFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, ASSESSMENT_DOMAIN_ENTRYPOINT );
            entryPointAAFilterMap.put( FilterBuilder.QUERY_NAME_KEY, ASSESSMENT_QUERY_NAME );

            List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
            entryPointFilterMaps.add( entryPointICFilterMap );
            entryPointFilterMaps.add( entryPointAAFilterMap );

            readAndAssertDomainData( readTemplateId, filterId, requestId, entryPointFilterMaps, resolvedPatients, null, null );
        }
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testHdrVistaAllergiesRead( )
        throws Exception
    {
        //return both assessment and intolerance condition data for a known HDR patient and a known Vista patient - using resolved identifiers
        String templateIds[] = { TemplateIdHelper.ALLERGIES_READ_TEMPLATE_ID };
        for ( int ii = 0; ii < templateIds.length; ii++ )
        {
            String readTemplateId = templateIds[ii];
            String requestId = TemplateIdHelper.getUniqueIdentifier();
            String filterId = TemplateIdHelper.ALLERGY_SINGLE_PATIENT_ALL_DATA_FILTER;

            String[] vistaPatient521 = { ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA, PATIENT_IDENTITY_VISTA };
            String[] hdrPatient = { ASSIGNING_AUTHORITY_HDR, ASSIGNING_FACILITY_HDR, PATIENT_IDENTITY_HDR };
            String[][] patientIdentifiers = { vistaPatient521, hdrPatient };
                       
            List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

            Map<String, String> entryPointICFilterMap = new HashMap<String, String>();
            entryPointICFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, INTOLERANCECONDITION_DOMAIN_ENTRYPOINT );
            entryPointICFilterMap.put( FilterBuilder.QUERY_NAME_KEY, INTOLERANCECONDITION_QUERY_NAME );

            Map<String, String> entryPointAAFilterMap = new HashMap<String, String>();
            entryPointAAFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, ASSESSMENT_DOMAIN_ENTRYPOINT );
            entryPointAAFilterMap.put( FilterBuilder.QUERY_NAME_KEY, ASSESSMENT_QUERY_NAME );

            List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
            entryPointFilterMaps.add( entryPointICFilterMap );
            entryPointFilterMaps.add( entryPointAAFilterMap );

            readAndAssertDomainData( readTemplateId, filterId, requestId, entryPointFilterMaps, resolvedPatients, null, null );
        }
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testHdrVistaAllergiesReadWithNationalId( )
        throws Exception
    {
        //return both assessment and intolerance condition data for a known HDR patient and a known Vista patient - using nationalId
        String templateIds[] = { TemplateIdHelper.ALLERGIES_READ_TEMPLATE_ID };
        for ( int ii = 0; ii < templateIds.length; ii++ )
        {
            String nationalId = "1008523096V381537";
            String readTemplateId = templateIds[ii];
            String requestId = TemplateIdHelper.getUniqueIdentifier();
            String filterId = TemplateIdHelper.ALLERGY_SINGLE_PATIENT_ALL_DATA_FILTER;

            Map<String, String> entryPointICFilterMap = new HashMap<String, String>();
            entryPointICFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, INTOLERANCECONDITION_DOMAIN_ENTRYPOINT );
            entryPointICFilterMap.put( FilterBuilder.QUERY_NAME_KEY, INTOLERANCECONDITION_QUERY_NAME );

            Map<String, String> entryPointAAFilterMap = new HashMap<String, String>();
            entryPointAAFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, ASSESSMENT_DOMAIN_ENTRYPOINT );
            entryPointAAFilterMap.put( FilterBuilder.QUERY_NAME_KEY, ASSESSMENT_QUERY_NAME );

            List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
            entryPointFilterMaps.add( entryPointICFilterMap );
            entryPointFilterMaps.add( entryPointAAFilterMap );

            readAndAssertDomainData( readTemplateId, filterId, requestId, entryPointFilterMaps, null, nationalId, null );
        }
    }


    @SuppressWarnings( "unchecked" )
    @Test
    @Suite( groups = { "timeouttest" } )
    public void testHdrVistaAllergiesReadWithNationalIdTimeoutError( )
        throws Exception
    {
        String TIMOUT_SECONDS = "2";

        //return both assessment and intolerance condition data for a known HDR patient and a known Vista patient - using nationalId
        String templateIds[] = { TemplateIdHelper.ALLERGIES_READ_TEMPLATE_ID };
        for ( int ii = 0; ii < templateIds.length; ii++ )
        {
            String nationalId = "1008523096V381537";
            String readTemplateId = templateIds[ii];
            String requestId = TemplateIdHelper.getUniqueIdentifier();
            String filterId = TemplateIdHelper.ALLERGY_SINGLE_PATIENT_ALL_DATA_FILTER;

            Map<String, String> entryPointICFilterMap = new HashMap<String, String>();
            entryPointICFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, INTOLERANCECONDITION_DOMAIN_ENTRYPOINT );
            entryPointICFilterMap.put( FilterBuilder.QUERY_NAME_KEY, INTOLERANCECONDITION_QUERY_NAME );
            entryPointICFilterMap.put( FilterBuilder.QUERY_TIMEOUT_SECONDS, TIMOUT_SECONDS );

            Map<String, String> entryPointAAFilterMap = new HashMap<String, String>();
            entryPointAAFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, ASSESSMENT_DOMAIN_ENTRYPOINT );
            entryPointAAFilterMap.put( FilterBuilder.QUERY_NAME_KEY, ASSESSMENT_QUERY_NAME );

            List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
            entryPointFilterMaps.add( entryPointICFilterMap );
            entryPointFilterMaps.add( entryPointAAFilterMap );
            String filterXml = FilterBuilder.buildFilterWithNationalId( filterId, entryPointFilterMaps, nationalId,
                            DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );

            templateRequestProcessor.setValidateReadResponseXML( false );
            Document clinicalDataDocument = templateRequestProcessor.readClinicalData( readTemplateId, filterXml, filterId, requestId );
            assertNotNull( clinicalDataDocument );
            detachExcludeIdentifierNodes( clinicalDataDocument );
            String clinicalDataXml = clinicalDataDocument.asXML();
            XmlValidator.validateXml( clinicalDataXml, readTemplateId );

            // Check for error sections
            List<Element> errorCodes = clinicalDataDocument.selectNodes( XPATH_ERRORSECTION_ERRORCODE );
            if ( errorCodes.size() == 1 )
                assertTrue( errorCodes.get( 0 ).getText().equals( TIMOUT_ERROR_CODE ) );
        }
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testHdrVistaAllergiesReadWithNationalIdAndExcludeIndentifiers( )
        throws Exception
    {
        //return both assessment and intolerance condition data for a known HDR patient and a known Vista patient - using nationalId
        String templateIds[] = { TemplateIdHelper.ALLERGIES_READ_TEMPLATE_ID };
        for ( int ii = 0; ii < templateIds.length; ii++ )
        {
            String nationalId = "1008523096V381537";
            String readTemplateId = templateIds[ii];
            String requestId = TemplateIdHelper.getUniqueIdentifier();
            String filterId = TemplateIdHelper.ALLERGY_SINGLE_PATIENT_ALL_DATA_FILTER;

            List<Map<String, String>> excludeIdentifiers = getExcludeIdentifiers( "USDOD", "578" );

            Map<String, String> entryPointICFilterMap = new HashMap<String, String>();
            entryPointICFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, INTOLERANCECONDITION_DOMAIN_ENTRYPOINT );
            entryPointICFilterMap.put( FilterBuilder.QUERY_NAME_KEY, INTOLERANCECONDITION_QUERY_NAME );

            Map<String, String> entryPointAAFilterMap = new HashMap<String, String>();
            entryPointAAFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, ASSESSMENT_DOMAIN_ENTRYPOINT );
            entryPointAAFilterMap.put( FilterBuilder.QUERY_NAME_KEY, ASSESSMENT_QUERY_NAME );

            List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
            entryPointFilterMaps.add( entryPointICFilterMap );
            entryPointFilterMaps.add( entryPointAAFilterMap );

            readAndAssertDomainData( readTemplateId, filterId, requestId, entryPointFilterMaps, null, nationalId, excludeIdentifiers );
        }
    }


    @Test
    @Suite( groups = { "brokentest" } )
    public void testHdrIntoleranceConditionRead( )
        throws Exception
    {
        //return only intolerance condition data for a known HDR patient - using resolved identifiers
        String templateIds[] = { TemplateIdHelper.INTOLERANCE_CONDITION_READ_TEMPLATE_ID, TemplateIdHelper.MHV_INTOLERANCE_CONDITION_READ_TEMPLATE_ID };
        for ( int ii = 0; ii < templateIds.length; ii++ )
        {
            String readTemplateId = templateIds[ii];
            String filterId = TemplateIdHelper.IC_SINGLE_PATIENT_ALL_DATA_FILTER;
            String requestId = TemplateIdHelper.getUniqueIdentifier();

            String[] hdrPatient = { ASSIGNING_AUTHORITY_HDR, ASSIGNING_FACILITY_HDR, PATIENT_IDENTITY_HDR };
            String[][] patientIdentifiers = { hdrPatient };
            List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

            Map<String, String> entryPointFilterMap = new HashMap<String, String>();
            entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, INTOLERANCECONDITION_DOMAIN_ENTRYPOINT );
            entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, INTOLERANCECONDITION_QUERY_NAME );

            List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
            entryPointFilterMaps.add( entryPointFilterMap );

            Document clinicalDataDocument = readAndAssertDomainData( readTemplateId, filterId, requestId, entryPointFilterMaps, resolvedPatients,
                            null, null );

            List<Element> icElements = clinicalDataDocument.selectNodes( XPATH_INTOLERANCE_CONDITIONS );
            assertTrue( icElements.size() > 0 );

        }
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testHdrVistaIntoleranceConditionRead( )
        throws Exception
    {
        //return only intolerance condition data for a known HDR patient and a known Vista patient - using resolved identifiers
        String templateIds[] = { TemplateIdHelper.INTOLERANCE_CONDITION_READ_TEMPLATE_ID, TemplateIdHelper.MHV_INTOLERANCE_CONDITION_READ_TEMPLATE_ID };
        for ( int ii = 0; ii < templateIds.length; ii++ )
        {
            String readTemplateId = templateIds[ii];
            String filterId = TemplateIdHelper.IC_SINGLE_PATIENT_ALL_DATA_FILTER;
            String requestId = TemplateIdHelper.getUniqueIdentifier();

            String[] vistaPatient521 = { ASSIGNING_AUTHORITY_VISTA, "580", "1" };
            String[] hdrPatient = { ASSIGNING_AUTHORITY_HDR, ASSIGNING_FACILITY_HDR, PATIENT_IDENTITY_HDR };
            String[][] patientIdentifiers = { vistaPatient521, hdrPatient };
            //String[][] patientIdentifiers = { vistaPatient521 };
            List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

            Map<String, String> entryPointFilterMap = new HashMap<String, String>();
            entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, INTOLERANCECONDITION_DOMAIN_ENTRYPOINT );
            entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, INTOLERANCECONDITION_QUERY_NAME );

            List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
            entryPointFilterMaps.add( entryPointFilterMap );

            Document clinicalDataDocument = readAndAssertDomainData( readTemplateId, filterId, requestId, entryPointFilterMaps, resolvedPatients,
                            null, null );

            List<Element> icElements = clinicalDataDocument.selectNodes( XPATH_INTOLERANCE_CONDITIONS );
            assertTrue( icElements.size() > 0 );

            //now apply a date range
            entryPointFilterMap.put( FilterBuilder.START_DATE_KEY, "1994-01-30" );
            entryPointFilterMap.put( FilterBuilder.END_DATE_KEY, "1994-01-31" );
            clinicalDataDocument = readAndAssertDomainData( readTemplateId, filterId, requestId, entryPointFilterMaps, resolvedPatients, null, null );

            icElements = clinicalDataDocument.selectNodes( XPATH_INTOLERANCE_CONDITIONS );
            assertTrue( icElements.size() > 0 );
        }
    }


    @SuppressWarnings( "unchecked" )
    protected Document readAndAssertDomainData( String templateId, String filterId, String requestId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String nationalId, List<Map<String, String>> excludeIdentifiers )
        throws Exception
    {
        String filterXml = null;

        if ( nationalId != null )
        {
            if ( excludeIdentifiers != null )
            {
                filterXml = FilterBuilder.buildFilterWithNationalIdAndExcludeIdentifiers( filterId, entryPointFilterMaps, nationalId,
                                excludeIdentifiers, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );
            }
            else
            {
                filterXml = FilterBuilder.buildFilterWithNationalId( filterId, entryPointFilterMaps, nationalId,
                                DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );
            }
        }
        else if ( resolvedPatients != null )
        {
            filterXml = FilterBuilder.buildFilterWithResolvedIdentfiers( filterId, entryPointFilterMaps, resolvedPatients,
                            DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );
        }
        templateRequestProcessor.setValidateReadResponseXML( false );
        Document clinicalDataDocument = templateRequestProcessor.readClinicalData( templateId, filterXml, filterId, requestId );
        assertNotNull( clinicalDataDocument );
        detachExcludeIdentifierNodes( clinicalDataDocument );
        String clinicalDataXml = clinicalDataDocument.asXML();
        XmlValidator.validateXml( clinicalDataXml, templateId );

        // Check for error sections
        List<Element> errorSections = clinicalDataDocument.selectNodes( XPATH_ERRORSECTION );
        assertTrue( errorSections.size() == 0 );

        // Check for domain entry point elements
        List<Element> domainElements = clinicalDataDocument.selectNodes( XPATH_PATIENT );
        assertTrue( domainElements.size() > 0 );

        // Assert that the resolved identifier assigning facility values from the filter are in the result document

        if ( nationalId != null )
        {
            Node requestedNationalId = clinicalDataDocument.selectSingleNode( XPATH_NATIONAL_ID );
            assertNotNull( requestedNationalId );
        }
        else
        {
            List<Element> resultsResolvedIdentifiersList = clinicalDataDocument.selectNodes( XPATH_IDENTIFIERS );
            for ( Element resultsResolvedIdentifiers : resultsResolvedIdentifiersList )
            {
                String resultsAssigningAuthority = resultsResolvedIdentifiers.element( ASSIGNING_AUTHORITY_ELEMENT_NAME ).getText();
                String resultsAssigningFacility = resultsResolvedIdentifiers.element( ASSIGNING_FACILITY_ELEMENT_NAME ).getText();
                String resultsPatientIdentity = resultsResolvedIdentifiers.element( PATIENT_IDENTITY_ELEMENT_NAME ).getText();

                Map<String, String> assigningAuthorityFacilityAndPatientIdentityMap = null;
                for ( Map<String, String> resolvedPatientMap : resolvedPatients )
                {
                    String mapAssigningAuthority = resolvedPatientMap.get( FilterBuilder.ASSIGNING_AUTHORITY_KEY );
                    String mapAssigningFacility = resolvedPatientMap.get( FilterBuilder.ASSIGNING_FACILITY );
                    if ( mapAssigningAuthority != null && mapAssigningAuthority.equalsIgnoreCase( resultsAssigningAuthority )
                                    && mapAssigningFacility != null && mapAssigningFacility.equalsIgnoreCase( resultsAssigningFacility ) )
                    {
                        assigningAuthorityFacilityAndPatientIdentityMap = resolvedPatientMap;
                        break;
                    }
                }

                assertNotNull( assigningAuthorityFacilityAndPatientIdentityMap );
                String mapPatientIdentity = assigningAuthorityFacilityAndPatientIdentityMap.get( FilterBuilder.IDENTITY );
                assertNotNull( mapPatientIdentity );
                assertTrue( mapPatientIdentity.equals( resultsPatientIdentity ) );
            }
        }

        return clinicalDataDocument;

    }


    private void detachExcludeIdentifierNodes( Document clinicalDataDocument )
    {
        while ( clinicalDataDocument.getRootElement().element( "patient" ).asXML().contains( "requestedExcludedIdentifiers" ) )
        {
            clinicalDataDocument.getRootElement().element( "patient" ).element( "requestedExcludedIdentifiers" ).detach();
        }
    }
}
