protected CMUrlInfos getTargets(NhinTargetCommunitiesType targetCommunities) {
    CMUrlInfos urlInfoList = null;

    // Obtain all the URLs for the targets being sent to
    try {
      urlInfoList =
          ConnectionManagerCache.getEndpontURLFromNhinTargetCommunities(
              targetCommunities, NhincConstants.PATIENT_DISCOVERY_ASYNC_RESP_SERVICE_NAME);
    } catch (ConnectionManagerException ex) {
      log.error(
          "Failed to obtain target URLs for service "
              + NhincConstants.PATIENT_DISCOVERY_ASYNC_RESP_SERVICE_NAME);
      return null;
    }

    return urlInfoList;
  }
  public SubscribeResponse handleSubscribe(
      TopicConfigurationEntry topicConfig,
      Subscribe subscribe,
      Element subscribeElement,
      AssertionType assertion,
      NhinTargetCommunitiesType targetCommunitites)
      throws TopicNotSupportedFault, InvalidTopicExpressionFault, SubscribeCreationFailedFault {
    log.debug(
        "In handleSubscribe - patient id: "
            + patientIdentifier.getSubjectIdentifier()
            + ", assigning authority: "
            + patientIdentifier.getAssigningAuthorityIdentifier());
    SubscribeResponse response = new SubscribeResponse();
    CMUrlInfos urlInfoList = null;

    // Store initial subscription received from agency adapter (the parent subscription)
    EndpointReferenceType parentSubscriptionReference =
        storeSubscription(subscribe, subscribeElement, assertion, targetCommunitites);
    String parentSubscriptionReferenceXml = null;
    if (parentSubscriptionReference != null) {
      parentSubscriptionReferenceXml = serializeEndpointReferenceType(parentSubscriptionReference);
    }

    // Obtain all the URLs for the targets being sent to
    try {
      urlInfoList =
          ConnectionManagerCache.getEndpontURLFromNhinTargetCommunities(
              targetCommunitites, NhincConstants.HIEM_SUBSCRIBE_SERVICE_NAME);
    } catch (ConnectionManagerException ex) {
      log.error("Failed to obtain target URLs");
      return null;
    }

    // Find patient correlations
    List<QualifiedSubjectIdentifierType> correlations = determineTargets(urlInfoList);

    // Common message preparation

    int correlationCount = 1;
    if (correlations != null) {
      log.debug("Processing correlation #" + correlationCount++);
      AssigningAuthorityHomeCommunityMappingDAO assigningAuthorityDao =
          new AssigningAuthorityHomeCommunityMappingDAO();
      for (QualifiedSubjectIdentifierType correlation : correlations) {
        CMUrlInfo community = new CMUrlInfo();
        String remoteCommunityId =
            assigningAuthorityDao.getHomeCommunityId(correlation.getAssigningAuthorityIdentifier());
        if (log.isDebugEnabled()) {
          log.debug(
              "Remote assigning authority id: " + correlation.getAssigningAuthorityIdentifier());
          log.debug("Mapped remote community id: " + remoteCommunityId);
        }

        community = findTarget(remoteCommunityId, urlInfoList);

        if (community == null) {
          continue;
        }

        //      Update Subscribe
        updateSubscribe(subscribeElement, correlation);
        if (log.isDebugEnabled()) {
          log.debug(
              "@@@ Updated subscribe: "
                  + XmlUtility.serializeElementIgnoreFaults(subscribeElement));
        }
        //      Policy check - performed in proxy?
        //      Audit Event - performed in proxy?
        //      Send Subscribe
        Element childSubscribeElement = subscribeElement;
        SubscribeResponse subscribeResponse =
            sendSubscribeRequest(childSubscribeElement, assertion, community);
        //
        //      Store subscription
        if (subscribeResponse != null) {
          String childSubscriptionReference = null;

          // Use reflection to get the correct subscription reference object
          Object subRef = getSubscriptionReference(subscribeResponse);
          if (subRef != null) {
            if (subRef.getClass().isAssignableFrom(EndpointReferenceType.class)) {
              childSubscriptionReference =
                  serializeEndpointReferenceType((EndpointReferenceType) subRef);
            } else if (subRef.getClass().isAssignableFrom(W3CEndpointReference.class)) {
              childSubscriptionReference =
                  serializeW3CEndpointReference((W3CEndpointReference) subRef);
            } else {
              log.error("Unknown subscription reference type: " + subRef.getClass().getName());
            }

            String childSubscribeXml;
            try {
              childSubscribeXml = XmlUtility.serializeElement(childSubscribeElement);
            } catch (Exception ex) {
              log.error("failed to process subscribe xml", ex);
              childSubscribeXml = null;
            }

            storeChildSubscription(
                childSubscribeXml, childSubscriptionReference, parentSubscriptionReferenceXml);
          } else {
            log.error("Subscription reference was null");
          }
        } else {
          log.error("The subscribe response message was null.");
        }
      }
    }
    setSubscriptionReference(response, parentSubscriptionReference);

    return response;
  }