// Path: action/src/main/java/org/atmosphere/vibe/platform/action/Action.java
// public interface Action<T> {
// 
//     /**
//      * Some action is taken.
//      */
//     void on(T object);
// 
// }
// 
// Path: action/src/main/java/org/atmosphere/vibe/platform/action/VoidAction.java
// public abstract class VoidAction implements Action<Void> {
// 
//     @Override
//     public void on(Void _) {
//         on();
//     }
// 
//     public abstract void on();
// 
// }
// 
// Path: websocket/src/main/java/org/atmosphere/vibe/platform/websocket/ServerWebSocket.java
// public interface ServerWebSocket {
// 
//     /**
//      * The URI used to connect.
//      */
//     String uri();
// 
//     /**
//      * Closes the connection. This method has no side effect if called more than
//      * once.
//      */
//     void close();
// 
//     /**
//      * Sends a text frame through the connection.
//      */
//     ServerWebSocket send(String data);
// 
//     /**
//      * Sends a binary frame through the connection.
//      */
//     ServerWebSocket send(ByteBuffer byteBuffer);
// 
//     /**
//      * Attaches an action for the text frame.
//      */
//     ServerWebSocket ontext(Action<String> action);
// 
//     /**
//      * Attaches an action for the binary frame.
//      */
//     ServerWebSocket onbinary(Action<ByteBuffer> action);
// 
//     /**
//      * Attaches an action for the close event. After this event, the instance
//      * shouldn't be used and all the other events will be disabled.
//      */
//     ServerWebSocket onclose(Action<Void> action);
// 
//     /**
//      * Attaches an action to handle error from various things. Its exact
//      * behavior is platform-specific and error created by the platform is
//      * propagated.
//      */
//     ServerWebSocket onerror(Action<Throwable> action);
// 
//     /**
//      * Returns the provider-specific component.
//      */
//     <T> T unwrap(Class<T> clazz);
// 
// }


import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import java.net.ServerSocket;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import org.atmosphere.vibe.platform.action.Action;
import org.atmosphere.vibe.platform.action.VoidAction;
import org.atmosphere.vibe.platform.websocket.ServerWebSocket;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
import org.eclipse.jetty.websocket.api.WebSocketListener;
import org.eclipse.jetty.websocket.api.WriteCallback;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Timeout;
                    public void on(String data) {
                        assertThat(data, is("A road of winds the water builds"));
                        if (done) {
                            performer.start();
                        } else {
                            done = true;
                        }
                    }
                })
                .onbinary(new Action<ByteBuffer>() {
                    @Override
                    public void on(ByteBuffer data) {
                        assertThat(data, is(ByteBuffer.wrap(new byte[] { 0x00, 0x01, 0x02 })));
                        if (done) {
                            performer.start();
                        } else {
                            done = true;
                        }
                    }
                });
            }
        })
        .connect();
    }

    @Test
    public void onclose_by_server() {
        performer.onserver(new Action<ServerWebSocket>() {
            @Override
            public void on(final ServerWebSocket ws) {
// Path: action/src/main/java/org/atmosphere/vibe/platform/action/Action.java
// public interface Action<T> {
// 
//     /**
//      * Some action is taken.
//      */
//     void on(T object);
// 
// }
// 
// Path: action/src/main/java/org/atmosphere/vibe/platform/action/VoidAction.java
// public abstract class VoidAction implements Action<Void> {
// 
//     @Override
//     public void on(Void _) {
//         on();
//     }
// 
//     public abstract void on();
// 
// }
// 
// Path: websocket/src/main/java/org/atmosphere/vibe/platform/websocket/ServerWebSocket.java
// public interface ServerWebSocket {
// 
//     /**
//      * The URI used to connect.
//      */
//     String uri();
// 
//     /**
//      * Closes the connection. This method has no side effect if called more than
//      * once.
//      */
//     void close();
// 
//     /**
//      * Sends a text frame through the connection.
//      */
//     ServerWebSocket send(String data);
// 
//     /**
//      * Sends a binary frame through the connection.
//      */
//     ServerWebSocket send(ByteBuffer byteBuffer);
// 
//     /**
//      * Attaches an action for the text frame.
//      */
//     ServerWebSocket ontext(Action<String> action);
// 
//     /**
//      * Attaches an action for the binary frame.
//      */
//     ServerWebSocket onbinary(Action<ByteBuffer> action);
// 
//     /**
//      * Attaches an action for the close event. After this event, the instance
//      * shouldn't be used and all the other events will be disabled.
//      */
//     ServerWebSocket onclose(Action<Void> action);
// 
//     /**
//      * Attaches an action to handle error from various things. Its exact
//      * behavior is platform-specific and error created by the platform is
//      * propagated.
//      */
//     ServerWebSocket onerror(Action<Throwable> action);
// 
//     /**
//      * Returns the provider-specific component.
//      */
//     <T> T unwrap(Class<T> clazz);
// 
// }


// Path: test/src/main/java/org/atmosphere/vibe/platform/test/ServerWebSocketTest.java
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import java.net.ServerSocket;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import org.atmosphere.vibe.platform.action.Action;
import org.atmosphere.vibe.platform.action.VoidAction;
import org.atmosphere.vibe.platform.websocket.ServerWebSocket;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
import org.eclipse.jetty.websocket.api.WebSocketListener;
import org.eclipse.jetty.websocket.api.WriteCallback;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Timeout;

                    public void on(String data) {
                        assertThat(data, is("A road of winds the water builds"));
                        if (done) {
                            performer.start();
                        } else {
                            done = true;
                        }
                    }
                })
                .onbinary(new Action<ByteBuffer>() {
                    @Override
                    public void on(ByteBuffer data) {
                        assertThat(data, is(ByteBuffer.wrap(new byte[] { 0x00, 0x01, 0x02 })));
                        if (done) {
                            performer.start();
                        } else {
                            done = true;
                        }
                    }
                });
            }
        })
        .connect();
    }

    @Test
    public void onclose_by_server() {
        performer.onserver(new Action<ServerWebSocket>() {
            @Override
            public void on(final ServerWebSocket ws) {
                ws.onclose(new VoidAction() {