private void invoke(ClientRegistrationKey registrationKey, Address address) throws Exception {
    ListenerMessageCodec codec = registrationKey.getCodec();
    ClientMessage request = codec.encodeAddRequest(true);
    EventHandler handler = registrationKey.getHandler();
    handler.beforeListenerRegister();

    ClientInvocation invocation = new ClientInvocation(client, request, address);
    invocation.setEventHandler(handler);
    String serverRegistrationId = codec.decodeAddResponse(invocation.invoke().get());

    handler.onListenerRegister();
    int correlationId = request.getCorrelationId();
    ClientEventRegistration registration =
        new ClientEventRegistration(serverRegistrationId, correlationId, address, codec);

    Map<Address, ClientEventRegistration> registrationMap = registrations.get(registrationKey);
    registrationMap.put(address, registration);
  }
  @Override
  public boolean deregisterListener(String userRegistrationId) {
    synchronized (listenerRegLock) {
      ClientRegistrationKey key = new ClientRegistrationKey(userRegistrationId);
      Map<Address, ClientEventRegistration> registrationMap = registrations.get(key);

      if (registrationMap == null) {
        return false;
      }

      boolean successful = true;
      for (ClientEventRegistration registration : registrationMap.values()) {
        Address subscriber = registration.getSubscriber();
        try {
          ListenerMessageCodec listenerMessageCodec = registration.getCodec();
          String serverRegistrationId = registration.getServerRegistrationId();
          ClientMessage request = listenerMessageCodec.encodeRemoveRequest(serverRegistrationId);
          Future future = new ClientInvocation(client, request, subscriber).invoke();
          future.get();
          removeEventHandler(registration.getCallId());
          registrationMap.remove(subscriber);
        } catch (Exception e) {
          successful = false;
          logger.warning(
              "Deregistration of listener with id "
                  + userRegistrationId
                  + " has failed to address "
                  + subscriber,
              e);
        }
      }

      if (successful) {
        registrations.remove(key);
      }
      return successful;
    }
  }