@Test
  public void testText() throws Exception {

    final AtomicBoolean connected = new AtomicBoolean(false);

    final ServletContainer container = ServletContainer.Factory.newInstance();

    DeploymentUtils.setupServlet(
        new ServletInfo(
                "websocket",
                WebSocketServlet.class,
                new ImmediateInstanceFactory<Servlet>(
                    new WebSocketServlet(
                        new WebSocketConnectionCallback() {
                          @Override
                          public void onConnect(
                              final WebSocketHttpExchange exchange,
                              final WebSocketChannel channel) {
                            connected.set(true);
                            channel
                                .getReceiveSetter()
                                .set(
                                    new AbstractReceiveListener() {

                                      @Override
                                      protected void onFullTextMessage(
                                          WebSocketChannel channel, BufferedTextMessage message)
                                          throws IOException {
                                        final String string = message.getData();
                                        if (string.equals("hello")) {
                                          WebSockets.sendText("world", channel, null);
                                        } else {
                                          WebSockets.sendText(string, channel, null);
                                        }
                                      }
                                    });
                            channel.resumeReceives();
                          }
                        })))
            .addMapping("/*"));

    final FutureResult latch = new FutureResult();
    WebSocketTestClient client =
        new WebSocketTestClient(
            org.jboss.netty.handler.codec.http.websocketx.WebSocketVersion.V13,
            new URI(
                "ws://"
                    + NetworkUtils.formatPossibleIpv6Address(
                        DefaultServer.getHostAddress("default"))
                    + ":"
                    + DefaultServer.getHostPort("default")
                    + "/servletContext/"));
    client.connect();
    client.send(
        new TextWebSocketFrame(ChannelBuffers.copiedBuffer("hello", US_ASCII)),
        new FrameChecker(TextWebSocketFrame.class, "world".getBytes(US_ASCII), latch));
    latch.getIoFuture().get();
    client.destroy();
  }
  @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();
  }