text:
package org.snf4j.websocket;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.net.SocketAddress;
import java.net.URI;
import java.util.Arrays;
import java.util.concurrent.ExecutionException;

import javax.net.ssl.SSLEngine;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.snf4j.core.HttpProxy;
import org.snf4j.core.SSLSession;
import org.snf4j.core.Server;
import org.snf4j.core.StreamSession;
import org.snf4j.core.TestHandler;
import org.snf4j.core.allocator.CachingAllocator;
import org.snf4j.core.allocator.DefaultAllocator;
import org.snf4j.core.allocator.DefaultAllocatorMetric;
import org.snf4j.core.codec.IDecoder;
import org.snf4j.core.codec.IEncoder;
import org.snf4j.core.codec.zip.ZlibDecoder;
import org.snf4j.core.codec.zip.ZlibEncoder;
import org.snf4j.core.future.IFuture;
import org.snf4j.core.proxy.HttpProxyHandler;
import org.snf4j.core.session.DefaultSessionConfig;
import org.snf4j.core.session.SSLEngineCreateException;
import org.snf4j.core.timer.TestTimer;
import org.snf4j.websocket.frame.Frame;
import org.snf4j.websocket.frame.FrameAggregator;
import org.snf4j.websocket.frame.PingFrame;
import org.snf4j.websocket.frame.PongFrame;
import org.snf4j.websocket.extensions.IExtension;
import org.snf4j.websocket.extensions.TestExtension;
import org.snf4j.websocket.extensions.compress.DeflateCodecTest;
import org.snf4j.websocket.extensions.compress.PerMessageDeflateExtension;
import org.snf4j.websocket.extensions.compress.PerMessageDeflateExtension.NoContext;
import org.snf4j.websocket.frame.BinaryFrame;
import org.snf4j.websocket.frame.CloseFrame;
import org.snf4j.websocket.frame.ContinuationFrame;
import org.snf4j.websocket.frame.TextFrame;
import org.snf4j.websocket.handshake.HandshakeTest;
import org.snf4j.websocket.handshake.IHandshaker;

public class WebSocketSessionTest extends HandshakeTest {

	long TIMEOUT = 2000;

	int PORT = 7777;

	boolean serverHandleClose;

	boolean clientHandleClose;

	boolean traceCloseDetails;

	boolean clientWaitForCloseMessage;

	boolean serverWaitForCloseMessage;

	WSServer s;

	WSClient c;

	HttpProxy p;

	@Before
	public void before() {
		s = c = null;
		p = null;
		serverHandleClose = clientHandleClose = false;
		traceCloseDetails = false;
	}

	@After
	public void after() throws InterruptedException {
		if (c != null) c.stop(TIMEOUT);
		if (s != null) s.stop(TIMEOUT);
		if (p != null) p.stop(TIMEOUT);
	}

	void waitFor(long millis) throws InterruptedException {
		Thread.sleep(millis);
	}

	public void testSuccessfulHandshake(boolean ssl) throws Exception {
		s = new WSServer(PORT, ssl);
		c = new WSClient(PORT, ssl);

		s.start();
		c.start();
		c.waitForOpen(TIMEOUT);
		c.session.getReadyFuture().sync(TIMEOUT);
		c.waitForReady(TIMEOUT);
		s.waitForReady(TIMEOUT);
		assertEquals("CR|OP|RE|", c.getTrace());
		assertEquals("CR|OP|RE|", s.getTrace());
		c.session.close();
		c.session.getEndFuture().sync(TIMEOUT);
		s.session.getEndFuture().sync(TIMEOUT);
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("CL|EN|", c.getTrace());
		assertEquals("CL|EN|", s.getTrace());
		c.stop(TIMEOUT);

		c = new WSClient(PORT, ssl);
		c.onlyTcp = true;
		c.start();
		c.waitForOpen(TIMEOUT);
		s.waitForOpen(TIMEOUT);
		c.session.getReadyFuture().sync(TIMEOUT);
		s.session.getOpenFuture().sync(TIMEOUT);
		waitFor(50);
		assertFalse(s.session.getReadyFuture().isDone());
		assertEquals("CR|OP|RE|", c.getTrace());
		assertEquals("CR|OP|", s.getTrace());

		byte[] b = bytes("GET /uri HTTP/1.1|"
				+"Host: host|"
				+"Upgrade: websocket|"
				+"Connection: Upgrade|"
				+"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==|"
				+"Sec-WebSocket-Version: 13|"
				+"|");

		c.session.write(b);
		s.session.getReadyFuture().sync(TIMEOUT);
		c.waitForMsgRead(TIMEOUT);
		s.waitForReady(TIMEOUT);
		assertEquals("RE|", s.getTrace());
		assertEquals("RES(101)|", c.getTrace());
		assertEquals("Switching Protocols", c.response.getReason());
		assertFields(c.response, "Upgrade:websocket;Connection:Upgrade;Sec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbK+xOo=;");
		c.stop(TIMEOUT);
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("CL|EN|", c.getTrace());
		assertEquals("CL|EN|", s.getTrace());

		c = new WSClient(PORT, ssl);
		c.onlyTcp = true;
		c.start();
		c.waitForOpen(TIMEOUT);
		s.waitForOpen(TIMEOUT);
		c.session.getReadyFuture().sync(TIMEOUT);
		s.session.getOpenFuture().sync(TIMEOUT);
		b = bytes("GET /uri HTTP/1.1|"
				+"Host: host|"
				+"Upgrade: websocket|"
				+"Connection: Upgrade|"
				+"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==|"
				+"Sec-WebSocket-Version: 12|"
				+"Sec-WebSocket-Version: 11, 13|"
				+"Sec-WebSocket-Version: 14|"
				+"|");
		c.session.write(b);
		c.waitForMsgRead(TIMEOUT);
		s.waitForReady(TIMEOUT);
		assertEquals(101, c.response.getStatus());
		assertFields(c.response, "Upgrade:websocket;Connection:Upgrade;Sec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbK+xOo=;");
		c.stop(TIMEOUT);
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);

		c = new WSClient(PORT, ssl);
		c.onlyTcp = true;
		c.start();
		c.waitForOpen(TIMEOUT);
		s.waitForOpen(TIMEOUT);
		c.session.getReadyFuture().sync(TIMEOUT);
		s.session.getOpenFuture().sync(TIMEOUT);
		b = bytes("GET /uri HTTP/1.1|"
				+"Host: host|"
				+"Upgrade: websocket|"
				+"Connection: Upgrade|"
				+"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==|"
				+"Sec-WebSocket-Version: 12,|"
				+" 11, 13|"
				+"|");
		c.session.write(b);
		c.waitForMsgRead(TIMEOUT);
		s.waitForReady(TIMEOUT);
		assertEquals(101, c.response.getStatus());
		assertFields(c.response, "Upgrade:websocket;Connection:Upgrade;Sec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbK+xOo=;");
		c.stop(TIMEOUT);
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
	}

	@Test
	public void testSuccessfulHandshakeSsl() throws Exception {
		testSuccessfulHandshake(true);
	}

	@Test
	public void testSuccessfulHandshake() throws Exception {
		testSuccessfulHandshake(false);
	}

	public void testFailingHandshake(boolean ssl) throws Exception {
		s = new WSServer(PORT, ssl);
		c = new WSClient(PORT, ssl);
		s.start();

		c.onlyTcp = true;
		c.start();
		c.waitForOpen(TIMEOUT);
		s.waitForOpen(TIMEOUT);
		c.session.getReadyFuture().sync(TIMEOUT);
		s.session.getOpenFuture().sync(TIMEOUT);

		byte[] b = bytes("GET /uri HTTP/1.1|"
				+"Host: host|"
				+"Upgrade: websocket|"
				+"Connection: Upgrade|"
				+"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==|"
				+"Sec-WebSocket-Version: 12, 14|"
				+"|");
		c.session.write(b);
		IFuture<Void> f = s.session.getReadyFuture().await(TIMEOUT);
		assertTrue(f.isFailed());
		assertEquals("Unsupported websocket version: 12, 14", f.cause().getMessage());
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals(426, c.response.getStatus());
		assertFields(c.response, "Sec-WebSocket-Version:13;");
		assertEquals("CR|OP|EX|CL|EN|", s.getTrace());
		assertEquals("CR|OP|RE|RES(426)|CL|EN|", c.getTrace());
		c.stop(TIMEOUT);

		c = new WSClient(PORT, ssl);
		c.onlyTcp = true;
		c.start();
		c.waitForOpen(TIMEOUT);
		c.session.getReadyFuture().sync(TIMEOUT);
		b = bytes("POST /uri HTTP/1.1|"
				+"Host: host|"
				+"Upgrade: websocket|"
				+"Connection: Upgrade|"
				+"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==|"
				+"Sec-WebSocket-Version: 13|"
				+"|");
		c.session.write(b);
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		f = s.session.getReadyFuture();
		assertTrue(f.isFailed());
		assertEquals("Forbidden http request command", f.cause().getMessage());
		assertEquals("CR|OP|EX|CL|EN|", s.getTrace());
		assertEquals("CR|OP|RE|RES(403)|CL|EN|", c.getTrace());
		c.stop(TIMEOUT);

		c = new WSClient(PORT, ssl);
		c.onlyTcp = true;
		c.start();
		c.waitForOpen(TIMEOUT);
		c.session.getReadyFuture().sync(TIMEOUT);
		b = bytes("GET /uri HTTP/1.2|"
				+"Host: host|"
				+"Upgrade: websocket|"
				+"Connection: Upgrade|"
				+"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==|"
				+"Sec-WebSocket-Version: 13|"
				+"|");
		c.session.write(b);
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		f = s.session.getReadyFuture();
		assertTrue(f.isFailed());
		assertEquals("Invalid http request version", f.cause().getMessage());
		assertEquals("CR|OP|EX|CL|EN|", s.getTrace());
		assertEquals("CR|OP|RE|RES(400)|CL|EN|", c.getTrace());
		c.stop(TIMEOUT);

		c = new WSClient(PORT, ssl);
		c.onlyTcp = true;
		c.start();
		c.waitForOpen(TIMEOUT);
		c.session.getReadyFuture().sync(TIMEOUT);
		b = bytes("GET HTTP/1.1|"
				+"Host: host|"
				+"Upgrade: websocket|"
				+"Connection: Upgrade|"
				+"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==|"
				+"Sec-WebSocket-Version: 13|"
				+"|");
		c.session.write(b);
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		f = s.session.getReadyFuture();
		assertTrue(f.isFailed());
		assertEquals("Invalid http request", f.cause().getMessage());
		assertEquals("CR|OP|EX|CL|EN|", s.getTrace());
		assertEquals("CR|OP|RE|RES(400)|CL|EN|", c.getTrace());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		s = new WSServer(PORT, ssl);
		c = new WSClient(PORT, ssl);
		s.onlyTcp = true;
		s.start();
		c.start();
		s.waitForMsgRead(TIMEOUT);
		c.waitForOpen(TIMEOUT);
		b = bytes("HTTP/1.1 101 Switching Protocols|"
				+"Upgrade: websocket|"
				+"Connection: Upgrade|"
				+"|");
		s.session.write(b);
		f = c.session.getReadyFuture().await(TIMEOUT);
		assertTrue(f.isFailed());
		assertEquals("Missing websocket key challenge", f.cause().getMessage());
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("CR|OP|RE|REQ(/)|CL|EN|", s.getTrace());
		assertEquals("CR|OP|EX|CL|EN|", c.getTrace());
		c.stop(TIMEOUT);

		c = new WSClient(PORT, ssl);
		c.start();
		s.waitForMsgRead(TIMEOUT);
		c.waitForOpen(TIMEOUT);
		b = bytes("HTTP/1.2 101 Switching Protocols|"
				+"Upgrade: websocket|"
				+"Connection: Upgrade|"
				+"|");
		s.session.write(b);
		f = c.session.getReadyFuture().await(TIMEOUT);
		assertTrue(f.isFailed());
		assertEquals("Invalid http response version", f.cause().getMessage());
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		if (ssl) {
			assertEquals("CR|OP|RE|REQ(/)|SSL_CLOSED_WITHOUT_CLOSE_NOTIFY|CL|EN|", s.getTrace());
		}
		else {
			assertEquals("CR|OP|RE|REQ(/)|CL|EN|", s.getTrace());
		}
		assertEquals("CR|OP|EX|CL|EN|", c.getTrace());
		c.stop(TIMEOUT);

		c = new WSClient(PORT, ssl);
		c.start();
		c.waitForOpen(TIMEOUT);
		s.waitForMsgRead(TIMEOUT);
		b = bytes("HTTP/1.1 1010 Switching Protocols|"
				+"Upgrade: websocket|"
				+"Connection: Upgrade|"
				+"|");
		s.session.write(b);
		f = c.session.getReadyFuture().await(TIMEOUT);
		assertTrue(f.isFailed());
		assertEquals("Invalid http response status", f.cause().getMessage());
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		if (ssl) {
			assertEquals("CR|OP|RE|REQ(/)|SSL_CLOSED_WITHOUT_CLOSE_NOTIFY|CL|EN|", s.getTrace());
		}
		else {
			assertEquals("CR|OP|RE|REQ(/)|CL|EN|", s.getTrace());
		}
		assertEquals("CR|OP|EX|CL|EN|", c.getTrace());
		c.stop(TIMEOUT);

		c = new WSClient(PORT, ssl);
		c.start();
		c.waitForOpen(TIMEOUT);
		s.waitForMsgRead(TIMEOUT);
		b = bytes("HTTP/1.2 101|"
				+"Upgrade: websocket|"
				+"Connection: Upgrade|"
				+"|");
		s.session.write(b);
		f = c.session.getReadyFuture().await(TIMEOUT);
		assertTrue(f.isFailed());
		assertEquals("Invalid http response", f.cause().getMessage());
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		if (ssl) {
			assertEquals("CR|OP|RE|REQ(/)|SSL_CLOSED_WITHOUT_CLOSE_NOTIFY|CL|EN|", s.getTrace());
		}
		else {
			assertEquals("CR|OP|RE|REQ(/)|CL|EN|", s.getTrace());
		}
		assertEquals("CR|OP|EX|CL|EN|", c.getTrace());
		c.stop(TIMEOUT);

	}

	public void testInvalidHandshakeCodecs(boolean ssl) throws Exception {
		s = new WSServer(PORT, ssl);
		c = new WSClient(PORT, ssl);
		c.changeHsEncoderMode = true;
		s.start();
		c.start();
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("CR|OP|EX|CL|EN|", c.getTrace());
		assertEquals("CR|OP|CL|EN|", s.getTrace().replace("SSL_CLOSED_WITHOUT_CLOSE_NOTIFY|CL|EN|", "CL|EN|"));
		c.stop(TIMEOUT);

		c = new WSClient(PORT, ssl);
		c.changeHsEncoderMode = true;
		c.throwInException = new RuntimeException();
		assertEquals(0, c.throwInExceptionCount.get());
		c.start();
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("CR|OP|EX|CL|EN|", c.getTrace());
		assertEquals("CR|OP|CL|EN|", s.getTrace().replace("SSL_CLOSED_WITHOUT_CLOSE_NOTIFY|CL|EN|", "CL|EN|"));
		assertEquals(1, c.throwInExceptionCount.get());
		c.stop(TIMEOUT);

		c = new WSClient(PORT, ssl);
		c.changeHsDecoderMode = true;
		c.start();
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("CR|OP|EX|EX|CL|EN|", c.getTrace());
		assertEquals("CR|OP|RE|CL|EN|", s.getTrace());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		s = new WSServer(PORT, ssl);
		c = new WSClient(PORT, ssl);
		s.changeHsEncoderMode = true;
		s.start();
		c.start();
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("CR|OP|CL|EN|", c.getTrace());
		assertEquals("CR|OP|EX|CL|EN|", s.getTrace());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		s = new WSServer(PORT, ssl);
		c = new WSClient(PORT, ssl);
		s.changeHsDecoderMode = true;
		s.start();
		c.start();
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		if (ssl) {
			assertEquals("CR|OP|SSL_CLOSED_WITHOUT_CLOSE_NOTIFY|CL|EN|", c.getTrace());
		}
		else {
			assertEquals("CR|OP|CL|EN|", c.getTrace());
		}
		assertEquals("CR|OP|EX|CL|EN|", s.getTrace());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

	}

	@Test
	public void testInvalidHandshakeCodecsSsl() throws Exception {
		testInvalidHandshakeCodecs(true);
	}

	@Test
	public void testInvalidHandshakeCodecs() throws Exception {
		testInvalidHandshakeCodecs(false);
	}

	@Test
	public void testFailingHandshakeSsl() throws Exception {
		testFailingHandshake(true);
	}

	@Test
	public void testFailingHandshake() throws Exception {
		testFailingHandshake(false);
	}

	void startClientServer(boolean ssl) throws Exception {
		startClientServer(ssl, null, null);
	}

	void startClientServer(boolean ssl, IExtension[] clientExt, IExtension[] serverExt) throws Exception {
		s = new WSServer(PORT, ssl);
		s.extensions = serverExt;
		s.handleCloseFrame = serverHandleClose;
		s.traceCloseDetails = traceCloseDetails;
		s.waitForCloseMessage = serverWaitForCloseMessage;
		c = new WSClient(PORT, ssl);
		c.extensions = clientExt;
		c.handleCloseFrame = clientHandleClose;
		c.traceCloseDetails = traceCloseDetails;
		c.waitForCloseMessage = clientWaitForCloseMessage;
		s.start();
		c.start();
		c.waitForOpen(TIMEOUT);
		s.waitForOpen(TIMEOUT);
		s.session.getReadyFuture().sync(TIMEOUT);
		c.session.getReadyFuture().sync(TIMEOUT);
		c.waitForReady(TIMEOUT);
		s.waitForReady(TIMEOUT);
		c.resetDataLocks();
		s.resetDataLocks();
		assertEquals("CR|OP|RE|", c.getTrace());
		assertEquals("CR|OP|RE|", s.getTrace());
	}

	public void testWrite(boolean ssl) throws Exception {
		startClientServer(ssl);

		c.session.write(new BinaryFrame("ABC".getBytes()));
		s.waitForMsgRead(TIMEOUT);
		assertEquals("F(BINARY)|", s.getTrace());
		c.session.write(new TextFrame("ABC"));
		s.waitForMsgRead(TIMEOUT);
		assertEquals("F(TEXT)|", s.getTrace());
		c.session.write(new TextFrame(false, 0, "ABC"));
		s.waitForMsgRead(TIMEOUT);
		assertEquals("F(TEXT)|", s.getTrace());
		assertFalse(((Frame)s.msgRead).isFinalFragment());
		c.session.write(new ContinuationFrame(false, 0, "ABC".getBytes()));
		s.waitForMsgRead(TIMEOUT);
		assertEquals("F(CONTINUATION)|", s.getTrace());
		c.getTrace();
		c.session.write(new PingFrame(0, "".getBytes()));
		s.waitForMsgRead(TIMEOUT);
		c.waitForMsgRead(TIMEOUT);
		assertEquals("F(PING)|", s.getTrace());
		assertEquals("F(PONG)|", c.getTrace());
		c.session.write(new CloseFrame(0, "".getBytes()));
		s.waitForMsgRead(TIMEOUT);
		assertEquals("F(CLOSE)|", s.getTrace());
		c.session.write(new CloseFrame(0, "".getBytes()));
		waitFor(100);
		assertEquals("", s.getTrace());

		s.session.write(new byte[] {(byte)0x82, (byte)0x0a, (byte)'A'});
		s.session.write("BCDEFGHI".getBytes());
		waitFor(100);
		assertEquals("", c.getTrace());
		s.session.write("J".getBytes());
		c.waitForMsgRead(TIMEOUT);
		assertEquals("F(BINARY)|", c.getTrace());
		assertEquals("ABCDEFGHIJ", new String(((Frame)c.msgRead).getPayload()));
	}

	@Test
	public void testWriteSsl() throws Exception {
		testWrite(true);
	}

	@Test
	public void testWrite() throws Exception {
		testWrite(false);
	}

	public void testReadInvalidFrame(boolean ssl) throws Exception {
		startClientServer(ssl);
		c.traceExceptionDetails = true;
		s.traceCloseDetails = true;
		c.session.write(new BinaryFrame("ABC".getBytes()));
		s.waitForMsgRead(TIMEOUT);
		assertEquals("F(BINARY)|", s.getTrace());
		s.session.write(new byte[] {(byte)0x80, (byte)0x00});
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("F(CLOSE=1002:)|CL|EN|", s.getTrace());
		assertEquals("EX|Continuation frame outside fragmented message|CL|EN|", c.getTrace());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		startClientServer(ssl);
		c.traceExceptionDetails = true;
		s.traceCloseDetails = true;
		s.session.write(new byte[] {(byte)0x80, (byte)0x7f,-1,-1,-1,-1,-1,-1,-1,-1});
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("F(CLOSE=1002:)|CL|EN|", s.getTrace());
		assertEquals("EX|Negative payload length (-1)|CL|EN|", c.getTrace());
	}

	@Test
	public void testReadInvalidFrameSsl() throws Exception {
		testReadInvalidFrame(true);
	}

	@Test
	public void testReadInvalidFrame() throws Exception {
		testReadInvalidFrame(false);
	}

	public void testReadNonUtf8Frame(boolean ssl) throws Exception {
		startClientServer(ssl);
		c.traceExceptionDetails = true;
		s.traceCloseDetails = true;
		s.session.write(new TextFrame(true, 0, new byte[] {(byte) 0xdf, (byte) 0xdf}));
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("F(CLOSE=1007:)|CL|EN|", s.getTrace());
		assertEquals("EX|Invalid text frame payload: bytes are not UTF-8|CL|EN|", c.getTrace());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		startClientServer(ssl);
		c.traceExceptionDetails = true;
		s.traceCloseDetails = true;
		s.session.write(new CloseFrame(0, new byte[] {3, (byte)0xe8, (byte) 0xdf, (byte) 0xdf}));
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("F(CLOSE=1007:)|CL|EN|", s.getTrace());
		assertEquals("EX|Invalid close frame reason value: bytes are not UTF-8|CL|EN|", c.getTrace());
	}

	@Test
	public void testReadNonUtf8FrameSsl() throws Exception {
		testReadNonUtf8Frame(true);
	}

	@Test
	public void testReadNonUtf8Frame() throws Exception {
		testReadNonUtf8Frame(false);
	}

	String[] customizedFields(int count, int nameLen, int valueLen) {
		String[] fields = new String[count*2];
		byte[] a;

		for (int i=0; i<count; i++) {
			a = new byte[nameLen];
			Arrays.fill(a, (byte)'N');
			String name = i + new String(a);

			a = new byte[valueLen];
			Arrays.fill(a, (byte)'V');
			String value = i + new String(a);
			fields[i*2] = name.substring(0, nameLen);
			fields[i*2+1] = value.substring(0, valueLen);
		}
		return fields;
	}

	public void testMaxFrameLength(boolean ssl) throws Exception {
		startClientServer(ssl);
		s.traceCloseDetails = true;
		s.session.write(new BinaryFrame(true, 0, new byte[65536]));
		c.waitForMsgRead(TIMEOUT);
		assertEquals("F(BINARY)|", c.getTrace());
		assertEquals(65536, ((Frame)c.msgRead).getPayloadLength());
		s.session.write(new BinaryFrame(true, 0, new byte[65537]));
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("EX|CL|EN|", c.getTrace());
		assertEquals("F(CLOSE=1002:)|CL|EN|", s.getTrace().replace("EX|CL|EN|", "CL|EN|"));
		c.stop(TIMEOUT);

		c = new WSClient(PORT, ssl);
		c.maxPayloadLength = 512;
		c.start();
		c.waitForOpen(TIMEOUT);
		s.waitForOpen(TIMEOUT);
		s.session.getReadyFuture().sync(TIMEOUT);
		c.session.getReadyFuture().sync(TIMEOUT);
		c.waitForReady(TIMEOUT);
		s.waitForReady(TIMEOUT);
		c.resetDataLocks();
		s.resetDataLocks();
		assertEquals("CR|OP|RE|", c.getTrace());
		assertEquals("CR|OP|RE|", s.getTrace());
		s.session.write(new BinaryFrame(true, 0, new byte[512]));
		c.waitForMsgRead(TIMEOUT);
		assertEquals("F(BINARY)|", c.getTrace());
		assertEquals(512, ((Frame)c.msgRead).getPayloadLength());
		s.session.write(new BinaryFrame(true, 0, new byte[513]));
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("EX|CL|EN|", c.getTrace());
		assertEquals("F(CLOSE=1002:)|CL|EN|", s.getTrace());
		c.stop(TIMEOUT);

		c = new WSClient(PORT, ssl);
		c.traceExceptionDetails = true;
		s.customizedResponse = customizedFields(600, 10, 100);
		c.start();
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("CR|OP|EX|Handshake frame too large|CL|EN|", c.getTrace());
		if (ssl)
			assertEquals("CR|OP|RE|SSL_CLOSED_WITHOUT_CLOSE_NOTIFY|CL|EN|", s.getTrace());
		else
			assertEquals("CR|OP|RE|CL|EN|", s.getTrace().replace("EX|CL|EN|", "CL|EN|"));
		c.stop(TIMEOUT);
		s.customizedResponse = null;

		String[] customizedFields = customizedFields(100, 10, 100);
		c = new WSClient(PORT, ssl);
		c.customizedRequest = customizedFields;
		c.start();
		c.waitForReady(TIMEOUT);
		s.waitForReady(TIMEOUT);
		int expectedSize = 11553;
		if (!ssl)
			assertEquals(expectedSize, s.session.getReadBytes());
		c.session.close();
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		c.stop(TIMEOUT);

		c = new WSClient(PORT, ssl);
		c.customizedRequest = customizedFields;
		s.maxHandshakeLength = expectedSize;
		c.start();
		c.waitForReady(TIMEOUT);
		s.waitForReady(TIMEOUT);
		c.stop(TIMEOUT);
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		c.getTrace();
		s.getTrace();

		c = new WSClient(PORT, ssl);
		c.customizedRequest = customizedFields;
		s.maxHandshakeLength = expectedSize-1;
		s.traceExceptionDetails = true;
		c.traceExceptionDetails = true;
		c.start();
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("CR|OP|EX|Invalid websocket response status: 413|CL|EN|", c.getTrace());
		assertEquals("CR|OP|EX|Handshake frame too large|CL|EN|", s.getTrace());
		c.stop(TIMEOUT);

		c = new WSClient(PORT, ssl);
		c.customizedRequest = customizedFields(1, 100, 64000);
		s.maxHandshakeLength = -1;
		s.traceExceptionDetails = true;
		c.traceExceptionDetails = true;
		c.start();
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		if (ssl) {
			String trace = s.getTrace();
			assertTrue(trace.startsWith("CR|OP|EX|Buffer allocation failure: maximum capacity ("));
			assertTrue(trace.endsWith("|CL|EN|"));
			assertTrue(c.getTrace().endsWith("|CL|EN|"));
		}
		else {
			assertTrue(c.getTrace().endsWith("|CL|EN|"));
			assertEquals("CR|OP|EX|Buffer allocation failure: maximum capacity (8192) reached|CL|EN|", s.getTrace());
		}
		c.stop(TIMEOUT);

	}

	@Test
	public void testMaxFrameLengthSsl() throws Exception {
		testMaxFrameLength(true);
	}

	@Test
	public void testMaxFrameLength() throws Exception {
		testMaxFrameLength(false);
	}

	@Test
	public void testGetWebSocketHandler() throws Exception {
		Handler h = new Handler("Handler1");

		WebSocketSession s = new WebSocketSession(h, true);
		assertTrue(h == s.getWebSocketHandler());
		s = new WebSocketSession("Name1", h, true);
		assertTrue(h == s.getWebSocketHandler());

		SSLWebSocketSession s2 = new SSLWebSocketSession("Name1", null, h, true);
		assertTrue(h == s2.getWebSocketHandler());
		s2 = new SSLWebSocketSession((SocketAddress)null, h, true);
		assertTrue(h == s2.getWebSocketHandler());
		s2 = new SSLWebSocketSession("Name1", h, true);
		assertTrue(h == s2.getWebSocketHandler());
		s2 = new SSLWebSocketSession(h, true);
		assertTrue(h == s2.getWebSocketHandler());
	}

	public void testTimer(boolean ssl) throws Exception {
		s = new WSServer(PORT, ssl);
		c = new WSClient(PORT, ssl);
		c.timer = new TestTimer();
		s.start();
		c.start();
		c.waitForOpen(TIMEOUT);
		s.waitForOpen(TIMEOUT);
		s.session.getReadyFuture().sync(TIMEOUT);
		c.session.getReadyFuture().sync(TIMEOUT);
		c.waitForReady(TIMEOUT);
		s.waitForReady(TIMEOUT);
		c.resetDataLocks();
		s.resetDataLocks();
		assertEquals("CR|OP|RE|", c.getTrace());
		assertEquals("CR|OP|RE|", s.getTrace());

		c.session.getTimer().scheduleEvent("T1", 300);
		waitFor(250);
		assertEquals("", c.getTrace());
		waitFor(350);
		assertEquals("TE(T1)|", c.getTrace());

		c.session.getTimer().scheduleTask(new Runnable() {

			@Override
			public void run() {
			}

			@Override
			public String toString() {
				return "T2";
			}

		}, 300, true);
		waitFor(250);
		assertEquals("", c.getTrace());
		waitFor(350);
		assertEquals("TT(T2)|", c.getTrace());

	}

	@Test
	public void testTimer() throws Exception {
		testTimer(false);
	}

	@Test
	public void testTimerSsl() throws Exception {
		testTimer(true);
	}

	IExtension[] extensions(IExtension... extensions) {
		return extensions;
	}

	void assertEncoders(String expected, WSServer s) {
		StringBuilder sb = new StringBuilder();

		for (Object key: s.session.getCodecPipeline().encoderKeys()) {
			sb.append(key);
			sb.append('|');
		}
		assertEquals(expected, sb.toString());
	}

	void assertDecoders(String expected, WSServer s) {
		StringBuilder sb = new StringBuilder();

		for (Object key: s.session.getCodecPipeline().decoderKeys()) {
			sb.append(key);
			sb.append('|');
		}
		assertEquals(expected, sb.toString());
	}

	void assertPipeline(String exencoder, String exdecoder, WSServer c, WSServer s) {
		assertEncoders("ws-encoder|" + exencoder, s);
		assertEncoders("ws-encoder|" + exencoder, c);
		assertDecoders("ws-decoder|" + exdecoder + "ws-utf8-validator|", s);
		assertDecoders("ws-decoder|" + exdecoder + "ws-utf8-validator|", c);
	}

	void assertExtensions(boolean ssl, IExtension[] cExt, IExtension[] sExt, String expEnc, String expDec) throws Exception {
		TextFrame f;

		startClientServer(ssl, cExt, sExt);
		c.session.write(new TextFrame(true, 0, "ABCDEF"));
		s.waitForMsgRead(TIMEOUT);
		f = (TextFrame)s.msgRead;
		assertEquals("", c.getTrace());
		assertEquals("F(TEXT)|", s.getTrace());
		assertEquals("ABCDEF", f.getText());
		assertEquals(0, f.getRsvBits());
		assertPipeline(expEnc, expDec, c, s);
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);
	}

	void testExtensions(boolean ssl) throws Exception {
		String USER1 = "USER1";
		IExtension e1A = new TestExtension("ext1", 'A', 4);
		IExtension e1B = new TestExtension("ext1", 'B', 4);
		IExtension e2C = new TestExtension("ext2", 'C', 4, true);
		IExtension e3D = new TestExtension("ext3", USER1, 'D', 4, true);
		IExtension e1D = new TestExtension("ext1", USER1, 'E', 4, true);

		assertExtensions(ssl, extensions(e1A), extensions(e1A), "ex-encoderA|", "ex-decoderA|");
		assertExtensions(ssl, extensions(e1A), null, "", "");
		assertExtensions(ssl, null, extensions(e1A), "", "");
		assertExtensions(ssl, extensions(e1A,e1B), extensions(e1A,e1B), "ex-encoderA|", "ex-decoderA|");
		assertExtensions(ssl, extensions(e1B,e1A), extensions(e1A,e1B), "ex-encoderB|", "ex-decoderB|");
		assertExtensions(ssl, extensions(e1A,e1B,e2C), extensions(e1A,e1B,e2C),
				"ex-encoderA|", "ex-decoderA|");
		assertExtensions(ssl, extensions(e1A,e1B,e3D), extensions(e1A,e1B,e3D),
				"ex-encoderD|ex-encoderA|", "ex-decoderD|ex-decoderA|");
		assertExtensions(ssl, extensions(e1A,e1D), extensions(e1A,e1D),
				"ex-encoderA|", "ex-decoderA|");
	}

	@Test
	public void testExtensions() throws Exception {
		testExtensions(false);
	}

	@Test
	public void testExtensionsSsl() throws Exception {
		testExtensions(true);
	}

	IDecoder<?,?> sdecoder,cdecoder;
	IEncoder<?,?> sencoder,cencoder;
	ZlibDecoder sd,cd;
	ZlibEncoder se,ce;

	void initCodecs() {
		sdecoder = (IDecoder<?, ?>) s.session.getCodecPipeline().get(PerMessageDeflateExtension.PERMESSAGE_DEFLATE_DECODER);
		sencoder = (IEncoder<?, ?>) s.session.getCodecPipeline().get(PerMessageDeflateExtension.PERMESSAGE_DEFLATE_ENCODER);
		cdecoder = (IDecoder<?, ?>) c.session.getCodecPipeline().get(PerMessageDeflateExtension.PERMESSAGE_DEFLATE_DECODER);
		cencoder = (IEncoder<?, ?>) c.session.getCodecPipeline().get(PerMessageDeflateExtension.PERMESSAGE_DEFLATE_ENCODER);
	}

	void initZlibCodecs() throws Exception {
		sd = DeflateCodecTest.getZlibDecoder(sdecoder);
		se = DeflateCodecTest.getZlibEncoder(sencoder);
		cd = DeflateCodecTest.getZlibDecoder(cdecoder);
		ce = DeflateCodecTest.getZlibEncoder(cencoder);
	}

	void assertNullZlibCodecs() throws Exception {
		assertNull(DeflateCodecTest.getZlibDecoder(sdecoder));
		assertNull(DeflateCodecTest.getZlibEncoder(sencoder));
		assertNull(DeflateCodecTest.getZlibDecoder(cdecoder));
		assertNull(DeflateCodecTest.getZlibEncoder(cencoder));
	}

	void assertNotNullZlibCodecs() throws Exception {
		assertNotNull(DeflateCodecTest.getZlibDecoder(sdecoder));
		assertNotNull(DeflateCodecTest.getZlibEncoder(sencoder));
		assertNotNull(DeflateCodecTest.getZlibDecoder(cdecoder));
		assertNotNull(DeflateCodecTest.getZlibEncoder(cencoder));
	}

	void assertEqualsZlibCodecs() throws Exception {
		assertTrue(sd == DeflateCodecTest.getZlibDecoder(sdecoder));
		assertTrue(se == DeflateCodecTest.getZlibEncoder(sencoder));
		assertTrue(cd == DeflateCodecTest.getZlibDecoder(cdecoder));
		assertTrue(ce == DeflateCodecTest.getZlibEncoder(cencoder));
	}

	void testCompression(boolean ssl) throws Exception {
		String text = "ABCDEFGHIJKLMNOP";
		byte[] binary = new byte[1000];

		for (int i=0; i<binary.length; ++i) {
			if (i % 10 == 0) {
				binary[i] = (byte) i;
			}
		}

		startClientServer(ssl, extensions(new PerMessageDeflateExtension(6,NoContext.REQUIRED, NoContext.REQUIRED)), extensions(new PerMessageDeflateExtension()));
		initCodecs();
		c.session.write(new TextFrame(true, 0, text));
		s.waitForMsgRead(TIMEOUT);
		s.session.write(new BinaryFrame(binary));
		c.waitForMsgRead(TIMEOUT);
		assertNullZlibCodecs();
		for (int i=0; i<100; ++i) {
			c.session.write(new TextFrame(true, 0, text));
			s.session.write(new BinaryFrame(binary));
			s.waitForMsgRead(TIMEOUT);
			c.waitForMsgRead(TIMEOUT);
			assertEquals(text, ((TextFrame)s.msgRead).getText());
			assertArrayEquals(binary, ((Frame)c.msgRead).getPayload());
			assertNullZlibCodecs();

			s.session.write(new BinaryFrame(false, 0, binary));
			c.session.write(new BinaryFrame(false, 0, binary));
			s.waitForMsgRead(TIMEOUT);
			c.waitForMsgRead(TIMEOUT);
			assertArrayEquals(binary, ((Frame)c.msgRead).getPayload());
			assertArrayEquals(binary, ((Frame)s.msgRead).getPayload());
			assertNotNullZlibCodecs();
			initZlibCodecs();
			s.session.write(new PongFrame(0, new byte[100]));
			c.waitForMsgRead(TIMEOUT);
			c.session.write(new PingFrame());
			s.waitForMsgRead(TIMEOUT);
			c.waitForMsgRead(TIMEOUT);
			s.session.write(new ContinuationFrame(false, 0, binary));
			c.session.write(new ContinuationFrame(false, 0, binary));
			s.waitForMsgRead(TIMEOUT);
			c.waitForMsgRead(TIMEOUT);
			assertArrayEquals(binary, ((Frame)c.msgRead).getPayload());
			assertArrayEquals(binary, ((Frame)s.msgRead).getPayload());
			assertEqualsZlibCodecs();
			s.session.write(new ContinuationFrame(true, 0, binary));
			c.session.write(new ContinuationFrame(true, 0, binary));
			s.waitForMsgRead(TIMEOUT);
			c.waitForMsgRead(TIMEOUT);
			assertArrayEquals(binary, ((Frame)c.msgRead).getPayload());
			assertArrayEquals(binary, ((Frame)s.msgRead).getPayload());
			assertNullZlibCodecs();
		}
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);
		assertNullZlibCodecs();

		startClientServer(ssl, extensions(new PerMessageDeflateExtension(6,NoContext.FORBIDDEN, NoContext.FORBIDDEN)), extensions(new PerMessageDeflateExtension()));
		initCodecs();
		c.session.write(new TextFrame(true, 0, text));
		s.waitForMsgRead(TIMEOUT);
		s.session.write(new BinaryFrame(binary));
		c.waitForMsgRead(TIMEOUT);
		assertNotNullZlibCodecs();
		initZlibCodecs();
		for (int i=0; i<100; ++i) {
			c.session.write(new TextFrame(true, 0, text));
			s.session.write(new BinaryFrame(binary));
			s.waitForMsgRead(TIMEOUT);
			c.waitForMsgRead(TIMEOUT);
			assertEquals(text, ((TextFrame)s.msgRead).getText());
			assertArrayEquals(binary, ((BinaryFrame)c.msgRead).getPayload());
			assertEqualsZlibCodecs();
		}
		assertTrue(!sd.isFinished());
		assertTrue(!cd.isFinished());
		assertTrue(!se.isFinished());
		assertTrue(!ce.isFinished());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);
		assertTrue(sd.isFinished());
		assertTrue(cd.isFinished());
		assertTrue(se.isFinished());
		assertTrue(ce.isFinished());

		startClientServer(ssl, extensions(new PerMessageDeflateExtension(6,NoContext.REQUIRED, NoContext.FORBIDDEN)), extensions(new PerMessageDeflateExtension()));
		for (int i=0; i<100; ++i) {
			c.session.write(new TextFrame(true, 0, text));
			s.session.write(new BinaryFrame(binary));
			s.waitForMsgRead(TIMEOUT);
			c.waitForMsgRead(TIMEOUT);
			assertEquals(text, ((TextFrame)s.msgRead).getText());
			assertArrayEquals(binary, ((BinaryFrame)c.msgRead).getPayload());
		}
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		startClientServer(ssl, extensions(new PerMessageDeflateExtension(6,NoContext.FORBIDDEN, NoContext.REQUIRED)), extensions(new PerMessageDeflateExtension()));
		for (int i=0; i<100; ++i) {
			c.session.write(new TextFrame(true, 0, text));
			s.session.write(new BinaryFrame(binary));
			s.waitForMsgRead(TIMEOUT);
			c.waitForMsgRead(TIMEOUT);
			assertEquals(text, ((TextFrame)s.msgRead).getText());
			assertArrayEquals(binary, ((BinaryFrame)c.msgRead).getPayload());
		}
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

	}

	@Test
	public void testCompression() throws Exception {
		testCompression(false);
	}

	@Test
	public void testCompressionSsl() throws Exception {
		testCompression(true);
	}

	void assertNoCompression(boolean ssl, boolean invalid, int encoders, int decoders, NoContext... noContext) throws Exception {
		s = new WSServer(PORT, ssl);
		s.extensions = extensions(new PerMessageDeflateExtension(
				6,
				noContext[2],
				noContext[3]
		));
		c = new WSClient(PORT, ssl);
		c.extensions = extensions(new PerMessageDeflateExtension(
				6,
				noContext[0],
				noContext[1]
		));
		s.start();
		c.start();
		c.waitForOpen(TIMEOUT);
		s.waitForOpen(TIMEOUT);
		s.session.getReadyFuture().sync(TIMEOUT);
		s.waitForReady(TIMEOUT);
		s.resetDataLocks();
		assertEquals("CR|OP|RE|", s.getTrace().replace("RE|CL|EN|", "RE|"));
		assertEquals(encoders, s.session.getCodecPipeline().encoderKeys().size());
		assertEquals(decoders, s.session.getCodecPipeline().decoderKeys().size());

		try {
			c.session.getReadyFuture().sync(TIMEOUT);
			if (invalid) {
				fail();
			}
			c.waitForReady(TIMEOUT);
			c.resetDataLocks();
			assertEquals("CR|OP|RE|", c.getTrace());
			assertEquals(encoders, c.session.getCodecPipeline().encoderKeys().size());
			assertEquals(decoders, c.session.getCodecPipeline().decoderKeys().size());
		}
		catch (ExecutionException e) {
			if (!invalid) {
				throw e;
			}
		}
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

	}

	void testNoCompression(boolean ssl) throws Exception {
		assertNoCompression(ssl, false, 2, 3, NoContext.FORBIDDEN, NoContext.FORBIDDEN, NoContext.FORBIDDEN, NoContext.FORBIDDEN);
		assertNoCompression(ssl, false, 1, 2, NoContext.REQUIRED, NoContext.REQUIRED, NoContext.FORBIDDEN, NoContext.FORBIDDEN);
		assertNoCompression(ssl, false, 1, 2, NoContext.REQUIRED, NoContext.FORBIDDEN, NoContext.FORBIDDEN, NoContext.FORBIDDEN);
		assertNoCompression(ssl, false, 1, 2, NoContext.FORBIDDEN, NoContext.REQUIRED, NoContext.FORBIDDEN, NoContext.FORBIDDEN);
		assertNoCompression(ssl, true, 2, 3, NoContext.FORBIDDEN, NoContext.FORBIDDEN, NoContext.REQUIRED, NoContext.REQUIRED);
		assertNoCompression(ssl, true, 2, 3, NoContext.FORBIDDEN, NoContext.FORBIDDEN, NoContext.REQUIRED, NoContext.FORBIDDEN);
		assertNoCompression(ssl, true, 2, 3, NoContext.FORBIDDEN, NoContext.FORBIDDEN, NoContext.FORBIDDEN, NoContext.REQUIRED);
	}

	@Test
	public void testNoCompression() throws Exception {
		testNoCompression(false);
	}

	@Test
	public void testNoCompressionSsl() throws Exception {
		testNoCompression(true);
	}

	void CompressionWithMoreExtensions(boolean ssl, int encoders, int decoders, IExtension[] cli, IExtension[] srv) throws Exception {
		startClientServer(ssl, cli, srv);
		assertEquals(encoders, s.session.getCodecPipeline().encoderKeys().size());
		assertEquals(encoders, c.session.getCodecPipeline().encoderKeys().size());
		assertEquals(decoders, s.session.getCodecPipeline().decoderKeys().size());
		assertEquals(decoders, c.session.getCodecPipeline().decoderKeys().size());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

	}

	IExtension[] extensions(NoContext... noContexts) {
		IExtension[] extensions = new IExtension[noContexts.length/2];

		for (int i=0; i<extensions.length; ++i) {
			extensions[i] = new PerMessageDeflateExtension(
					6,
					noContexts[i*2],
					noContexts[i*2+1]);
		}
		return extensions;
	}

	void testCompressionWithMoreExtensions(boolean ssl) throws Exception {
		CompressionWithMoreExtensions(ssl, 1, 2,
				extensions(NoContext.REQUIRED, NoContext.REQUIRED),
				extensions(NoContext.FORBIDDEN, NoContext.FORBIDDEN));
		CompressionWithMoreExtensions(ssl, 2, 3,
				extensions(NoContext.REQUIRED, NoContext.REQUIRED),
				extensions(NoContext.FORBIDDEN, NoContext.FORBIDDEN, NoContext.REQUIRED, NoContext.REQUIRED));
		CompressionWithMoreExtensions(ssl, 2, 3,
				extensions(NoContext.REQUIRED, NoContext.REQUIRED, NoContext.FORBIDDEN, NoContext.FORBIDDEN),
				extensions(NoContext.FORBIDDEN, NoContext.FORBIDDEN));
	}

	@Test
	public void testCompressionWithMoreExtensions() throws Exception {
		testCompressionWithMoreExtensions(false);
	}

	@Test
	public void testCompressionWithMoreExtensionsSsl() throws Exception {
		testCompressionWithMoreExtensions(true);
	}

	void testHandleCloseFrame(boolean ssl) throws Exception {
		traceCloseDetails = true;
		startClientServer(ssl);
		c.session.write(new TextFrame("ABC"));
		s.waitForMsgRead(TIMEOUT);
		assertEquals("F(TEXT)|", s.getTrace());
		c.session.write(new CloseFrame(1111));
		s.waitForMsgRead(TIMEOUT);
		assertEquals("F(CLOSE=1111:)|", s.getTrace());
		s.session.write(new PongFrame());
		c.waitForMsgRead(TIMEOUT);
		assertEquals("F(PONG)|", c.getTrace());
		((IWebSocketSession)s.session).close(1112);
		s.waitForEnding(TIMEOUT);
		c.waitForEnding(TIMEOUT);
		assertEquals("F(CLOSE=1112:)|CL|EN|", c.getTrace());
		assertEquals("CL|EN|", s.getTrace());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		serverHandleClose = true;
		clientHandleClose = true;
		startClientServer(ssl);
		c.session.write(new TextFrame("ABC"));
		s.waitForMsgRead(TIMEOUT);
		assertEquals("F(TEXT)|", s.getTrace());
		c.session.write(new CloseFrame(1111));
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("CL|EN|", c.getTrace());
		assertEquals("CL|EN|", s.getTrace());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		serverHandleClose = true;
		clientHandleClose = false;
		startClientServer(ssl);
		c.session.write(new CloseFrame(1111, "Error"));
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("F(CLOSE=1111:Error)|CL|EN|", c.getTrace());
		assertEquals("CL|EN|", s.getTrace());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		serverHandleClose = true;
		clientHandleClose = false;
		clientWaitForCloseMessage = true;
		startClientServer(ssl);
		((IWebSocketSession)c.session).close(1112);
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("F(CLOSE=1112:)|CL|EN|", c.getTrace());
		assertEquals("CL|EN|", s.getTrace());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		serverHandleClose = true;
		clientHandleClose = false;
		startClientServer(ssl);
		((IWebSocketSession)c.session).close(1113, "Error2");
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("F(CLOSE=1113:Error2)|CL|EN|", c.getTrace());
		assertEquals("CL|EN|", s.getTrace());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		serverHandleClose = true;
		clientHandleClose = false;
		startClientServer(ssl);
		((IWebSocketSession)c.session).close(-1);
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("F(CLOSE=-1:)|CL|EN|", c.getTrace());
		assertEquals("CL|EN|", s.getTrace());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		serverHandleClose = true;
		clientHandleClose = false;
		clientWaitForCloseMessage = true;
		startClientServer(ssl);
		((IWebSocketSession)c.session).close();
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("CL|EN|", c.getTrace());
		assertEquals("CL|EN|", s.getTrace());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		serverHandleClose = true;
		clientHandleClose = false;
		startClientServer(ssl);
		c.loop.execute(new Runnable() {
			@Override
			public void run() {
				((IWebSocketSession)c.session).close(1113, "Error2");
			}
		});
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("F(CLOSE=1113:Error2)|CL|EN|", c.getTrace());
		assertEquals("CL|EN|", s.getTrace());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

	}

	@Test
	public void testHandleCloseFrame() throws Exception {
		testHandleCloseFrame(false);
	}

	@Test
	public void testHandleCloseFrameSsl() throws Exception {
		testHandleCloseFrame(true);
	}

	void testFrameAggregation(boolean ssl) throws Exception {
		traceCloseDetails = true;
		startClientServer(ssl);
		s.session.getCodecPipeline().add("1", new FrameAggregator(100));

		c.session.write(new TextFrame("ABC"));
		s.waitForMsgRead(TIMEOUT);
		assertEquals("F(TEXT)|",s.getTrace());
		assertEquals("ABC", ((TextFrame)s.msgRead).getText());

		c.session.write(new TextFrame(false, 0, "BCD"));
		waitFor(100);
		assertEquals("",s.getTrace());
		c.session.write(new PingFrame());
		s.waitForMsgRead(TIMEOUT);
		assertEquals("F(PING)|",s.getTrace());
		c.session.write(new ContinuationFrame(false, 0, "EFG"));
		waitFor(100);
		assertEquals("",s.getTrace());
		c.session.write(new ContinuationFrame("HIJ"));
		s.waitForMsgRead(TIMEOUT);
		assertEquals("F(TEXT)|",s.getTrace());
		assertEquals("BCDEFGHIJ", ((TextFrame)s.msgRead).getText());

		c.session.write(new BinaryFrame(false, 0, new byte[99]));
		waitFor(100);
		assertEquals("",s.getTrace());
		c.session.write(new ContinuationFrame(false, 0, new byte[2]));
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("F(PONG)|F(CLOSE=1009:)|CL|EN|",c.getTrace());
		assertEquals("EX|CL|EN|",s.getTrace());
	}

	@Test
	public void testFrameAggregation() throws Exception {
		testFrameAggregation(false);
	}

	@Test
	public void testFrameAggregationSsl() throws Exception {
		testFrameAggregation(true);
	}

	void assertAllocations(DefaultAllocatorMetric m, int allocated, int allocating, int released, int releasing) {
		assertEquals("allocated", allocated, m.getAllocatedCount());
		assertEquals("allocating", allocating, m.getAllocatingCount());
		assertEquals("released",released, m.getReleasedCount());
		assertEquals("releasing", releasing, m.getReleasingCount());
	}

	void testBufferAllocation(boolean ssl) throws Exception {
		DefaultAllocatorMetric sm = new DefaultAllocatorMetric();
		DefaultAllocatorMetric cm = new DefaultAllocatorMetric();
		s = new WSServer(PORT, ssl);
		s.allocator = new DefaultAllocator(false, sm);
		s.optimieDataCopying = false;
		c = new WSClient(PORT, ssl);
		c.allocator = new DefaultAllocator(false, cm);
		c.optimieDataCopying = false;
		s.start();
		c.start();
		c.waitForReady(TIMEOUT);
		s.waitForReady(TIMEOUT);
		c.resetDataLocks();
		s.resetDataLocks();

		int inc = ssl ? 4 : 0;
		assertAllocations(sm,3+inc,3+inc,0,0);
		assertAllocations(cm,3+inc,3+inc,0,0);
		for (int i=0; i<100; ++i) {
			c.session.write(new TextFrame("ABCD")).sync(TIMEOUT);
		}
		waitFor(100);
		assertAllocations(sm,3+inc,3+inc,0,0);
		assertAllocations(cm,103+inc,103+inc,0,0);
		c.session.close();
		s.waitForEnding(TIMEOUT);
		c.waitForEnding(TIMEOUT);
		waitFor(100);
		assertAllocations(cm,103+inc,103+inc,0,0);
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		sm = new DefaultAllocatorMetric();
		cm = new DefaultAllocatorMetric();
		s = new WSServer(PORT, ssl);
		s.allocator = new CachingAllocator(false, sm);
		s.optimieDataCopying = false;
		c = new WSClient(PORT, ssl);
		c.allocator = new CachingAllocator(false, cm);
		c.optimieDataCopying = false;
		s.start();
		c.start();
		c.waitForReady(TIMEOUT);
		s.waitForReady(TIMEOUT);
		c.resetDataLocks();
		s.resetDataLocks();

		assertAllocations(sm,3+inc,3+inc,0,0);
		assertAllocations(cm,3+inc,3+inc,0,0);
		for (int i=0; i<100; ++i) {
			c.session.write(new TextFrame("ABCD")).sync(TIMEOUT);
		}
		waitFor(100);
		assertAllocations(sm,3+inc,3+inc,0,100);
		assertAllocations(cm,103+inc,103+inc,0,0);
		c.session.close();
		s.waitForEnding(TIMEOUT);
		c.waitForEnding(TIMEOUT);
		waitFor(100);
		assertAllocations(sm,3+inc,3+inc,2+inc,102+inc);
		assertAllocations(cm,103+inc,103+inc,2+inc,2+inc);
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		sm = new DefaultAllocatorMetric();
		cm = new DefaultAllocatorMetric();
		s = new WSServer(PORT, ssl);
		s.allocator = new CachingAllocator(false, sm);
		s.optimieDataCopying = true;
		c = new WSClient(PORT, ssl);
		c.allocator = new CachingAllocator(false, cm);
		c.optimieDataCopying = true;
		s.start();
		c.start();
		c.waitForReady(TIMEOUT);
		s.waitForReady(TIMEOUT);
		c.resetDataLocks();
		s.resetDataLocks();
		waitFor(200);

		long allocated = sm.getAllocatedCount();
		if (ssl) {
			assertEquals(allocated, sm.getAllocatedCount());
			assertEquals(sm.getAllocatingCount(), sm.getReleasingCount());
			assertEquals(sm.getReleasedCount(), sm.getReleasingCount());
			assertEquals(cm.getAllocatingCount(), cm.getReleasingCount());
			assertEquals(cm.getReleasedCount(), cm.getReleasingCount());
		}
		else {
			assertAllocations(sm,2,2,2,2);
			assertAllocations(cm,2,2,2,2);
		}
		for (int i=0; i<100; ++i) {
			c.session.write(new TextFrame("ABCD")).sync(TIMEOUT);
			waitFor(20);
		}
		waitFor(100);
		if (ssl) {
			assertEquals(allocated, sm.getAllocatedCount());
			assertEquals(sm.getAllocatingCount(), sm.getReleasingCount());
			assertEquals(sm.getReleasedCount(), sm.getReleasingCount());
			assertEquals(cm.getAllocatingCount(), cm.getReleasingCount());
			assertEquals(cm.getReleasedCount(), cm.getReleasingCount());
		}
		else {
			assertAllocations(sm,2,102,102,102);
			assertAllocations(cm,3,102,102,102);
		}
		c.session.close();
		s.waitForEnding(TIMEOUT);
		c.waitForEnding(TIMEOUT);
		waitFor(100);
		if (ssl) {
			assertEquals(allocated, sm.getAllocatedCount());
			assertEquals(sm.getAllocatingCount(), sm.getReleasingCount());
			assertEquals(sm.getReleasedCount(), sm.getReleasingCount());
			assertEquals(cm.getAllocatingCount(), cm.getReleasingCount());
			assertEquals(cm.getReleasedCount(), cm.getReleasingCount());
		}
		else {
			assertAllocations(sm,2,103,103,103);
			assertAllocations(cm,3,103,103,103);
		}
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

	}

	@Test
	public void testBufferAllocation() throws Exception {
		testBufferAllocation(false);
	}

	@Test
	public void testBufferAllocationSsl() throws Exception {
		testBufferAllocation(true);
	}

	void testHandshakeInfo(boolean ssl) throws Exception {
		startClientServer(ssl);
		IHandshaker ci = ((IWebSocketSession)c.session).getHandshaker();
		IHandshaker si = ((IWebSocketSession)s.session).getHandshaker();
		assertTrue(ci.isClientMode());
		assertFalse(si.isClientMode());
		assertNull(ci.getSubProtocol());
		assertNull(si.getSubProtocol());
		assertTrue(ci.isFinished());
		assertTrue(si.isFinished());
		assertArrayEquals(new String[0], ci.getExtensionNames());
		assertArrayEquals(new String[0], si.getExtensionNames());
		assertEquals((ssl ? "wss" : "ws") + "://127.0.0.1:7777/", si.getUri().toString());
		assertEquals((ssl ? "wss" : "ws") + "://127.0.0.1:7777/", ci.getUri().toString());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		startClientServer(ssl, new IExtension[] {new PerMessageDeflateExtension()}, new IExtension[] {new PerMessageDeflateExtension()});
		ci = ((IWebSocketSession)c.session).getHandshaker();
		si = ((IWebSocketSession)s.session).getHandshaker();
		assertArrayEquals(new String[] {"permessage-deflate"}, ci.getExtensionNames());
		assertArrayEquals(new String[] {"permessage-deflate"}, si.getExtensionNames());
		c.stop(TIMEOUT);
		s.stop(TIMEOUT);

		s = new WSServer(PORT, ssl);
		s.subProtocols = new String[] {"proto1", "proto2"};
		c = new WSClient(PORT, ssl);
		c.subProtocols = new String[] {"proto2"};
		c.requestUri = new URI((ssl ? "wss" : "ws") + "://127.0.0.1:7777/req?55");
		s.start();
		c.start();
		c.waitForReady(TIMEOUT);
		s.waitForReady(TIMEOUT);
		ci = ((IWebSocketSession)c.session).getHandshaker();
		si = ((IWebSocketSession)s.session).getHandshaker();
		assertEquals("proto2", ci.getSubProtocol());
		assertEquals("proto2", si.getSubProtocol());
		assertEquals((ssl ? "wss" : "ws") + "://127.0.0.1:7777/req?55", si.getUri().toString());
		assertEquals((ssl ? "wss" : "ws") + "://127.0.0.1:7777/req?55", ci.getUri().toString());

	}

	@Test
	public void testHandshakeInfo() throws Exception {
		testHandshakeInfo(false);
	}

	@Test
	public void testHandshakeInfoSsl() throws Exception {
		testHandshakeInfo(true);
	}

	void testProxyConnection(boolean ssl) throws Exception {
		//clear proxy
		p = new HttpProxy(PORT+1);
		p.start(TIMEOUT);
		s = new WSServer(PORT, ssl);
		s.start();
		c = new WSClient(PORT+1, ssl) {

			@Override
			StreamSession createSession(IWebSocketHandler handler) throws Exception {
				StreamSession s = super.createSession(handler);

				s.getPipeline().add("proxy", new StreamSession(new HttpProxyHandler(new URI("http://127.0.0.1:" + PORT))));
				return s;
			}
		};
		c.start();
		c.waitForReady(TIMEOUT);
		s.waitForReady(TIMEOUT);
		assertEquals("CR|OP|RE|", c.getTrace());
		assertEquals("CR|OP|RE|", s.getTrace());
		c.session.write(new TextFrame("Hello!")).sync(TIMEOUT);
		s.waitForMsgRead(TIMEOUT);
		assertEquals("F(TEXT)|", s.getTrace());
		((IWebSocketSession)c.session).close(CloseFrame.NORMAL);
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("CL|EN|", c.getTrace());
		assertEquals("F(CLOSE)|CL|EN|", s.getTrace());
		c.stop(TIMEOUT);
		p.stop(TIMEOUT);

		//secure proxy
		p = new HttpProxy(PORT+1);
		p.start(TIMEOUT, true);
		final DefaultSessionConfig config = new DefaultSessionConfig() {
			@Override
			public SSLEngine createSSLEngine(boolean clientMode) throws SSLEngineCreateException {
				return Server.createSSLEngine(null, clientMode);
			}
		};
		config.setWaitForInboundCloseMessage(true);
		c = new WSClient(PORT+1, ssl) {

			@Override
			StreamSession createSession(IWebSocketHandler handler) throws Exception {
				StreamSession s = super.createSession(handler);

				s.getPipeline().add("proxy", new SSLSession(new HttpProxyHandler(new URI("http://127.0.0.1:" + PORT), config), true));
				return s;
			}
		};
		s.resetDataLocks();
		c.start();
		c.waitForReady(TIMEOUT);
		s.waitForReady(TIMEOUT);
		assertEquals("CR|OP|RE|", c.getTrace());
		assertEquals("CR|OP|RE|", s.getTrace());
		c.session.write(new TextFrame("Hello!")).sync(TIMEOUT);
		s.waitForMsgRead(TIMEOUT);
		assertEquals("F(TEXT)|", s.getTrace());
		((IWebSocketSession)c.session).close(CloseFrame.NORMAL);
		c.waitForEnding(TIMEOUT);
		s.waitForEnding(TIMEOUT);
		assertEquals("CL|EN|", c.getTrace());
		assertEquals("F(CLOSE)|CL|EN|", s.getTrace());
	}

	@Test
	public void testProxyConnection() throws Exception {
		testProxyConnection(false);
	}

	@Test
	public void testProxyConnectionSsl() throws Exception {
		testProxyConnection(true);
	}

	static class Handler extends TestHandler implements IWebSocketHandler {

		Handler(String name) {
			super(name);
		}

		@Override
		public IWebSocketSessionConfig getConfig() {
			return new DefaultWebSocketSessionConfig();
		}
	}
}


text:
/**
 *
 */
package com.allogy.app.xml.messages;

/**
 * @author pramod
 *
 */
public class ListMessage extends Message {
  /**
   * Exact names of the xml tags for the xxx information
   * access the elements using the class indexing contants.*/
  public static final String[] xmlFields = new String[]{"list","id","title",
                                                        "tag"
                                                         };
  public static final int XML_FIELDS_ROOT_INDEX = 0;
  public static final int XML_FIELDS_ROOT_CHILD_ID = 1;
  public static final int XML_FIELDS_ROOT_CHILD_TITLE = 2;
  public static final int XML_FIELDS_ROOT_CHILD_TAG = 3;

  private String id;
  private String tag;
  /**
   *
   */
  public ListMessage() {
    // TODO Auto-generated constructor stub
  }

  /* (non-Javadoc)
   * @see com.ist.Message#copy()
   */
  @Override
  public Message copy() {
    // TODO Auto-generated method stub
    return null;
  }

  public void setId(String data) {
    this.id = data.trim();
  }

  public String getId() {
    return id;
  }

  public void setTag(String data) {
    this.tag = data.trim();
  }

  public String getTag() {
    return tag;
  }

}

redpajama_set_name: RedPajamaGithub


text:
require 'rails/generators'
require 'rails/generators/migration'

module Humdrum
  module Generators
    module Api
      class SessionGenerator < Rails::Generators::Base

      include Rails::Generators::Migration

      def self.next_migration_number(path)
        @migration_number = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i.to_s
      end

      source_root File.expand_path('../templates', __FILE__)

      desc "Generates a controller, view and route entries for CRUD operations of a resource"

      argument :resource_name, :type=>:string
      argument :fields, :type=>:hash, :banner =>"Resource Fields."

      class_option :fixed, :type => :boolean, :default => false, :desc => "Create fixed layouts. Default is fluid (Gumby doesn't support fluid framework. Hence applicable only for bootstrap for the timebeing.)"
      class_option :debug, :type => :boolean, :default => false, :desc => "This will print the arguments for debugging"

      class_option :front_end_framework, :type => :string, :default => 'bootstrap', :desc => "Support Twitter Bootstrap (twitter.github.io/bootstrap/) and Gumpy (http://gumbyframework.com/). Default is bootstrap. Pass gumby for Gumby Framework"

      def debug_args
        print_args if options.debug?
      end

      def generate_controllers
        template "controllers/resource_controller.rb", "app/controllers/#{controller_path}_controller.rb"
      end

      def generate_views
        template "views/#{framework}/resource/_edit.html.erb", "app/views/#{controller_path}/_edit.html.erb"
        template "views/#{framework}/resource/_filters.html.erb", "app/views/#{controller_path}/_filters.html.erb"
        template "views/#{framework}/resource/_field.html.erb", "app/views/#{controller_path}/_field.html.erb"
        template "views/#{framework}/resource/_form.html.erb", "app/views/#{controller_path}/_form.html.erb"
        template "views/#{framework}/resource/_index.html.erb", "app/views/#{controller_path}/_index.html.erb"
        template "views/#{framework}/resource/_item.html.erb", "app/views/#{controller_path}/_item.html.erb"
        template "views/#{framework}/resource/_nav_filters.html.erb", "app/views/#{controller_path}/_nav_filters.html.erb"
        template "views/#{framework}/resource/_new.html.erb", "app/views/#{controller_path}/_new.html.erb"
        template "views/#{framework}/resource/_show.html.erb", "app/views/#{controller_path}/_show.html.erb"
        template "views/#{framework}/resource/_summary.html.erb", "app/views/#{controller_path}/_summary.html.erb"
        template "views/#{framework}/resource/create.js.erb", "app/views/#{controller_path}/create.js.erb"
        template "views/#{framework}/resource/destroy.js.erb", "app/views/#{controller_path}/destroy.js.erb"
        template "views/#{framework}/resource/edit.js.erb", "app/views/#{controller_path}/edit.js.erb"
        template "views/#{framework}/resource/index.js.erb", "app/views/#{controller_path}/index.js.erb"
        template "views/#{framework}/resource/new.js.erb", "app/views/#{controller_path}/new.js.erb"
        template "views/#{framework}/resource/show.js.erb", "app/views/#{controller_path}/show.js.erb"
        template "views/#{framework}/resource/update.js.erb", "app/views/#{controller_path}/update.js.erb"
        template "views/#{framework}/resource/index.html.erb", "app/views/#{controller_path}/index.html.erb"
      end

      def generate_models
        template "models/resource.rb", "app/models/#{model_path}.rb"
      end

      def generate_javascript_validations
        template "javascripts/validations/validator.js", "app/assets/javascripts/validations/#{model_path}.js"
      end

      def generate_migrations
        migration_dir = "db/migrate"
        migration_file_name = "create_#{instances_name}.rb"
        destination = self.class.migration_exists?(migration_dir, migration_file_name)
        if destination
          say_status("skipped", "Migration #{migration_file_name}.rb already exists")
        else
          migration_template "migrations/create_resources.rb", "db/migrate/create_#{instances_name}.rb"
        end
      end

      def generate_routes
        words = name_phrases
        resource = words.pop
        route words.reverse.inject("resources :#{resource.pluralize}") { |acc, phrase|
          "namespace(:#{phrase}){ #{acc} }"
        }
      end

      private

      def print_args
        puts ":fields: #{fields}"
        puts ":form_link_param: #{form_link_param}"
        puts "name_phrases: #{name_phrases}"
        puts "controller_path: #{controller_path}"
        puts "controller_class: #{controller_class}"
        puts "model_path: #{model_path}"
        puts "model_class: #{model_class}"
        puts "instance_name: #{instance_name}"
        puts "instances_name: #{instances_name}"
        puts "table_name: #{table_name}"

        puts "index path: #{resource_link}"
        puts "show path: #{resource_link('show')}"
        puts "new path: #{resource_link('new')}"
        puts "edit path: #{resource_link('edit')}"
        puts "create path: #{resource_link('create')}"
        puts "update path: #{resource_link('update')}"
        puts "destroy path: #{resource_link('destroy')}"

        puts "index url: #{resource_link('index','url')}"
        puts "show url: #{resource_link('show','url')}"
        puts "new url: #{resource_link('new','url')}"
        puts "edit url: #{resource_link('edit','url')}"
        puts "create url: #{resource_link('create','url')}"
        puts "update url: #{resource_link('update','url')}"
        puts "destroy url: #{resource_link('destroy','url')}"
      end

      def name_phrases
        if resource_name.include?('::')
          resource_name.split("::")
        elsif resource_name.include?('/')
          resource_name.split("/")
        else
          [resource_name]
        end
      end

      def controller_path
        words = name_phrases
        resource = words.pop
        if words.any?
          words.collect(&:downcase).join("/") + "/#{resource.pluralize}"
        else
          "#{resource.pluralize}"
        end
      end

      def controller_class
        words = name_phrases
        resource = words.pop
        if words.any?
          words.collect(&:camelize).join("::") + "::#{resource.camelize.pluralize}Controller"
        else
          "#{resource.camelize.pluralize}Controller"
        end
      end

      def model_path
        name_phrases.last.downcase
      end

      def model_class
        name_phrases.last.camelize
      end

      def instance_name
        name_phrases.last.underscore
      end

      def instances_name
        instance_name.pluralize
      end

      def instance_title
        instance_name.titleize
      end

      def instances_title
        instances_name.titleize
      end

      def table_name
        instances_name
      end

      def resource_link(actn='index', ltype='path')
        map = {
          'index' => '',
          'show' => '',
          'edit' => 'edit_',
          'new' => 'new_',
          'update' => '',
          'create' => '',
          'destroy' => '',
        }
        words = name_phrases
        resource = words.pop
        if actn == "index"
          map[actn] + (words.any? ? words.join("_" + "_") : "") + resource.pluralize + "_" + ltype
        else
          map[actn] + (words.any? ? words.join("_") + "_" : "") + resource + "_" + ltype
        end
      end

      def form_link_param
        words = name_phrases
        resource = words.pop
        if words.any?
          # to print like this [:admin, :user, :location, @chakka]
          # in form.html.erb
          "[" + (words.map{|x| ":" + x.downcase} << "@" + resource.downcase).join(", ") + "]"
        else
          "@#{resource.downcase}"
        end
      end

      ## List of all the string fields
      def string_fields
        main_field = main_string_field
        fields.map{|name, type| name if name != main_field && type == "string" }.uniq.compact
      end

      ## List of all the string fields including main field
      def string_fields_including_main_field
        main_field = main_string_field
        fields.map{|name, type| name if type == "string" }.uniq.compact
      end

      ## The main string field like 'name'
      def main_string_field
        fields.map{|name, type| name if name.include?("name") && type == "string"}.uniq.compact || fields.keys.any? ? fields.keys.first : "id"
      end

      def guess_input_type(name, type)
        case type
        when "string"
          if name.include?("url")
            return "url"
          elsif name.include?("email")
            return "email"
          elsif name.include?("phone") || name.include?("mobile") || name.include?("landline") || name.include?("contact number")
            return "tel"
          elsif name.include?("time")
            return "time"
          elsif name.include?("date")
            return "date"
          elsif name.include?("password")
            return "password"
          else
            "text"
          end
        when "text"
          "textarea"
        when "integer"
          "number"
        when "references"
          "type"
        when "date"
          "date"
        when "datetime"
          "datetime-local"
        when "timestamp", "time"
          "time"
        when "boolean"
          "checkbox"
        else
          "text"
        end
      end

      ## Text Fields like description or summary
      def text_fields
        fields.map{|name, type| name if type == "text"}.uniq.compact
      end

      def container_class
        if options.front_end_framework == "bootstrap"
          options.fixed? ? "container" : "container-fluid"
        elsif options.front_end_framework == "gumby"
          "container"
        else
          options.fixed? ? "container" : "container-fluid"
        end
      end

      def row_class
        if options.front_end_framework == "bootstrap"
          options.fixed? ? "row" : "row-fluid"
        elsif options.front_end_framework == "gumby"
          "row"
        else
          options.fixed? ? "row" : "row-fluid"
        end
      end

      def column_class(grid_width_value)
        grid_width_value_hash = {"1" => "one",
                                 "2" => "two",
                                 "3" => "three",
                                 "4" => "four",
                                 "5" => "five",
                                 "6" => "six",
                                 "7" => "seven",
                                 "8" => "eight",
                                 "9" => "nine",
                                 "10" => "ten",
                                 "11" => "eleven",
                                 "12" => "twelve",
                                 "13" => "thirteen",
                                 "14" => "fourteen",
                                 "15" => "fifteen",
                                 "16" => "sixteen"}
        if options.front_end_framework == "bootstrap"
          "span#{grid_width_value}"
        elsif options.front_end_framework == "gumby"
          "#{grid_width_value_hash[grid_width_value.to_s]} columns"
        else
          "col#{grid_width_value}"
        end
      end

      # This function is not used now.
      def button_class(color, size, rounded="", pretty="")
        if options.front_end_framework == "bootstrap"
          color_hash = {"blue" => "btn-primary",
                       "light-blue" => "btn-info",
                       "grey" => "",
                       "black" => "btn-inverse",
                       "red" => "btn-danger",
                       "green" => "btn-success",
                       "orange" => "btn-warning"}
          size_hash = {"large" => "btn-large",
                      "medium" => "",
                      "small" => "btn-tiny"}
        elsif options.front_end_framework == "gumby"
          color_hash = {"blue" => "primary",
                       "dark-green" => "secondary",
                       "grey" => "default",
                       "black" => "info",
                       "red" => "danger",
                       "green" => "success",
                       "orange" => "warning"}
           size_hash = {"xlarge" => "xlarge",
                       "large" => "large",
                       "medium" => "medium",
                       "small" => "small",
                       "green" => "btn-success"}
        end
        "#{pretty.blank? ? "" : "#{pretty} "}#{rounded.blank? ? "" : "#{rounded} "}#{size_hash[size]} #{color_hash[color]} btn"
      end

    end
    end
  end
end


text:
<?php

namespace Drupal\simpletest_example\Tests;

use Drupal\simpletest\WebTestBase;

/**
 * Ensure that the simpletest_example content type provided functions properly.
 *
 * The SimpleTestExampleTest is a functional test case, meaning that it
 * actually exercises a particular sequence of actions through the web UI.
 * The majority of core test cases are done this way, but the SimpleTest suite
 * also provides unit tests as demonstrated in the unit test case example later
 * in this file.
 *
 * Functional test cases are far slower to execute than unit test cases because
 * they require a complete Drupal install to be done for each test.
 *
 * @see Drupal\simpletest\WebTestBase
 * @see SimpleTestUnitTestExampleTestCase
 *
 * @ingroup simpletest_example
 *
 * SimpleTest uses group annotations to help you organize your tests.
 *
 * @group simpletest_example
 * @group examples
 */
class SimpleTestExampleTest extends WebTestBase {

  /**
   * Our module dependencies.
   *
   * In Drupal 8's SimpleTest, we declare module dependencies in a public
   * static property called $modules. WebTestBase automatically enables these
   * modules for us.
   *
   * @var array
   */
  static public $modules = array('simpletest_example');

  /**
   * The installation profile to use with this test.
   *
   * We use the 'minimal' profile so that there are some reasonable default
   * blocks defined, and so we can see the menu link created by our module.
   *
   * @var string
   */
  protected $profile = 'minimal';

  /**
   * Test SimpleTest Example menu and page.
   *
   * Enable SimpleTest Example and see if it can successfully return its main
   * page and if there is a link to the simpletest_example in the Tools menu.
   */
  public function testSimpleTestExampleMenu() {
    // Test for a link to the simpletest_example in the Tools menu.
    $this->drupalGet('');
    $this->assertResponse(200, 'The Home page is available.');
    $this->assertLinkByHref('examples/simpletest-example');

    // Verify that anonymous can access the simpletest_examples page.
    $this->drupalGet('examples/simpletest-example');
    $this->assertResponse(200, 'The SimpleTest Example description page is available.');
  }

  /**
   * Test node creation through the user interface.
   *
   * Creates a node using the node/add form and verifies its consistency in
   * the database.
   */
  public function testSimpleTestExampleCreate() {
    // Create a user with the ability to create our content type. This
    // permission is generated by the node module.
    $user = $this->createUser(array('create simpletest_example content'));
    // Log in our user.
    $this->drupalLogin($user);

    // Create a node using the node/add form.
    $edit = array();
    $edit['title[0][value]'] = $this->randomMachineName(8);
    $edit['body[0][value]'] = $this->randomMachineName(16);
    $this->drupalPostForm('node/add/simpletest_example', $edit, t('Save'));

    // Check that our simpletest_example node has been created.
    $this->assertText(t('@post @title has been created.', array(
      '@post' => 'SimpleTest Example Node Type',
      '@title' => $edit['title[0][value]'],
    )));
    // Check that the node exists in the database.
    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
    $this->assertTrue($node, 'Node found in database.');

    // Verify 'submitted by' information. Drupal adds a newline in there, so
    // we have to check for that.
    $submitted_by = t("Submitted by @username\n on @datetime", array(
      '@username' => $this->loggedInUser->getUsername(),
      '@datetime' => format_date($node->getCreatedTime()),
    ));

    $this->drupalGet('node/' . $node->id());
    $this->assertText($submitted_by);
  }

  /**
   * Create a simpletest_example node and then see if our user can edit it.
   *
   * Note that some assertions in this test will fail. We do this to show what
   * a failing test looks like. Since we don't want this to interfere with
   * automated tests, however, we jump through some hoops to determine our
   * environment.
   */
  public function testSimpleTestExampleEdit() {
    // Create a user with our special permission.
    $user = $this->drupalCreateUser(array('extra special edit any simpletest_example'));
    // Log in our user.
    $this->drupalLogin($user);

    // Create a node with our user as the creator.
    // drupalCreateNode() uses the logged-in user by default.
    $settings = array(
      'type' => 'simpletest_example',
      'title' => $this->randomMachineName(32),
    );
    $node = $this->drupalCreateNode($settings);

    // For debugging, we might output some information using $this->verbose()
    // It will only be output if the testing settings have 'verbose' set.
    $this->verbose('Node created: ' . $node->getTitle());

    // This section demonstrates a failing test. However, we want this test to
    // pass when it's running on the Drupal QA testbot. So we need to determine
    // which environment we're running inside of before we continue.
    if (!$this->runningOnTestbot()) {
      $this->drupalGet('node/' . $node->id() . '/edit');
      // The debug() statement will output information into the test results.
      // It can also be used in Drupal anywhere in code and will come out
      // as a drupal_set_message().
      debug('The following test should fail. Examine the verbose message above it to see why.');
      // Make sure we don't get a 401 unauthorized response:
      $this->assertResponse(200, 'User is allowed to edit the content.');

      // Looking for title text in the page to determine whether we were
      // successful opening edit form.
      $this->assertText(t("@title", array('@title' => $settings['title'])), "Found title in edit form");
    }
  }

  /**
   * Detect if we're running on PIFR testbot.
   *
   * We can skip intentional failure if we're on the testbot. It happens that
   * on the testbot the site under test is in a directory named 'checkout' or
   * 'site_under_test'.
   *
   * @return bool
   *   TRUE if running on testbot.
   */
  public function runningOnTestbot() {
    // @todo: Add this line back once the testbot variable is available.
    // https://www.drupal.org/node/2565181
    // return env('DRUPALCI');
    return TRUE;
  }

}


text:
package org.dashbuilder.renderer.google.client;

import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.googlecode.gwt.charts.client.ChartPackage;
import com.googlecode.gwt.charts.client.corechart.AreaChart;
import com.googlecode.gwt.charts.client.corechart.AreaChartOptions;
import com.googlecode.gwt.charts.client.options.Animation;
import com.googlecode.gwt.charts.client.options.AnimationEasing;
import org.dashbuilder.dataset.ColumnType;
import org.dashbuilder.dataset.DataSetLookupConstraints;
import org.dashbuilder.displayer.DisplayerAttributeDef;
import org.dashbuilder.displayer.DisplayerAttributeGroupDef;
import org.dashbuilder.displayer.DisplayerConstraints;
import org.dashbuilder.displayer.DisplayerSubType;
import org.dashbuilder.displayer.DisplayerType;
import org.dashbuilder.renderer.google.client.resources.i18n.GoogleDisplayerConstants;

public class GoogleAreaChartDisplayer extends GoogleCategoriesDisplayer {

    protected Panel chartPanel = new FlowPanel();
    protected AreaChart chart;
    protected Panel filterPanel = new SimplePanel();

    @Override
    public ChartPackage getPackage() {
        return ChartPackage.CORECHART;
    }

    @Override
    public DisplayerConstraints createDisplayerConstraints() {

        DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints()
                .setGroupRequired(true)
                .setGroupColumn(true)
                .setMaxGroups(1)
                .setMinColumns(2)
                .setMaxColumns(10)
                .setExtraColumnsAllowed(true)
                .setExtraColumnsType(ColumnType.NUMBER)
                .setGroupsTitle(GoogleDisplayerConstants.INSTANCE.common_Categories())
                .setColumnsTitle(GoogleDisplayerConstants.INSTANCE.common_Series())
                .setColumnTypes(new ColumnType[] {
                        ColumnType.LABEL,
                        ColumnType.NUMBER});

        return new DisplayerConstraints(lookupConstraints)
                .supportsAttribute(DisplayerAttributeDef.TYPE)
                .supportsAttribute(DisplayerAttributeDef.SUBTYPE)
                .supportsAttribute(DisplayerAttributeDef.RENDERER)
                .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP)
                .supportsAttribute( DisplayerAttributeGroupDef.FILTER_GROUP )
                .supportsAttribute( DisplayerAttributeGroupDef.REFRESH_GROUP )
                .supportsAttribute( DisplayerAttributeGroupDef.GENERAL_GROUP)
                .supportsAttribute( DisplayerAttributeDef.CHART_WIDTH )
                .supportsAttribute( DisplayerAttributeDef.CHART_HEIGHT )
                .supportsAttribute(DisplayerAttributeDef.CHART_BGCOLOR)
                .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP)
                .supportsAttribute( DisplayerAttributeGroupDef.CHART_LEGEND_GROUP )
                .supportsAttribute(DisplayerAttributeGroupDef.AXIS_GROUP);
    }

    @Override
    protected Widget createVisualization() {
        HTML titleHtml = new HTML();
        if (displayerSettings.isTitleVisible()) {
            titleHtml.setText(displayerSettings.getTitle());
        }

        FlowPanel container = new FlowPanel();
        container.add(titleHtml);
        container.add(filterPanel);
        container.add(chartPanel);

        chart = new AreaChart();
        chart.addSelectHandler(createSelectHandler(chart));

        updateChartPanel();
        return container;
    }

    protected void updateChartPanel() {
        chartPanel.clear();
        if (dataSet.getRowCount() == 0) {
            chartPanel.add(super.createNoDataMsgPanel());
        } else {
            chart.draw(createTable(), createOptions());
            chartPanel.add(chart);
        }
    }

    protected void updateVisualization() {
        filterPanel.clear();
        Widget filterReset = createCurrentSelectionWidget();
        if (filterReset != null) filterPanel.add(filterReset);

        updateChartPanel();
    }

    private AreaChartOptions createOptions() {
        Animation anim = Animation.create();
        anim.setDuration(700);
        anim.setEasing(AnimationEasing.IN_AND_OUT);

        AreaChartOptions options = AreaChartOptions.create();
        options.setWidth(displayerSettings.getChartWidth());
        options.setHeight(displayerSettings.getChartHeight());
        options.setBackgroundColor(displayerSettings.getChartBackgroundColor());
        options.setLegend( createChartLegend() );
        if ( displayerSettings.isXAxisShowLabels() ) options.setHAxis( createHAxis() );
        if ( displayerSettings.isYAxisShowLabels() ) options.setVAxis( createVAxis() );
        options.setAnimation(anim);
        options.setChartArea(createChartArea());
        options.setColors(createColorArray(googleTable));
        options.setIsStacked(DisplayerSubType.AREA_STACKED.equals(displayerSettings.getSubtype()));
        return options;
    }
}


text:
title: tokens
---
# Tokens in Java
These are the fundamental building blocks of a program or the smallest unit of a program.
Java supports five types of tokens:
## 1. Keywords
These are the words which have their predefined definitions in the compiler and cannot be used as the names of the identifiers.There are 51 keywords and 2 reserved words in Java.
## 2. Identifiers
These are the various names given to different components of the program. These includes the names of variables, methods, class, etc. They must not begin with a digit but can contain digits, letters, underscore, currency symbols.
## 3. Literals
These provide a way to express specific values in a program.These are of following types:
### Numeric Literals
These are of three types in Java.
 * #### Integer Literals
 * #### Floating Point Literals
 * #### Character Literals
### Boolean Literals
These are of two types
 * #### true
 * #### false
### String Literals
## 4. Operators
These are the special types of symbols used to perform certain operations. For example +, -, *, /, %
## 5. Seperators
These include tab, enter, space bar.
##### Now let us consider a program
```java
       //Printing Hello World

public class Hello

{

public static void main(String args[])

{

System.out.println("Hello World");

}

}
```

The source code contains tokens such as _public_, _class_, _Hello_, {, _public_, _static_, _void_, _main_, (, _String_, [], _args_, {, _System_, _out_, _println_, (, _"Hello World"_, }, }. The resulting tokens· are compiled into Java bytecodes that is capable of being run from within an interpreted java environment. Token are useful for compiler to detect errors. When tokens are not arranged in a particular sequence, the compiler generates an error message.


text: morpheus.renderer =


text:
<?php

// Require the base class
require_once __DIR__ . "/../BaseExample.php";

/**
 * Gets all accounts for the logged in user.
 *
 * Tags: accounts.list
 *
 * @author Silvano Luciani <silvano.luciani@gmail.com>
 */
class GetAllAccounts extends BaseExample {
  public function render() {
    $optParams['maxResults'] = AD_MAX_PAGE_SIZE;
    $listClass = 'list';
    printListHeader($listClass);
    $pageToken = null;
    do {
      $optParams['pageToken'] = $pageToken;
      // Retrieve account list, and display it.
      $result = $this->adSenseService->accounts->listAccounts($optParams);
      $accounts = $result['items'];
      if (isset($accounts)) {
        foreach ($accounts as $account) {
          $format = 'Account with ID "%s" and name "%s" was found.';
          $content = sprintf(
              $format, $account['id'], $account['name']);
          printListElement($content);
        }
        $pageToken = isset($result['nextPageToken']) ? $result['nextPageToken']
            : null;
      } else {
        printNoResultForList();
      }
    } while ($pageToken);
    printListFooter();
  }
}


text:
package com.arrayfire;

public class DoubleComplex {
  private double real;
  private double imag;

  public double real() {
    return real;
  }

  public double imag() {
    return imag;
  }

  public void set(double re, double im) {
    real = re;
    imag = im;
  }

  public void setReal(double re) {
    real = re;
  }

  public void setImag(double im) {
    imag = im;
  }

  public DoubleComplex(double re, double im) {
    set(re, im);
  }

  public DoubleComplex() {
    set(0, 0);
  }

  public String toString() {
    String str = String.valueOf(real);

    if (imag < 0)
      str = str + " - ";
    else
      str = str + " + ";

    return str + String.valueOf(Math.abs(imag)) + "i";
  }
}


text:
<?php

class Google_Service_Compute_InstancesScopedList extends Google_Collection
{
  protected $collection_key = 'instances';
  protected $instancesType = 'Google_Service_Compute_Instance';
  protected $instancesDataType = 'array';
  protected $warningType = 'Google_Service_Compute_InstancesScopedListWarning';
  protected $warningDataType = '';

  /**
   * @param Google_Service_Compute_Instance
   */
  public function setInstances($instances)
  {
    $this->instances = $instances;
  }
  /**
   * @return Google_Service_Compute_Instance
   */
  public function getInstances()
  {
    return $this->instances;
  }
  /**
   * @param Google_Service_Compute_InstancesScopedListWarning
   */
  public function setWarning(Google_Service_Compute_InstancesScopedListWarning $warning)
  {
    $this->warning = $warning;
  }
  /**
   * @return Google_Service_Compute_InstancesScopedListWarning
   */
  public function getWarning()
  {
    return $this->warning;
  }
}


text:
/*                     __                                               *\
**     ________ ___   / /  ___      __ ____  Scala.js Test Suite        **
**    / __/ __// _ | / /  / _ | __ / // __/  (c) 2013, LAMP/EPFL        **
**  __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \    http://scala-js.org/       **
** /____/\___/_/ |_/____/_/ | |__/ /____/                               **
**                          |/____/                                     **
\*                                                                      */
package org.scalajs.testsuite.scalalib

import scala.language.implicitConversions

import scala.reflect._

import scala.scalajs.js
import org.scalajs.jasminetest.JasmineTest

object ClassTagTest extends JasmineTest {

  implicit def class2jsAny(clazz: Class[_]): js.Any =
    clazz.asInstanceOf[js.Any]

  implicit def classTag2jsAny(ct: ClassTag[_]): js.Any =
    ct.asInstanceOf[js.Any]

  describe("scala.reflect.ClassTag") {

    it("apply() should get the existing instances for pre-defined ClassTags") {
      expect(ClassTag(classOf[Byte])).toBe(ClassTag.Byte)
      expect(ClassTag(classOf[Short])).toBe(ClassTag.Short)
      expect(ClassTag(classOf[Char])).toBe(ClassTag.Char)
      expect(ClassTag(classOf[Int])).toBe(ClassTag.Int)
      expect(ClassTag(classOf[Long])).toBe(ClassTag.Long)
      expect(ClassTag(classOf[Float])).toBe(ClassTag.Float)
      expect(ClassTag(classOf[Double])).toBe(ClassTag.Double)
      expect(ClassTag(classOf[Boolean])).toBe(ClassTag.Boolean)
      expect(ClassTag(classOf[Unit])).toBe(ClassTag.Unit)
      expect(ClassTag(classOf[Object])).toBe(ClassTag.Object)
      expect(ClassTag(classOf[Nothing])).toBe(ClassTag.Nothing)
      expect(ClassTag(classOf[Null])).toBe(ClassTag.Null)

      expect(classTag[Byte]).toBe(ClassTag.Byte)
      expect(classTag[Short]).toBe(ClassTag.Short)
      expect(classTag[Char]).toBe(ClassTag.Char)
      expect(classTag[Int]).toBe(ClassTag.Int)
      expect(classTag[Long]).toBe(ClassTag.Long)
      expect(classTag[Float]).toBe(ClassTag.Float)
      expect(classTag[Double]).toBe(ClassTag.Double)
      expect(classTag[Boolean]).toBe(ClassTag.Boolean)
      expect(classTag[Unit]).toBe(ClassTag.Unit)
      expect(classTag[Any]).toBe(ClassTag.Any)
      expect(classTag[Object]).toBe(ClassTag.Object)
      expect(classTag[AnyVal]).toBe(ClassTag.AnyVal)
      expect(classTag[AnyRef]).toBe(ClassTag.AnyRef)
      expect(classTag[Nothing]).toBe(ClassTag.Nothing)
      expect(classTag[Null]).toBe(ClassTag.Null)
    }

    it("runtimeClass") {
      expect(ClassTag.Byte.runtimeClass).toBe(classOf[Byte])
      expect(ClassTag.Short.runtimeClass).toBe(classOf[Short])
      expect(ClassTag.Char.runtimeClass).toBe(classOf[Char])
      expect(ClassTag.Int.runtimeClass).toBe(classOf[Int])
      expect(ClassTag.Long.runtimeClass).toBe(classOf[Long])
      expect(ClassTag.Float.runtimeClass).toBe(classOf[Float])
      expect(ClassTag.Double.runtimeClass).toBe(classOf[Double])
      expect(ClassTag.Boolean.runtimeClass).toBe(classOf[Boolean])
      expect(ClassTag.Unit.runtimeClass).toBe(classOf[Unit])
      expect(ClassTag.Any.runtimeClass).toBe(classOf[Any])
      expect(ClassTag.Object.runtimeClass).toBe(classOf[Object])
      expect(ClassTag.AnyVal.runtimeClass).toBe(classOf[AnyVal])
      expect(ClassTag.AnyRef.runtimeClass).toBe(classOf[AnyRef])
      expect(ClassTag.Nothing.runtimeClass).toBe(classOf[Nothing])
      expect(ClassTag.Null.runtimeClass).toBe(classOf[Null])

      expect(classTag[String].runtimeClass).toBe(classOf[String])
      expect(classTag[Integer].runtimeClass).toBe(classOf[Integer])
      expect(classTag[Seq[_]].runtimeClass).toBe(classOf[Seq[_]])

      expect(classTag[Array[_]].runtimeClass).toBe(classOf[Array[_]])
      expect(classTag[Array[Object]].runtimeClass).toBe(classOf[Array[Object]])
      expect(classTag[Array[_ <: AnyRef]].runtimeClass).toBe(classOf[Array[_ <: AnyRef]])
      expect(classTag[Array[String]].runtimeClass).toBe(classOf[Array[String]])
      expect(classTag[Array[_ <: Seq[_]]].runtimeClass).toBe(classOf[Array[_ <: Seq[_]]])
      expect(classTag[Array[Int]].runtimeClass).toBe(classOf[Array[Int]])
      expect(classTag[Array[Unit]].runtimeClass).toBe(classOf[Array[Unit]])

      // Weird, those two return Array[s.r.Nothing$] instead of Array[Object]
      // The same happens on the JVM
      expect(classTag[Array[Nothing]].runtimeClass).toBe(classOf[Array[scala.runtime.Nothing$]])
      expect(classTag[Array[Null]].runtimeClass).toBe(classOf[Array[scala.runtime.Null$]])

      expect(ClassTag(classOf[String]).runtimeClass).toBe(classOf[String])
      expect(ClassTag(classOf[Integer]).runtimeClass).toBe(classOf[Integer])
      expect(ClassTag(classOf[Seq[_]]).runtimeClass).toBe(classOf[Seq[_]])

      expect(ClassTag(classOf[Array[_]]).runtimeClass).toBe(classOf[Array[_]])
      expect(ClassTag(classOf[Array[Object]]).runtimeClass).toBe(classOf[Array[Object]])
      expect(ClassTag(classOf[Array[_ <: AnyRef]]).runtimeClass).toBe(classOf[Array[_ <: AnyRef]])
      expect(ClassTag(classOf[Array[String]]).runtimeClass).toBe(classOf[Array[String]])
      expect(ClassTag(classOf[Array[_ <: Seq[_]]]).runtimeClass).toBe(classOf[Array[_ <: Seq[_]]])
      expect(ClassTag(classOf[Array[Int]]).runtimeClass).toBe(classOf[Array[Int]])
      expect(ClassTag(classOf[Array[Unit]]).runtimeClass).toBe(classOf[Array[Unit]])

      // These work as expected, though
      expect(ClassTag(classOf[Array[Nothing]]).runtimeClass).toBe(classOf[Array[Nothing]])
      expect(ClassTag(classOf[Array[Null]]).runtimeClass).toBe(classOf[Array[Null]])
    }

  }

}


text:
import {Injectable} from '@angular/core';
import {Http, Headers} from '@angular/http';

//This is used as an shared/global class
//We create only once instance of this class
@Injectable()
export class UserService {

// Static/Shared Variables
  public id: string;
  public email: string;
  public username: string;
  public currency: string;

  public isLogged: boolean;
  public isSeller: boolean;
  public isBuyer: boolean;
  public isAdmin: boolean;

  public latitude: number;
  public longitude: number;

  public urlSignup='/api/auth/signup';
  public urlSignin = '/api/auth/signin';
  public urlCart = '/api/cart';
  public urlOrder = '/api/order';
  public urlUserProfile = '/api/secure/user/profile/';

  public shopId: string;
  public shopTitle: string;

  public location: any;
  public profile: any = {firstName:''};

  public address: any;
  public map_address: any;

  public cart: any = [];
  public cartItems: any = [];
  public cartOptions: any = [];

  constructor(public http:Http) {

  }

  check(data) {
      console.log('in');
      let headers = new Headers();
      headers.append('Content-Type', 'application/json');
      let r = this.http.post(this.urlSignin, JSON.stringify(data),
          { headers: headers })
          .map(res => res.json());
      console.log('out');
      return r;
  }

  verify(data) {
      console.log('in');
      let headers = new Headers();
      headers.append('Content-Type', 'application/json');
      let r = this.http.post(this.urlSignin, JSON.stringify(data),
          { headers: headers })
          .map(res => res.json());
      console.log('out');
      return r;
  }

  create(data) {
    console.log('in');
    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    let r = this.http.post(this.urlSignup, JSON.stringify(data),
          {headers: headers})
        .map(res => res.json());
    console.log('out');
    return r;

    //return this.http.post(this.url, JSON.stringify(data),
    //      {headers: headers})
    //    .map(res => res.json());
  }

  setLocation() {
      console.log('setting location');
      let u = this;

      //Asking for get current location and stroring it  in user service
      if (window && window.navigator && window.navigator.geolocation) {
          window.navigator.geolocation.getCurrentPosition(
              (position) => {
                  console.log('location', position);
                  if (position.coords) {
                      u.location = position.coords;
                      u.latitude = position.coords.latitude;
                      u.longitude = position.coords.longitude;
                      u.latitude = position.coords.latitude;
                      u.longitude = position.coords.longitude;

                  }

              }
          )
      } // if

     // return r;

      //return this.http.post(this.url, JSON.stringify(data),
      //      {headers: headers})
      //    .map(res => res.json());
  }

  postData(url, data) {

      console.log('saving in post data', url,data);
      console.log('saving in post data', url);

      let headers = new Headers();
      headers.append('Content-Type', 'application/json');
      let r = this.http.post(url, JSON.stringify(data),
          { headers: headers })
          .map(res => res.json());
      console.log('out');
      return r;

  }
  updateProfile(data) {
      this.profile = data;
      return this.postData(this.urlUserProfile+ this.id,data);
  }

  order()
  {
      let data:any = {};
      data.items = this.cartItems;
      data.options = this.cartOptions;
      data.userId = this.id;
      data.email = this.email;

      console.log("order data", data);

      let headers = new Headers();
      headers.append('Content-Type', 'application/json');
      let r = this.http.post(this.urlOrder, JSON.stringify(data),
          { headers: headers })
          .map(res => res.json());
      console.log('out');
      return r;

  }

  addToCart(data) {
      this.cartItems.push(data);

      return this.postData(this.urlCart, data);

  }

}


text:
namespace mega
{
	ref class MegaSDK;

	using namespace Windows::Foundation;
	using Platform::String;

	private class DelegateMTreeProcessor : public MegaTreeProcessor
	{
	public:
		DelegateMTreeProcessor(MTreeProcessorInterface^ listener);
		virtual bool processMegaNode(MegaNode* node);

	private:
		MTreeProcessorInterface^ processor;
	};
}


text:
class Reward < ActiveRecord::Base
  include RankedModel
  include ERB::Util

  before_destroy :check_if_is_destroyable

  belongs_to :project
  has_many :payments, through: :contributions
  has_many :benefits, class_name: 'RewardBenefit', dependent: :destroy
  has_many :contributions, dependent: :nullify

  ranks :row_order, with_same: :project_id

  accepts_nested_attributes_for :benefits, reject_if: :all_blank, allow_destroy: true
  validates_presence_of :minimum_value, :description, :deliver_at
  validates_numericality_of :minimum_value, greater_than_or_equal_to: 10.00, message: 'Valor deve ser maior ou igual a R$ 10'
  validates_numericality_of :maximum_contributions, only_integer: true, greater_than: 0, allow_nil: true
  validate :deliver_at_cannot_be_in_the_past

  mount_uploader :uploaded_image, RewardUploader

  scope :remaining, -> { where("
                               rewards.maximum_contributions IS NULL
                               OR (
                                rewards.maximum_contributions IS NOT NULL
                                AND (
                                      SELECT
                                      COUNT(distinct c.id)
                                      FROM
                                        contributions c JOIN payments p ON p.contribution_id = c.id
                                      WHERE
                                        (p.state = 'paid' OR
                                        p.waiting_payment)
                                        AND reward_id = rewards.id
                                    ) < maximum_contributions)") }
  scope :sort_asc, -> { order('id ASC') }

  delegate :display_deliver_estimate, :display_remaining, :name, :display_minimum, :short_description,
           :medium_description, :last_description, :display_description, to: :decorator

  before_save :log_changes
  after_save :expires_project_cache

  def deliver_at_cannot_be_in_the_past
    self.errors.add(:deliver_at, "Previsão de entrega deve ser superior a data em que o projeto entra no ar") if
      self.project.expires_at.present? ? self.deliver_at < self.project.expires_at.beginning_of_month : self.deliver_at < Time.current.beginning_of_month
  end

  def log_changes
    self.last_changes = self.changes.to_json
  end

  def to_s
    display_description
  end

  def decorator
    @decorator ||= RewardDecorator.new(self)
  end

  def sold_out?
    maximum_contributions && total_compromised >= maximum_contributions
  end

  def any_sold?
    total_compromised > 0
  end

  def total_contributions states = %w(paid pending)
    payments.with_states(states).count("DISTINCT contributions.id")
  end

  def total_compromised
    paid_count + in_time_to_confirm
  end

  def paid_count
    pluck_from_database('paid_count')
  end

  def in_time_to_confirm
    pluck_from_database('waiting_payment_count')
  end

  def remaining
    return nil unless maximum_contributions
    maximum_contributions - total_compromised
  end

  def check_if_is_destroyable
    if any_sold?
      project.errors.add 'reward.destroy', "can't destroy"
      return false
    end
  end

  def expires_project_cache
    project.expires_fragments 'project-rewards'
  end

  private
  def pluck_from_database attribute
    Reward.where(id: self.id).pluck("rewards.#{attribute}").first
  end
end