// TODO: naming
  @SuppressWarnings("unchecked")
  void sendSyncObject(Object o, SendHandler handler) {
    if (o instanceof String) {
      remoteEndpoint.sendText((String) o, handler);
    } else {
      Object toSend = null;
      try {
        toSend = tyrusEndpointWrapper.doEncode(session, o);
      } catch (final Exception e) {
        handler.onResult(new SendResult(e));
      }

      if (toSend instanceof String) {
        remoteEndpoint.sendText((String) toSend, handler);
      } else if (toSend instanceof ByteBuffer) {
        remoteEndpoint.sendBinary((ByteBuffer) toSend, handler);
      } else if (toSend instanceof StringWriter) {
        StringWriter writer = (StringWriter) toSend;
        StringBuffer sb = writer.getBuffer();
        remoteEndpoint.sendText(sb.toString(), handler);
      } else if (toSend instanceof ByteArrayOutputStream) {
        ByteArrayOutputStream baos = (ByteArrayOutputStream) toSend;
        ByteBuffer buffer = ByteBuffer.wrap(baos.toByteArray());
        remoteEndpoint.sendBinary(buffer, handler);
      }
    }
  }
  @SuppressWarnings("unchecked")
  Future<?> sendSyncObject(Object o) {
    if (o instanceof String) {
      return remoteEndpoint.sendText((String) o);
    } else {
      Object toSend;
      try {
        toSend = tyrusEndpointWrapper.doEncode(session, o);
      } catch (final Exception e) {
        return new Future<Object>() {
          @Override
          public boolean cancel(boolean mayInterruptIfRunning) {
            return false;
          }

          @Override
          public boolean isCancelled() {
            return false;
          }

          @Override
          public boolean isDone() {
            return true;
          }

          @Override
          public Object get() throws InterruptedException, ExecutionException {
            throw new ExecutionException(e);
          }

          @Override
          public Object get(long timeout, TimeUnit unit)
              throws InterruptedException, ExecutionException, TimeoutException {
            throw new ExecutionException(e);
          }
        };
      }

      if (toSend instanceof String) {
        return remoteEndpoint.sendText((String) toSend);
      } else if (toSend instanceof ByteBuffer) {
        return remoteEndpoint.sendBinary((ByteBuffer) toSend);
      } else if (toSend instanceof StringWriter) {
        StringWriter writer = (StringWriter) toSend;
        StringBuffer sb = writer.getBuffer();
        return remoteEndpoint.sendText(sb.toString());
      } else if (toSend instanceof ByteArrayOutputStream) {
        ByteArrayOutputStream baos = (ByteArrayOutputStream) toSend;
        ByteBuffer buffer = ByteBuffer.wrap(baos.toByteArray());
        return remoteEndpoint.sendBinary(buffer);
      }
    }

    return null;
  }
 @Override
 public void sendPong(ByteBuffer applicationData) throws IOException {
   if (applicationData != null && applicationData.remaining() > 125) {
     throw new IllegalArgumentException(
         "Pong applicationData exceeded the maximum allowed payload of 125 bytes.");
   }
   session.restartIdleTimeoutExecutor();
   remoteEndpoint.sendPong(applicationData);
 }
 public void close(CloseReason cr) {
   Logger.getLogger(RemoteEndpointWrapper.class.getName())
       .fine("Close public void close(CloseReason cr): " + cr);
   remoteEndpoint.close(cr);
 }