@Override
  public void sendPushMessage(
      Variant variant,
      Collection<String> clientIdentifiers,
      UnifiedPushMessage pushMessage,
      String pushMessageInformationId,
      NotificationSenderCallback senderCallback) {
    final AdmService admService = ADM.newService();

    final PayloadBuilder builder = ADM.newPayload();

    // flatten the "special keys"
    builder.dataField("alert", pushMessage.getMessage().getAlert());

    // if present, apply the time-to-live metadata:
    int ttl = pushMessage.getConfig().getTimeToLive();
    if (ttl != -1) {
      builder.expiresAfter(ttl);
    }

    // dirty hack for cordova,
    // TODO should be removed once we have our clients SDKs, tracked by AGPUSH-1269
    builder.dataField("message", "useless payload");

    // Handle consolidation key
    builder.consolidationKey(pushMessage.getMessage().getConsolidationKey());

    pushMessage
        .getMessage()
        .getUserData()
        .keySet()
        .forEach(key -> builder.dataField(key, pushMessage.getMessage().getUserData().get(key)));

    // add the aerogear-push-id
    builder.dataField(InternalUnifiedPushMessage.PUSH_MESSAGE_ID, pushMessageInformationId);

    final AdmVariant admVariant = (AdmVariant) variant;

    clientIdentifiers.forEach(
        token -> {
          try {
            admService.sendMessageToDevice(
                token, admVariant.getClientId(), admVariant.getClientSecret(), builder.build());
            senderCallback.onSuccess();
          } catch (Exception e) {
            logger.error("Error sending payload to ADM server", e);
            senderCallback.onError(e.getMessage());
          }
        });
    logger.info(
        String.format(
            "Sent push notification to Amazon's ADM Server for %d tokens",
            clientIdentifiers.size()));
  }