EndpointType selectOptimalEndpoint(SignedServiceMetadataType serviceMetadata) {

    // List of end points contained in the signed service meta data type
    List<EndpointType> endPointsForDocumentTypeIdentifier =
        serviceMetadata
            .getServiceMetadata()
            .getServiceInformation()
            .getProcessList()
            .getProcess()
            .get(0)
            .getServiceEndpointList()
            .getEndpoint();

    Map<BusDoxProtocol, EndpointType> protocolsAndEndpointType =
        new HashMap<BusDoxProtocol, EndpointType>();

    for (EndpointType endpointType : endPointsForDocumentTypeIdentifier) {
      BusDoxProtocol busDoxProtocol =
          BusDoxProtocol.instanceFrom(endpointType.getTransportProfile());
      protocolsAndEndpointType.put(busDoxProtocol, endpointType);
    }

    BusDoxProtocol preferredProtocol =
        busDoxProtocolSelectionStrategy.selectOptimalProtocol(
            new ArrayList<BusDoxProtocol>(protocolsAndEndpointType.keySet()));

    return protocolsAndEndpointType.get(preferredProtocol);
  }
 /** Provides the end point data required for transmission of a message. */
 @Override
 public PeppolEndpointData getEndpointTransmissionData(
     ParticipantId participantId, PeppolDocumentTypeId documentTypeIdentifier) {
   EndpointType endpointType = getEndpointType(participantId, documentTypeIdentifier);
   String transportProfile = endpointType.getTransportProfile();
   String address = getEndPointUrl(endpointType);
   X509Certificate x509Certificate = getX509CertificateFromEndpointType(endpointType);
   try {
     return new PeppolEndpointData(
         new URL(address),
         BusDoxProtocol.instanceFrom(transportProfile),
         CommonName.valueOf(x509Certificate.getSubjectX500Principal()));
   } catch (Exception e) {
     throw new IllegalStateException(
         "Unable to provide end point data for "
             + participantId
             + " for "
             + documentTypeIdentifier.toString());
   }
 }