

package gov.va.med.cds.testharness.vhim400.builders;


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

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;

import gov.va.med.cds.testharness.vhim400.TemplateIdHelper;


public class FilterBuilder
{
    public static final String NO_XPATH = "";
    public static final String NO_XPATH_QUERY = "";
    public static final String ASSESSMENT_XPATH = "allergyAssessments[status != 'E']";
    public static final String IC_XPATH = "intoleranceConditions[status != 'E']";
    public static final String VITALS_HTH_XPATH = "vitalSignObservationEvents[((recordSource/namespaceId[starts-with(., '200T')]) and (status != 'E'))]";
    public static final String VITALS_VISTA_XPATH = "vitalSignObservationEvents[((recordSource/namespaceId[not(starts-with(.,'200T'))]) and (status != 'E'))]";
    public static final String VITALS_XPATH = "vitalSignObservationEvents[status != 'E']";
    public static final String RDI_IC_XPATH = "intoleranceConditions[((gmrAllergyAgent[(code!='') and (codingSystem = '99VHA_ERT' or contains(.,'99VA'))]) or (drugClass/code[(code!='') and (codingSystem = '99VHA_ERT' or contains(.,'99VA'))]) or (drugIngredient/code[(code!='') and (codingSystem = '99VHA_ERT' or contains(.,'99VA'))])) and (status = 'F')]";
    public static final String RDI_RX_XPATH = "outpatientMedicationPromises[pharmacyRequest/orderedMedication/medicationCode[(code!='') and (codingSystem = '99VHA_ERT' or contains(.,'99VA'))]]";
    public static final String REQUEST_ID_XPATH = "ClinicalData/requestId";

    //entry point element map keys
    public static final String DOMAIN_ENTRYPOINT_KEY = "domainEntryPoint";
    public static final String START_DATE_KEY = "startDate";
    public static final String END_DATE_KEY = "endDate";
    public static final String QUERY_TIMEOUT_SECONDS = "queryTimeoutSeconds";
    public static final String QUERY_NAME_KEY = "queryName";
    public static final String PATIENT_CENTRIC_KEY = "isPatientCentric";
    public static final String FACILITY_ID_KEY = "facilityId";
    public static final String X_PATH_KEY = "xPath";
    public static final String XPATH_QUERY = "xpathQuery";
    public static final String RECORD_IDENTITY = "identity";
    public static final String NAMESPACEID = "namespaceId";
    public static final String UNIVERSALID = "universalId";
    public static final String UNIVERSALIDTYPE = "universalIdType";
    public static final String OTHERQUERYPARAMETERS = "otherQueryParameters";

    //resolved identifier map keys
    public static final String ASSIGNING_AUTHORITY_KEY = "assigningAuthority";
    public static final String ASSIGNING_FACILITY = "assigningFacility";
    public static final String IDENTITY = "identity";


    public static Document buildEmptyFilterDocument( )
    {
        Namespace filterNamespace = DocumentHelper.createNamespace( "filter", "Filter" );
        Element filterElement = DocumentHelper.createElement( DocumentHelper.createQName( "filter", filterNamespace ) );
        return DocumentHelper.createDocument( filterElement );
    }


    //<xs:complexType name="patient">
    //<xs:choice>
    //    <xs:element name="resolvedIdentifiers" type="filter:PersonIdentifier" maxOccurs="unbounded"/>
    //    <xs:sequence>
    //        <xs:element name="NationalId" type="xs:string"/>
    //        <xs:element name="excludeIdentifiers" type="filter:ExcludeIdentifier" minOccurs="0" maxOccurs="unbounded"/>
    //    </xs:sequence>
    //</xs:choice>
    //</xs:complexType>
    /**
     * Method to create patient based on create xml information
     */
    public static Element createPatient( String elementName, String assigningAuthority, String assigningFacility, String identity )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createPersonIdentifier( "resolvedIdentifiers", assigningAuthority, assigningFacility, identity ) );

        return element;
    }


    public static Element createPatient( String elementName, String dodPatient, String vistAPatient,
                    Map<String, String> assigningFacilityAndPatientIdentityMap )
    {
        Element element = DocumentHelper.createElement( elementName );
        String assigningAuthority = null;
        String assigningFacility = null;
        String patientIdentity = null;
        for ( Map.Entry<String, String> entry : assigningFacilityAndPatientIdentityMap.entrySet() )
        {
            assigningAuthority = entry.getKey();
            assigningFacility = entry.getValue();
            if ( assigningAuthority.equals( "USDOD" ) )
            {
                patientIdentity = dodPatient;
            }
            else
            {
                patientIdentity = vistAPatient;
            }

            element.add( createPersonIdentifier( "resolvedIdentifiers", assigningAuthority, assigningFacility, patientIdentity ) );
        }
        return element;
    }


    public static Element createPatient( String elementName, String assigningAuthority, Map<String, String> assigningFacilityAndPatientIdentityMap )
    {
        Element element = DocumentHelper.createElement( elementName );

        for ( Map.Entry<String, String> entry : assigningFacilityAndPatientIdentityMap.entrySet() )
        {
            String assigningFacility = entry.getKey();
            String patientIdentity = entry.getValue();
            element.add( createPersonIdentifier( "resolvedIdentifiers", assigningAuthority, assigningFacility, patientIdentity ) );
        }
        return element;
    }


    /**
     * Method to create patient based on create xml information
     */
    public static Element createPatientWithEdipi( String elementName, String patientIdentifier, List<Element> excludeIdentifiers,
                    String assigningAuthority, String assigningFacility )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createPersonIdentifier( "EdiPi", assigningAuthority, assigningFacility, patientIdentifier ) );

        if ( excludeIdentifiers != null )
        {
            for ( Element excludeIdentifier : excludeIdentifiers )
            {
                element.add( excludeIdentifier );
            }
        }

        return element;
    }


    /**
     * Method to create patient based on create xml information
     */
    public static Element createPatientWithNationalId( String elementName, String nationalId, List<Element> excludeIdentifiers )
    {
        Element element = DocumentHelper.createElement( elementName );
        //        <xs:element name="NationalId" type="xs:string"/>
        element.addElement( "NationalId" ).addText( nationalId );

        if ( excludeIdentifiers != null )
        {
            for ( Element excludeIdentifier : excludeIdentifiers )
            {
                element.add( excludeIdentifier );
            }
        }
        return element;
    }


    public static Element createPatientWithNationalIdAndExcludeIdentifiers( String elementName, String nationalId,
                    List<Map<String, String>> excludeIdentifiers )
    {
        Element element = DocumentHelper.createElement( elementName );
        //        <xs:element name="NationalId" type="xs:string"/>
        element.addElement( "NationalId" ).addText( nationalId );

        for ( Map<String, String> excludeIdentifier : excludeIdentifiers )
        {
            String assigningAuthority = excludeIdentifier.get( ASSIGNING_AUTHORITY_KEY );
            String assigningFacility = excludeIdentifier.get( ASSIGNING_FACILITY );
            element.add( createCHDRExcludeIdentifier( "excludeIdentifiers", assigningAuthority, assigningFacility ) );
        }

        return element;
    }


    /**
     * 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 filter <Document> the filter document created
     */
    @SuppressWarnings( "unchecked" )
    public static Element buildFilterElementWithResolvedIdentfiers( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String clientRequestInitiationTime )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createClientName( "clientName", "testClientName" ) );
        element.add( FilterBuilder.createClientRequestInitiationTime( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );
            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 = null;
            if ( filterId.equals( TemplateIdHelper.RDI_IC_RX_CANNED_FILTER_ID ) )
            {
                String xpathQuery = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.XPATH_QUERY ) != null ? ( String )entryFilterMap
                                .get( FilterBuilder.XPATH_QUERY ) : NO_XPATH_QUERY ) : NO_XPATH_QUERY;

                if ( domainEntryPoint.equals( "IntoleranceCondition" ) )
                {
                    xPath = FilterBuilder.RDI_IC_XPATH;
                }
                else if ( domainEntryPoint.equals( "OutpatientMedicationPromise" ) )
                {
                    xPath = FilterBuilder.RDI_RX_XPATH;
                }

            }
            else
            {
                xPath = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.X_PATH_KEY ) != null ? ( String )entryFilterMap
                                .get( FilterBuilder.X_PATH_KEY ) : NO_XPATH ) : NO_XPATH;
            }

            String queryTimeoutSeconds = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.QUERY_TIMEOUT_SECONDS ) ) : null;
            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
            String recordIdentity = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.RECORD_IDENTITY ) ) : null;
            String namespaceId = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.NAMESPACEID ) ) : null;
            String universalId = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.UNIVERSALID ) ) : null;
            String universalIdType = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.UNIVERSALIDTYPE ) ) : null;

            if ( recordIdentity != null && !recordIdentity.equals( "" ) )
                element.add( FilterBuilder.createEntryFilterWithRecordIdentifiers( "entryPointFilter", domainEntryPoint, recordIdentity, namespaceId,
                                universalId, universalIdType, queryName, queryTimeoutSeconds ) );
            else
                element.add( FilterBuilder.createEntryFilter( "entryPointFilter", domainEntryPoint, startDate, endDate, queryName, xPath,
                                queryTimeoutSeconds ) );

        }

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


    /**
     * 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 filter <Document> the filter document created
     */
    @SuppressWarnings( "unchecked" )
    public static Element buildFilterElementWithOptionalParams( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String clientRequestInitiationTime, Map<String, String> optionalParamsMap,
                    String xpath )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createClientName( "clientName", "testClientName" ) );
        element.add( FilterBuilder.createClientRequestInitiationTime( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );
            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 = null;

            xPath = ( entryFilterMap != null ) ? ( entryFilterMap.get( xpath ) != null ? ( String )entryFilterMap.get( FilterBuilder.X_PATH_KEY )
                            : NO_XPATH ) : NO_XPATH;

            String queryTimeoutSeconds = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.QUERY_TIMEOUT_SECONDS ) ) : null;
            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
            String recordIdentity = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.RECORD_IDENTITY ) ) : null;
            String namespaceId = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.NAMESPACEID ) ) : null;
            String universalId = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.UNIVERSALID ) ) : null;
            String universalIdType = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.UNIVERSALIDTYPE ) ) : null;

            /*if ( recordIdentity != null && !recordIdentity.equals( "" ) )
                element.add( FilterBuilder.createEntryFilterWithRecordIdentifiers( "entryPointFilter", domainEntryPoint, recordIdentity, namespaceId,
                                universalId, universalIdType, queryName, queryTimeoutSeconds ) );
            else*/
            element.add( FilterBuilder.createEntryFilter( "entryPointFilter", domainEntryPoint, startDate, endDate, queryName, xpath,
                            queryTimeoutSeconds, null, null, optionalParamsMap ) );
        }

        element.addAttribute( "vhimVersion", "Vhim_4_00" );
        return element;
    }
    
    public static String buildSiteCentricFilterWithOptionalParams( String filterId, List<Map<String, String>> entryPointFilterMaps, String clientRequestInitiationTime, String clientName, Map<String, String> optionalParamsMap)
    {
    	Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
    	Element element = filterDocument.getRootElement();

    	element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
    	element.add( FilterBuilder.createClientName( "clientName", clientName ) );
    	element.add( FilterBuilder.createClientRequestInitiationTime( "clientRequestInitiationTime", clientRequestInitiationTime ) );
    	

    	for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
    	{
    		String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );
    		String patientCentric = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.PATIENT_CENTRIC_KEY ) ) : null;
    		String facilityId = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.FACILITY_ID_KEY) ) : null;
    		String queryTimeoutSeconds = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.QUERY_TIMEOUT_SECONDS ) ) : null;
    		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.createEntryFilterWithoutIdentifiers("entryPointFilter", domainEntryPoint, queryName, patientCentric, facilityId, queryTimeoutSeconds, optionalParamsMap));
    	}

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


    public static String buildFilterWithEdiPi( String filterId, List<Map<String, String>> entryPointFilterMaps, List<Map<String, String>> patients,
                    String clientRequestInitiationTime )
    {
        return buildFilterWithEdiPi( filterId, entryPointFilterMaps, patients, clientRequestInitiationTime, "filter:defaultDomainEntryPointFilter" );
    }


    public static String buildFilterWithEdiPi( String filterId, List<Map<String, String>> entryPointFilterMaps, List<Map<String, String>> patients,
                    String clientRequestInitiationTime, String specializedEntryFilterElementName )
    {
        return buildFilterWithEdiPi( filterId, entryPointFilterMaps, patients, clientRequestInitiationTime, specializedEntryFilterElementName, null );
    }


    public static String buildFilterWithEdiPi( String filterId, List<Map<String, String>> entryPointFilterMaps, List<Map<String, String>> patients,
                    String clientRequestInitiationTime, String specializedEntryFilterElementName, Map<String, String> optionalQueryParameters )
    {
        Element element = buildFilterElementWithEdiPi( filterId, entryPointFilterMaps, patients, clientRequestInitiationTime,
                        specializedEntryFilterElementName, optionalQueryParameters );
        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 patients -  a <List> of arrays that define a resolved patient identifier - the array contains the authority, facility and identity
     * @return - a filter <Document> the filter document created
     */
    @SuppressWarnings( "unchecked" )
    public static Element buildFilterElementWithEdiPi( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> patients, String clientRequestInitiationTime, String specializedEntryPointFilterName,
                    Map<String, String> optionalParamsMap )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createClientName( "clientName", "testClientName" ) );
        element.add( FilterBuilder.createClientRequestInitiationTime( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithEdiPi( "patients", patients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );
            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 queryTimeoutSeconds = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.QUERY_TIMEOUT_SECONDS ) ) : null;
            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
            String recordIdentity = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.RECORD_IDENTITY ) ) : null;
            String namespaceId = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.NAMESPACEID ) ) : null;
            String universalId = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.UNIVERSALID ) ) : null;
            String universalIdType = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.UNIVERSALIDTYPE ) ) : null;
            element.add( FilterBuilder.createEntryFilter( "entryPointFilter", domainEntryPoint, startDate, endDate, queryName, null,
                            queryTimeoutSeconds, null, specializedEntryPointFilterName, optionalParamsMap ) );

        }

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


    public static Element buildFilterElementWithEdiPi( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> patients, String clientRequestInitiationTime, String specializedEntryPointFilterName )
    {
        return buildFilterElementWithEdiPi( filterId, entryPointFilterMaps, patients, clientRequestInitiationTime, specializedEntryPointFilterName,
                        null );

    }


    public static Element buildFilterElementWithEdiPi( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> patients, String clientRequestInitiationTime )
    {
        return buildFilterElementWithEdiPi( filterId, entryPointFilterMaps, patients, clientRequestInitiationTime,
                        "filter:defaultDomainEntryPointFilter" );
    }


    /**
     * 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 static String buildFilterWithNationalId( String filterId, List<Map<String, String>> entryPointFilterMaps, String nationalId,
                    String clientRequestInitiationTime )
    {
        return buildFilterWithNationalId( filterId, entryPointFilterMaps, nationalId, clientRequestInitiationTime, null );
    }


    public static String buildFilterWithNationalId( String filterId, List<Map<String, String>> entryPointFilterMaps, String nationalId,
                    String clientRequestInitiationTime, String specializedDomainEntryPoint )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createClientName( "clientName", "testClientName" ) );
        element.add( FilterBuilder.createClientName( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithNationalId( "patients", nationalId, null ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );
            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 queryTimeoutSeconds = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.QUERY_TIMEOUT_SECONDS ) ) : null;
            String xPath = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.X_PATH_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.X_PATH_KEY ) : NO_XPATH ) : 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", domainEntryPoint, startDate, endDate, queryName, xPath,
                            queryTimeoutSeconds, null, specializedDomainEntryPoint, 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 filter <Document> the filter document created
     */
    public static Element buildFilterElementWithResolvedIdentfiers2x( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String clientRequestInitiationTime )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );
            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 = null;
            if ( filterId.equals( TemplateIdHelper.RDI_IC_RX_CANNED_FILTER_ID ) )
            {
                String xpathQuery = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.XPATH_QUERY ) != null ? ( String )entryFilterMap
                                .get( FilterBuilder.XPATH_QUERY ) : NO_XPATH_QUERY ) : NO_XPATH_QUERY;

                if ( domainEntryPoint.equals( "IntoleranceCondition" ) )
                {
                    xPath = FilterBuilder.RDI_IC_XPATH;
                }
                else if ( domainEntryPoint.equals( "OutpatientMedicationPromise" ) )
                {
                    xPath = FilterBuilder.RDI_RX_XPATH;
                }

            }
            else
            {
                xPath = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.X_PATH_KEY ) != null ? ( String )entryFilterMap
                                .get( FilterBuilder.X_PATH_KEY ) : NO_XPATH ) : NO_XPATH;
            }

            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
            String recordIdentity = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.RECORD_IDENTITY ) ) : null;
            String namespaceId = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.NAMESPACEID ) ) : null;
            String universalId = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.UNIVERSALID ) ) : null;
            String universalIdType = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.UNIVERSALIDTYPE ) ) : null;

            if ( recordIdentity != null && !recordIdentity.equals( "" ) )
                element.add( FilterBuilder.createEntryFilterWithRecordIdentifiers( "entryPointFilter", domainEntryPoint, recordIdentity, namespaceId,
                                universalId, universalIdType, queryName, null ) );
            else
                element.add( FilterBuilder.createEntryFilter( "entryPointFilter", domainEntryPoint, startDate, endDate, queryName, xPath, null ) );

        }

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


    /**
     * 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 static String buildFilterWithResolvedIdentfiers2x( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String clientRequestInitiationTime )
    {
        Element element = buildFilterElementWithResolvedIdentfiers2x( filterId, entryPointFilterMaps, resolvedPatients, clientRequestInitiationTime );
        return element.asXML();
    }


    public static String buildFilterWithNationalIdAndExcludeIdentifiers( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    String nationalId, List<Map<String, String>> excludeIdentifiers, String clientRequestInitiationTime )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createClientName( "clientName", "testClientName" ) );
        element.add( FilterBuilder.createClientName( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithNationalIdAndExcludeIdentifiers( "patients", nationalId, excludeIdentifiers ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );
            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 ) : NO_XPATH ) : 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", domainEntryPoint, startDate, endDate, queryName, xPath, 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 static String buildFilterWithResolvedIdentfiers( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String clientRequestInitiationTime )
    {
        Element element = buildFilterElementWithResolvedIdentfiers( filterId, entryPointFilterMaps, resolvedPatients, clientRequestInitiationTime );
        return element.asXML();
    }


    public static String buildFilterWithAddionalParms( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String clientRequestInitiationTime, Map<String, String> optionalParamsMap,
                    String xpath )
    {
        Element element = buildFilterElementWithOptionalParams( filterId, entryPointFilterMaps, resolvedPatients, clientRequestInitiationTime,
                        optionalParamsMap, xpath );

        return element.asXML();
    }


    public static String buildFilterWithResolvedIdentfiersTimeout( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String clientRequestInitiationTime, String timoutSeconds )
    {
        Element element = buildFilterElementWithResolvedIdentfiers( filterId, entryPointFilterMaps, resolvedPatients, clientRequestInitiationTime );
        return element.asXML();
    }


    /**
     * Method creates a filter with record identifiers for single record (detail) queries, non patient centric
     * 
     */
    public static String buildDetailFilterWithRecordIdentifier( String filterId, Map<String, String> entryPointFilterMap,
                    String clientRequestInitiationTime )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createClientName( "clientName", "testClientName" ) );
        if ( clientRequestInitiationTime != null )
        {
            element.add( FilterBuilder.createClientName( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        }

        String domainEntryPoint = entryPointFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );

        String queryTimeoutSeconds = ( entryPointFilterMap != null ) ? ( ( String )entryPointFilterMap.get( FilterBuilder.QUERY_TIMEOUT_SECONDS ) )
                        : null;
        String queryName = ( entryPointFilterMap != null ) ? ( entryPointFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryPointFilterMap
                        .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" )
                        : "id_1";
        String patientCentric = ( entryPointFilterMap != null ) ? ( entryPointFilterMap.get( FilterBuilder.PATIENT_CENTRIC_KEY ) != null ? ( String )entryPointFilterMap
                        .get( FilterBuilder.PATIENT_CENTRIC_KEY ) : "false" )
                        : "false";
        String recordIdentity = entryPointFilterMap.get( FilterBuilder.RECORD_IDENTITY );
        String namespaceId = entryPointFilterMap.get( FilterBuilder.NAMESPACEID );
        String universalId = entryPointFilterMap.get( FilterBuilder.UNIVERSALID );
        String universalIdType = entryPointFilterMap.get( FilterBuilder.UNIVERSALIDTYPE );

        element.add( FilterBuilder.createEntryFilterWithRecordIdentifiers( "entryPointFilter", domainEntryPoint, recordIdentity, namespaceId,
                        universalId, universalIdType, queryName, patientCentric, queryTimeoutSeconds ) );

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

        return element.asXML();
    }


    /**
     * 
     * @param domainEntryPoint
     * @param recordIdentifier
     * @param otherQueryParameters 
     * @return the filter as a string
     * @throws IllegalArgumentException if domainEntryPoint and recordIdentifier arguments are null or empty strings
     */
    public static String buildHealthAdapterJournalDetailsFilter( String domainEntryPoint, String recordIdentifier,
                    Map<String, String> otherQueryParameters )
    {
        if ( domainEntryPoint == null || domainEntryPoint.trim().equals( "" ) )
            throw new IllegalArgumentException( "domainEntryPoint argument cannot be null or empty string" );
        if ( recordIdentifier == null || recordIdentifier.trim().equals( "" ) )
            throw new IllegalArgumentException( "recordIdentifier argument cannot be null or empty string" );

        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.addAttribute( "vhimVersion", "Vhim_4_00" );
        element.addAttribute( "xsi:schemaLocation", "Filter Health_Adapter_Journal_Detail_Filter.xsd" );
        element.addAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );

        element.add( FilterBuilder.createFilterId( "filterId", TemplateIdHelper.HEALTH_ADAPTER_JOURNAL_DETAIL_FILTER ) );
        element.add( FilterBuilder.createClientName( "clientName", "testClientName" ) );
        element.add( DocumentHelper.createElement( "clientRequestInitiationTime" ).addText( "2001-12-17T09:30:47Z" ) );

        Element entryPointFilterElement = DocumentHelper.createElement( "entryPointFilter" );

        Attribute queryNameAttribute = DocumentHelper.createAttribute( entryPointFilterElement, "queryName", "ID_1" );
        entryPointFilterElement.add( queryNameAttribute );

        Attribute isPatientCentricAttribute = DocumentHelper.createAttribute( entryPointFilterElement, "isPatientCentric", "false" );
        entryPointFilterElement.add( isPatientCentricAttribute );

        Element domainEntryPointElement = DocumentHelper.createElement( "domainEntryPoint" );
        domainEntryPointElement.setText( domainEntryPoint );
        entryPointFilterElement.add( domainEntryPointElement );

        Element recordIdentifiersElement = DocumentHelper.createElement( "recordIdentifiers" );
        Element identityElement = DocumentHelper.createElement( "identity" ).addText( recordIdentifier );
        recordIdentifiersElement.add( identityElement );
        entryPointFilterElement.add( recordIdentifiersElement );

        if ( otherQueryParameters != null && !otherQueryParameters.isEmpty() )
        {
            Element otherQueryParametersElement = DocumentHelper.createElement( "otherQueryParameters" );
            for ( String key : otherQueryParameters.keySet() )
            {
                otherQueryParametersElement.add( DocumentHelper.createElement( key ).addText( otherQueryParameters.get( key ) ) );
            }
            entryPointFilterElement.add( otherQueryParametersElement );
        }
        element.add( entryPointFilterElement );

        return element.asXML();
    }


    /**
     * Method creates a patient with resolved identifiers
     * 
     */
    public static Element createPatientWithResolvedIdentifiers( String elementName, List<Map<String, String>> resolvedPatients )
    {

        Element element = DocumentHelper.createElement( elementName );
        for ( Map<String, String> patient : resolvedPatients )
        {
            String assigningAuthority = patient.get( FilterBuilder.ASSIGNING_AUTHORITY_KEY );
            String assigningFacility = patient.get( FilterBuilder.ASSIGNING_FACILITY );
            String patientIdentity = patient.get( FilterBuilder.IDENTITY );

            element.add( createPersonIdentifier( "resolvedIdentifiers", assigningAuthority, assigningFacility, patientIdentity ) );

        }
        return element;
    }


    /**
     * Method creates a patient with resolved identifiers
     * 
     */
    public static Element createPatientWithEdiPi( String elementName, List<Map<String, String>> patients )
    {

        Element element = DocumentHelper.createElement( elementName );
        for ( Map<String, String> patient : patients )
        {
            String assigningAuthority = patient.get( FilterBuilder.ASSIGNING_AUTHORITY_KEY );
            String assigningFacility = patient.get( FilterBuilder.ASSIGNING_FACILITY );
            String patientIdentity = patient.get( FilterBuilder.IDENTITY );

            element.add( createPersonIdentifier( "EdiPi", assigningAuthority, assigningFacility, patientIdentity ) );

        }
        return element;
    }


    /**
     * Method to create patient based on create xml information
     */
    public static Element createCHDRPatient( String elementName, String nationalId, String assigningAuthority, String assigningFacility )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.addElement( "NationalId" ).setText( nationalId );
        element.add( createCHDRExcludeIdentifier( "excludeIdentifiers", assigningAuthority, assigningFacility ) );
        return element;
    }


    //<xs:complexType name="PersonIdentifier">
    //<xs:sequence>
    //    <xs:element name="assigningAuthority" type="xs:string"/>
    //    <xs:element name="assigningFacility" type="xs:string"/>
    //    <xs:element name="identity" type="xs:string"/>
    //</xs:sequence>
    //</xs:complexType>
    public static Element createPersonIdentifier( String elementName, String assigningAuthority, String assigningFacility, String identity )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.addElement( "assigningAuthority" ).addText( assigningAuthority );
        element.addElement( "assigningFacility" ).addText( assigningFacility );
        element.addElement( "identity" ).addText( identity );
        return element;
    }


    //<xs:complexType name="EntityIdentifier">
    //    <xs:sequence>
    //        <xs:element name="identity" type="xs:string" minOccurs="0"/>
    //        <xs:element name="namespaceId" type="xs:string" default="VHA" minOccurs="0"/>
    //        <xs:element name="universalId" type="xs:string" minOccurs="0"/>
    //        <xs:element name="universalIdType" type="xs:string" minOccurs="0"/>
    //    </xs:sequence>
    //</xs:complexType>
    public static Element createEntityIdentifier( String elementName )
    {
        return BaseDatatypesBuilder.createHL72EntityIdentifier( elementName );
    }


    public static Element createEntityIdentifier( String elementName, String identity, String namespaceId, String universalId )
    {
        return BaseDatatypesBuilder.createHL72EntityIdentifier( elementName, identity, namespaceId, universalId );
    }


    public static Element createEntityIdentifier( String elementName, String identity, String namespaceId, String universalId, String universalIdType )
    {
        return BaseDatatypesBuilder.createHL72EntityIdentifier( elementName, identity, namespaceId, universalId, universalIdType );
    }


    //<xs:complexType name="EntryFilter">
    //    <xs:sequence>
    //        <xs:element name="domainEntryPoint" type="filter:DomainEntryPoint"/>
    //        <xs:element name="startDate" type="filter:DateParameter" minOccurs="0"/>
    //        <xs:element name="endDate" type="filter:DateParameter" minOccurs="0"/>
    //        <xs:element name="xpathQuery" type="filter:XpathQuery"/>
    //    </xs:sequence>
    //    <xs:attribute name="queryName" type="xs:ID" use="required"/>
    //</xs:complexType>    

    public static Element createEntryFilter( String elementName, String domainEntryPoint, String startDate, String endDate, String queryName,
                    String xpath, String queryTimeoutSeconds, String clientRequestInitiationTime, String specializedDomainEntryPointFilter,
                    Map<String, String> optionalParamsMap )
    {
        Element element = DocumentHelper.createElement( elementName );
        /*if ( specializedDomainEntryPointFilter != null )
        {
            Element specialized = DocumentHelper.createElement( specializedDomainEntryPointFilter );
            specialized.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );
            if ( optionalParamsMap != null )
            {
                Element otherQueryParameters = DocumentHelper.createElement( "otherQueryParameters" );

                for ( Map.Entry<String, String> optionalParam : optionalParamsMap.entrySet() )
                {
                    if ( optionalParam.getValue() != null && optionalParam.getValue().length() > 0 )
                    {
                        otherQueryParameters.add( DocumentHelper.createElement( optionalParam.getKey() ).addText( optionalParam.getValue() ) );
                    }
                }
                specialized.add( otherQueryParameters );
            }

            element.add( specialized );
        }
        else
        {*/
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );

        //}

        if ( startDate != null && endDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
            element.add( createDateParameter( "endDate", endDate ) );
        }

        if ( xpath != null && xpath.length() > 0 )
        {
            element.add( createXpathQuery( "xpathQuery", xpath ) );
        }
        if ( optionalParamsMap != null )
        {
            Element otherQueryParameters = DocumentHelper.createElement( "otherQueryParameters" );

            for ( Map.Entry<String, String> optionalParam : optionalParamsMap.entrySet() )
            {
                if ( optionalParam.getValue() != null && optionalParam.getValue().length() > 0 )
                {
                    otherQueryParameters.add( DocumentHelper.createElement( optionalParam.getKey() ).addText( optionalParam.getValue() ) );
                }
            }
            element.add( otherQueryParameters );
        }
        if ( queryTimeoutSeconds != null )
        {
            element.add( createDateParameter( "queryTimeoutSeconds", queryTimeoutSeconds ) );
        }

        if ( clientRequestInitiationTime != null )
        {
            element.add( createDateParameter( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        }

        element.addAttribute( "queryName", queryName );
        return element;
    }


    public static Element createEntryFilter( String elementName, String domainEntryPoint, String startDate, String endDate, String queryName,
                    String xpath, String queryTimeoutSeconds )
    {
        return createEntryFilter( elementName, domainEntryPoint, startDate, endDate, queryName, xpath, queryTimeoutSeconds, null );
    }


    public static Element createEntryFilter( String elementName, String domainEntryPoint, String startDate, String endDate, String queryName,
                    String xpath, String queryTimeoutSeconds, String clientRequestInitiationTime )
    {
        return createEntryFilter( elementName, domainEntryPoint, startDate, endDate, queryName, xpath, queryTimeoutSeconds,
                        clientRequestInitiationTime, null, null );
    }


    //<xs:complexType name="EntryFilter">
    //    <xs:sequence>
    //        <xs:element name="domainEntryPoint" type="filter:DomainEntryPoint"/>
    //        <xs:element name="startDate" type="filter:DateParameter" minOccurs="0"/>
    //        <xs:element name="endDate" type="filter:DateParameter" minOccurs="0"/>
    //        <xs:element name="otherQueryParameters" type="filter:AdditionalParameters" minOccurs="0"/>
    //    </xs:sequence>
    //    <xs:attribute name="queryName" type="xs:ID" use="required"/>
    //</xs:complexType>
    public static Element createEntryFilterWithAdditionalParameters( String elementName, String domainEntryPoint, String startDate, String endDate,
                    String documentClassValue, String[] documentTypeValues, String queryName, String xQueryCriteria )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );

        if ( startDate != null && endDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
            element.add( createDateParameter( "endDate", endDate ) );
        }

        if ( ( null != documentClassValue && documentClassValue.length() > 0 ) || ( null != documentTypeValues && documentTypeValues.length > 0 ) )
        {
            element.add( createAdditionalParameters( "otherQueryParameters", documentClassValue, documentTypeValues ) );
        }

        if ( xQueryCriteria != null )
        {
            Element orderByElement = DocumentHelper.createElement( "orderBy" );
            orderByElement.add( DocumentHelper.createElement( "xqueryExpression" ).addText( xQueryCriteria ) );

            element.add( orderByElement );
        }

        element.addAttribute( "queryName", queryName );
        return element;
    }


    public static Element createOutpatientMedicationPromiseEntryFilterWithAdditionalParameters( String elementName, String domainEntryPoint,
                    String startDate, String endDate, String queryName )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );

        if ( startDate != null && endDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
            element.add( createDateParameter( "endDate", endDate ) );
        }
        element.addAttribute( "queryName", queryName );
        return element;
    }


    public static Element createOutpatientMedicationPromiseEntryFilterWithXpath( String elementName, String domainEntryPoint, String startDate,
                    String endDate, String queryName )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );

        if ( startDate != null && endDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
            element.add( createDateParameter( "endDate", endDate ) );
        }

        element.add( createXpathQuery( "xpathQuery",
                        "outpatientMedicationPromises[pharmacyRequest/statusModifier[contains(displayText,'StatusModifierDisplayTextLite')]]" ) );
        element.addAttribute( "queryName", queryName );
        return element;
    }


    public static Element createMHAEntryFilterWithAdditionalParameters( String elementName, String domainEntryPoint, String startDate,
                    String endDate, String queryName )
    {
        return createMHAEntryFilterWithAdditionalParameters( elementName, domainEntryPoint, startDate, endDate, queryName, null );
    }


    public static Element createMHAEntryFilterWithAdditionalParameters( String elementName, String domainEntryPoint, String startDate,
                    String endDate, String queryName, String specializedDomainEntryPoint )
    {
        Element element = DocumentHelper.createElement( elementName );
        String specializedName = "filter:defaultDomainEntryPointFilter";
        if ( specializedDomainEntryPoint != null )
        {
            specializedName = specializedDomainEntryPoint;
        }
        Element specialized = DocumentHelper.createElement( specializedName );
        specialized.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );
        element.add( specialized );

        if ( startDate != null && endDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
            element.add( createDateParameter( "endDate", endDate ) );
        }
        element.addAttribute( "queryName", queryName );
        return element;
    }


    public static Element createMHAEntryFilterWithAdditionalParametersNoEndDate( String elementName, String domainEntryPoint, String startDate,
                    String endDate, String queryName )
    {
        return createMHAEntryFilterWithAdditionalParametersNoEndDate( elementName, domainEntryPoint, startDate, endDate, queryName, null );
    }


    public static Element createMHAEntryFilterWithAdditionalParametersNoEndDate( String elementName, String domainEntryPoint, String startDate,
                    String endDate, String queryName, String specializedDomainEntryPoint )
    {
        Element element = DocumentHelper.createElement( elementName );

        String specializedName = "filter:defaultDomainEntryPointFilter";
        if ( specializedDomainEntryPoint != null )
        {
            specializedName = specializedDomainEntryPoint;
        }
        Element specialized = DocumentHelper.createElement( specializedName );
        specialized.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );
        element.add( specialized );

        if ( startDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );

            if ( endDate != null )
                element.add( createDateParameter( "endDate", endDate ) );
        }
        element.addAttribute( "queryName", queryName );
        return element;
    }


    public static Element createOutpatientMedicationPromiseEntryFilterWithAdditionalParametersAndTimeout( String elementName,
                    String domainEntryPoint, String startDate, String endDate, String queryName, String queryTimeoutSeconds )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );

        if ( startDate != null && endDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
            element.add( createDateParameter( "endDate", endDate ) );

        }

        if ( queryTimeoutSeconds != null )
        {
            element.add( createDateParameter( "queryTimeoutSeconds ", queryTimeoutSeconds ) );
        }
        element.addAttribute( "queryName", queryName );
        return element;
    }


    public static Element createOutpatientMedicationPromiseEntryFilterWithAdditionalQueryParameters( String elementName, String domainEntryPoint,
                    String identity, String namespaceId, String universalId, String universalIdType, String queryName, String queryTimeoutSeconds )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );
        element.add( createRecordIdentifier( "recordIdentifiers", identity, namespaceId, universalId, universalIdType ) );
        if ( queryTimeoutSeconds != null )
        {
            element.add( createDateParameter( "queryTimeoutSeconds", queryTimeoutSeconds ) );
        }

        element.addAttribute( "queryName", queryName );
        return element;
    }


    /*
    <xs:complexType name="EntryFilter">
    <xs:sequence>
        <xs:element name="domainEntryPoint" type="filter:DomainEntryPoint"/>
        <xs:element name="otherQueryParameters" type="filter:AdditionalParameters" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="queryName" type="xs:ID" use="required"/>
    </xs:complexType> 
    */
    public static Element createNonVaMedEntryFilterWithAdditionalParameters( String elementName, String domainEntryPoint, String statusValue,
                    String queryName )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );

        if ( ( null != statusValue && statusValue.length() > 0 ) )
        {
            element.add( createNonVaMedAdditionalParameters( "otherQueryParameters", statusValue ) );
        }

        element.addAttribute( "queryName", queryName );
        return element;

    }


    public static Element createAppointmentEntryFilterWithAdditionalParameters( String elementName, String domainEntryPoint, String startDate,
                    String endDate, String statusValue, String queryName )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );
        if ( startDate != null && endDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
            element.add( createDateParameter( "endDate", endDate ) );
        }
        else if ( startDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
        }
        else if ( endDate != null )
        {
            element.add( createDateParameter( "endDate", endDate ) );
        }
        if ( ( null != statusValue && statusValue.length() > 0 ) )
        {
            element.add( createAppointmentAdditionalParameters( "otherQueryParameters", statusValue ) );
        }

        element.addAttribute( "queryName", queryName );
        return element;

    }


    //<xs:complexType name="EntryFilter">
    //    <xs:sequence>
    //        <xs:element name="domainEntryPoint" type="filter:DomainEntryPoint"/>
    //        <xs:element name="recordIdentifiers" type="filter:EntityIdentifier"/>
    //    </xs:sequence>
    //    <xs:attribute name="queryName" type="xs:ID" use="required"/>
    //</xs:complexType>
    public static Element createEntryFilterWithRecordIdentifiers( String elementName, String domainEntryPoint, String identity, String namespaceId,
                    String universalId, String queryName )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );
        element.add( createEntityIdentifier( "recordIdentifiers", identity, namespaceId, universalId ) );
        element.addAttribute( "queryName", queryName );
        return element;
    }


    public static Element createEntryFilterWithRecordIdentifiers( String elementName, String domainEntryPoint, String identity, String namespaceId,
                    String universalId, String universalIdType, String queryName )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );

        if ( domainEntryPoint.equals( "PatientAlert" ) )
        {
            Element startDateElement = DocumentHelper.createElement( "startDate" );
            startDateElement.setText( namespaceId );
            element.add( startDateElement );
            element.add( DocumentHelper.createElement( "otherQueryParameters" ) );

            element.element( "otherQueryParameters" ).add( DocumentHelper.createElement( "identity" ).addText( identity ) );
        }
        else
        {
            element.add( createEntityIdentifier( "recordIdentifiers", identity, namespaceId, universalId, universalIdType ) );
        }

        element.addAttribute( "queryName", queryName );

        return element;
    }


    public static Element createEntryFilterWithRecordIdentifiers( String elementName, String domainEntryPoint, String identity, String namespaceId,
                    String universalId, String universalIdType, String queryName, String queryTimeoutSeconds )
    {
        return createEntryFilterWithRecordIdentifiers( elementName, domainEntryPoint, identity, namespaceId, universalId, universalIdType, queryName,
                        null, queryTimeoutSeconds );
    }


    public static Element createEntryFilterWithRecordIdentifiers( String elementName, String domainEntryPoint, String identity, String namespaceId,
                    String universalId, String universalIdType, String queryName, String patientCentric, String queryTimeoutSeconds )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );
        element.add( createEntityIdentifier( "recordIdentifiers", identity, namespaceId, universalId, universalIdType ) );

        if ( queryTimeoutSeconds != null )
            element.add( DocumentHelper.createElement( "queryTimeoutSeconds" ).addText( queryTimeoutSeconds ) );

        element.addAttribute( "queryName", queryName );
        element.addAttribute( "isPatientCentric", patientCentric );

        return element;
    }
    
    public static Element createEntryFilterWithoutIdentifiers( String elementName, String domainEntryPoint, String queryName, String patientCentric, String facilityId, String queryTimeoutSeconds, Map<String, String> optionalParamsMap )
    {
    	Element element = DocumentHelper.createElement( elementName );
    	element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );
    	
    	if ( queryTimeoutSeconds != null )
    		element.add( DocumentHelper.createElement( "queryTimeoutSeconds" ).addText( queryTimeoutSeconds ) );

    	element.addAttribute( "queryName", queryName );
    	element.addAttribute( "isPatientCentric", patientCentric );
    	if(facilityId != null){
    		element.addAttribute( "facilityId", facilityId );
    	}
    	
    	 if ( optionalParamsMap != null )
         {
             Element otherQueryParameters = DocumentHelper.createElement( "otherQueryParameters" );

             for ( Map.Entry<String, String> optionalParam : optionalParamsMap.entrySet() )
             {
                 if ( optionalParam.getValue() != null && optionalParam.getValue().length() > 0 )
                 {
                     otherQueryParameters.add( DocumentHelper.createElement( optionalParam.getKey() ).addText( optionalParam.getValue() ) );
                 }
             }
             element.add( otherQueryParameters );
         }

    	return element;
    }


    //<xs:complexType name="XpathQuery">
    //    <xs:sequence>
    //        <xs:element name="xpath" type="filter:XPath"/>
    //    </xs:sequence>
    //</xs:complexType>
    public static Element createXpathQuery( String elementName, String xpath )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createXPath( "xpath", xpath ) );
        return element;
    }


    //<xs:simpleType name="XPath">
    //    <xs:restriction base="xs:string">
    //        <xs:enumeration value="intoleranceConditions[status != 'E']"/>
    //    </xs:restriction>
    //</xs:simpleType>
    public static Element createXPath( String elementName, String xpath )
    {
        return DocumentHelper.createElement( elementName ).addText( xpath );
    }


    //<xs:simpleType name="DateParameter">
    //    <xs:restriction base="xs:date"/>
    //</xs:simpleType>
    public static Element createDateParameter( String elementName, String date )
    {
        return DocumentHelper.createElement( elementName ).addText( date );
    }


    //<xs:simpleType name="DateParameter">
    //    <xs:restriction base="xs:date"/>
    //</xs:simpleType>
    public static Element createClientRequestInitiationTimeParameter( String elementName, String clientRequestInitiationTime )
    {
        return DocumentHelper.createElement( elementName ).addText( clientRequestInitiationTime );
    }


    //<xs:simpleType name="FilterId">
    //    <xs:restriction base="xs:string"/>
    //</xs:simpleType>
    public static Element createFilterId( String elementName, String filterId )
    {
        return DocumentHelper.createElement( elementName ).addText( filterId );
    }


    public static Element createClientRequestInitiationTime( String elementName, String clientRequestInitiationTime )
    {
        return DocumentHelper.createElement( elementName ).addText( clientRequestInitiationTime );
    }


    public static Element createClientName( String elementName, String clientName )
    {
        return DocumentHelper.createElement( elementName ).addText( clientName );
    }


    //<xs:simpleType name="DomainEntryPoint">
    //    <xs:restriction base="xs:string">
    //        <xs:enumeration value="AllergyAssessment"/>
    //        <xs:enumeration value="IntoleranceCondition"/>
    //    </xs:restriction>
    //</xs:simpleType>
    public static Element createDomainEntryPoint( String elementName, String domainEntryPoint )
    {
        return DocumentHelper.createElement( elementName ).addText( domainEntryPoint );
    }


    public static Element createRecordIdentifier( String elementName, String identity, String namespaceId, String universalId, String universalIdType )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createRecordIdentity( "identity", identity ) );
        element.add( createRecordNamespaceId( "namespaceId", namespaceId ) );
        element.add( createRecordUniversalId( "universalId", universalId ) );
        element.add( createRecordUniversalIdType( "universalIdType", universalIdType ) );
        return element;
    }


    public static Element createRecordIdentity( String elementName, String identity )
    {
        return DocumentHelper.createElement( elementName ).addText( identity );
    }


    public static Element createRecordNamespaceId( String elementName, String namespaceId )
    {
        return DocumentHelper.createElement( elementName ).addText( namespaceId );
    }


    public static Element createRecordUniversalId( String elementName, String universalId )
    {
        return DocumentHelper.createElement( elementName ).addText( universalId );
    }


    public static Element createRecordUniversalIdType( String elementName, String universalIdType )
    {
        return DocumentHelper.createElement( elementName ).addText( universalIdType );
    }


    //<xs:complexType name="ExcludeIdentifier">
    //    <xs:sequence>
    //        <xs:element name="assigningAuthority" type="filter:CHDRAuthority"/>
    //        <xs:element name="assigningFacility" type="filter:CHDRFacility"/>
    //    </xs:sequence>
    //</xs:complexType>
    public static Element createCHDRExcludeIdentifier( String elementName, String assigningAuthority, String assigningFacility )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createChdrAuthority( "assigningAuthority", assigningAuthority ) );
        element.add( createChdrFacility( "assigningFacility", assigningFacility ) );
        return element;
    }


    //<xs:simpleType name="CHDRAuthority">
    //    <xs:restriction base="xs:string">
    //        <xs:enumeration value="USDOD"/>
    //    </xs:restriction>
    //</xs:simpleType>
    public static Element createChdrAuthority( String elementName, String assigningAuthority )
    {
        return DocumentHelper.createElement( elementName ).addText( assigningAuthority );
    }


    //<xs:simpleType name="CHDRFacility">
    //    <xs:restriction base="xs:string">
    //        <xs:enumeration value="200HD"/>
    //        <xs:enumeration value="200CH"/>
    //    </xs:restriction>
    //</xs:simpleType>
    public static Element createChdrFacility( String elementName, String assigningFacility )
    {
        return DocumentHelper.createElement( elementName ).addText( assigningFacility );
    }


    //<xs:complexType name="AdditionalParameters">
    //    <xs:choice>
    //        <xs:element name="documentClass" type="filter:DocumentClassValues"/>
    //        <xs:element name="documentType" type="filter:DocumentTypeValues" maxOccurs="unbounded"/>
    //    </xs:choice>
    //</xs:complexType>
    public static Element createAdditionalParameters( String elementName, String documentClassValue, String[] documentTypeValues )
    {
        Element element = DocumentHelper.createElement( elementName );

        if ( null != documentClassValue && documentClassValue.length() > 0 )
        {
            element.add( createDocumentClassValues( "documentClass", documentClassValue ) );
        }

        if ( null != documentTypeValues )
        {
            for ( String documentTypeValue : documentTypeValues )
            {
                element.add( createDocumentTypeValues( "documentType", documentTypeValue ) );
            }
        }

        return element;
    }


    /*
     <xs:complexType name="AdditionalParameters">
        <xs:choice>
            <xs:element name="status" type="filter:StatusValues"/>
        </xs:choice>
     </xs:complexType>
     */

    public static Element createNonVaMedAdditionalParameters( String elementName, String statusValue )
    {
        Element element = DocumentHelper.createElement( elementName );

        if ( null != statusValue && statusValue.length() > 0 )
        {
            element.add( createDocumentClassValues( "status", statusValue ) );
        }

        return element;
    }


    public static Element createAppointmentAdditionalParameters( String elementName, String statusValue )
    {
        Element element = DocumentHelper.createElement( elementName );

        if ( null != statusValue && statusValue.length() > 0 )
        {
            element.add( createDocumentClassValues( "appointmentStatus", statusValue ) );
        }

        return element;
    }


    //<xs:simpleType name="DocumentClassValues">
    //    <xs:restriction base="xs:string">
    //        <xs:enumeration value="3"/>
    //        <xs:enumeration value="244"/>
    //        <!--"PROGRESS NOTES"/-->
    //        <!--"DISCHARGE SUMMARY"/-->
    //    </xs:restriction>
    //</xs:simpleType>
    public static Element createDocumentClassValues( String elementName, String documentClassValue )
    {
        return DocumentHelper.createElement( elementName ).addText( documentClassValue );
    }


    //<xs:simpleType name="DocumentTypeValues">
    //    <xs:restriction base="xs:string">
    //        <xs:enumeration value="4696095"/>
    //        <xs:enumeration value="4696107"/>
    //        <xs:enumeration value="4697146"/>
    //        <xs:enumeration value="4696112"/>
    //        <xs:enumeration value="4696113"/>
    //        <xs:enumeration value="4696119"/>
    //        <xs:enumeration value="4696120"/>
    //        <xs:enumeration value="4696125"/>
    //        <xs:enumeration value="4696444"/>
    //        <!--"ADVANCE DIRECTIVE"/-->
    //        <!--"CONSULT"/-->
    //        <!--"CRISIS NOTE"/-->
    //        <!--"DISCHARGE SUMMARY"/-->
    //        <!--"DO NOT RESUSCITATE"/-->
    //        <!--"LIVING WILL"/-->
    //        <!--"NOTE"/-->
    //        <!--"RESCINDED ADVANCE DIRECTIVE"/-->
    //        <!--"RESCINDED DO NOT RESUSCITATE"/-->
    //    </xs:restriction>
    //</xs:simpleType>    
    public static Element createDocumentTypeValues( String elementName, String DocumentTypeValue )
    {
        return DocumentHelper.createElement( elementName ).addText( DocumentTypeValue );
    }


    /*
    <xs:complexType name="OptionalParameters">
    <xs:all>
        <xs:element name="status" type="filter:StatusValues" minOccurs="0"/>
        <xs:element name="condition" type="filter:ConditionValues" minOccurs="0"/>
    </xs:all>
    </xs:complexType>
    */
    public static Element createProlemListAdditionalParameters( String elementName, Map<String, String> optionalParamsMap )
    {
        Element element = DocumentHelper.createElement( elementName );

        for ( Map.Entry<String, String> optionalParam : optionalParamsMap.entrySet() )
        {
            if ( optionalParam.getValue() != null && optionalParam.getValue().length() > 0 )
            {
                element.add( createDocumentClassValues( optionalParam.getKey(), optionalParam.getValue() ) );
            }
        }

        return element;
    }


    /**
     * This method is used to convert a XML String to a Document object
     *
     * @param xml - XML string which has to be converted to a Document object
     * @return
     */
    public static Document convertString2Document( String xml )
    {
        Document document = null;
        try
        {
            document = DocumentHelper.parseText( xml );
        }
        catch ( DocumentException e )
        {
            e.printStackTrace();
        }
        return document;
    }


    public static Element buildVrmFilterElementWithResolvedIdentfiers( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String startDate, String endDate, String statusValue )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );

            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";

            if ( statusValue != null )
            {
                element.add( FilterBuilder.createVrmEntryFilterWithAdditionalParameters( "entryPointFilter", domainEntryPoint, startDate, endDate,
                                statusValue, queryName ) );
            }
            else
            {
                element.add( FilterBuilder.createEntryFilter( "entryPointFilter", domainEntryPoint, null, null, queryName, null, null ) );
            }

        }

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


    public static String buildRequestsNExamsFilterElementWithResolvedIdentfiers( String filterId, String clientName,
                    String clientRequestInitiationTime, List<Map<String, String>> entryPointFilterMaps, List<Map<String, String>> resolvedPatients,
                    Map<String, String> optionalParamsMap )
    {

        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createClientName( "clientName", clientName ) );
        if ( clientRequestInitiationTime != null )
            element.add( FilterBuilder.createClientRequestInitiationTime( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );
            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
            String startDate = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.START_DATE_KEY ) ) : null;
            String endDate = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.END_DATE_KEY ) ) : null;

            if ( ( optionalParamsMap != null && optionalParamsMap.size() > 0 ) || startDate != null || endDate != null )
            {
                element.add( FilterBuilder.createRequestsNExamsFilterWithAdditionalParameters( "entryPointFilter", domainEntryPoint,
                                optionalParamsMap, startDate, endDate, queryName ) );
            }
            else
            {
                element.add( FilterBuilder.createEntryFilter( "entryPointFilter", domainEntryPoint, startDate, endDate, queryName, null, null ) );
            }
        }

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

    }


    public static Element createRequestsNExamsFilterWithAdditionalParameters( String elementName, String domainEntryPoint,
                    Map<String, String> optionalParamsMap, String startDate, String endDate, String queryName )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );

        if ( startDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
        }

        if ( endDate != null )
        {
            element.add( createDateParameter( "endDate", endDate ) );
        }

        if ( optionalParamsMap != null )
        {
            element.add( createRequestsNExamsAdditionalParameters( "otherQueryParameters", domainEntryPoint, optionalParamsMap ) );
        }

        element.addAttribute( "queryName", queryName );
        return element;
    }


    public static Element createRequestsNExamsAdditionalParameters( String elementName, String domainEntryPoint, Map<String, String> optionalParamsMap )
    {
        Element element = DocumentHelper.createElement( elementName );
        String optionalParamKey = null;
        String optionalParamValue = null;

        if ( !optionalParamsMap.isEmpty() )
        {
            if ( domainEntryPoint.equals( "ExamRequest2507" ) )
            {
                optionalParamKey = "requestStatus";
                optionalParamValue = optionalParamsMap.get( "requestStatus" );
            }
            else if ( domainEntryPoint.equals( "Exam2507" ) )
            {
                optionalParamKey = "status";
                optionalParamValue = optionalParamsMap.get( "status" );
            }
            element.add( createDocumentClassValues( optionalParamKey, optionalParamValue ) );

        }

        return element;
    }


    public static Element buildExamRequestsFilterElementWithResolvedIdentfiers( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String startDate, String endDate, String clientRequestInitiationTime, String status )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( DocumentHelper.createElement( "clientName" ).addText( "VRM 1.0" ) );
        element.add( createDateParameter( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );

            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
            if ( status != null || startDate != null || clientRequestInitiationTime != null )
            {
                element.add( FilterBuilder.createExamRequestsDomainEntryPointWithAdditionalParameters( "entryPointFilter", domainEntryPoint,
                                startDate, endDate, clientRequestInitiationTime, status, queryName ) );
            }
            else
            {
                element.add( FilterBuilder.createEntryFilter( "entryPointFilter", domainEntryPoint, null, null, queryName, null, null ) );
            }

        }

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


    public static Element buildClinicalRemindersFilterElementWithResolvedIdentfiers( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String startDate, String endDate, String clientRequestInitiationTime, String status,
                    String token )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( DocumentHelper.createElement( "clientName" ).addText( "VRM 1.0" ) );
        element.add( createDateParameter( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );

            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
            if ( status != null || startDate != null || clientRequestInitiationTime != null )
            {
                element.add( FilterBuilder.createClinicalRemindersDomainEntryPointWithAdditionalParameters( "entryPointFilter", domainEntryPoint,
                                startDate, endDate, clientRequestInitiationTime, status, token, queryName ) );
            }
            else
            {
                element.add( FilterBuilder.createEntryFilter( "entryPointFilter", domainEntryPoint, null, null, queryName, null, null ) );
            }

        }

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


    public static Element createClinicalRemindersDomainEntryPointWithAdditionalParameters( String elementName, String domainEntryPoint,
                    String startDate, String endDate, String clientRequestInitiationTime, String status, String token, String queryName )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );

        if ( startDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
        }
        if ( endDate != null )
        {
            element.add( createDateParameter( "endDate", endDate ) );
        }
        Element otherQueryParameters = DocumentHelper.createElement( "otherQueryParameters" );
        if ( token != null )
        {
            otherQueryParameters.add( DocumentHelper.createElement( "samlToken" ).addText( token ) );

        }
        if ( otherQueryParameters.hasContent() )
        {
            element.add( otherQueryParameters );
        }
        if ( status != null )
        {

            if ( status.indexOf( "," ) > 0 )
            {
                String[] statusArray = status.split( "," );
                for ( int i = 0; i < statusArray.length; i++ )
                {
                    otherQueryParameters.add( DocumentHelper.createElement( "status" ).addText( statusArray[i] ) );
                }
            }
            else
            {
                otherQueryParameters.add( DocumentHelper.createElement( "status" ).addText( status ) );
            }

        }
        element.addAttribute( "queryName", queryName );
        return element;
    }


    public static Element createExamRequestsDomainEntryPointWithAdditionalParameters( String elementName, String domainEntryPoint, String startDate,
                    String endDate, String clientRequestInitiationTime, String status, String queryName )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );

        if ( startDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
        }
        if ( endDate != null )
        {
            element.add( createDateParameter( "endDate", endDate ) );
        }
        if ( status != null )
        {
            Element otherQueryParameters = DocumentHelper.createElement( "otherQueryParameters" );
            if ( status.indexOf( "," ) > 0 )
            {
                String[] statusArray = status.split( "," );
                for ( int i = 0; i < statusArray.length; i++ )
                {
                    otherQueryParameters.add( DocumentHelper.createElement( "requestStatus" ).addText( statusArray[i] ) );
                }
            }
            else
            {
                otherQueryParameters.add( DocumentHelper.createElement( "requestStatus" ).addText( status ) );
            }
            element.add( otherQueryParameters );
        }

        element.addAttribute( "queryName", queryName );
        return element;
    }


    public static Element createExamRequestsDomainEntryPointWithAdditionalParameters( String elementName, String domainEntryPoint, String startDate,
                    String endDate, String clientRequestInitiationTime, ArrayList<String> statusList, String queryName )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );

        if ( startDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
        }
        if ( endDate != null )
        {
            element.add( createDateParameter( "endDate", endDate ) );
        }
        if ( statusList != null )
        {
            Element otherQueryParameters = DocumentHelper.createElement( "otherQueryParameters" );
            for ( String status : statusList )
            {
                otherQueryParameters.add( DocumentHelper.createElement( "requestStatus" ).addText( status ) );
            }

            element.add( otherQueryParameters );
        }

        element.addAttribute( "queryName", queryName );
        return element;
    }


    public static Element buildExamsFilterElementWithResolvedIdentfiers( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String startDate, String endDate, String clientRequestInitiationTime, String status )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( DocumentHelper.createElement( "clientName" ).addText( "VRM 1.0" ) );
        element.add( createDateParameter( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );

            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
            if ( status != null || startDate != null || clientRequestInitiationTime != null )
            {
                element.add( FilterBuilder.createExamsDomainEntryPointWithAdditionalParameters( "entryPointFilter", domainEntryPoint, startDate,
                                endDate, clientRequestInitiationTime, status, queryName ) );
            }
            else
            {
                element.add( FilterBuilder.createEntryFilter( "entryPointFilter", domainEntryPoint, null, null, queryName, null, null ) );
            }

        }

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


    public static Element createExamsDomainEntryPointWithAdditionalParameters( String elementName, String domainEntryPoint, String startDate,
                    String endDate, String clientRequestInitiationTime, String status, String queryName )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );

        if ( startDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
        }
        if ( endDate != null )
        {
            element.add( createDateParameter( "endDate", endDate ) );
        }
        if ( status != null )
        {
            Element otherQueryParameters = DocumentHelper.createElement( "otherQueryParameters" );
            otherQueryParameters.add( DocumentHelper.createElement( "status" ).addText( status ) );
            element.add( otherQueryParameters );
        }

        element.addAttribute( "queryName", queryName );
        return element;
    }


    public static Element buildAppointmentsFilterElementWithResolvedIdentfiers( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String startDate, String endDate, String clientRequestInitiationTime )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( DocumentHelper.createElement( "clientName" ).addText( "VRM 1.0" ) );
        element.add( createDateParameter( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );

            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
            String queryTimeoutSeconds = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.QUERY_TIMEOUT_SECONDS ) ) : null;

            if ( startDate != null || clientRequestInitiationTime != null )
            {
                element.add( FilterBuilder.createAppointmentsDomainEntryPointWithAdditionalParameters( "entryPointFilter", domainEntryPoint,
                                startDate, endDate, clientRequestInitiationTime, queryName, queryTimeoutSeconds ) );
            }
            else
            {
                element.add( FilterBuilder.createEntryFilter( "entryPointFilter", domainEntryPoint, null, null, queryName, null, queryTimeoutSeconds ) );
            }

        }

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


    /***
     * The Patient Alerts filter
     * @param filterId name of the Patient Alerts filters
     * @param entryPointFilterMaps
     * @param resolvedPatients
     * @param startDate
     * @param endDate
     * @param clientRequestInitiationTime
     * @param identity
     * @param namespaceId
     * @param universalId
     * @param universalIdType
     * @return
     */
    public static Element buildPatientAlertFilterElementWithRequestId( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String startDate, String endDate, String clientRequestInitiationTime,
                    String identity, String namespaceId, String universalId, String universalIdType )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( DocumentHelper.createElement( "clientName" ).addText( "Fix The Phones" ) );
        element.add( createDateParameter( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );

            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
            String queryTimeoutSeconds = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.QUERY_TIMEOUT_SECONDS ) ) : null;

            if ( startDate != null || clientRequestInitiationTime != null )
            {
                element.add( FilterBuilder.createEntryFilterWithRecordIdentifiers( "entryPointFilter", "PatientAlert", identity, namespaceId, null,
                                null, queryName ) );
            }
            else
            {
                element.add( FilterBuilder.createEntryFilter( "entryPointFilter", domainEntryPoint, null, null, queryName, null, queryTimeoutSeconds ) );
            }

        }

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


    /***
     * 
     * @param elementName
     * @param elementValue
     * @return
     */
    private Element createElement( String elementName, String elementValue )
    {

        return DocumentHelper.createElement( elementName ).addText( elementValue );
    }


    public static Element buildAppointmentsFilterElementWithResolvedIdentfiersNoClientName( String filterId,
                    List<Map<String, String>> entryPointFilterMaps, List<Map<String, String>> resolvedPatients, String startDate, String endDate,
                    String clientRequestInitiationTime )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( DocumentHelper.createElement( "clientName" ).addText( "" ) );
        element.add( createDateParameter( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );

            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
            if ( startDate != null || clientRequestInitiationTime != null )
            {
                element.add( FilterBuilder.createAppointmentsDomainEntryPointWithAdditionalParameters( "entryPointFilter", domainEntryPoint,
                                startDate, endDate, clientRequestInitiationTime, queryName, null ) );
            }
            else
            {
                element.add( FilterBuilder.createEntryFilter( "entryPointFilter", domainEntryPoint, null, null, queryName, null, null ) );
            }

        }

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


    public static Element createAppointmentsDomainEntryPointWithAdditionalParameters( String elementName, String domainEntryPoint, String startDate,
                    String endDate, String clientRequestInitiationTime, String queryName, String queryTimeoutSeconds )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );

        if ( startDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
        }
        if ( endDate != null )
        {
            element.add( createDateParameter( "endDate", endDate ) );
        }
        element.addAttribute( "queryName", queryName );

        if ( queryTimeoutSeconds != null )
        {
            element.add( DocumentHelper.createElement( "queryTimeoutSeconds" ).addText( queryTimeoutSeconds ) );
        }
        return element;
    }


    public static Element createVrmEntryFilterWithAdditionalParameters( String elementName, String domainEntryPoint, String startDate,
                    String endDate, String statusValue, String queryName )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );

        if ( startDate != null && endDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
            element.add( createDateParameter( "endDate", endDate ) );
        }

        if ( null != statusValue )
        {
            Element otherQueryParameters = DocumentHelper.createElement( "otherQueryParameters" );
            otherQueryParameters.add( DocumentHelper.createElement( "status" ).addText( statusValue ) );
            element.add( otherQueryParameters );
        }

        element.addAttribute( "queryName", queryName );
        return element;
    }


    public static String buildNonVaMedFilterWithResolvedIdentfiers( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String statusValue, String clientRequestInitiationTime )
    {
        Element filter = buildNonVaMedFilterElementWithResolvedIdentfiers( filterId, entryPointFilterMaps, resolvedPatients, statusValue,
                        clientRequestInitiationTime );
        return filter.asXML();
    }


    public static Element buildNonVaMedFilterElementWithResolvedIdentfiers( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String statusValue, String clientRequestInitiationTime )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createClientName( "clientName", "testClientName" ) );
        element.add( FilterBuilder.createClientName( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );

            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
            if ( statusValue != null )
            {
                element.add( FilterBuilder.createNonVaMedEntryFilterWithAdditionalParameters( "entryPointFilter", domainEntryPoint, statusValue,
                                queryName ) );
            }
            else
            {
                element.add( FilterBuilder.createEntryFilter( "entryPointFilter", domainEntryPoint, null, null, queryName, null, null ) );
            }

        }

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


    public static String buildAppointmentFilterWithResolvedIdentfiers( String filterId, String clientName, String clientRequestInitiationTime,
                    List<Map<String, String>> entryPointFilterMaps, List<Map<String, String>> resolvedPatients, String statusValue )
    {
        Element filter = buildAppointmentFilterElementWithResolvedIdentfiers( filterId, clientName, clientRequestInitiationTime,
                        entryPointFilterMaps, resolvedPatients, statusValue );
        return filter.asXML();
    }


    public static Element buildAppointmentFilterElementWithResolvedIdentfiers( String filterId, String clientName,
                    String clientRequestInitiationTime, List<Map<String, String>> entryPointFilterMaps, List<Map<String, String>> resolvedPatients,
                    String statusValue )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createClientName( "clientName", clientName ) );
        element.add( FilterBuilder.createClientName( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );
            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";
            String startDate = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.START_DATE_KEY ) ) : null;
            String endDate = ( entryFilterMap != null ) ? ( ( String )entryFilterMap.get( FilterBuilder.END_DATE_KEY ) ) : null;
            if ( statusValue != null )
            {
                element.add( FilterBuilder.createAppointmentEntryFilterWithAdditionalParameters( "entryPointFilter", domainEntryPoint, startDate,
                                endDate, statusValue, queryName ) );
            }
            else
            {
                element.add( FilterBuilder.createEntryFilter( "entryPointFilter", domainEntryPoint, startDate, endDate, queryName, null, null ) );
            }

        }

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


    public static String buildProblemListFilterElementWithResolvedIdentfiers( String filterId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, String startDate, String endDate, Map<String, String> optionalParamsMap,
                    String clientRequestInitiationTime )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createClientName( "clientName", "testClientName" ) );
        element.add( FilterBuilder.createClientName( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );

            String queryName = ( entryFilterMap != null ) ? ( entryFilterMap.get( FilterBuilder.QUERY_NAME_KEY ) != null ? ( String )entryFilterMap
                            .get( FilterBuilder.QUERY_NAME_KEY ) : "id_1" ) : "id_1";

            if ( ( optionalParamsMap != null && optionalParamsMap.size() > 0 ) || startDate != null || endDate != null )
            {
                element.add( FilterBuilder.createProblemListFilterWithAdditionalParameters( "entryPointFilter", domainEntryPoint, optionalParamsMap,
                                startDate, endDate, queryName ) );
            }
            else
            {
                element.add( FilterBuilder.createEntryFilter( "entryPointFilter", domainEntryPoint, null, null, queryName, null, null ) );
            }

        }

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


    /*
    <xs:complexType name="EntryFilter">
        <xs:sequence>
            <xs:element name="domainEntryPoint" type="filter:DomainEntryPoint"/>
            <xs:element name="startDate" type="filter:DateParameter" minOccurs="0"/>
            <xs:element name="endDate" type="filter:DateParameter" minOccurs="0"/>
            <xs:element name="otherQueryParameters" type="filter:OptionalParameters" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="queryName" type="xs:ID" use="required"/>
    </xs:complexType>
    */
    public static Element createProblemListFilterWithAdditionalParameters( String elementName, String domainEntryPoint,
                    Map<String, String> optionalParamsMap, String startDate, String endDate, String queryName )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( createDomainEntryPoint( "domainEntryPoint", domainEntryPoint ) );

        if ( startDate != null )
        {
            element.add( createDateParameter( "startDate", startDate ) );
        }

        if ( endDate != null )
        {
            element.add( createDateParameter( "endDate", endDate ) );
        }

        if ( optionalParamsMap != null )
        {
            element.add( createProlemListAdditionalParameters( "otherQueryParameters", optionalParamsMap ) );
        }

        element.addAttribute( "queryName", queryName );
        return element;
    }


    public static String build3xOutpatientMedicationPromiseFilterWithResolvedIdentfiers( String filterId,
                    List<Map<String, String>> entryPointFilterMaps, List<Map<String, String>> resolvedPatients, String clientRequestInitiationTime )
    {
        Element filter = build3xOutpatientMedicationPromiseFilterElementWithResolvedIdentfiers( filterId, entryPointFilterMaps, resolvedPatients,
                        clientRequestInitiationTime );
        return filter.asXML();
    }


    public static Element build3xOutpatientMedicationPromiseFilterElementWithResolvedIdentfiers( String filterId,
                    List<Map<String, String>> entryPointFilterMaps, List<Map<String, String>> resolvedPatients, String clientRequestInitiationTime )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();

        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        element.add( FilterBuilder.createClientName( "clientName", "testClientName" ) );
        element.add( FilterBuilder.createClientName( "clientRequestInitiationTime", clientRequestInitiationTime ) );
        element.add( FilterBuilder.createPatientWithResolvedIdentifiers( "patients", resolvedPatients ) );

        for ( Map<String, String> entryFilterMap : entryPointFilterMaps )
        {
            String domainEntryPoint = entryFilterMap.get( FilterBuilder.DOMAIN_ENTRYPOINT_KEY );

            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", domainEntryPoint, null, null, queryName, null, null ) );
        }

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