private void send(ClientDescriptor client, Message message) {
   LOGGER.trace("[{}] send({}, {})", consumerId, client, message);
   try {
     clientCommunicator.sendNoResponse(
         client, ProxyEntityResponse.response(Message.class, message));
   } catch (Exception e) {
     LOGGER.error("Unable to send message " + message + " to client " + client);
   }
 }
 public void fireAndForgetMessage(Object message, ClientDescriptor... clients) {
   final Class<?> type = message.getClass();
   if (!messageTypes.contains(type)) {
     throw new IllegalArgumentException("Event type '" + type + "' isn't supported");
   }
   for (ClientDescriptor client : clients) {
     try {
       clientCommunicator.sendNoResponse(client, ProxyEntityResponse.response(type, message));
     } catch (MessageCodecException ex) {
       throw new RuntimeException(ex);
     }
   }
 }
 public ProxyEntityResponse invoke(
     final ClientDescriptor clientDescriptor, final ProxyEntityMessage message) {
   try {
     try {
       invocationContext.set(new InvocationContext(clientDescriptor));
       return ProxyEntityResponse.response(
           message.messageType(), message.invoke(target, clientDescriptor));
     } finally {
       invocationContext.remove();
     }
   } catch (IllegalAccessException e) {
     throw new IllegalArgumentException(e);
   } catch (InvocationTargetException e) {
     Throwable target = e.getTargetException();
     if (target instanceof Error) {
       throw (Error) target;
     }
     if (target instanceof RuntimeException) {
       throw (RuntimeException) target;
     }
     throw new RuntimeException(target.getMessage(), target);
   }
 }
 public void fireMessage(Object message) {
   final Class<?> type = message.getClass();
   if (!messageTypes.contains(type)) {
     throw new IllegalArgumentException("Event type '" + type + "' isn't supported");
   }
   Set<Future<Void>> futures = new HashSet<Future<Void>>();
   final InvocationContext invocationContext = this.invocationContext.get();
   final ClientDescriptor caller = invocationContext == null ? null : invocationContext.caller;
   for (ClientDescriptor client : clients) {
     if (!client.equals(caller)) {
       try {
         futures.add(clientCommunicator.send(client, ProxyEntityResponse.response(type, message)));
       } catch (MessageCodecException ex) {
         throw new RuntimeException(ex);
       }
     }
   }
   boolean interrupted = false;
   while (!futures.isEmpty()) {
     for (Iterator<Future<Void>> iterator = futures.iterator(); iterator.hasNext(); ) {
       final Future<Void> future = iterator.next();
       try {
         future.get();
         iterator.remove();
       } catch (InterruptedException e) {
         interrupted = true;
       } catch (ExecutionException e) {
         iterator.remove();
         e.printStackTrace();
       }
     }
   }
   if (interrupted) {
     Thread.currentThread().interrupt();
   }
 }