@org.junit.Test
  public void testBinaryWithByteBufferAsync() throws Exception {
    final byte[] payload = "payload".getBytes();
    final AtomicReference<Throwable> cause = new AtomicReference<Throwable>();
    final AtomicBoolean connected = new AtomicBoolean(false);
    final FutureResult latch = new FutureResult();

    class TestEndPoint extends Endpoint {
      @Override
      public void onOpen(final Session session, EndpointConfig config) {
        connected.set(true);
        session.addMessageHandler(
            new MessageHandler.Partial<ByteBuffer>() {
              @Override
              public void onMessage(ByteBuffer message, boolean last) {
                Assert.assertTrue(last);
                ByteBuffer buf = ByteBuffer.allocate(message.remaining());
                buf.put(message);
                buf.flip();
                try {
                  session.getBasicRemote().sendBinary(buf);
                } catch (IOException e) {
                  e.printStackTrace();
                  cause.set(e);
                  latch.setException(e);
                }
              }
            });
      }
    }
    ServerWebSocketContainer builder = new ServerWebSocketContainer(TestClassIntrospector.INSTANCE);
    builder.start(
        HttpClient.create(DefaultServer.getWorker(), OptionMap.EMPTY),
        new ByteBufferSlicePool(100, 100));

    builder.addEndpoint(
        ServerEndpointConfig.Builder.create(TestEndPoint.class, "/")
            .configurator(new InstanceConfigurator(new TestEndPoint()))
            .build());
    deployServlet(builder);

    WebSocketTestClient client =
        new WebSocketTestClient(
            getVersion(),
            new URI(
                "ws://"
                    + DefaultServer.getHostAddress("default")
                    + ":"
                    + DefaultServer.getHostPort("default")
                    + "/"));
    client.connect();
    client.send(
        new BinaryWebSocketFrame(ChannelBuffers.wrappedBuffer(payload)),
        new FrameChecker(BinaryWebSocketFrame.class, payload, latch));
    latch.getIoFuture().get();
    Assert.assertNull(cause.get());
    client.destroy();
  }
  @org.junit.Test
  public void testCloseFrame() throws Exception {
    final int code = 1000;
    final String reasonText = "TEST";
    final AtomicReference<CloseReason> reason = new AtomicReference<CloseReason>();
    ByteBuffer payload = ByteBuffer.allocate(reasonText.length() + 2);
    payload.putShort((short) code);
    payload.put(reasonText.getBytes("UTF-8"));
    payload.flip();

    final AtomicBoolean connected = new AtomicBoolean(false);
    final FutureResult latch = new FutureResult();
    final AtomicInteger closeCount = new AtomicInteger();

    class TestEndPoint extends Endpoint {
      @Override
      public void onOpen(final Session session, EndpointConfig config) {
        connected.set(true);
      }

      @Override
      public void onClose(Session session, CloseReason closeReason) {
        closeCount.incrementAndGet();
        reason.set(closeReason);
      }
    }
    ServerWebSocketContainer builder = new ServerWebSocketContainer(TestClassIntrospector.INSTANCE);
    builder.start(
        HttpClient.create(DefaultServer.getWorker(), OptionMap.EMPTY),
        new ByteBufferSlicePool(100, 100));

    builder.addEndpoint(
        ServerEndpointConfig.Builder.create(TestEndPoint.class, "/")
            .configurator(new InstanceConfigurator(new TestEndPoint()))
            .build());
    deployServlet(builder);

    WebSocketTestClient client =
        new WebSocketTestClient(
            getVersion(),
            new URI(
                "ws://"
                    + DefaultServer.getHostAddress("default")
                    + ":"
                    + DefaultServer.getHostPort("default")
                    + "/"));
    client.connect();
    client.send(
        new CloseWebSocketFrame(code, reasonText),
        new FrameChecker(CloseWebSocketFrame.class, payload.array(), latch));
    latch.getIoFuture().get();
    Assert.assertEquals(code, reason.get().getCloseCode().getCode());
    Assert.assertEquals(reasonText, reason.get().getReasonPhrase());
    Assert.assertEquals(1, closeCount.get());
    client.destroy();
  }
  @org.junit.Test
  public void testTextByFuture() throws Exception {
    final byte[] payload = "payload".getBytes();
    final AtomicReference<Future<Void>> sendResult = new AtomicReference<Future<Void>>();
    final AtomicBoolean connected = new AtomicBoolean(false);
    final FutureResult latch = new FutureResult();

    class TestEndPoint extends Endpoint {
      @Override
      public void onOpen(final Session session, EndpointConfig config) {
        connected.set(true);
        session.addMessageHandler(
            new MessageHandler.Whole<String>() {
              @Override
              public void onMessage(String message) {
                sendResult.set(session.getAsyncRemote().sendText(message));
              }
            });
      }
    }
    ServerWebSocketContainer builder = new ServerWebSocketContainer(TestClassIntrospector.INSTANCE);
    builder.start(
        HttpClient.create(DefaultServer.getWorker(), OptionMap.EMPTY),
        new ByteBufferSlicePool(100, 100));
    builder.addEndpoint(
        ServerEndpointConfig.Builder.create(TestEndPoint.class, "/")
            .configurator(new InstanceConfigurator(new TestEndPoint()))
            .build());
    deployServlet(builder);

    WebSocketTestClient client =
        new WebSocketTestClient(
            getVersion(),
            new URI(
                "ws://"
                    + DefaultServer.getHostAddress("default")
                    + ":"
                    + DefaultServer.getHostPort("default")
                    + "/"));
    client.connect();
    client.send(
        new TextWebSocketFrame(ChannelBuffers.wrappedBuffer(payload)),
        new FrameChecker(TextWebSocketFrame.class, payload, latch));
    latch.getIoFuture().get();

    sendResult.get();

    client.destroy();
  }
  @org.junit.Test
  public void testBinaryWithByteBufferByCompletion() throws Exception {
    final byte[] payload = "payload".getBytes();
    final AtomicReference<SendResult> sendResult = new AtomicReference<SendResult>();
    final AtomicBoolean connected = new AtomicBoolean(false);
    final FutureResult latch = new FutureResult();
    final FutureResult latch2 = new FutureResult();

    class TestEndPoint extends Endpoint {
      @Override
      public void onOpen(final Session session, EndpointConfig config) {
        connected.set(true);
        session.addMessageHandler(
            new MessageHandler.Whole<ByteBuffer>() {
              @Override
              public void onMessage(ByteBuffer message) {
                ByteBuffer buf = ByteBuffer.allocate(message.remaining());
                buf.put(message);
                buf.flip();
                session
                    .getAsyncRemote()
                    .sendBinary(
                        buf,
                        new SendHandler() {
                          @Override
                          public void onResult(SendResult result) {
                            sendResult.set(result);
                            if (result.getException() != null) {
                              latch2.setException(new IOException(result.getException()));
                            } else {
                              latch2.setResult(null);
                            }
                          }
                        });
              }
            });
      }
    }
    ServerWebSocketContainer builder = new ServerWebSocketContainer(TestClassIntrospector.INSTANCE);
    builder.start(
        HttpClient.create(DefaultServer.getWorker(), OptionMap.EMPTY),
        new ByteBufferSlicePool(100, 100));

    builder.addEndpoint(
        ServerEndpointConfig.Builder.create(TestEndPoint.class, "/")
            .configurator(new InstanceConfigurator(new TestEndPoint()))
            .build());
    deployServlet(builder);

    WebSocketTestClient client =
        new WebSocketTestClient(
            getVersion(),
            new URI(
                "ws://"
                    + DefaultServer.getHostAddress("default")
                    + ":"
                    + DefaultServer.getHostPort("default")
                    + "/"));
    client.connect();
    client.send(
        new BinaryWebSocketFrame(ChannelBuffers.wrappedBuffer(payload)),
        new FrameChecker(BinaryWebSocketFrame.class, payload, latch));
    latch.getIoFuture().get();
    latch2.getIoFuture().get();

    SendResult result = sendResult.get();
    Assert.assertNotNull(result);
    Assert.assertNull(result.getException());

    client.destroy();
  }