From 4120abbb22f70eca120bb12d9bdc0556f1e39976 Mon Sep 17 00:00:00 2001
From: Robert Scalfani <rscalfani@mitre.org>
Date: Thu, 4 Aug 2022 15:24:11 -0400
Subject: [PATCH] Add Support For Multiple Prefetch and Updated Prefetch
 Templates (#276)

* Updated prefetch templates to match the key->bundle format.

* Updated hydrator to use new multiple prefetch format

* Add support for coverage bundles

* Updated bundle processor to properly extract patients and coverages.

* Updated tests to support new coverage bundle

* Fixed broken tests

* Fixed a potential issue with medication request/dispense

* Removed extraneous logging

* removed extranous logging
---
 .../hl7/davinci/PrefetchTemplateElement.java  |   8 +-
 .../org/hl7/davinci/r4/CrdRequestCreator.java |  83 +++++--
 .../hl7/davinci/r4/crdhook/CrdPrefetch.java   |  60 +++--
 .../CrdPrefetchTemplateElements.java          |  26 +-
 .../CrdPrefetchTemplateElements.java          |  96 ++++----
 .../cdshooks/services/crd/CdsService.java     |   5 -
 .../services/crd/r4/FhirBundleProcessor.java  | 183 +++++++++-----
 .../services/crd/r4/FhirRequestProcessor.java |   1 +
 .../services/crd/r4/OrderSelectService.java   |   3 +-
 .../services/crd/r4/OrderSignService.java     |  25 +-
 .../endpoint/components/PrefetchHydrator.java |  19 +-
 .../r4/QuestionnairePackageOperation.java     |   9 +-
 .../crd/r4/EndToEndRequestPrefetchTest.java   |  30 ++-
 ...iceRequestFullPrefetchWithCoverage_r4.json | 225 ++++++++++++++++++
 14 files changed, 583 insertions(+), 190 deletions(-)
 create mode 100644 server/src/test/resources/deviceRequestFullPrefetchWithCoverage_r4.json

diff --git a/resources/src/main/java/org/hl7/davinci/PrefetchTemplateElement.java b/resources/src/main/java/org/hl7/davinci/PrefetchTemplateElement.java
index d7cfbc6ad..e738817a9 100644
--- a/resources/src/main/java/org/hl7/davinci/PrefetchTemplateElement.java
+++ b/resources/src/main/java/org/hl7/davinci/PrefetchTemplateElement.java
@@ -1,10 +1,12 @@
 package org.hl7.davinci;
 
+import org.hl7.fhir.instance.model.api.IBaseResource;
+
 public class PrefetchTemplateElement {
 
   private String key;
   private String query;
-  private Class returnType;
+  private Class<? extends IBaseResource> returnType;
 
   /**
    * Describes a prefetch element. Note that the key and query are exposed in the service
@@ -13,7 +15,7 @@ public class PrefetchTemplateElement {
    * @param query The query to execute against the fhir server.
    * @param returnType The type to cast the result of a successful query to (e.g. a Bundle)
    */
-  public PrefetchTemplateElement(String key, String query, Class returnType) {
+  public PrefetchTemplateElement(String key, Class<? extends IBaseResource> returnType, String query) {
     this.key = key;
     this.query = query;
     this.returnType = returnType;
@@ -27,7 +29,7 @@ public String getQuery() {
     return query;
   }
 
-  public Class getReturnType() {
+  public Class<? extends IBaseResource> getReturnType() {
     return returnType;
   }
 
diff --git a/resources/src/main/java/org/hl7/davinci/r4/CrdRequestCreator.java b/resources/src/main/java/org/hl7/davinci/r4/CrdRequestCreator.java
index 6f7efef0c..b76567cda 100644
--- a/resources/src/main/java/org/hl7/davinci/r4/CrdRequestCreator.java
+++ b/resources/src/main/java/org/hl7/davinci/r4/CrdRequestCreator.java
@@ -1,8 +1,10 @@
 package org.hl7.davinci.r4;
 
 import java.util.Date;
+import java.util.HashMap;
 import java.util.UUID;
 import java.util.List;
+import java.util.Map;
 import java.util.ArrayList;
 
 import org.cdshooks.Hook;
@@ -11,9 +13,26 @@
 import org.hl7.davinci.r4.crdhook.orderselect.OrderSelectRequest;
 import org.hl7.davinci.r4.crdhook.ordersign.OrderSignContext;
 import org.hl7.davinci.r4.crdhook.ordersign.OrderSignRequest;
-import org.hl7.fhir.r4.model.*;
 import org.hl7.fhir.r4.model.Address.AddressType;
 import org.hl7.fhir.r4.model.Address.AddressUse;
+import org.hl7.fhir.r4.model.Address;
+import org.hl7.fhir.r4.model.Bundle;
+import org.hl7.fhir.r4.model.CodeableConcept;
+import org.hl7.fhir.r4.model.Coding;
+import org.hl7.fhir.r4.model.Coverage;
+import org.hl7.fhir.r4.model.Device;
+import org.hl7.fhir.r4.model.Enumerations;
+import org.hl7.fhir.r4.model.HumanName;
+import org.hl7.fhir.r4.model.Identifier;
+import org.hl7.fhir.r4.model.Location;
+import org.hl7.fhir.r4.model.MedicationRequest;
+import org.hl7.fhir.r4.model.MedicationStatement;
+import org.hl7.fhir.r4.model.Organization;
+import org.hl7.fhir.r4.model.Patient;
+import org.hl7.fhir.r4.model.Practitioner;
+import org.hl7.fhir.r4.model.PractitionerRole;
+import org.hl7.fhir.r4.model.Reference;
+import org.hl7.fhir.r4.model.ServiceRequest;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -25,7 +44,7 @@ public class CrdRequestCreator {
   static final Logger logger = LoggerFactory.getLogger(CrdRequestCreator.class);
 
   /**
-   * Generate a order select request that contains a DeviceRequest.
+   * Generate a order select request that contains a MedicationRequest.
    *
    * @param patientGender Desired gender of the patient in the request
    * @param patientBirthdate Desired birth date of the patient in the request
@@ -55,10 +74,14 @@ public static OrderSelectRequest createOrderSelectRequest(
       mr.setPerformer(new Reference(p));
       mr.addInsurance(new Reference(c));
     };
-    mr.setSubject(new Reference(patient));
+    Reference patientReference = new Reference(patient);
+    patientReference.setReference(patient.getId());
+    mr.setSubject(patientReference);
+    mr.getSubject().setId(patient.getId());
     Practitioner provider = createPractitioner();
-    Bundle prefetchBundle = createPrefetchBundle(patient, provider, callback, providerAddressState);
-
+    Map<String, Bundle> prefetchBundles = createPrefetchBundles(patient, provider, callback, providerAddressState);
+    Bundle prefetchBundleMedicationRequest = prefetchBundles.get("nonCoverage");
+    Bundle prefetchBundleCoverage = prefetchBundles.get("coverage");
 
     mr.setMedication(new CodeableConcept().addCoding(requestCoding));
     Bundle orderBundle = new Bundle();
@@ -67,7 +90,7 @@ public static OrderSelectRequest createOrderSelectRequest(
     orderBundle.addEntry(bec);
     Bundle.BundleEntryComponent pfDrBec = new Bundle.BundleEntryComponent();
     pfDrBec.setResource(mr);
-    prefetchBundle.addEntry(pfDrBec);
+    prefetchBundleMedicationRequest.addEntry(pfDrBec);
     context.setDraftOrders(orderBundle);
     context.setSelections(new String[] {"123"});
 
@@ -80,14 +103,17 @@ public static OrderSelectRequest createOrderSelectRequest(
     MedicationStatement ms = new MedicationStatement();
     ms.setId("MedciationStatement/12345");
     ms.setMedication(new CodeableConcept().addCoding(statementCoding));
+    ms.setSubject(patientReference);
+    ms.getSubject().setId(patient.getId());
     bec.setResource(ms);
     prefetchMedicationStatementBundle.addEntry(bec);
 
 
     // add the prefetch into the request
     CrdPrefetch prefetch = new CrdPrefetch();
-    prefetch.setMedicationRequestBundle(prefetchBundle);
+    prefetch.setMedicationRequestBundle(prefetchBundleMedicationRequest);
     prefetch.setMedicationStatementBundle(prefetchMedicationStatementBundle);
+    prefetch.setCoverageBundle(prefetchBundleCoverage);
     request.setPrefetch(prefetch);
 
     return request;
@@ -115,16 +141,21 @@ public static OrderSignRequest createOrderSignRequest(
 
     ServiceRequest sr = new ServiceRequest();
     sr.setStatus(ServiceRequest.ServiceRequestStatus.DRAFT);
-    sr.setId("DeviceRequest/123");
+    sr.setId("ServiceRequest/123");
     sr.setIntent(ServiceRequest.ServiceRequestIntent.ORDER);
 
     PrefetchCallback callback = (p, c) -> {
       sr.addPerformer(new Reference(p));
       sr.addInsurance(new Reference(c));
     };
-    sr.setSubject(new Reference(patient));
+    Reference patientReference = new Reference(patient);
+    patientReference.setReference(patient.getId());
+    sr.setSubject(patientReference);
+    // sr.getSubject().setId(patient.getId());
     Practitioner provider = createPractitioner();
-    Bundle prefetchBundle = createPrefetchBundle(patient, provider, callback, providerAddressState);
+    Map<String, Bundle> prefetchBundles = createPrefetchBundles(patient, provider, callback, providerAddressState);
+    Bundle prefetchBundleServiceRequest = prefetchBundles.get("nonCoverage");
+    Bundle prefetchBundleCoverage = prefetchBundles.get("coverage");
 
     Coding oxygen = new Coding().setCode("A0426")
         .setSystem("https://bluebutton.cms.gov/resources/codesystem/hcpcs")
@@ -136,33 +167,34 @@ public static OrderSignRequest createOrderSignRequest(
     orderBundle.addEntry(bec);
     Bundle.BundleEntryComponent pfDrBec = new Bundle.BundleEntryComponent();
     pfDrBec.setResource(sr);
-    prefetchBundle.addEntry(pfDrBec);
+    prefetchBundleServiceRequest.addEntry(pfDrBec);
     context.setDraftOrders(orderBundle);
 
     Device device = new Device();
     device.setType(new CodeableConcept().addCoding(oxygen));
     bec = new Bundle.BundleEntryComponent();
     bec.setResource(device);
-    prefetchBundle.addEntry(bec);
+    prefetchBundleServiceRequest.addEntry(bec);
 
     CrdPrefetch prefetch = new CrdPrefetch();
-    prefetch.setServiceRequestBundle(prefetchBundle);
+    prefetch.setServiceRequestBundle(prefetchBundleServiceRequest);
+    prefetch.setCoverageBundle(prefetchBundleCoverage);
     request.setPrefetch(prefetch);
 
     return request;
   }
 
-  private static Bundle createPrefetchBundle(Patient patient, Practitioner provider,
+  private static Map<String, Bundle> createPrefetchBundles(Patient patient, Practitioner provider,
       PrefetchCallback cb, String providerAddressState) {
-    Bundle prefetchBundle = new Bundle();
+    Bundle prefetchBundleServiceRequest = new Bundle();
 
     Bundle.BundleEntryComponent bec = new Bundle.BundleEntryComponent();
     bec.setResource(patient);
-    prefetchBundle.addEntry(bec);
+    prefetchBundleServiceRequest.addEntry(bec);
 
     bec = new Bundle.BundleEntryComponent();
     bec.setResource(provider);
-    prefetchBundle.addEntry(bec);
+    prefetchBundleServiceRequest.addEntry(bec);
 
     // create an Organization object with ID and Name set
     Organization insurer = new Organization();
@@ -170,7 +202,7 @@ private static Bundle createPrefetchBundle(Patient patient, Practitioner provide
     insurer.setName("Centers for Medicare and Medicaid Services");
     bec = new Bundle.BundleEntryComponent();
     bec.setResource(insurer);
-    prefetchBundle.addEntry(bec);
+    prefetchBundleServiceRequest.addEntry(bec);
 
     // create a Location Object
     Location facility = new Location();
@@ -181,7 +213,7 @@ private static Bundle createPrefetchBundle(Patient patient, Practitioner provide
         .setPostalCode("01730"));
     bec = new Bundle.BundleEntryComponent();
     bec.setResource(facility);
-    prefetchBundle.addEntry(bec);
+    prefetchBundleServiceRequest.addEntry(bec);
 
     PractitionerRole pr = new PractitionerRole();
     pr.setId(idString());
@@ -190,9 +222,10 @@ private static Bundle createPrefetchBundle(Patient patient, Practitioner provide
 
     bec = new Bundle.BundleEntryComponent();
     bec.setResource(pr);
-    prefetchBundle.addEntry(bec);
+    prefetchBundleServiceRequest.addEntry(bec);
 
-    // create a Coverage object with ID set
+    // create a Coverage prefetch with ID set
+    Bundle prefetchBundleCoverage = new Bundle();
     Coverage coverage = new Coverage();
     coverage.setId(idString());
     Coding planCode = new Coding().setCode("plan").setSystem("http://hl7.org/fhir/coverage-class");
@@ -206,10 +239,14 @@ private static Bundle createPrefetchBundle(Patient patient, Practitioner provide
     coverage.addPayor(new Reference(insurer));
     bec = new Bundle.BundleEntryComponent();
     bec.setResource(coverage);
-    prefetchBundle.addEntry(bec);
+    prefetchBundleCoverage.addEntry(bec);
     cb.callback(pr, coverage);
 
-    return prefetchBundle;
+    Map<String, Bundle> prefetchMap = new HashMap<>();
+    prefetchMap.put("nonCoverage", prefetchBundleServiceRequest);
+    prefetchMap.put("coverage", prefetchBundleCoverage);
+
+    return prefetchMap;
   }
 
   private static Patient createPatient(Enumerations.AdministrativeGender patientGender,
diff --git a/resources/src/main/java/org/hl7/davinci/r4/crdhook/CrdPrefetch.java b/resources/src/main/java/org/hl7/davinci/r4/crdhook/CrdPrefetch.java
index 528c1406c..b93740e36 100644
--- a/resources/src/main/java/org/hl7/davinci/r4/crdhook/CrdPrefetch.java
+++ b/resources/src/main/java/org/hl7/davinci/r4/crdhook/CrdPrefetch.java
@@ -16,6 +16,10 @@
  */
 public class CrdPrefetch {
 
+  @JsonSerialize(using = JacksonHapiSerializer.class)
+  @JsonDeserialize(using = JacksonBundleDeserializer.class)
+  private Bundle coverageBundle;
+
   @JsonSerialize(using = JacksonHapiSerializer.class)
   @JsonDeserialize(using = JacksonBundleDeserializer.class)
   private Bundle deviceRequestBundle;
@@ -52,6 +56,17 @@ public class CrdPrefetch {
   @JsonDeserialize(using = JacksonBundleDeserializer.class)
   private Bundle medicationStatementBundle;
 
+  public Bundle getCoverageBundle() {
+    if (coverageBundle == null) {
+      this.coverageBundle = new Bundle();
+    }
+    return coverageBundle;
+  }
+
+  public void setCoverageBundle(Bundle coverageBundle) {
+    this.coverageBundle = coverageBundle;
+  }
+
   public Bundle getDeviceRequestBundle() {
     return deviceRequestBundle;
   }
@@ -114,7 +129,8 @@ public void setSupplyRequestBundle(Bundle supplyRequestBundle) {
    * @return
    */
   public boolean containsRequestResourceId(String id) {
-    return this.bundleContainsResourceId(this.deviceRequestBundle, id)
+    return this.bundleContainsResourceId(this.coverageBundle, id)
+        || this.bundleContainsResourceId(this.deviceRequestBundle, id)
         || this.bundleContainsResourceId(this.medicationRequestBundle, id)
         || this.bundleContainsResourceId(this.nutritionOrderBundle, id)
         || this.bundleContainsResourceId(this.serviceRequestBundle, id)
@@ -145,31 +161,33 @@ private boolean bundleContainsResourceId(Bundle bundle, String id) {
 
   @Override
   public String toString() {
-    StringBuilder sb = new StringBuilder();
     List<BundleEntryComponent> entries = new ArrayList<>();
-    if(this.deviceRequestBundle != null){
-      entries = this.deviceRequestBundle.getEntry();
-    } else if(this.nutritionOrderBundle != null){
-      entries = this.nutritionOrderBundle.getEntry();
-    } else if(this.serviceRequestBundle != null){
-      entries = this.serviceRequestBundle.getEntry();
-    } else if(this.medicationDispenseBundle != null){
-      entries = this.medicationDispenseBundle.getEntry();
-    } else if(this.medicationStatementBundle != null){
-      entries = this.medicationStatementBundle.getEntry();
-    } else if(this.encounterBundle != null){
-      entries = this.encounterBundle.getEntry();
-    } else if(this.appointmentBundle != null){
-      entries = this.appointmentBundle.getEntry();
-    } else if(this.medicationRequestBundle != null){
-      entries = this.medicationRequestBundle.getEntry();
-    } else if(this.supplyRequestBundle != null){
-      entries = this.supplyRequestBundle.getEntry();
+    if(this.deviceRequestBundle != null) {
+    entries.addAll(this.deviceRequestBundle.getEntry());
+    } if(this.nutritionOrderBundle != null){
+      entries.addAll(this.nutritionOrderBundle.getEntry());
+    } if(this.serviceRequestBundle != null){
+      entries.addAll(this.serviceRequestBundle.getEntry());
+    } if(this.medicationDispenseBundle != null){
+      entries.addAll(this.medicationDispenseBundle.getEntry());
+    } if(this.medicationStatementBundle != null){
+      entries.addAll(this.medicationStatementBundle.getEntry());
+    } if(this.encounterBundle != null){
+      entries.addAll(this.encounterBundle.getEntry());
+    } if(this.appointmentBundle != null){
+      entries.addAll(this.appointmentBundle.getEntry());
+    } if(this.medicationRequestBundle != null){
+      entries.addAll(this.medicationRequestBundle.getEntry());
+    } if(this.supplyRequestBundle != null){
+      entries.addAll(this.supplyRequestBundle.getEntry());
+    } if(this.coverageBundle != null) {
+      entries.addAll(this.coverageBundle.getEntry());
     }
+    StringBuilder sb = new StringBuilder();
     sb.append("[");
     for(BundleEntryComponent entry : entries) {
       sb.append(entry.getResource());
-      sb.append("-");
+      sb.append("~");
       sb.append(entry.getResource().getId());
       sb.append(",");
     }
diff --git a/resources/src/main/java/org/hl7/davinci/r4/crdhook/orderselect/CrdPrefetchTemplateElements.java b/resources/src/main/java/org/hl7/davinci/r4/crdhook/orderselect/CrdPrefetchTemplateElements.java
index 4f01b4b76..f961dbfb9 100644
--- a/resources/src/main/java/org/hl7/davinci/r4/crdhook/orderselect/CrdPrefetchTemplateElements.java
+++ b/resources/src/main/java/org/hl7/davinci/r4/crdhook/orderselect/CrdPrefetchTemplateElements.java
@@ -8,24 +8,30 @@
  */
 public class CrdPrefetchTemplateElements {
 
+  public static final PrefetchTemplateElement COVERAGE_PREFETCH_QUERY = new PrefetchTemplateElement(
+      "coverageBundle",
+      Bundle.class,
+      "Coverage?patient={{context.patient}}");
+
   public static final PrefetchTemplateElement MEDICATION_STATEMENT_BUNDLE = new PrefetchTemplateElement(
       "medicationStatementBundle",
-      "MedicationStatement?subject={{context.patientId}}"
-          + "&_include=MedicationStatement:patient",
-      Bundle.class);
+      Bundle.class,
+      "MedicationRequest?_id={{context.medications.MedicationRequest.id}}"
+          + "&_include=MedicationRequest:patient"
+          + "&_include=MedicationRequest:intended-dispenser"
+          + "&_include=MedicationRequest:requester:PractitionerRole"
+          + "&_include=MedicationRequest:medication"
+          + "&_include:iterate=PractitionerRole:organization"
+          + "&_include:iterate=PractitionerRole:practitioner");
 
   public static final PrefetchTemplateElement MEDICATION_REQUEST_BUNDLE = new PrefetchTemplateElement(
       "medicationRequestBundle",
+      Bundle.class,
       "MedicationRequest?_id={{context.draftOrders.MedicationRequest.id}}"
           + "&_include=MedicationRequest:patient"
           + "&_include=MedicationRequest:intended-dispenser"
-          + "&_include=MedicationRequest:intended-performer"
-          + "&_include=MedicationRequest:performer"
-          + "&_include:recurse=PractitionerRole:location"
           + "&_include=MedicationRequest:requester:PractitionerRole"
           + "&_include=MedicationRequest:medication"
-          + "&_include=PractitionerRole:organization"
-          + "&_include=PractitionerRole:practitioner"
-          + "&_include=MedicationRequest:insurance:Coverage",
-      Bundle.class);
+          + "&_include:iterate=PractitionerRole:organization"
+          + "&_include:iterate=PractitionerRole:practitioner");
 }
\ No newline at end of file
diff --git a/resources/src/main/java/org/hl7/davinci/r4/crdhook/ordersign/CrdPrefetchTemplateElements.java b/resources/src/main/java/org/hl7/davinci/r4/crdhook/ordersign/CrdPrefetchTemplateElements.java
index 0eeaba1f7..8e2ec544f 100644
--- a/resources/src/main/java/org/hl7/davinci/r4/crdhook/ordersign/CrdPrefetchTemplateElements.java
+++ b/resources/src/main/java/org/hl7/davinci/r4/crdhook/ordersign/CrdPrefetchTemplateElements.java
@@ -5,40 +5,40 @@
 
 /**
  * Class that contains the different prefetch template elements used in crd requests.
+ * The templates are based on https://build.fhir.org/ig/HL7/davinci-crd/hooks.html#prefetch
  */
 public class CrdPrefetchTemplateElements {
 
+  public static final PrefetchTemplateElement COVERAGE_REQUEST_BUNDLE = new PrefetchTemplateElement(
+      "coverageBundle",
+      Bundle.class,
+      "Coverage?patient={{context.patientId}}");
+
   public static final PrefetchTemplateElement DEVICE_REQUEST_BUNDLE = new PrefetchTemplateElement(
       "deviceRequestBundle",
+      Bundle.class,
       "DeviceRequest?_id={{context.draftOrders.DeviceRequest.id}}"
           + "&_include=DeviceRequest:patient"
           + "&_include=DeviceRequest:performer"
           + "&_include=DeviceRequest:requester"
           + "&_include=DeviceRequest:device"
-          + "&_include=PractitionerRole:organization"
-          + "&_include=PractitionerRole:practitioner"
-          + "&_include:recurse=PractitionerRole:location"
-          + "&_include:iterate=PractitionerRole:location"
-          + "&_include=DeviceRequest:insurance:Coverage",
-      Bundle.class);
+          + "&_include:iterate=PractitionerRole:organization"
+          + "&_include:iterate=PractitionerRole:practitioner");
 
   public static final PrefetchTemplateElement MEDICATION_REQUEST_BUNDLE = new PrefetchTemplateElement(
       "medicationRequestBundle",
-      "MedicationRequest?_id={{context.draftOrders.MedicationRequest.id}}"
+      Bundle.class,
+      "MedicationRequest?_id={{context.medications.MedicationRequest.id}}"
           + "&_include=MedicationRequest:patient"
           + "&_include=MedicationRequest:intended-dispenser"
-          + "&_include=MedicationRequest:intended-performer"
-          + "&_include=MedicationRequest:performer"
-          + "&_include:recurse=PractitionerRole:location"
           + "&_include=MedicationRequest:requester:PractitionerRole"
           + "&_include=MedicationRequest:medication"
-          + "&_include=PractitionerRole:organization"
-          + "&_include=PractitionerRole:practitioner"
-          + "&_include=MedicationRequest:insurance:Coverage",
-      Bundle.class);
+          + "&_include:iterate=PractitionerRole:organization"
+          + "&_include:iterate=PractitionerRole:practitioner");
 
   public static final PrefetchTemplateElement NUTRITION_ORDER_BUNDLE = new PrefetchTemplateElement(
       "nutritionOrderBundle",
+      Bundle.class,
       "NutritionOrder?_id={{context.draftOrders.NutritionOrder.id}}"
           + "&_include=NutritionOrder:patient"
           + "&_include=NutritionOrder:provider"
@@ -46,62 +46,58 @@ public class CrdPrefetchTemplateElements {
           + "&_include=PractitionerRole:organization"
           + "&_include=PractitionerRole:practitioner"
           + "&_include=NutritionOrder:encounter"
-          + "&_include=Encounter:location"
-          + "&_include=NutritionOrder:insurance:Coverage",
-      Bundle.class);
+          + "&_include=Encounter:location");
 
   public static final PrefetchTemplateElement SERVICE_REQUEST_BUNDLE = new PrefetchTemplateElement(
       "serviceRequestBundle",
+      Bundle.class,
       "ServiceRequest?_id={{context.draftOrders.ServiceRequest.id}}"
           + "&_include=ServiceRequest:patient"
           + "&_include=ServiceRequest:performer"
           + "&_include=ServiceRequest:requester"
-          + "&_include=PractitionerRole:organization"
-          + "&_include=PractitionerRole:practitioner"
-          + "&_include=ServiceRequest:insurance:Coverage",
-      Bundle.class);
+          + "&_include:iterate=PractitionerRole:organization"
+          + "&_include:iterate=PractitionerRole:practitioner");
 
-  public static final PrefetchTemplateElement SUPPLY_REQUEST_BUNDLE = new PrefetchTemplateElement(
-      "supplyRequestBundle",
-      "SupplyRequest?_id={{context.draftOrders.SupplyRequest.id}}&"
-          + "_include=SupplyRequest:patient"
-          + "&_include=SupplyRequest:supplier:Organization"
-          + "&_include=SupplyRequest:requester:Practitioner"
-          + "&_include=SupplyRequest:requester:Organization"
-          + "&_include=SupplyRequest:Requester:PractitionerRole"
-          + "&_include=PractitionerRole:organization"
-          + "&_include=PractitionerRole:practitioner"
-          + "&_include=SupplyRequest:insurance:Coverage",
-      Bundle.class);
+  // public static final PrefetchTemplateElement SUPPLY_REQUEST_BUNDLE = new PrefetchTemplateElement(
+  //     "supplyRequestBundle",
+  //     "SupplyRequest?_id={{context.draftOrders.SupplyRequest.id}}&"
+  //         + "_include=SupplyRequest:patient"
+  //         + "&_include=SupplyRequest:supplier:Organization"
+  //         + "&_include=SupplyRequest:requester:Practitioner"
+  //         + "&_include=SupplyRequest:requester:Organization"
+  //         + "&_include=SupplyRequest:Requester:PractitionerRole"
+  //         + "&_include=PractitionerRole:organization"
+  //         + "&_include=PractitionerRole:practitioner"
+  //         + "&_include=SupplyRequest:insurance:Coverage",
+  //     Bundle.class);
 
   public static final PrefetchTemplateElement APPOINTMENT_BUNDLE = new PrefetchTemplateElement(
       "appointmentBundle",
+      Bundle.class,
       "Appointment?_id={{context.appointments.Appointment.id}}"
           + "&_include=Appointment:patient"
           + "&_include=Appointment:practitioner:PractitionerRole"
           + "&_include:iterate=PractitionerRole:organization"
           + "&_include:iterate=PractitionerRole:practitioner"
-          + "&_include=Appointment:location"
-          + "&_include=Appointment:insurance:Coverage",
-      Bundle.class);
+          + "&_include=Appointment:location");
 
   public static final PrefetchTemplateElement ENCOUNTER_BUNDLE = new PrefetchTemplateElement(
       "encounterBundle",
+      Bundle.class,
       "Encounter?_id={{context.encounterId}}"
-          + "&_include=Encounter:patient&_include=Encounter:service-provider"
+          + "&_include=Encounter:patient"
+          + "&_include=Encounter:service-provider"
           + "&_include=Encounter:practitioner"
-          + "&_include=Encounter:location"
-          + "&_include=Encounter:insurance:Coverage",
-      Bundle.class);
+          + "&_include=Encounter:location");
 
-    public static final PrefetchTemplateElement MEDICATION_DISPENSE_BUNDLE = new PrefetchTemplateElement(
-        "medicationDispenseBundle",
-        "MedicationDispense?_id={{context.draftOrders.MedicationDispense.id}}"
-            + "&_include=MedicationDispense:patient"
-            + "&_include:recurse=PractitionerRole:location"
-            + "&_include=MedicationDispense:performer:PractitionerRole"
-            + "&_include=MedicationDispense:medication"
-            + "&_include=PractitionerRole:organization"
-            + "&_include=PractitionerRole:practitioner",
-        Bundle.class);
+  //   public static final PrefetchTemplateElement MEDICATION_DISPENSE_BUNDLE = new PrefetchTemplateElement(
+  //       "medicationDispenseBundle",
+  //       "MedicationDispense?_id={{context.draftOrders.MedicationDispense.id}}"
+  //           + "&_include=MedicationDispense:patient"
+  //           + "&_include:recurse=PractitionerRole:location"
+  //           + "&_include=MedicationDispense:performer:PractitionerRole"
+  //           + "&_include=MedicationDispense:medication"
+  //           + "&_include=PractitionerRole:organization"
+  //           + "&_include=PractitionerRole:practitioner",
+  //       Bundle.class);
 }
\ No newline at end of file
diff --git a/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/CdsService.java b/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/CdsService.java
index 59225068a..105d888f7 100755
--- a/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/CdsService.java
+++ b/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/CdsService.java
@@ -32,7 +32,6 @@
 import org.hl7.davinci.r4.CardTypes;
 import org.hl7.davinci.r4.CoverageGuidance;
 import org.hl7.davinci.r4.crdhook.orderselect.OrderSelectRequest;
-import org.hl7.davinci.r4.crdhook.CrdPrefetch;
 import org.hl7.davinci.r4.crdhook.DiscoveryExtension;
 import org.opencds.cqf.cql.engine.execution.Context;
 import org.slf4j.Logger;
@@ -166,10 +165,6 @@ public CdsResponse handleRequest(@Valid @RequestBody requestTypeT request, URL a
 
     CdsResponse response = new CdsResponse();
 
-    Gson gson = new Gson();
-    final String jsonObject = gson.toJson(request.getPrefetch());
-    logger.info("Final populated CRDPrefetch: " + jsonObject);
-
     // CQL Fetched
     List<CoverageRequirementRuleResult> lookupResults;
     try {
diff --git a/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/FhirBundleProcessor.java b/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/FhirBundleProcessor.java
index badaf288a..1c53356ca 100644
--- a/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/FhirBundleProcessor.java
+++ b/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/FhirBundleProcessor.java
@@ -21,6 +21,7 @@ public class FhirBundleProcessor {
   static final Logger logger = LoggerFactory.getLogger(FhirBundleProcessor.class);
 
   private FileStore fileStore;
+
   private String baseUrl;
   private List<String> selections;
   private List<CoverageRequirementRuleResult> results = new ArrayList<>();
@@ -38,89 +39,149 @@ public FhirBundleProcessor(FileStore fileStore, String baseUrl) {
 
   public List<CoverageRequirementRuleResult> getResults() { return results; }
 
-  public void processDeviceRequests(Bundle deviceRequestBundle) {
+  public void processDeviceRequests(Bundle deviceRequestBundle, Bundle coverageBundle) {
     List<DeviceRequest> deviceRequestList = Utilities.getResourcesOfTypeFromBundle(DeviceRequest.class, deviceRequestBundle);
-    if (!deviceRequestList.isEmpty()) {
-      logger.info("r4/FhirBundleProcessor::processDeviceRequests: DeviceRequest(s) found");
-
-      for (DeviceRequest deviceRequest : deviceRequestList) {
-        if (idInSelectionsList(deviceRequest.getId())) {
-          List<CoverageRequirementRuleCriteria> criteriaList = createCriteriaList(deviceRequest.getCodeCodeableConcept(), deviceRequest.getInsurance(), null);
-          buildExecutionContexts(criteriaList, (Patient) deviceRequest.getSubject().getResource(), "device_request", deviceRequest);
+    List<Patient> patients = Utilities.getResourcesOfTypeFromBundle(Patient.class, deviceRequestBundle);
+    logger.info("r4/FhirBundleProcessor::processDeviceRequests: Found " + patients.size() + " patients.");
+    List<Organization> payorList = Utilities.getResourcesOfTypeFromBundle(Organization.class, coverageBundle); // TODO - do something with the coverage.
+    if (deviceRequestList.isEmpty()) return;
+    
+    logger.info("r4/FhirBundleProcessor::processDeviceRequests: " + deviceRequestList.size() + " DeviceRequest(s) found");
+
+    for (DeviceRequest deviceRequest : deviceRequestList) {
+      if (idInSelectionsList(deviceRequest.getId())) {
+        List<CoverageRequirementRuleCriteria> criteriaList = createCriteriaList(deviceRequest.getCodeCodeableConcept(), deviceRequest.getInsurance(), payorList);
+        
+        String patientReference = deviceRequest.getSubject().getReference();
+        List<Patient> referencedPrefetechedPatients = extractReferencedResources(patients, patientReference);
+            
+        if (referencedPrefetechedPatients.size() < 1) {
+          logger.error("r4/FhirBundleProcessor::processDeviceRequests: ERROR - Device Request '"
+              + deviceRequest.getId() + "' does not contain a reference to any prefetched patients. Resource contains patient reference '"
+              + patientReference + "' and prefetch contains patients " + patients.stream().map(patient -> patient.getId()).collect(Collectors.toSet()) + ".");
         }
+
+        Patient patientToUse = referencedPrefetechedPatients.get(0);
+        buildExecutionContexts(criteriaList, patientToUse, "device_request", deviceRequest);
       }
     }
   }
 
-  public void processMedicationRequests(Bundle medicationRequestBundle) {
+  public void processMedicationRequests(Bundle medicationRequestBundle, Bundle coverageBundle) {
     List<MedicationRequest> medicationRequestList = Utilities.getResourcesOfTypeFromBundle(MedicationRequest.class, medicationRequestBundle);
-    if (!medicationRequestList.isEmpty()) {
-      logger.info("r4/FhirBundleProcessor::processMedicationRequests: MedicationRequest(s) found");
+    List<Patient> patients = Utilities.getResourcesOfTypeFromBundle(Patient.class, medicationRequestBundle);
+    List<Organization> payorList = Utilities.getResourcesOfTypeFromBundle(Organization.class, coverageBundle);
+    if (medicationRequestList.isEmpty()) return;
+
+    logger.info("r4/FhirBundleProcessor::processMedicationRequests: MedicationRequest(s) found");
 
-      for (MedicationRequest medicationRequest : medicationRequestList) {
-        if (idInSelectionsList(medicationRequest.getId())) {
-          List<CoverageRequirementRuleCriteria> criteriaList = createCriteriaList(medicationRequest.getMedicationCodeableConcept(), medicationRequest.getInsurance(), null);
-          buildExecutionContexts(criteriaList, (Patient) medicationRequest.getSubject().getResource(), "medication_request", medicationRequest);
+    for (MedicationRequest medicationRequest : medicationRequestList) {
+      if (idInSelectionsList(medicationRequest.getId())) {
+        String patientReference = medicationRequest.getSubject().getReference();
+
+        List<Patient> referencedPrefetechedPatients = extractReferencedResources(patients, patientReference);
+        if (referencedPrefetechedPatients.size() < 1) {
+          logger.error("r4/FhirBundleProcessor::processMedicationRequests: ERROR - Medication Request '"
+              + medicationRequest.getId() + "' does not contain a reference to any prefetched patients. Resource contains patient reference '"
+              + patientReference + "' and prefetch contains patients " + patients.stream().map(patient -> patient.getId()).collect(Collectors.toSet()) + ".");
         }
+        
+        List<CoverageRequirementRuleCriteria> criteriaList = createCriteriaList(medicationRequest.getMedicationCodeableConcept(), medicationRequest.getInsurance(), payorList);
+        Patient patientToUse = referencedPrefetechedPatients.get(0);
+        buildExecutionContexts(criteriaList, patientToUse, "medication_request", medicationRequest);
       }
     }
   }
 
-  public void processMedicationDispenses(Bundle medicationDispenseBundle) {
+  public void processMedicationDispenses(Bundle medicationDispenseBundle, Bundle coverageBundle) {
     List<MedicationDispense> medicationDispenseList = Utilities.getResourcesOfTypeFromBundle(MedicationDispense.class, medicationDispenseBundle);
-    if (!medicationDispenseList.isEmpty()) {
-      logger.info("r4/FhirBundleProcessor::processMedicationDispenses: MedicationDispense(s) found");
-
-      List<Organization> payorList = Utilities.getResourcesOfTypeFromBundle(Organization.class,
-          medicationDispenseBundle);
-
-      for (MedicationDispense medicationDispense : medicationDispenseList) {
-        if (idInSelectionsList(medicationDispense.getId())) {
-          List<CoverageRequirementRuleCriteria> criteriaList = createCriteriaList(medicationDispense.getMedicationCodeableConcept(), null, payorList);
-          buildExecutionContexts(criteriaList, (Patient) medicationDispense.getSubject().getResource(), "medication_dispense", medicationDispense);
+    List<Patient> patients = Utilities.getResourcesOfTypeFromBundle(Patient.class, medicationDispenseBundle);
+    List<Organization> payorList = Utilities.getResourcesOfTypeFromBundle(Organization.class, coverageBundle);
+    List<Organization> medicationPayorList = Utilities.getResourcesOfTypeFromBundle(Organization.class,
+        medicationDispenseBundle);
+    payorList.addAll(medicationPayorList);
+    if (medicationDispenseList.isEmpty()) return;
+
+    logger.info("r4/FhirBundleProcessor::processMedicationDispenses: MedicationDispense(s) found");
+
+    for (MedicationDispense medicationDispense : medicationDispenseList) {
+      if (idInSelectionsList(medicationDispense.getId())) {
+        String patientReference = medicationDispense.getSubject().getReference();
+        List<Patient> referencedPrefetechedPatients = extractReferencedResources(patients, patientReference);
+        if (referencedPrefetechedPatients.size() < 1) {
+          logger.error("r4/FhirBundleProcessor::processMedicationDispenses: ERROR - Medication Dispense '"
+              + medicationDispense.getId() + "' does not contain a reference to any prefetched patients. Resource contains patient reference '"
+              + patientReference + "' and prefetch contains patients " + patients.stream().map(patient -> patient.getId()).collect(Collectors.toSet()) + ".");
+          return;
         }
+        List<CoverageRequirementRuleCriteria> criteriaList = createCriteriaList(medicationDispense.getMedicationCodeableConcept(), null, payorList);
+        Patient patientToUse = referencedPrefetechedPatients.get(0);
+        buildExecutionContexts(criteriaList,patientToUse, "medication_dispense", medicationDispense);
       }
     }
   }
 
-  public void processServiceRequests(Bundle serviceRequestBundle) {
+  public void processServiceRequests(Bundle serviceRequestBundle, Bundle coverageBundle) {
+    List<Organization> payorList = Utilities.getResourcesOfTypeFromBundle(Organization.class, coverageBundle);
     List<ServiceRequest> serviceRequestList = Utilities.getResourcesOfTypeFromBundle(ServiceRequest.class, serviceRequestBundle);
-    if (!serviceRequestList.isEmpty()) {
-      logger.info("r4/FhirBundleProcessor::processServiceRequests: ServiceRequest(s) found");
+    List<Patient> patients = Utilities.getResourcesOfTypeFromBundle(Patient.class, serviceRequestBundle);
+    if (serviceRequestList.isEmpty()) return;
+
+    logger.info("r4/FhirBundleProcessor::getAndProcessServiceRequests: ServiceRequest(s) found");
+
+    for (ServiceRequest serviceRequest : serviceRequestList) {
+      if (idInSelectionsList(serviceRequest.getId())) {
+        String patientReference = serviceRequest.getSubject().getReference();
+        List<Patient> referencedPrefetechedPatients = extractReferencedResources(patients, patientReference);
+        if (referencedPrefetechedPatients.size() < 1) {
+          logger.error("r4/FhirBundleProcessor::processServiceRequests: ERROR - Service Request '"
+              + serviceRequest.getId() + "' does not contain a reference to any prefetched patients. Resource contains patient reference '"
+              + patientReference + "' and prefetch contains patients " + patients.stream().map(patient -> patient.getId()).collect(Collectors.toSet()) + ".");
 
-      for (ServiceRequest serviceRequest : serviceRequestList) {
-        if (idInSelectionsList(serviceRequest.getId())) {
-          List<CoverageRequirementRuleCriteria> criteriaList = createCriteriaList(serviceRequest.getCode(), serviceRequest.getInsurance(), null);
-          buildExecutionContexts(criteriaList, (Patient) serviceRequest.getSubject().getResource(), "service_request", serviceRequest);
         }
+        List<CoverageRequirementRuleCriteria> criteriaList = createCriteriaList(serviceRequest.getCode(), serviceRequest.getInsurance(), payorList);
+        Patient patientToUse = referencedPrefetechedPatients.iterator().next();
+        logger.info("r4/FhirBundleProcessor::processMedicationDispenses: Found Patient '" + patientToUse + "'.");
+        buildExecutionContexts(criteriaList, patientToUse, "service_request", serviceRequest);
       }
     }
   }
 
-  public void processOrderSelectMedicationStatements(Bundle medicationRequestBundle, Bundle medicationStatementBundle) {
+  public void processOrderSelectMedicationStatements(Bundle medicationRequestBundle, Bundle medicationStatementBundle, Bundle coverageBundle) {
     List<MedicationRequest> medicationRequestList = Utilities.getResourcesOfTypeFromBundle(MedicationRequest.class, medicationRequestBundle);
     List<MedicationStatement> medicationStatementList = Utilities.getResourcesOfTypeFromBundle(MedicationStatement.class, medicationStatementBundle);
 
-    if (!medicationRequestList.isEmpty()) {
-      logger.info("r4/FhirBundleProcessor::processOrderSelectMedicationStatements: MedicationRequests(s) found");
-
-      // process each of the MedicationRequests
-      for (MedicationRequest medicationRequest : medicationRequestList) {
-        if (idInSelectionsList(medicationRequest.getId())) {
+    List<Patient> medStatementPatients = Utilities.getResourcesOfTypeFromBundle(Patient.class, medicationStatementBundle);
+    List<Organization> payorList = Utilities.getResourcesOfTypeFromBundle(Organization.class, coverageBundle);
 
-          // run on each of the MedicationStatements
-          for (MedicationStatement medicationStatement : medicationStatementList) {
-            logger.info("r4/FhirBundleProcessor::processOrderSelectMedicationStatements: MedicationStatement found: " + medicationStatement.getId());
+    if (medicationRequestList.isEmpty()) return;
 
-            List<CoverageRequirementRuleCriteria> criteriaList = createCriteriaList(medicationRequest.getMedicationCodeableConcept(), medicationRequest.getInsurance(), null);
+    logger.info("r4/FhirBundleProcessor::processOrderSelectMedicationStatements: MedicationRequests(s) found");
 
-            HashMap<String, Resource> cqlParams = new HashMap<>();
-            cqlParams.put("Patient", (Patient) medicationRequest.getSubject().getResource());
-            cqlParams.put("medication_request", medicationRequest);
-            cqlParams.put("medication_statement", medicationStatement);
+    // process each of the MedicationRequests
+    for (MedicationRequest medicationRequest : medicationRequestList) {
+      if (idInSelectionsList(medicationRequest.getId())) {
 
-            buildExecutionContexts(criteriaList, cqlParams);
+        // run on each of the MedicationStatements
+        for (MedicationStatement medicationStatement : medicationStatementList) {
+          logger.info("r4/FhirBundleProcessor::processOrderSelectMedicationStatements: MedicationStatement found: " + medicationStatement.getId());
+          String patientReference = medicationStatement.getSubject().getReference();
+          List<Patient> referencedPrefetechedPatients = extractReferencedResources(medStatementPatients, patientReference);
+          if (referencedPrefetechedPatients.size() < 1) {
+            logger.error("r4/FhirBundleProcessor::processMedicationStatements: ERROR - Medication Statement '"
+                + medicationStatement.getId() + "' does not contain a reference to any prefetched patients. Resource contains patient reference '"
+                + patientReference + "' and prefetch contains patients " + medStatementPatients.stream().map(patient -> patient.getId()).collect(Collectors.toSet()) + ".");
           }
+
+          List<CoverageRequirementRuleCriteria> criteriaList = createCriteriaList(medicationRequest.getMedicationCodeableConcept(), medicationRequest.getInsurance(), payorList);
+          Patient patientToUse = referencedPrefetechedPatients.get(0);
+
+          HashMap<String, Resource> cqlParams = new HashMap<>();
+          cqlParams.put("Patient", (Patient) patientToUse);
+          cqlParams.put("medication_request", medicationRequest);
+          cqlParams.put("medication_statement", medicationStatement);
+
+          buildExecutionContexts(criteriaList, cqlParams);
         }
       }
     }
@@ -141,9 +202,10 @@ private List<CoverageRequirementRuleCriteria> createCriteriaList(CodeableConcept
             .map(reference -> (Coverage) reference.getResource()).collect(Collectors.toList());
         // Remove null coverages that may not have resolved.
         coverages = coverages.stream().filter(coverage -> coverage != null).collect(Collectors.toList());
-        payors = Utilities.getPayors(coverages);
-      } else if (payorList != null) {
-        payors = payorList;
+        payors.addAll(Utilities.getPayors(coverages));
+      }
+      if (payorList != null) {
+        payors.addAll(payorList);
       }
 
       if (payors.size() > 0) {
@@ -173,6 +235,7 @@ private List<CoverageRequirementRuleCriteria> createCriteriaList(CodeableConcept
   }
 
   private void buildExecutionContexts(List<CoverageRequirementRuleCriteria> criteriaList, Patient patient, String requestType, DomainResource request) {
+    System.out.println("buildExecutionContexts::PATIENT: " + patient);
     HashMap<String, Resource> cqlParams = new HashMap<>();
     cqlParams.put("Patient", patient);
     cqlParams.put(requestType, request);
@@ -227,4 +290,18 @@ private boolean idInSelectionsList(String identifier) {
     }
   }
 
-}
+  /**
+   * Extracts the resources from the list that have the given id.
+   * @param <R> The resource type to extract from.
+   * @param resources The resources to extact from.
+   * @param resourceId  The resource Id to extract with.
+   * @return  The list of resources with the given Id.
+   */
+  private static <R extends Resource> List<R> extractReferencedResources(List<R> resources, String resourceId) {
+    return resources.stream().filter((currentResource) -> {
+      String currentId = currentResource.getId();
+      return currentId != null && (currentId.contains(resourceId) || resourceId.contains(currentId));
+    }).collect(Collectors.toList());
+  }
+
+}
\ No newline at end of file
diff --git a/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/FhirRequestProcessor.java b/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/FhirRequestProcessor.java
index b65c61f3c..a4ae2d9d7 100644
--- a/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/FhirRequestProcessor.java
+++ b/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/FhirRequestProcessor.java
@@ -348,6 +348,7 @@ public static void addInsuranceAndSubject(Resource resource, List<Patient> patie
         if(!patients.isEmpty()){
           medicationRequest.getSubject().setResource(patients.get(0));
         }
+        break;
       case MedicationDispense:
         MedicationDispense dispense = (MedicationDispense) resource;
         // MedicationDispense does not have an insurance field.
diff --git a/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/OrderSelectService.java b/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/OrderSelectService.java
index 178679788..72ea12c76 100644
--- a/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/OrderSelectService.java
+++ b/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/OrderSelectService.java
@@ -38,6 +38,7 @@ public class OrderSelectService extends CdsService<OrderSelectRequest> {
   public static final String DESCRIPTION =
       "Get information regarding the coverage requirements for durable medical equipment";
   public static final List<PrefetchTemplateElement> PREFETCH_ELEMENTS = Arrays.asList(
+      CrdPrefetchTemplateElements.COVERAGE_PREFETCH_QUERY,
       CrdPrefetchTemplateElements.MEDICATION_STATEMENT_BUNDLE,
       CrdPrefetchTemplateElements.MEDICATION_REQUEST_BUNDLE);
   public static final FhirComponents FHIRCOMPONENTS = new FhirComponents();
@@ -52,7 +53,7 @@ public List<CoverageRequirementRuleResult> createCqlExecutionContexts(OrderSelec
 
     FhirBundleProcessor fhirBundleProcessor = new FhirBundleProcessor(fileStore, baseUrl, selections);
     CrdPrefetch prefetch = orderSelectRequest.getPrefetch();
-    fhirBundleProcessor.processOrderSelectMedicationStatements(prefetch.getMedicationRequestBundle(), prefetch.getMedicationStatementBundle());
+    fhirBundleProcessor.processOrderSelectMedicationStatements(prefetch.getMedicationRequestBundle(), prefetch.getMedicationStatementBundle(), prefetch.getCoverageBundle());
     List<CoverageRequirementRuleResult> results = fhirBundleProcessor.getResults();
 
     if (results.isEmpty()) {
diff --git a/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/OrderSignService.java b/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/OrderSignService.java
index 778f2c736..3f5d7a013 100644
--- a/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/OrderSignService.java
+++ b/server/src/main/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/OrderSignService.java
@@ -24,6 +24,7 @@
 import org.hl7.davinci.r4.crdhook.ordersign.CrdPrefetchTemplateElements;
 import org.hl7.davinci.r4.crdhook.ordersign.OrderSignRequest;
 import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.hl7.fhir.r4.model.Bundle;
 import org.json.simple.JSONObject;
 import org.opencds.cqf.cql.engine.execution.Context;
 import org.opencds.cqf.cql.engine.runtime.Code;
@@ -41,12 +42,13 @@ public class OrderSignService extends CdsService<OrderSignRequest> {
   public static final String DESCRIPTION =
       "Get information regarding the coverage requirements for durable medical equipment";
   public static final List<PrefetchTemplateElement> PREFETCH_ELEMENTS = Arrays.asList(
+      CrdPrefetchTemplateElements.COVERAGE_REQUEST_BUNDLE,
       CrdPrefetchTemplateElements.DEVICE_REQUEST_BUNDLE,
-      CrdPrefetchTemplateElements.SUPPLY_REQUEST_BUNDLE,
-      CrdPrefetchTemplateElements.NUTRITION_ORDER_BUNDLE,
+      // CrdPrefetchTemplateElements.SUPPLY_REQUEST_BUNDLE,
+      // CrdPrefetchTemplateElements.NUTRITION_ORDER_BUNDLE,
       CrdPrefetchTemplateElements.MEDICATION_REQUEST_BUNDLE,
-      CrdPrefetchTemplateElements.SERVICE_REQUEST_BUNDLE,
-      CrdPrefetchTemplateElements.MEDICATION_DISPENSE_BUNDLE);
+      CrdPrefetchTemplateElements.SERVICE_REQUEST_BUNDLE);
+      // CrdPrefetchTemplateElements.MEDICATION_DISPENSE_BUNDLE);
   public static final FhirComponents FHIRCOMPONENTS = new FhirComponents();
   static final Logger logger = LoggerFactory.getLogger(OrderSignService.class);
 
@@ -61,10 +63,11 @@ public class OrderSignService extends CdsService<OrderSignRequest> {
   public List<CoverageRequirementRuleResult> createCqlExecutionContexts(OrderSignRequest orderSignRequest, FileStore fileStore, String baseUrl) {
     FhirBundleProcessor fhirBundleProcessor = new FhirBundleProcessor(fileStore, baseUrl);
     CrdPrefetch prefetch = orderSignRequest.getPrefetch();
-    fhirBundleProcessor.processDeviceRequests(prefetch.getDeviceRequestBundle());
-    fhirBundleProcessor.processMedicationRequests(prefetch.getMedicationRequestBundle());
-    fhirBundleProcessor.processServiceRequests(prefetch.getServiceRequestBundle());
-    fhirBundleProcessor.processMedicationDispenses(prefetch.getMedicationDispenseBundle());
+    Bundle coverageBundle = prefetch.getCoverageBundle(); // TODO - do something with coverage.
+    fhirBundleProcessor.processDeviceRequests(prefetch.getDeviceRequestBundle(), coverageBundle);
+    fhirBundleProcessor.processMedicationRequests(prefetch.getMedicationRequestBundle(), coverageBundle);
+    fhirBundleProcessor.processServiceRequests(prefetch.getServiceRequestBundle(), coverageBundle);
+    fhirBundleProcessor.processMedicationDispenses(prefetch.getMedicationDispenseBundle(), coverageBundle);
     List<CoverageRequirementRuleResult> results = fhirBundleProcessor.getResults();
 
     if (results.isEmpty()) {
@@ -87,9 +90,9 @@ protected CqlResultsForCard executeCqlAndGetRelevantResults(Context context, Str
 
     String humanReadableTopic = StringUtils.join(StringUtils.splitByCharacterTypeCamelCase(topic), ' ');
 
-    coverageRequirements.setInfoLink(evaluateStatement("RESULT_InfoLink", context).toString())
-        .setPriorAuthRequired((Boolean) evaluateStatement("PRIORAUTH_REQUIRED", context))
-        .setDocumentationRequired((Boolean) evaluateStatement("DOCUMENTATION_REQUIRED", context));
+    coverageRequirements.setInfoLink(evaluateStatement("RESULT_InfoLink", context).toString());
+    coverageRequirements.setPriorAuthRequired((Boolean) evaluateStatement("PRIORAUTH_REQUIRED", context));
+    coverageRequirements.setDocumentationRequired((Boolean) evaluateStatement("DOCUMENTATION_REQUIRED", context));
 
     // if prior auth, supercede the documentation required
     if (coverageRequirements.isPriorAuthRequired()) {
diff --git a/server/src/main/java/org/hl7/davinci/endpoint/components/PrefetchHydrator.java b/server/src/main/java/org/hl7/davinci/endpoint/components/PrefetchHydrator.java
index 8f5c109f0..ea7758334 100644
--- a/server/src/main/java/org/hl7/davinci/endpoint/components/PrefetchHydrator.java
+++ b/server/src/main/java/org/hl7/davinci/endpoint/components/PrefetchHydrator.java
@@ -13,6 +13,7 @@
 import org.hl7.davinci.endpoint.cdshooks.services.crd.CdsService;
 import org.hl7.davinci.endpoint.cdshooks.services.crd.r4.FhirRequestProcessor;
 import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.hl7.fhir.r4.model.Bundle;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.http.HttpMethod;
@@ -104,7 +105,7 @@ public void hydrate() {
         alreadyIncluded = (PropertyUtils.getProperty(crdResponse, prefetchKey) != null);
       } catch (Exception e) {
         throw new RuntimeException("System error: Mismatch in prefetch keys between the "
-            + "CrdPrefetch and the key templates set in the service.", e);
+            + "CrdPrefetch and the key templates set in the service. Given prefetch key '" + prefetchKey + "''.", e);
       }
       if (!alreadyIncluded) {
         // check if the bundle actually has element
@@ -118,10 +119,18 @@ public void hydrate() {
                 + "server provided. Either provide a full prefetch or provide a fhir server.");
           }
           try {
-            PropertyUtils
+            Bundle bundle = (Bundle) PropertyUtils.getProperty(crdResponse, prefetchKey);
+            if (bundle == null) {
+              PropertyUtils
                 .setProperty(crdResponse, prefetchKey,
-                    prefetchElement.getReturnType().cast(FhirRequestProcessor.executeFhirQueryUrl(
-                      hydratedPrefetchQuery, cdsRequest, fhirComponents, HttpMethod.GET)));
+                    prefetchElement.getReturnType().cast(
+                        FhirRequestProcessor.executeFhirQueryUrl(hydratedPrefetchQuery, cdsRequest, fhirComponents, HttpMethod.GET)));
+            } else {
+              Bundle newBundle = (Bundle) prefetchElement.getReturnType().cast(
+                  FhirRequestProcessor.executeFhirQueryUrl(hydratedPrefetchQuery, cdsRequest, fhirComponents, HttpMethod.GET));
+              bundle.getEntry().addAll(newBundle.getEntry());
+              PropertyUtils.setProperty(crdResponse, prefetchKey, bundle);
+            }
           } catch (Exception e) {
             logger.warn("Failed to fill prefetch for key: " + prefetchKey, e);
           }
@@ -151,4 +160,4 @@ private String resolvePrefetchToken(String prefetchToken) {
     resolvePrefetchTokenRecursive(dataForPrefetchToken, pathList, elementList);
     return String.join(",", elementList);
   }
-}
+}
\ No newline at end of file
diff --git a/server/src/main/java/org/hl7/davinci/endpoint/fhir/r4/QuestionnairePackageOperation.java b/server/src/main/java/org/hl7/davinci/endpoint/fhir/r4/QuestionnairePackageOperation.java
index 5f0e432e9..0f91dc43a 100644
--- a/server/src/main/java/org/hl7/davinci/endpoint/fhir/r4/QuestionnairePackageOperation.java
+++ b/server/src/main/java/org/hl7/davinci/endpoint/fhir/r4/QuestionnairePackageOperation.java
@@ -82,10 +82,11 @@ public String execute(String resourceString) {
 
             // process the orders to find the topics
             FhirBundleProcessor fhirBundleProcessor = new FhirBundleProcessor(fileStore, baseUrl);
-            fhirBundleProcessor.processDeviceRequests(orders);
-            fhirBundleProcessor.processMedicationRequests(orders);
-            fhirBundleProcessor.processServiceRequests(orders);
-            fhirBundleProcessor.processMedicationDispenses(orders);
+            Bundle coverageBundle = new Bundle(); // TODO - No coverages here, so an empty bundle.
+            fhirBundleProcessor.processDeviceRequests(orders, coverageBundle);
+            fhirBundleProcessor.processMedicationRequests(orders, coverageBundle);
+            fhirBundleProcessor.processServiceRequests(orders, coverageBundle);
+            fhirBundleProcessor.processMedicationDispenses(orders, coverageBundle);
             List<String> topics = createTopicList(fhirBundleProcessor);
 
             for (String topic : topics) {
diff --git a/server/src/test/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/EndToEndRequestPrefetchTest.java b/server/src/test/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/EndToEndRequestPrefetchTest.java
index 74c0f31fb..d8e00a4b1 100644
--- a/server/src/test/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/EndToEndRequestPrefetchTest.java
+++ b/server/src/test/java/org/hl7/davinci/endpoint/cdshooks/services/crd/r4/EndToEndRequestPrefetchTest.java
@@ -33,16 +33,26 @@ public class EndToEndRequestPrefetchTest {
 
   @Rule
   public WireMockRule wireMockRule = new WireMockRule(9089);
-  private String deviceRequestFullPrefetch = FileUtils
+  private String deviceRequestFullPrefetchNoCoverage = FileUtils
       .readFileToString(new ClassPathResource("deviceRequestFullPrefetch_r4.json").getFile(),
           Charset.defaultCharset());
+  private String deviceRequestFullPrefetchWithCoverage = FileUtils
+      .readFileToString(new ClassPathResource("deviceRequestFullPrefetchWithCoverage_r4.json").getFile(),
+          Charset.defaultCharset());
   private String deviceRequestEmptyPrefetchJson = FileUtils
       .readFileToString(new ClassPathResource("deviceRequestEmptyPrefetch_r4.json").getFile(),
           Charset.defaultCharset());
   private String deviceRequestPrefetchResponseJson = FileUtils
       .readFileToString(new ClassPathResource("deviceRequestPrefetchResponse_r4.json").getFile(),
           Charset.defaultCharset());
-  private String prefetchUrlMatcher = "\\/DeviceRequest\\?_id=123.*";
+  private String prefetchUrlMatcher = "\\/DeviceRequest\\?_id=123"
+      + "&_include=DeviceRequest:patient"
+      + "&_include=DeviceRequest:performer"
+      + "&_include=DeviceRequest:requester"
+      + "&_include=DeviceRequest:device"
+      + "&_include:iterate=PractitionerRole:organization"
+      + "&_include:iterate=PractitionerRole:practitioner(.*?)"
+      +"|\\/Coverage\\?patient=c2f0f972-5f84-4518-948f-63d00a1fa5a0";
 
   @LocalServerPort
   private int port;
@@ -55,10 +65,22 @@ public EndToEndRequestPrefetchTest() throws IOException {
   }
 
   @Test
-  public void shouldRunSuccessfully() {
+  public void shouldRunSuccessfullyWithoutCoverage() {
+    HttpHeaders headers = new HttpHeaders();
+    headers.setContentType(MediaType.APPLICATION_JSON);
+    HttpEntity<String> entity = new HttpEntity<String>(deviceRequestFullPrefetchNoCoverage, headers);
+    JsonNode cards = restTemplate
+        .postForObject("http://localhost:" + port + "/r4/cds-services/order-sign-crd", entity,
+            JsonNode.class);
+
+    assertEquals(1, cards.get("cards").size());
+  }
+
+  @Test
+  public void shouldRunSuccessfullyWithCoverage() {
     HttpHeaders headers = new HttpHeaders();
     headers.setContentType(MediaType.APPLICATION_JSON);
-    HttpEntity<String> entity = new HttpEntity<String>(deviceRequestFullPrefetch, headers);
+    HttpEntity<String> entity = new HttpEntity<String>(deviceRequestFullPrefetchWithCoverage, headers);
     JsonNode cards = restTemplate
         .postForObject("http://localhost:" + port + "/r4/cds-services/order-sign-crd", entity,
             JsonNode.class);
diff --git a/server/src/test/resources/deviceRequestFullPrefetchWithCoverage_r4.json b/server/src/test/resources/deviceRequestFullPrefetchWithCoverage_r4.json
new file mode 100644
index 000000000..a845adeee
--- /dev/null
+++ b/server/src/test/resources/deviceRequestFullPrefetchWithCoverage_r4.json
@@ -0,0 +1,225 @@
+{
+  "hook": "order-sign",
+  "hookInstance": "ff939efe-1c97-4c2a-b4e5-d34e6edc2f7b",
+  "fhirServer": "http://localhost:9089/",
+  "fhirAuthorization": null,
+  "user": "Practitioner/1234",
+  "context": {
+    "patientId": "c2f0f972-5f84-4518-948f-63d00a1fa5a0",
+    "encounterId": null,
+    "services": null,
+    "draftOrders": {
+      "resourceType": "Bundle",
+      "entry": [
+        {
+          "resource": {
+            "resourceType": "DeviceRequest",
+            "id": "123",
+            "status": "draft",
+            "codeCodeableConcept": {
+              "coding": [
+                {
+                  "system": "https://bluebutton.cms.gov/resources/codesystem/hcpcs",
+                  "code": "E0250"
+                }
+              ],
+              "text": "Stationary Compressed Gaseous Oxygen System, Rental"
+            },
+            "subject": {
+              "reference": "Patient/c2f0f972-5f84-4518-948f-63d00a1fa5a0"
+            },
+            "performer": {
+              "reference": "PractitionerRole/1eccf4fb-2cf4-400e-891f-54c89b45cfff"
+            },
+            "insurance": [
+              {
+                "reference": "Coverage/c3d24ccd-ad1b-480e-9545-bbf35a3d89ff"
+              }
+            ]
+          }
+        }
+      ]
+    }
+  },
+  "prefetch": {
+    "deviceRequestBundle": {
+      "resourceType": "Bundle",
+      "entry": [
+        {
+          "resource": {
+            "resourceType": "Patient",
+            "id": "c2f0f972-5f84-4518-948f-63d00a1fa5a0",
+            "gender": "male",
+            "birthDate": "1970-07-04",
+            "address": [
+              {
+                "use": "home",
+                "type": "both",
+                "state": "MA"
+              }
+            ]
+          }
+        },
+        {
+          "resource": {
+            "resourceType": "Practitioner",
+            "id": "c259b7a8-cf01-4418-98dd-70e0ddb9c816",
+            "identifier": [
+              {
+                "system": "http://hl7.org/fhir/sid/us-npi",
+                "value": "1122334455"
+              }
+            ],
+            "name": [
+              {
+                "family": "Doe",
+                "given": [
+                  "Jane"
+                ],
+                "prefix": [
+                  "Dr."
+                ]
+              }
+            ]
+          }
+        },
+        {
+          "resource": {
+            "resourceType": "Organization",
+            "id": "68c69399-27f8-47e5-94cd-06509b7d9f56",
+            "name": "Centers for Medicare and Medicaid Services"
+          }
+        },
+        {
+          "resource": {
+            "resourceType": "Location",
+            "id": "f0db1a3f-35da-43aa-9f22-883a94d24dd1",
+            "address": {
+              "line": [
+                "100 Good St"
+              ],
+              "city": "Bedford",
+              "state": "MA",
+              "postalCode": "01730"
+            }
+          }
+        },
+        {
+          "resource": {
+            "resourceType": "PractitionerRole",
+            "id": "1eccf4fb-2cf4-400e-891f-54c89b45cfff",
+            "practitioner": {
+              "reference": "Practitioner/c259b7a8-cf01-4418-98dd-70e0ddb9c816"
+            },
+            "location": [
+              {
+                "reference": "Location/f0db1a3f-35da-43aa-9f22-883a94d24dd1"
+              }
+            ]
+          }
+        },
+        {
+          "resource": {
+            "resourceType": "Coverage",
+            "id": "c3d24ccd-ad1b-480e-9545-bbf35a3d89ff",
+            "payor": [
+              {
+                "reference": "Organization/68c69399-27f8-47e5-94cd-06509b7d9f56"
+              }
+            ],
+            "class": [
+              {
+                "type": {
+                  "system": "http://hl7.org/fhir/coverage-class",
+                  "code": "plan"
+                },
+                "value": "Medicare Part D"
+              }
+            ]
+          }
+        },
+        {
+          "resource": {
+            "resourceType": "DeviceRequest",
+            "id": "123",
+            "status": "draft",
+            "codeCodeableConcept": {
+              "coding": [
+                {
+                  "system": "https://bluebutton.cms.gov/resources/codesystem/hcpcs",
+                  "code": "E0250"
+                }
+              ],
+              "text": "Stationary Compressed Gaseous Oxygen System, Rental"
+            },
+            "subject": {
+              "reference": "Patient/c2f0f972-5f84-4518-948f-63d00a1fa5a0"
+            },
+            "performer": {
+              "reference": "PractitionerRole/1eccf4fb-2cf4-400e-891f-54c89b45cfff"
+            },
+            "insurance": [
+              {
+                "reference": "Coverage/c3d24ccd-ad1b-480e-9545-bbf35a3d89ff"
+              }
+            ]
+          }
+        },
+        {
+          "resource": {
+            "resourceType": "Device",
+            "type": {
+              "coding": [
+                {
+                  "system": "https://bluebutton.cms.gov/resources/codesystem/hcpcs",
+                  "code": "E0250",
+                  "display": "Stationary Compressed Gaseous Oxygen System, Rental"
+                }
+              ]
+            }
+          }
+        }
+      ]
+    },
+    "coverageBundle": {
+      "resourceType": "Bundle",
+      "type": "collection",
+      "entry": [
+          {
+              "fullUrl": "http://localhost:8080/test-ehr/r4/Coverage/cov014",
+              "resource": {
+                  "resourceType": "Coverage",
+                  "id": "cov014",
+                  "meta": {
+                      "versionId": "1",
+                      "lastUpdated": "2022-06-02T10:44:48.765-04:00",
+                      "source": "#k1BlBvuDroEVBvK9"
+                  },
+                  "status": "active",
+                  "subscriberId": "10A3D58WH1600",
+                  "beneficiary": {
+                      "reference": "Patient/pat014"
+                  },
+                  "payor": [
+                      {
+                          "reference": "Organization/org1234"
+                      }
+                  ],
+                  "class": [
+                      {
+                          "value": "Medicare Part A"
+                      }
+                  ]
+              },
+              "search": {
+                  "mode": "match"
+              }
+          }
+      ]
+  },
+    "medicationRequestBundle": null,
+    "nutritionOrderBundle": null,
+    "serviceRequestBundle": null,
+    "supplyRequestBundle": null
+  }
+}
