private Object sendMessages(DeviceClient device, Object proxyObj, Method method, Object[] args)
      throws Throwable {
    Message message = null;
    // check arguments are primitives
    Object[] checkedArgs = new Object[args.length];
    for (int i = 0; i < args.length; i++) {
      if (TypeUtils.isPrimitive(args[i].getClass()) || args[i].getClass().equals(Class.class)) {
        checkedArgs[i] = args[i];
      } else {
        int sysRef = System.identityHashCode(proxyObj);
        String objRemoteID = messageWorker.getProxyObjectRemoteID(sysRef);
        if (objRemoteID != null) checkedArgs[i] = objRemoteID;
        else throw new UnsupportedOperationException("Argument type is not supported.");
      }
    }

    if (isSolo(proxyObj)) {
      message =
          MessageFactory.createEventMessage(
              proxyObj.getClass(),
              UUID.randomUUID().toString(),
              method,
              method.getParameterTypes(),
              checkedArgs);
    } else {

      // TODO: the invoke executes method on single remote object.
      // The client should find the same objects on other devices and
      // execute the invocation too!!
      // only for non-solo based invocation

      // Then it could be a proxy object
      int sysRef = System.identityHashCode(proxyObj);
      String objRemoteID = messageWorker.getProxyObjectRemoteID(sysRef);
      // remove them from memory
      // messageWorker.removeProxyObject(sysRef, proxyObj);
      if (objRemoteID != null) {
        // construct a message and request for action
        message =
            MessageFactory.createEventMessage(
                proxyObj.getClass(), objRemoteID, method, method.getParameterTypes(), checkedArgs);
      } else {
        System.err.println("cannot find proxy object");
        return null;
      }
    }

    device.sendMessage(message.toString());
    // System.out.println("Sent Msg: " + message.toString());

    // wait for response
    int slept = 0;
    boolean timedOut = false;
    while (!messageWorker.hasResponseFor(message)) {
      if (slept >= TIMEOUT) {
        break;
      }
      Thread.sleep(SLEEP_TIME);
      slept += SLEEP_TIME;
    }

    if (timedOut == true) throw new RemoteException("Server time out");

    return messageWorker.digestMessage(message.getMessageId().toString());
  }
 public void addMessage(Message message) {
   MessageWorker.addMessage(message);
 }