diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..0b0766f
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,27 @@
+
+
+	
+		
+			
+		
+	
+	
+		
+			
+			
+		
+	
+	
+		
+			
+			
+			
+		
+	
+	
+		
+			
+		
+	
+	
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..09e3bc9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/bin/
+/target/
diff --git a/.project b/.project
new file mode 100644
index 0000000..16957d7
--- /dev/null
+++ b/.project
@@ -0,0 +1,23 @@
+
+
+	java-nio-server
+	
+	
+	
+	
+		
+			org.eclipse.jdt.core.javabuilder
+			
+			
+		
+		
+			org.eclipse.m2e.core.maven2Builder
+			
+			
+		
+	
+	
+		org.eclipse.m2e.core.maven2Nature
+		org.eclipse.jdt.core.javanature
+	
+
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..943e578
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..e3b3192
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,29 @@
+
+	4.0.0
+	informatik-ag-ngl
+	java-nio-server
+	0.0.1-SNAPSHOT
+
+	
+		
+			org.junit.jupiter
+			junit-jupiter-api
+			5.6.0-M1
+			test
+		
+	
+
+	
+		
+			
+				maven-compiler-plugin
+				3.8.0
+				
+					8
+				
+			
+		
+	
+
\ No newline at end of file
diff --git a/src/main/java/com/jenkov/nioserver/IMessageProcessor.java b/src/main/java/com/jenkov/nioserver/IMessageProcessor.java
index 3d5e9b9..f05e880 100644
--- a/src/main/java/com/jenkov/nioserver/IMessageProcessor.java
+++ b/src/main/java/com/jenkov/nioserver/IMessageProcessor.java
@@ -1,10 +1,13 @@
 package com.jenkov.nioserver;
 
 /**
- * Created by jjenkov on 16-10-2015.
+ * Project: java-nio-server
+ * File: HttpUtilTest.java
+ * Created: 16 Oct 2015
+ *
+ * @author jjenkov
  */
 public interface IMessageProcessor {
 
-    public void process(Message message, WriteProxy writeProxy);
-
-}
+	public void process(Message message, WriteProxy writeProxy);
+}
\ No newline at end of file
diff --git a/src/main/java/com/jenkov/nioserver/IMessageReader.java b/src/main/java/com/jenkov/nioserver/IMessageReader.java
index 19a6d1b..16ec876 100644
--- a/src/main/java/com/jenkov/nioserver/IMessageReader.java
+++ b/src/main/java/com/jenkov/nioserver/IMessageReader.java
@@ -5,16 +5,17 @@ import java.nio.ByteBuffer;
 import java.util.List;
 
 /**
- * Created by jjenkov on 16-10-2015.
+ * Project: java-nio-server
+ * File: HttpUtilTest.java
+ * Created: 16 Oct 2015
+ *
+ * @author jjenkov
  */
 public interface IMessageReader {
 
-    public void init(MessageBuffer readMessageBuffer);
+	public void init(MessageBuffer readMessageBuffer);
 
-    public void read(Socket socket, ByteBuffer byteBuffer) throws IOException;
+	public void read(Socket socket, ByteBuffer byteBuffer) throws IOException;
 
-    public List getMessages();
-
-
-
-}
+	public List getMessages();
+}
\ No newline at end of file
diff --git a/src/main/java/com/jenkov/nioserver/IMessageReaderFactory.java b/src/main/java/com/jenkov/nioserver/IMessageReaderFactory.java
index 66bb80e..39b3139 100644
--- a/src/main/java/com/jenkov/nioserver/IMessageReaderFactory.java
+++ b/src/main/java/com/jenkov/nioserver/IMessageReaderFactory.java
@@ -1,10 +1,13 @@
 package com.jenkov.nioserver;
 
 /**
- * Created by jjenkov on 16-10-2015.
+ * Project: java-nio-server
+ * File: HttpUtilTest.java
+ * Created: 16 Oct 2015
+ *
+ * @author jjenkov
  */
 public interface IMessageReaderFactory {
 
-    public IMessageReader createMessageReader();
-
-}
+	public IMessageReader createMessageReader();
+}
\ No newline at end of file
diff --git a/src/main/java/com/jenkov/nioserver/Message.java b/src/main/java/com/jenkov/nioserver/Message.java
index d11579a..50ba073 100644
--- a/src/main/java/com/jenkov/nioserver/Message.java
+++ b/src/main/java/com/jenkov/nioserver/Message.java
@@ -3,103 +3,92 @@ package com.jenkov.nioserver;
 import java.nio.ByteBuffer;
 
 /**
- * Created by jjenkov on 16-10-2015.
+ * Project: java-nio-server
+ * File: HttpUtilTest.java
+ * Created: 16 Oct 2015
+ *
+ * @author jjenkov
  */
 public class Message {
 
-    private MessageBuffer messageBuffer = null;
+	private MessageBuffer messageBuffer;
 
-    public long socketId = 0; // the id of source socket or destination socket, depending on whether is going in or out.
+	public long socketId; // the id of source socket or destination socket, depending on whether is going
+							// in or out.
 
-    public byte[] sharedArray = null;
-    public int    offset      = 0; //offset into sharedArray where this message data starts.
-    public int    capacity    = 0; //the size of the section in the sharedArray allocated to this message.
-    public int    length      = 0; //the number of bytes used of the allocated section.
+	public byte[]	sharedArray;
+	public int		offset;		// offset into sharedArray where this message data starts.
+	public int		capacity;	// the size of the section in the sharedArray allocated to this message.
+	public int		length;		// the number of bytes used of the allocated section.
 
-    public Object metaData    = null;
+	public Object metaData;
 
-    public Message(MessageBuffer messageBuffer) {
-        this.messageBuffer = messageBuffer;
-    }
+	public Message(MessageBuffer messageBuffer) { this.messageBuffer = messageBuffer; }
 
-    /**
-     * Writes data from the ByteBuffer into this message - meaning into the buffer backing this message.
-     *
-     * @param byteBuffer The ByteBuffer containing the message data to write.
-     * @return
-     */
-    public int writeToMessage(ByteBuffer byteBuffer){
-        int remaining = byteBuffer.remaining();
+	/**
+	 * Writes data from the ByteBuffer into this message - meaning into the buffer
+	 * backing this message.
+	 *
+	 * @param byteBuffer The ByteBuffer containing the message data to write.
+	 * @return
+	 */
+	public int writeToMessage(ByteBuffer byteBuffer) {
+		int remaining = byteBuffer.remaining();
 
-        while(this.length + remaining > capacity){
-            if(!this.messageBuffer.expandMessage(this)) {
-                return -1;
-            }
-        }
+		while (this.length + remaining > capacity)
+			if (!this.messageBuffer.expandMessage(this)) return -1;
 
-        int bytesToCopy = Math.min(remaining, this.capacity - this.length);
-        byteBuffer.get(this.sharedArray, this.offset + this.length, bytesToCopy);
-        this.length += bytesToCopy;
+		int bytesToCopy = Math.min(remaining, capacity - length);
+		byteBuffer.get(sharedArray, offset + length, bytesToCopy);
+		length += bytesToCopy;
 
-        return bytesToCopy;
-    }
+		return bytesToCopy;
+	}
 
+	/**
+	 * Writes data from the byte array into this message - meaning into the buffer
+	 * backing this message.
+	 *
+	 * @param byteArray The byte array containing the message data to write.
+	 * @return
+	 */
+	public int writeToMessage(byte[] byteArray) { return writeToMessage(byteArray, 0, byteArray.length); }
 
+	/**
+	 * Writes data from the byte array into this message - meaning into the buffer
+	 * backing this message.
+	 *
+	 * @param byteArray The byte array containing the message data to write.
+	 * @return
+	 */
+	public int writeToMessage(byte[] byteArray, int offset, int length) {
+		int remaining = length;
 
+		while (this.length + remaining > capacity)
+			if (!this.messageBuffer.expandMessage(this)) return -1;
 
-    /**
-     * Writes data from the byte array into this message - meaning into the buffer backing this message.
-     *
-     * @param byteArray The byte array containing the message data to write.
-     * @return
-     */
-    public int writeToMessage(byte[] byteArray){
-        return writeToMessage(byteArray, 0, byteArray.length);
-    }
+		int bytesToCopy = Math.min(remaining, capacity - length);
+		System.arraycopy(byteArray, offset, sharedArray, offset + this.length, bytesToCopy);
+		this.length += bytesToCopy;
+		return bytesToCopy;
+	}
 
+	/**
+	 * In case the buffer backing the nextMessage contains more than one HTTP
+	 * message, move all data after the first
+	 * message to a new Message object.
+	 *
+	 * @param message  The message containing the partial message (after the first
+	 *                 message).
+	 * @param endIndex The end index of the first message in the buffer of the
+	 *                 message given as parameter.
+	 */
+	public void writePartialMessageToMessage(Message message, int endIndex) {
+		int	startIndexOfPartialMessage	= message.offset + endIndex;
+		int	lengthOfPartialMessage		= message.offset + message.length - endIndex;
 
-    /**
-     * Writes data from the byte array into this message - meaning into the buffer backing this message.
-     *
-     * @param byteArray The byte array containing the message data to write.
-     * @return
-     */
-    public int writeToMessage(byte[] byteArray, int offset, int length){
-        int remaining = length;
+		System.arraycopy(message.sharedArray, startIndexOfPartialMessage, sharedArray, offset, lengthOfPartialMessage);
+	}
 
-        while(this.length + remaining > capacity){
-            if(!this.messageBuffer.expandMessage(this)) {
-                return -1;
-            }
-        }
-
-        int bytesToCopy = Math.min(remaining, this.capacity - this.length);
-        System.arraycopy(byteArray, offset, this.sharedArray, this.offset + this.length, bytesToCopy);
-        this.length += bytesToCopy;
-        return bytesToCopy;
-    }
-
-
-
-
-    /**
-     * In case the buffer backing the nextMessage contains more than one HTTP message, move all data after the first
-     * message to a new Message object.
-     *
-     * @param message   The message containing the partial message (after the first message).
-     * @param endIndex  The end index of the first message in the buffer of the message given as parameter.
-     */
-    public void writePartialMessageToMessage(Message message, int endIndex){
-        int startIndexOfPartialMessage = message.offset + endIndex;
-        int lengthOfPartialMessage     = (message.offset + message.length) - endIndex;
-
-        System.arraycopy(message.sharedArray, startIndexOfPartialMessage, this.sharedArray, this.offset, lengthOfPartialMessage);
-    }
-
-    public int writeToByteBuffer(ByteBuffer byteBuffer){
-        return 0;
-    }
-
-
-
-}
+	public int writeToByteBuffer(ByteBuffer byteBuffer) { return 0; }
+}
\ No newline at end of file
diff --git a/src/main/java/com/jenkov/nioserver/MessageBuffer.java b/src/main/java/com/jenkov/nioserver/MessageBuffer.java
index bf78a54..6a22287 100644
--- a/src/main/java/com/jenkov/nioserver/MessageBuffer.java
+++ b/src/main/java/com/jenkov/nioserver/MessageBuffer.java
@@ -1,88 +1,83 @@
 package com.jenkov.nioserver;
 
 /**
- * A shared buffer which can contain many messages inside. A message gets a section of the buffer to use. If the
- * message outgrows the section in size, the message requests a larger section and the message is copied to that
- * larger section. The smaller section is then freed again.
+ * A shared buffer which can contain many messages inside. A message gets a
+ * section of the buffer to use. If the message outgrows the section in size,
+ * the message requests a larger section and the message is copied to that
+ * larger section. The smaller section is then freed again.
+ * 
+ * Project: java-nio-server
+ * File: MessageBuffer.java
+ * Created: 18 Oct 2015
  *
- *
- * Created by jjenkov on 18-10-2015.
+ * @author jjenkov
  */
 public class MessageBuffer {
 
-    public static int KB = 1024;
-    public static int MB = 1024 * KB;
+	public static int	KB	= 1024;
+	public static int	MB	= 1024 * KB;
 
-    private static final int CAPACITY_SMALL  =   4  * KB;
-    private static final int CAPACITY_MEDIUM = 128  * KB;
-    private static final int CAPACITY_LARGE  = 1024 * KB;
+	private static final int	CAPACITY_SMALL	= 4 * KB;
+	private static final int	CAPACITY_MEDIUM	= 128 * KB;
+	private static final int	CAPACITY_LARGE	= 1 * MB;
 
-    //package scope (default) - so they can be accessed from unit tests.
-    byte[]  smallMessageBuffer  = new byte[1024 *   4 * KB];   //1024 x   4KB messages =  4MB.
-    byte[]  mediumMessageBuffer = new byte[128  * 128 * KB];   // 128 x 128KB messages = 16MB.
-    byte[]  largeMessageBuffer  = new byte[16   *   1 * MB];   //  16 *   1MB messages = 16MB.
+	// package scope (default) - so they can be accessed from unit tests.
+	byte[]	smallMessageBuffer	= new byte[1024 * 4 * KB];	// 1024 x 4KB messages = 4MB.
+	byte[]	mediumMessageBuffer	= new byte[128 * 128 * KB];	// 128 x 128KB messages = 16MB.
+	byte[]	largeMessageBuffer	= new byte[16 * 1 * MB];	// 16 * 1MB messages = 16MB.
 
-    QueueIntFlip smallMessageBufferFreeBlocks  = new QueueIntFlip(1024); // 1024 free sections
-    QueueIntFlip mediumMessageBufferFreeBlocks = new QueueIntFlip(128);  // 128  free sections
-    QueueIntFlip largeMessageBufferFreeBlocks  = new QueueIntFlip(16);   // 16   free sections
+	QueueIntFlip	smallMessageBufferFreeBlocks	= new QueueIntFlip(1024);	// 1024 free sections
+	QueueIntFlip	mediumMessageBufferFreeBlocks	= new QueueIntFlip(128);	// 128 free sections
+	QueueIntFlip	largeMessageBufferFreeBlocks	= new QueueIntFlip(16);		// 16 free sections
 
-    //todo make all message buffer capacities and block sizes configurable
-    //todo calculate free block queue sizes based on capacity and block size of buffers.
+	// TODO: make all message buffer capacities and block sizes configurable
+	// TODO: calculate free block queue sizes based on capacity and block size of
+	// buffers.
 
-    public MessageBuffer() {
-        //add all free sections to all free section queues.
-        for(int i=0; ijava-nio-server
+ * File: MessageWriter.java
+ * Created: 21 Oct 2015
+ *
+ * @author jjenkov
  */
 public class MessageWriter {
 
-    private List writeQueue   = new ArrayList<>();
-    private Message  messageInProgress = null;
-    private int      bytesWritten      =    0;
+	private List	writeQueue	= new ArrayList<>();
+	private Message			messageInProgress;
+	private int				bytesWritten;
 
-    public MessageWriter() {
-    }
+	public void enqueue(Message message) {
+		if (messageInProgress == null) messageInProgress = message;
+		else writeQueue.add(message);
+	}
 
-    public void enqueue(Message message) {
-        if(this.messageInProgress == null){
-            this.messageInProgress = message;
-        } else {
-            this.writeQueue.add(message);
-        }
-    }
+	public void write(Socket socket, ByteBuffer byteBuffer) throws IOException {
+		byteBuffer.put(messageInProgress.sharedArray, messageInProgress.offset + bytesWritten, messageInProgress.length - bytesWritten);
+		byteBuffer.flip();
 
-    public void write(Socket socket, ByteBuffer byteBuffer) throws IOException {
-        byteBuffer.put(this.messageInProgress.sharedArray, this.messageInProgress.offset + this.bytesWritten, this.messageInProgress.length - this.bytesWritten);
-        byteBuffer.flip();
+		bytesWritten += socket.write(byteBuffer);
+		byteBuffer.clear();
 
-        this.bytesWritten += socket.write(byteBuffer);
-        byteBuffer.clear();
+		if (bytesWritten >= messageInProgress.length) {
+			if (writeQueue.size() > 0) messageInProgress = writeQueue.remove(0);
+			else messageInProgress = null;
+			// TODO: unregister from selector
+		}
+	}
 
-        if(bytesWritten >= this.messageInProgress.length){
-            if(this.writeQueue.size() > 0){
-                this.messageInProgress = this.writeQueue.remove(0);
-            } else {
-                this.messageInProgress = null;
-                //todo unregister from selector
-            }
-        }
-    }
-
-    public boolean isEmpty() {
-        return this.writeQueue.isEmpty() && this.messageInProgress == null;
-    }
-
-}
+	public boolean isEmpty() { return writeQueue.isEmpty() && messageInProgress == null; }
+}
\ No newline at end of file
diff --git a/src/main/java/com/jenkov/nioserver/QueueIntFlip.java b/src/main/java/com/jenkov/nioserver/QueueIntFlip.java
index ca1efd7..d1338a8 100644
--- a/src/main/java/com/jenkov/nioserver/QueueIntFlip.java
+++ b/src/main/java/com/jenkov/nioserver/QueueIntFlip.java
@@ -1,186 +1,158 @@
 package com.jenkov.nioserver;
 
 /**
- * Same as QueueFillCount, except that QueueFlip uses a flip flag to keep track of when the internal writePos has
- * "overflowed" (meaning it goes back to 0). Other than that, the two implementations are very similar in functionality.
+ * Same as QueueFillCount, except that QueueFlip uses a flip flag to keep track
+ * of when the internal writePos has "overflowed" (meaning it goes back to 0).
+ * Other than that, the two implementations are very similar in
+ * functionality.
+ * 
+ * One additional difference is that QueueFlip has an available() method, where
+ * this is a public variable in QueueFillCount.
+ * 
+ * Project: java-nio-server
+ * File: QueueIntFlip.java
+ * Created: 18 Oct 2015
  *
- * One additional difference is that QueueFlip has an available() method, where this is a public variable in
- * QueueFillCount.
- *
- * Created by jjenkov on 18-09-2015.
+ * @author jjenkov
  */
 public class QueueIntFlip {
 
-    public int[] elements = null;
+	public int[] elements;
 
-    public int capacity = 0;
-    public int writePos = 0;
-    public int readPos  = 0;
-    public boolean flipped = false;
+	public int		capacity;
+	public int		writePos;
+	public int		readPos;
+	public boolean	flipped;
 
-    public QueueIntFlip(int capacity) {
-        this.capacity = capacity;
-        this.elements = new int[capacity]; //todo get from TypeAllocator ?
-    }
+	public QueueIntFlip(int capacity) {
+		this.capacity	= capacity;
+		elements		= new int[capacity];	// TODO: get from TypeAllocator ?
+	}
 
-    public void reset() {
-        this.writePos = 0;
-        this.readPos  = 0;
-        this.flipped  = false;
-    }
+	public void reset() {
+		writePos	= 0;
+		readPos		= 0;
+		flipped		= false;
+	}
 
-    public int available() {
-        if(!flipped){
-            return writePos - readPos;
-        }
-        return capacity - readPos + writePos;
-    }
+	public int available() { return flipped ? capacity - readPos + writePos : writePos - readPos; }
 
-    public int remainingCapacity() {
-        if(!flipped){
-            return capacity - writePos;
-        }
-        return readPos - writePos;
-    }
+	public int remainingCapacity() { return flipped ? readPos - writePos : capacity - writePos; }
 
-    public boolean put(int element){
-        if(!flipped){
-            if(writePos == capacity){
-                writePos = 0;
-                flipped = true;
+	public boolean put(int element) {
+		if (!flipped) {
+			if (writePos == capacity) {
+				writePos	= 0;
+				flipped		= true;
 
-                if(writePos < readPos){
-                    elements[writePos++] = element;
-                    return true;
-                } else {
-                    return false;
-                }
-            } else {
-                elements[writePos++] = element;
-                return true;
-            }
-        } else {
-            if(writePos < readPos ){
-                elements[writePos++] = element;
-                return true;
-            } else {
-                return false;
-            }
-        }
-    }
+				if (writePos < readPos) {
+					elements[writePos++] = element;
+					return true;
+				} else return false;
+			} else {
+				elements[writePos++] = element;
+				return true;
+			}
+		} else {
+			if (writePos < readPos) {
+				elements[writePos++] = element;
+				return true;
+			} else return false;
+		}
+	}
 
-    public int put(int[] newElements, int length){
-        int newElementsReadPos = 0;
-        if(!flipped){
-            //readPos lower than writePos - free sections are:
-            //1) from writePos to capacity
-            //2) from 0 to readPos
+	public int put(int[] newElements, int length) {
+		int newElementsReadPos = 0;
+		if (!flipped) {
+			// readPos lower than writePos - free sections are:
+			// 1) from writePos to capacity
+			// 2) from 0 to readPos
 
-            if(length <= capacity - writePos){
-                //new elements fit into top of elements array - copy directly
-                for(; newElementsReadPos < length; newElementsReadPos++){
-                    this.elements[this.writePos++] = newElements[newElementsReadPos];
-                }
+			if (length <= capacity - writePos) {
+				// new elements fit into top of elements array - copy directly
+				for (; newElementsReadPos < length; newElementsReadPos++)
+					elements[writePos++] = newElements[newElementsReadPos];
 
-                return newElementsReadPos;
-            } else {
-                //new elements must be divided between top and bottom of elements array
+				return newElementsReadPos;
+			} else {
+				// new elements must be divided between top and bottom of elements array
 
-                //writing to top
-                for(;this.writePos < capacity; this.writePos++){
-                    this.elements[this.writePos] = newElements[newElementsReadPos++];
-                }
+				// writing to top
+				for (; writePos < capacity; writePos++)
+					elements[writePos] = newElements[newElementsReadPos++];
 
-                //writing to bottom
-                this.writePos = 0;
-                this.flipped  = true;
-                int endPos = Math.min(this.readPos, length - newElementsReadPos);
-                for(; this.writePos < endPos; this.writePos++){
-                    this.elements[writePos] = newElements[newElementsReadPos++];
-                }
+				// writing to bottom
+				this.writePos	= 0;
+				this.flipped	= true;
+				int endPos = Math.min(readPos, length - newElementsReadPos);
+				for (; writePos < endPos; writePos++)
+					this.elements[writePos] = newElements[newElementsReadPos++];
 
+				return newElementsReadPos;
+			}
 
-                return newElementsReadPos;
-            }
+		} else {
+			// readPos higher than writePos - free sections are:
+			// 1) from writePos to readPos
 
-        } else {
-            //readPos higher than writePos - free sections are:
-            //1) from writePos to readPos
+			int endPos = Math.min(readPos, writePos + length);
 
-            int endPos = Math.min(this.readPos, this.writePos + length);
+			for (; writePos < endPos; writePos++)
+				elements[writePos] = newElements[newElementsReadPos++];
 
-            for(; this.writePos < endPos; this.writePos++){
-                this.elements[this.writePos] = newElements[newElementsReadPos++];
-            }
+			return newElementsReadPos;
+		}
+	}
 
-            return newElementsReadPos;
-        }
-    }
+	public int take() {
+		if (!flipped) return readPos < writePos ? elements[readPos++] : -1;
+		else {
+			if (readPos == capacity) {
+				readPos	= 0;
+				flipped	= false;
 
+				return readPos < writePos ? elements[readPos++] : -1;
+			} else return elements[readPos++];
+		}
+	}
 
-    public int take() {
-        if(!flipped){
-            if(readPos < writePos){
-                return elements[readPos++];
-            } else {
-                return -1;
-            }
-        } else {
-            if(readPos == capacity){
-                readPos = 0;
-                flipped = false;
+	public int take(int[] into, int length) {
+		int intoWritePos = 0;
+		if (!flipped) {
+			// writePos higher than readPos - available section is writePos - readPos
 
-                if(readPos < writePos){
-                    return elements[readPos++];
-                } else {
-                    return -1;
-                }
-            } else {
-                return elements[readPos++];
-            }
-        }
-    }
+			int endPos = Math.min(writePos, readPos + length);
+			for (; readPos < endPos; readPos++)
+				into[intoWritePos++] = elements[readPos];
+			return intoWritePos;
+		} else {
+			// readPos higher than writePos - available sections are top + bottom of
+			// elements array
 
-    public int take(int[] into, int length){
-        int intoWritePos = 0;
-        if(!flipped){
-            //writePos higher than readPos - available section is writePos - readPos
+			if (length <= capacity - readPos) {
+				// length is lower than the elements available at the top of the elements array
+				// - copy directly
+				for (; intoWritePos < length; intoWritePos++)
+					into[intoWritePos] = elements[readPos++];
 
-            int endPos = Math.min(this.writePos, this.readPos + length);
-            for(; this.readPos < endPos; this.readPos++){
-                into[intoWritePos++] = this.elements[this.readPos];
-            }
-            return intoWritePos;
-        } else {
-            //readPos higher than writePos - available sections are top + bottom of elements array
+				return intoWritePos;
+			} else {
+				// length is higher than elements available at the top of the elements array
+				// split copy into a copy from both top and bottom of elements array.
 
-            if(length <= capacity - readPos){
-                //length is lower than the elements available at the top of the elements array - copy directly
-                for(; intoWritePos < length; intoWritePos++){
-                    into[intoWritePos] = this.elements[this.readPos++];
-                }
+				// copy from top
+				for (; readPos < capacity; readPos++)
+					into[intoWritePos++] = elements[readPos];
 
-                return intoWritePos;
-            } else {
-                //length is higher than elements available at the top of the elements array
-                //split copy into a copy from both top and bottom of elements array.
+				// copy from bottom
+				readPos	= 0;
+				flipped	= false;
+				int endPos = Math.min(writePos, length - intoWritePos);
+				for (; readPos < endPos; readPos++)
+					into[intoWritePos++] = elements[readPos];
 
-                //copy from top
-                for(; this.readPos < capacity; this.readPos++){
-                    into[intoWritePos++] = this.elements[this.readPos];
-                }
-
-                //copy from bottom
-                this.readPos = 0;
-                this.flipped = false;
-                int endPos = Math.min(this.writePos, length - intoWritePos);
-                for(; this.readPos < endPos; this.readPos++){
-                    into[intoWritePos++] = this.elements[this.readPos];
-                }
-
-                return intoWritePos;
-            }
-        }
-    }
-
-}
+				return intoWritePos;
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/com/jenkov/nioserver/Server.java b/src/main/java/com/jenkov/nioserver/Server.java
index 7bf8aac..2926384 100644
--- a/src/main/java/com/jenkov/nioserver/Server.java
+++ b/src/main/java/com/jenkov/nioserver/Server.java
@@ -3,44 +3,44 @@ package com.jenkov.nioserver;
 import java.io.IOException;
 import java.util.Queue;
 import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
 
 /**
- * Created by jjenkov on 24-10-2015.
+ * Project: java-nio-server
+ * File: Server.java
+ * Created: 24 Oct 2015
+ *
+ * @author jjenkov
  */
 public class Server {
 
-    private SocketAccepter  socketAccepter  = null;
-    private SocketProcessor socketProcessor = null;
+	private SocketAcceptor	socketAccepter;
+	private SocketProcessor	socketProcessor;
 
-    private int tcpPort = 0;
-    private IMessageReaderFactory messageReaderFactory = null;
-    private IMessageProcessor     messageProcessor = null;
+	private int						tcpPort;
+	private IMessageReaderFactory	messageReaderFactory;
+	private IMessageProcessor		messageProcessor;
 
-    public Server(int tcpPort, IMessageReaderFactory messageReaderFactory, IMessageProcessor messageProcessor) {
-        this.tcpPort = tcpPort;
-        this.messageReaderFactory = messageReaderFactory;
-        this.messageProcessor = messageProcessor;
-    }
+	public Server(int tcpPort, IMessageReaderFactory messageReaderFactory, IMessageProcessor messageProcessor) {
+		this.tcpPort				= tcpPort;
+		this.messageReaderFactory	= messageReaderFactory;
+		this.messageProcessor		= messageProcessor;
+	}
 
-    public void start() throws IOException {
+	public void start() throws IOException {
 
-        Queue socketQueue = new ArrayBlockingQueue(1024); //move 1024 to ServerConfig
+		Queue socketQueue = new ArrayBlockingQueue<>(1024); // TODO: move 1024 to ServerConfig
 
-        this.socketAccepter  = new SocketAccepter(tcpPort, socketQueue);
+		socketAccepter = new SocketAcceptor(tcpPort, socketQueue);
 
+		MessageBuffer	readBuffer	= new MessageBuffer();
+		MessageBuffer	writeBuffer	= new MessageBuffer();
 
-        MessageBuffer readBuffer  = new MessageBuffer();
-        MessageBuffer writeBuffer = new MessageBuffer();
+		socketProcessor = new SocketProcessor(socketQueue, readBuffer, writeBuffer, this.messageReaderFactory, this.messageProcessor);
 
-        this.socketProcessor = new SocketProcessor(socketQueue, readBuffer, writeBuffer,  this.messageReaderFactory, this.messageProcessor);
+		Thread	accepterThread	= new Thread(socketAccepter);
+		Thread	processorThread	= new Thread(socketProcessor);
 
-        Thread accepterThread  = new Thread(this.socketAccepter);
-        Thread processorThread = new Thread(this.socketProcessor);
-
-        accepterThread.start();
-        processorThread.start();
-    }
-
-
-}
+		accepterThread.start();
+		processorThread.start();
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/com/jenkov/nioserver/Socket.java b/src/main/java/com/jenkov/nioserver/Socket.java
index 298e7bb..9cad6ea 100644
--- a/src/main/java/com/jenkov/nioserver/Socket.java
+++ b/src/main/java/com/jenkov/nioserver/Socket.java
@@ -5,51 +5,47 @@ import java.nio.ByteBuffer;
 import java.nio.channels.SocketChannel;
 
 /**
- * Created by jjenkov on 16-10-2015.
+ * Project: java-nio-server
+ * File: Socket.java
+ * Created: 16 Oct 2015
+ *
+ * @author jjenkov
  */
 public class Socket {
 
-    public long socketId;
+	public long socketId;
 
-    public SocketChannel  socketChannel = null;
-    public IMessageReader messageReader = null;
-    public MessageWriter  messageWriter = null;
+	public SocketChannel	socketChannel;
+	public IMessageReader	messageReader;
+	public MessageWriter	messageWriter;
 
-    public boolean endOfStreamReached = false;
+	public boolean endOfStreamReached;
 
-    public Socket() {
-    }
+	public Socket(SocketChannel socketChannel) { this.socketChannel = socketChannel; }
 
-    public Socket(SocketChannel socketChannel) {
-        this.socketChannel = socketChannel;
-    }
+	public int read(ByteBuffer byteBuffer) throws IOException {
+		int	bytesRead		= socketChannel.read(byteBuffer);
+		int	totalBytesRead	= bytesRead;
 
-    public int read(ByteBuffer byteBuffer) throws IOException {
-        int bytesRead = this.socketChannel.read(byteBuffer);
-        int totalBytesRead = bytesRead;
+		while (bytesRead > 0) {
+			bytesRead		= socketChannel.read(byteBuffer);
+			totalBytesRead	+= bytesRead;
+		}
+		if (bytesRead == -1) endOfStreamReached = true;
 
-        while(bytesRead > 0){
-            bytesRead = this.socketChannel.read(byteBuffer);
-            totalBytesRead += bytesRead;
-        }
-        if(bytesRead == -1){
-            this.endOfStreamReached = true;
-        }
+		return totalBytesRead;
+	}
 
-        return totalBytesRead;
-    }
+	public int write(ByteBuffer byteBuffer) throws IOException {
+		int	bytesWritten		= socketChannel.write(byteBuffer);
+		int	totalBytesWritten	= bytesWritten;
 
-    public int write(ByteBuffer byteBuffer) throws IOException{
-        int bytesWritten      = this.socketChannel.write(byteBuffer);
-        int totalBytesWritten = bytesWritten;
-
-        while(bytesWritten > 0 && byteBuffer.hasRemaining()){
-            bytesWritten = this.socketChannel.write(byteBuffer);
-            totalBytesWritten += bytesWritten;
-        }
-
-        return totalBytesWritten;
-    }
+		while (bytesWritten > 0 && byteBuffer.hasRemaining()) {
+			bytesWritten		= socketChannel.write(byteBuffer);
+			totalBytesWritten	+= bytesWritten;
+		}
 
+		return totalBytesWritten;
+	}
 
 }
diff --git a/src/main/java/com/jenkov/nioserver/SocketAccepter.java b/src/main/java/com/jenkov/nioserver/SocketAccepter.java
deleted file mode 100644
index 138a39f..0000000
--- a/src/main/java/com/jenkov/nioserver/SocketAccepter.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.jenkov.nioserver;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.util.Queue;
-
-/**
- * Created by jjenkov on 19-10-2015.
- */
-public class SocketAccepter implements Runnable{
-
-    private int tcpPort = 0;
-    private ServerSocketChannel serverSocket = null;
-
-    private Queue socketQueue = null;
-
-    public SocketAccepter(int tcpPort, Queue socketQueue)  {
-        this.tcpPort     = tcpPort;
-        this.socketQueue = socketQueue;
-    }
-
-
-
-    public void run() {
-        try{
-            this.serverSocket = ServerSocketChannel.open();
-            this.serverSocket.bind(new InetSocketAddress(tcpPort));
-        } catch(IOException e){
-            e.printStackTrace();
-            return;
-        }
-
-
-        while(true){
-            try{
-                SocketChannel socketChannel = this.serverSocket.accept();
-
-                System.out.println("Socket accepted: " + socketChannel);
-
-                //todo check if the queue can even accept more sockets.
-                this.socketQueue.add(new Socket(socketChannel));
-
-            } catch(IOException e){
-                e.printStackTrace();
-            }
-
-        }
-
-    }
-}
diff --git a/src/main/java/com/jenkov/nioserver/SocketAcceptor.java b/src/main/java/com/jenkov/nioserver/SocketAcceptor.java
new file mode 100644
index 0000000..bde9c7a
--- /dev/null
+++ b/src/main/java/com/jenkov/nioserver/SocketAcceptor.java
@@ -0,0 +1,51 @@
+package com.jenkov.nioserver;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.util.Queue;
+
+/**
+ * Project: java-nio-server
+ * File: SocketAcceptor.java
+ * Created: 19 Oct 2015
+ *
+ * @author jjenkov
+ */
+public class SocketAcceptor implements Runnable {
+
+	private int					tcpPort;
+	private ServerSocketChannel	serverSocket;
+
+	private Queue socketQueue;
+
+	public SocketAcceptor(int tcpPort, Queue socketQueue) {
+		this.tcpPort		= tcpPort;
+		this.socketQueue	= socketQueue;
+	}
+
+	public void run() {
+		try {
+			serverSocket = ServerSocketChannel.open();
+			serverSocket.bind(new InetSocketAddress(tcpPort));
+		} catch (IOException e) {
+			e.printStackTrace();
+			return;
+		}
+
+		while (true) {
+			try {
+				SocketChannel socketChannel = serverSocket.accept();
+
+				System.out.println("Socket accepted: " + socketChannel);
+
+				// TODO: check if the queue can even accept more sockets.
+				this.socketQueue.add(new Socket(socketChannel));
+
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/com/jenkov/nioserver/SocketProcessor.java b/src/main/java/com/jenkov/nioserver/SocketProcessor.java
index 251fee6..f05e76b 100644
--- a/src/main/java/com/jenkov/nioserver/SocketProcessor.java
+++ b/src/main/java/com/jenkov/nioserver/SocketProcessor.java
@@ -5,211 +5,207 @@ import java.nio.ByteBuffer;
 import java.nio.channels.ClosedChannelException;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
-import java.util.*;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
 
 /**
- * Created by jjenkov on 16-10-2015.
+ * Project: java-nio-server
+ * File: SocketProcessor.java
+ * Created: 16 Oct 2015
+ *
+ * @author jjenkov
  */
 public class SocketProcessor implements Runnable {
 
-    private Queue  inboundSocketQueue   = null;
+	private Queue inboundSocketQueue;
 
-    private MessageBuffer  readMessageBuffer    = null; //todo   Not used now - but perhaps will be later - to check for space in the buffer before reading from sockets
-    private MessageBuffer  writeMessageBuffer   = null; //todo   Not used now - but perhaps will be later - to check for space in the buffer before reading from sockets (space for more to write?)
+	private MessageBuffer	readMessageBuffer;	// TODO: Not used now - but perhaps will be later - to check for space in the
+												// buffer before reading from sockets
+	@SuppressWarnings("unused")
+	private MessageBuffer	writeMessageBuffer;	// TODO: Not used now - but perhaps will be later - to check for space in the
+												// buffer before reading from sockets (space for more to write?)
 
-    private IMessageReaderFactory messageReaderFactory = null;
+	private IMessageReaderFactory messageReaderFactory;
 
-    private Queue outboundMessageQueue = new LinkedList<>(); //todo use a better / faster queue.
+	private Queue outboundMessageQueue = new LinkedList<>(); // TODO: use a better / faster queue.
 
-    private Map socketMap         = new HashMap<>();
+	private Map socketMap = new HashMap<>();
 
-    private ByteBuffer readByteBuffer  = ByteBuffer.allocate(1024 * 1024);
-    private ByteBuffer writeByteBuffer = ByteBuffer.allocate(1024 * 1024);
-    private Selector   readSelector    = null;
-    private Selector   writeSelector   = null;
+	private ByteBuffer	readByteBuffer	= ByteBuffer.allocate(1024 * 1024);
+	private ByteBuffer	writeByteBuffer	= ByteBuffer.allocate(1024 * 1024);
+	private Selector	readSelector;
+	private Selector	writeSelector;
 
-    private IMessageProcessor messageProcessor = null;
-    private WriteProxy        writeProxy       = null;
+	private IMessageProcessor	messageProcessor;
+	private WriteProxy			writeProxy;
 
-    private long              nextSocketId = 16 * 1024; //start incoming socket ids from 16K - reserve bottom ids for pre-defined sockets (servers).
+	private long nextSocketId = 16 * 1024; // start incoming socket ids from 16K - reserve bottom ids for pre-defined
+											// sockets (servers).
 
-    private Set emptyToNonEmptySockets = new HashSet<>();
-    private Set nonEmptyToEmptySockets = new HashSet<>();
+	private Set	emptyToNonEmptySockets	= new HashSet<>();
+	private Set	nonEmptyToEmptySockets	= new HashSet<>();
 
+	public SocketProcessor(Queue inboundSocketQueue, MessageBuffer readMessageBuffer, MessageBuffer writeMessageBuffer,
+			IMessageReaderFactory messageReaderFactory, IMessageProcessor messageProcessor) throws IOException {
+		this.inboundSocketQueue = inboundSocketQueue;
 
-    public SocketProcessor(Queue inboundSocketQueue, MessageBuffer readMessageBuffer, MessageBuffer writeMessageBuffer, IMessageReaderFactory messageReaderFactory, IMessageProcessor messageProcessor) throws IOException {
-        this.inboundSocketQueue = inboundSocketQueue;
+		this.readMessageBuffer	= readMessageBuffer;
+		this.writeMessageBuffer	= writeMessageBuffer;
+		writeProxy				= new WriteProxy(writeMessageBuffer, this.outboundMessageQueue);
 
-        this.readMessageBuffer    = readMessageBuffer;
-        this.writeMessageBuffer   = writeMessageBuffer;
-        this.writeProxy           = new WriteProxy(writeMessageBuffer, this.outboundMessageQueue);
+		this.messageReaderFactory = messageReaderFactory;
 
-        this.messageReaderFactory = messageReaderFactory;
+		this.messageProcessor = messageProcessor;
 
-        this.messageProcessor     = messageProcessor;
+		readSelector	= Selector.open();
+		writeSelector	= Selector.open();
+	}
 
-        this.readSelector         = Selector.open();
-        this.writeSelector        = Selector.open();
-    }
+	public void run() {
+		while (true) {
+			try {
+				executeCycle();
+				Thread.sleep(100);
+			} catch (IOException | InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+	}
 
-    public void run() {
-        while(true){
-            try{
-                executeCycle();
-            } catch(IOException e){
-                e.printStackTrace();
-            }
+	public void executeCycle() throws IOException {
+		takeNewSockets();
+		readFromSockets();
+		writeToSockets();
+	}
 
-            try {
-                Thread.sleep(100);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
-    }
+	public void takeNewSockets() throws IOException {
+		Socket newSocket = inboundSocketQueue.poll();
 
+		while (newSocket != null) {
+			newSocket.socketId = nextSocketId++;
+			newSocket.socketChannel.configureBlocking(false);
 
-    public void executeCycle() throws IOException {
-        takeNewSockets();
-        readFromSockets();
-        writeToSockets();
-    }
+			newSocket.messageReader = messageReaderFactory.createMessageReader();
+			newSocket.messageReader.init(readMessageBuffer);
 
+			newSocket.messageWriter = new MessageWriter();
 
-    public void takeNewSockets() throws IOException {
-        Socket newSocket = this.inboundSocketQueue.poll();
+			socketMap.put(newSocket.socketId, newSocket);
 
-        while(newSocket != null){
-            newSocket.socketId = this.nextSocketId++;
-            newSocket.socketChannel.configureBlocking(false);
+			SelectionKey key = newSocket.socketChannel.register(readSelector, SelectionKey.OP_READ);
+			key.attach(newSocket);
 
-            newSocket.messageReader = this.messageReaderFactory.createMessageReader();
-            newSocket.messageReader.init(this.readMessageBuffer);
+			newSocket = inboundSocketQueue.poll();
+		}
+	}
 
-            newSocket.messageWriter = new MessageWriter();
+	public void readFromSockets() throws IOException {
+		int readReady = readSelector.selectNow();
 
-            this.socketMap.put(newSocket.socketId, newSocket);
+		if (readReady > 0) {
+			Set		selectedKeys	= this.readSelector.selectedKeys();
+			Iterator	keyIterator		= selectedKeys.iterator();
 
-            SelectionKey key = newSocket.socketChannel.register(this.readSelector, SelectionKey.OP_READ);
-            key.attach(newSocket);
+			while (keyIterator.hasNext()) {
+				SelectionKey key = keyIterator.next();
+				readFromSocket(key);
+				keyIterator.remove();
+			}
+			selectedKeys.clear();
+		}
+	}
 
-            newSocket = this.inboundSocketQueue.poll();
-        }
-    }
+	private void readFromSocket(SelectionKey key) throws IOException {
+		Socket socket = (Socket) key.attachment();
+		socket.messageReader.read(socket, this.readByteBuffer);
 
+		List fullMessages = socket.messageReader.getMessages();
+		if (fullMessages.size() > 0) {
+			for (Message message : fullMessages) {
+				message.socketId = socket.socketId;
+				messageProcessor.process(message, writeProxy); // the message processor will eventually push outgoing messages into an
+																// IMessageWriter for this socket.
+			}
+			fullMessages.clear();
+		}
 
-    public void readFromSockets() throws IOException {
-        int readReady = this.readSelector.selectNow();
+		if (socket.endOfStreamReached) {
+			System.out.println("Socket closed: " + socket.socketId);
+			socketMap.remove(socket.socketId);
+			key.attach(null);
+			key.cancel();
+			key.channel().close();
+		}
+	}
 
-        if(readReady > 0){
-            Set selectedKeys = this.readSelector.selectedKeys();
-            Iterator keyIterator = selectedKeys.iterator();
+	public void writeToSockets() throws IOException {
 
-            while(keyIterator.hasNext()) {
-                SelectionKey key = keyIterator.next();
+		// Take all new messages from outboundMessageQueue
+		takeNewOutboundMessages();
 
-                readFromSocket(key);
+		// Cancel all sockets which have no more data to write.
+		cancelEmptySockets();
 
-                keyIterator.remove();
-            }
-            selectedKeys.clear();
-        }
-    }
+		// Register all sockets that *have* data and which are not yet registered.
+		registerNonEmptySockets();
 
-    private void readFromSocket(SelectionKey key) throws IOException {
-        Socket socket = (Socket) key.attachment();
-        socket.messageReader.read(socket, this.readByteBuffer);
+		// Select from the Selector.
+		int writeReady = this.writeSelector.selectNow();
 
-        List fullMessages = socket.messageReader.getMessages();
-        if(fullMessages.size() > 0){
-            for(Message message : fullMessages){
-                message.socketId = socket.socketId;
-                this.messageProcessor.process(message, this.writeProxy);  //the message processor will eventually push outgoing messages into an IMessageWriter for this socket.
-            }
-            fullMessages.clear();
-        }
+		if (writeReady > 0) {
+			Set		selectionKeys	= this.writeSelector.selectedKeys();
+			Iterator	keyIterator		= selectionKeys.iterator();
 
-        if(socket.endOfStreamReached){
-            System.out.println("Socket closed: " + socket.socketId);
-            this.socketMap.remove(socket.socketId);
-            key.attach(null);
-            key.cancel();
-            key.channel().close();
-        }
-    }
+			while (keyIterator.hasNext()) {
+				SelectionKey key = keyIterator.next();
 
+				Socket socket = (Socket) key.attachment();
 
-    public void writeToSockets() throws IOException {
+				socket.messageWriter.write(socket, this.writeByteBuffer);
 
-        // Take all new messages from outboundMessageQueue
-        takeNewOutboundMessages();
+				if (socket.messageWriter.isEmpty()) { this.nonEmptyToEmptySockets.add(socket); }
 
-        // Cancel all sockets which have no more data to write.
-        cancelEmptySockets();
+				keyIterator.remove();
+			}
+			selectionKeys.clear();
+		}
+	}
 
-        // Register all sockets that *have* data and which are not yet registered.
-        registerNonEmptySockets();
+	private void registerNonEmptySockets() throws ClosedChannelException {
+		for (Socket socket : emptyToNonEmptySockets)
+			socket.socketChannel.register(writeSelector, SelectionKey.OP_WRITE, socket);
+		emptyToNonEmptySockets.clear();
+	}
 
-        // Select from the Selector.
-        int writeReady = this.writeSelector.selectNow();
+	private void cancelEmptySockets() {
+		for (Socket socket : nonEmptyToEmptySockets) {
+			SelectionKey key = socket.socketChannel.keyFor(this.writeSelector);
+			key.cancel();
+		}
+		nonEmptyToEmptySockets.clear();
+	}
 
-        if(writeReady > 0){
-            Set      selectionKeys = this.writeSelector.selectedKeys();
-            Iterator keyIterator   = selectionKeys.iterator();
+	private void takeNewOutboundMessages() {
+		Message outMessage = outboundMessageQueue.poll();
+		while (outMessage != null) {
+			Socket socket = socketMap.get(outMessage.socketId);
 
-            while(keyIterator.hasNext()){
-                SelectionKey key = keyIterator.next();
+			if (socket != null) {
+				MessageWriter messageWriter = socket.messageWriter;
+				if (messageWriter.isEmpty()) {
+					messageWriter.enqueue(outMessage);
+					nonEmptyToEmptySockets.remove(socket);
+					emptyToNonEmptySockets.add(socket); // not necessary if removed from nonEmptyToEmptySockets in prev. statement.
+				} else messageWriter.enqueue(outMessage);
+			}
 
-                Socket socket = (Socket) key.attachment();
-
-                socket.messageWriter.write(socket, this.writeByteBuffer);
-
-                if(socket.messageWriter.isEmpty()){
-                    this.nonEmptyToEmptySockets.add(socket);
-                }
-
-                keyIterator.remove();
-            }
-
-            selectionKeys.clear();
-
-        }
-    }
-
-    private void registerNonEmptySockets() throws ClosedChannelException {
-        for(Socket socket : emptyToNonEmptySockets){
-            socket.socketChannel.register(this.writeSelector, SelectionKey.OP_WRITE, socket);
-        }
-        emptyToNonEmptySockets.clear();
-    }
-
-    private void cancelEmptySockets() {
-        for(Socket socket : nonEmptyToEmptySockets){
-            SelectionKey key = socket.socketChannel.keyFor(this.writeSelector);
-
-            key.cancel();
-        }
-        nonEmptyToEmptySockets.clear();
-    }
-
-    private void takeNewOutboundMessages() {
-        Message outMessage = this.outboundMessageQueue.poll();
-        while(outMessage != null){
-            Socket socket = this.socketMap.get(outMessage.socketId);
-
-            if(socket != null){
-                MessageWriter messageWriter = socket.messageWriter;
-                if(messageWriter.isEmpty()){
-                    messageWriter.enqueue(outMessage);
-                    nonEmptyToEmptySockets.remove(socket);
-                    emptyToNonEmptySockets.add(socket);    //not necessary if removed from nonEmptyToEmptySockets in prev. statement.
-                } else{
-                   messageWriter.enqueue(outMessage);
-                }
-            }
-
-            outMessage = this.outboundMessageQueue.poll();
-        }
-    }
-
-}
+			outMessage = outboundMessageQueue.poll();
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/com/jenkov/nioserver/WriteProxy.java b/src/main/java/com/jenkov/nioserver/WriteProxy.java
index 2c99529..ff4aff0 100644
--- a/src/main/java/com/jenkov/nioserver/WriteProxy.java
+++ b/src/main/java/com/jenkov/nioserver/WriteProxy.java
@@ -3,24 +3,23 @@ package com.jenkov.nioserver;
 import java.util.Queue;
 
 /**
- * Created by jjenkov on 22-10-2015.
+ * Project: java-nio-server
+ * File: WriteProxy.java
+ * Created: 22 Oct 2015
+ *
+ * @author jjenkov
  */
 public class WriteProxy {
 
-    private MessageBuffer messageBuffer = null;
-    private Queue        writeQueue     = null;
+	private MessageBuffer	messageBuffer;
+	private Queue	writeQueue;
 
-    public WriteProxy(MessageBuffer messageBuffer, Queue writeQueue) {
-        this.messageBuffer = messageBuffer;
-        this.writeQueue = writeQueue;
-    }
+	public WriteProxy(MessageBuffer messageBuffer, Queue writeQueue) {
+		this.messageBuffer	= messageBuffer;
+		this.writeQueue		= writeQueue;
+	}
 
-    public Message getMessage(){
-        return this.messageBuffer.getMessage();
-    }
+	public Message getMessage() { return messageBuffer.getMessage(); }
 
-    public boolean enqueue(Message message){
-        return this.writeQueue.offer(message);
-    }
-
-}
+	public boolean enqueue(Message message) { return writeQueue.offer(message); }
+}
\ No newline at end of file
diff --git a/src/main/java/com/jenkov/nioserver/example/Main.java b/src/main/java/com/jenkov/nioserver/example/Main.java
index 238c8ea..fb5483c 100644
--- a/src/main/java/com/jenkov/nioserver/example/Main.java
+++ b/src/main/java/com/jenkov/nioserver/example/Main.java
@@ -1,42 +1,40 @@
 package com.jenkov.nioserver.example;
 
-import com.jenkov.nioserver.*;
+import java.io.IOException;
+
+import com.jenkov.nioserver.IMessageProcessor;
+import com.jenkov.nioserver.Message;
+import com.jenkov.nioserver.Server;
 import com.jenkov.nioserver.http.HttpMessageReaderFactory;
 
-import java.io.IOException;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-
 /**
- * Created by jjenkov on 19-10-2015.
+ * Project: java-nio-server
+ * File: Main.java
+ * Created: 19 Oct 2015
+ *
+ * @author jjenkov
  */
 public class Main {
 
-    public static void main(String[] args) throws IOException {
+	public static void main(String[] args) throws IOException {
 
-        String httpResponse = "HTTP/1.1 200 OK\r\n" +
-                "Content-Length: 38\r\n" +
-                "Content-Type: text/html\r\n" +
-                "\r\n" +
-                "Hello World!";
+		String httpResponse = "HTTP/1.1 200 OK\r\n" + "Content-Length: 38\r\n" + "Content-Type: text/html\r\n" + "\r\n"
+				+ "Hello World!";
 
-        byte[] httpResponseBytes = httpResponse.getBytes("UTF-8");
+		byte[] httpResponseBytes = httpResponse.getBytes("UTF-8");
 
-        IMessageProcessor messageProcessor = (request, writeProxy) -> {
-            System.out.println("Message Received from socket: " + request.socketId);
+		IMessageProcessor messageProcessor = (request, writeProxy) -> {
+			System.out.println("Message Received from socket: " + request.socketId);
 
-            Message response = writeProxy.getMessage();
-            response.socketId = request.socketId;
-            response.writeToMessage(httpResponseBytes);
+			Message response = writeProxy.getMessage();
+			response.socketId = request.socketId;
+			response.writeToMessage(httpResponseBytes);
 
-            writeProxy.enqueue(response);
-        };
+			writeProxy.enqueue(response);
+		};
 
-        Server server = new Server(9999, new HttpMessageReaderFactory(), messageProcessor);
+		Server server = new Server(9999, new HttpMessageReaderFactory(), messageProcessor);
 
-        server.start();
-
-    }
-
-
-}
+		server.start();
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/com/jenkov/nioserver/http/HttpHeaders.java b/src/main/java/com/jenkov/nioserver/http/HttpHeaders.java
index 25e5a1b..bd02701 100644
--- a/src/main/java/com/jenkov/nioserver/http/HttpHeaders.java
+++ b/src/main/java/com/jenkov/nioserver/http/HttpHeaders.java
@@ -1,27 +1,27 @@
 package com.jenkov.nioserver.http;
 
 /**
- * Created by jjenkov on 19-10-2015.
+ * Project: java-nio-server
+ * File: HttpHeaders.java
+ * Created: 19 Oct 2015
+ *
+ * @author jjenkov
  */
 public class HttpHeaders {
 
-    public static int HTTP_METHOD_GET    = 1;
-    public static int HTTP_METHOD_POST   = 2;
-    public static int HTTP_METHOD_PUT    = 3;
-    public static int HTTP_METHOD_HEAD   = 4;
-    public static int HTTP_METHOD_DELETE = 5;
+	public static int	HTTP_METHOD_GET		= 1;
+	public static int	HTTP_METHOD_POST	= 2;
+	public static int	HTTP_METHOD_PUT		= 3;
+	public static int	HTTP_METHOD_HEAD	= 4;
+	public static int	HTTP_METHOD_DELETE	= 5;
 
-    public int httpMethod    = 0;
+	public int httpMethod = 0;
 
-    public int hostStartIndex = 0;
-    public int hostEndIndex   = 0;
+	public int	hostStartIndex	= 0;
+	public int	hostEndIndex	= 0;
 
-    public int contentLength = 0;
+	public int contentLength = 0;
 
-    public int bodyStartIndex = 0;
-    public int bodyEndIndex   = 0;
-
-
-
-
-}
+	public int	bodyStartIndex	= 0;
+	public int	bodyEndIndex	= 0;
+}
\ No newline at end of file
diff --git a/src/main/java/com/jenkov/nioserver/http/HttpMessageReader.java b/src/main/java/com/jenkov/nioserver/http/HttpMessageReader.java
index cf3a6e1..3738276 100644
--- a/src/main/java/com/jenkov/nioserver/http/HttpMessageReader.java
+++ b/src/main/java/com/jenkov/nioserver/http/HttpMessageReader.java
@@ -1,64 +1,64 @@
 package com.jenkov.nioserver.http;
 
-import com.jenkov.nioserver.IMessageReader;
-import com.jenkov.nioserver.Message;
-import com.jenkov.nioserver.MessageBuffer;
-import com.jenkov.nioserver.Socket;
-
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.List;
 
+import com.jenkov.nioserver.IMessageReader;
+import com.jenkov.nioserver.Message;
+import com.jenkov.nioserver.MessageBuffer;
+import com.jenkov.nioserver.Socket;
+
 /**
- * Created by jjenkov on 18-10-2015.
+ * Project: java-nio-server
+ * File: HttpMessageReader.java
+ * Created: 18 Oct 2015
+ *
+ * @author jjenkov
  */
 public class HttpMessageReader implements IMessageReader {
 
-    private MessageBuffer messageBuffer    = null;
+	private MessageBuffer messageBuffer;
 
-    private List completeMessages = new ArrayList();
-    private Message       nextMessage      = null;
+	private List	completeMessages	= new ArrayList<>();
+	private Message			nextMessage;
 
-    public HttpMessageReader() {
-    }
+	@Override
+	public void init(MessageBuffer readMessageBuffer) {
+		messageBuffer			= readMessageBuffer;
+		nextMessage				= messageBuffer.getMessage();
+		nextMessage.metaData	= new HttpHeaders();
+	}
 
-    @Override
-    public void init(MessageBuffer readMessageBuffer) {
-        this.messageBuffer        = readMessageBuffer;
-        this.nextMessage          = messageBuffer.getMessage();
-        this.nextMessage.metaData = new HttpHeaders();
-    }
+	@Override
+	public void read(Socket socket, ByteBuffer byteBuffer) throws IOException {
+		socket.read(byteBuffer);
+		byteBuffer.flip();
 
-    @Override
-    public void read(Socket socket, ByteBuffer byteBuffer) throws IOException {
-        int bytesRead = socket.read(byteBuffer);
-        byteBuffer.flip();
+		if (byteBuffer.remaining() == 0) {
+			byteBuffer.clear();
+			return;
+		}
 
-        if(byteBuffer.remaining() == 0){
-            byteBuffer.clear();
-            return;
-        }
+		nextMessage.writeToMessage(byteBuffer);
 
-        this.nextMessage.writeToMessage(byteBuffer);
+		int endIndex = HttpUtil.parseHttpRequest(nextMessage.sharedArray,
+				nextMessage.offset,
+				nextMessage.offset + nextMessage.length,
+				(HttpHeaders) nextMessage.metaData);
+		if (endIndex != -1) {
+			Message message = messageBuffer.getMessage();
+			message.metaData = new HttpHeaders();
 
-        int endIndex = HttpUtil.parseHttpRequest(this.nextMessage.sharedArray, this.nextMessage.offset, this.nextMessage.offset + this.nextMessage.length, (HttpHeaders) this.nextMessage.metaData);
-        if(endIndex != -1){
-            Message message = this.messageBuffer.getMessage();
-            message.metaData = new HttpHeaders();
+			message.writePartialMessageToMessage(nextMessage, endIndex);
 
-            message.writePartialMessageToMessage(nextMessage, endIndex);
+			completeMessages.add(nextMessage);
+			nextMessage = message;
+		}
+		byteBuffer.clear();
+	}
 
-            completeMessages.add(nextMessage);
-            nextMessage = message;
-        }
-        byteBuffer.clear();
-    }
-
-
-    @Override
-    public List getMessages() {
-        return this.completeMessages;
-    }
-
-}
+	@Override
+	public List getMessages() { return completeMessages; }
+}
\ No newline at end of file
diff --git a/src/main/java/com/jenkov/nioserver/http/HttpMessageReaderFactory.java b/src/main/java/com/jenkov/nioserver/http/HttpMessageReaderFactory.java
index e855aed..82b4c91 100644
--- a/src/main/java/com/jenkov/nioserver/http/HttpMessageReaderFactory.java
+++ b/src/main/java/com/jenkov/nioserver/http/HttpMessageReaderFactory.java
@@ -2,18 +2,16 @@ package com.jenkov.nioserver.http;
 
 import com.jenkov.nioserver.IMessageReader;
 import com.jenkov.nioserver.IMessageReaderFactory;
-import com.jenkov.nioserver.MessageBuffer;
 
 /**
- * Created by jjenkov on 18-10-2015.
+ * Project: java-nio-server
+ * File: HttpMessageReaderFactory.java
+ * Created: 18 Oct 2015
+ *
+ * @author jjenkov
  */
 public class HttpMessageReaderFactory implements IMessageReaderFactory {
 
-    public HttpMessageReaderFactory() {
-    }
-
-    @Override
-    public IMessageReader createMessageReader() {
-        return new HttpMessageReader();
-    }
-}
+	@Override
+	public IMessageReader createMessageReader() { return new HttpMessageReader(); }
+}
\ No newline at end of file
diff --git a/src/main/java/com/jenkov/nioserver/http/HttpUtil.java b/src/main/java/com/jenkov/nioserver/http/HttpUtil.java
index ed2904d..16f4543 100644
--- a/src/main/java/com/jenkov/nioserver/http/HttpUtil.java
+++ b/src/main/java/com/jenkov/nioserver/http/HttpUtil.java
@@ -3,153 +3,143 @@ package com.jenkov.nioserver.http;
 import java.io.UnsupportedEncodingException;
 
 /**
- * Created by jjenkov on 19-10-2015.
+ * Project: java-nio-server
+ * File: HttpUtil.java
+ * Created: 19 Oct 2015
+ *
+ * @author jjenkov
  */
 public class HttpUtil {
 
-    private static final byte[] GET    = new byte[]{'G','E','T'};
-    private static final byte[] POST   = new byte[]{'P','O','S','T'};
-    private static final byte[] PUT    = new byte[]{'P','U','T'};
-    private static final byte[] HEAD   = new byte[]{'H','E','A','D'};
-    private static final byte[] DELETE = new byte[]{'D','E','L','E','T','E'};
+	private static final byte[]	GET		= new byte[] { 'G', 'E', 'T' };
+	private static final byte[]	POST	= new byte[] { 'P', 'O', 'S', 'T' };
+	private static final byte[]	PUT		= new byte[] { 'P', 'U', 'T' };
+	private static final byte[]	HEAD	= new byte[] { 'H', 'E', 'A', 'D' };
+	private static final byte[]	DELETE	= new byte[] { 'D', 'E', 'L', 'E', 'T', 'E' };
 
-    private static final byte[] HOST           = new byte[]{'H','o','s','t'};
-    private static final byte[] CONTENT_LENGTH = new byte[]{'C','o','n','t','e','n','t','-','L','e','n','g','t','h'};
+	@SuppressWarnings("unused")
+	private static final byte[]	HOST			= new byte[] { 'H', 'o', 's', 't' };
+	private static final byte[]	CONTENT_LENGTH	= new byte[] { 'C', 'o', 'n', 't', 'e', 'n', 't', '-', 'L', 'e', 'n', 'g', 't', 'h' };
 
-    public static int parseHttpRequest(byte[] src, int startIndex, int endIndex, HttpHeaders httpHeaders){
+	public static int parseHttpRequest(byte[] src, int startIndex, int endIndex, HttpHeaders httpHeaders) {
 
+		/*
+		 * int endOfHttpMethod = findNext(src, startIndex, endIndex, (byte) ' ');
+		 * if(endOfHttpMethod == -1) return false;
+		 * resolveHttpMethod(src, startIndex, httpHeaders);
+		 */
 
-        /*
-        int endOfHttpMethod = findNext(src, startIndex, endIndex, (byte) ' ');
-        if(endOfHttpMethod == -1) return false;
-        resolveHttpMethod(src, startIndex, httpHeaders);
-        */
+		// parse HTTP request line
+		int endOfFirstLine = findNextLineBreak(src, startIndex, endIndex);
+		if (endOfFirstLine == -1) return -1;
 
-        //parse HTTP request line
-        int endOfFirstLine = findNextLineBreak(src, startIndex, endIndex);
-        if(endOfFirstLine == -1) return -1;
+		// parse HTTP headers
+		int	prevEndOfHeader	= endOfFirstLine + 1;
+		int	endOfHeader		= findNextLineBreak(src, prevEndOfHeader, endIndex);
 
+		while (endOfHeader != -1 && endOfHeader != prevEndOfHeader + 1) { // prevEndOfHeader + 1 = end of previous header + 2 (+2 = CR + LF)
 
-        //parse HTTP headers
-        int prevEndOfHeader = endOfFirstLine + 1;
-        int endOfHeader = findNextLineBreak(src, prevEndOfHeader, endIndex);
+			if (matches(src, prevEndOfHeader, CONTENT_LENGTH)) {
+				try {
+					findContentLength(src, prevEndOfHeader, endIndex, httpHeaders);
+				} catch (UnsupportedEncodingException e) {
+					e.printStackTrace();
+				}
+			}
 
-        while(endOfHeader != -1 && endOfHeader != prevEndOfHeader + 1){    //prevEndOfHeader + 1 = end of previous header + 2 (+2 = CR + LF)
+			prevEndOfHeader	= endOfHeader + 1;
+			endOfHeader		= findNextLineBreak(src, prevEndOfHeader, endIndex);
+		}
 
-            if(matches(src, prevEndOfHeader, CONTENT_LENGTH)){
-                try {
-                    findContentLength(src, prevEndOfHeader, endIndex, httpHeaders);
-                } catch (UnsupportedEncodingException e) {
-                    e.printStackTrace();
-                }
-            }
+		if (endOfHeader == -1) { return -1; }
 
-            prevEndOfHeader = endOfHeader + 1;
-            endOfHeader = findNextLineBreak(src, prevEndOfHeader, endIndex);
-        }
+		// check that byte array contains full HTTP message.
+		int	bodyStartIndex	= endOfHeader + 1;
+		int	bodyEndIndex	= bodyStartIndex + httpHeaders.contentLength;
 
-        if(endOfHeader == -1){
-            return -1;
-        }
+		if (bodyEndIndex <= endIndex) {
+			// byte array contains a full HTTP request
+			httpHeaders.bodyStartIndex	= bodyStartIndex;
+			httpHeaders.bodyEndIndex	= bodyEndIndex;
+			return bodyEndIndex;
+		}
 
-        //check that byte array contains full HTTP message.
-        int bodyStartIndex = endOfHeader + 1;
-        int bodyEndIndex  = bodyStartIndex + httpHeaders.contentLength;
+		return -1;
+	}
 
-        if(bodyEndIndex <= endIndex){
-            //byte array contains a full HTTP request
-            httpHeaders.bodyStartIndex = bodyStartIndex;
-            httpHeaders.bodyEndIndex   = bodyEndIndex;
-            return bodyEndIndex;
-        }
+	private static void findContentLength(byte[] src, int startIndex, int endIndex, HttpHeaders httpHeaders) throws UnsupportedEncodingException {
+		int indexOfColon = findNext(src, startIndex, endIndex, (byte) ':');
 
+		// skip spaces after colon
+		int index = indexOfColon + 1;
+		while (src[index] == ' ') {
+			index++;
+		}
 
-       return -1;
-    }
+		int		valueStartIndex	= index;
+		int		valueEndIndex	= index;
+		boolean	endOfValueFound	= false;
 
-    private static void findContentLength(byte[] src, int startIndex, int endIndex, HttpHeaders httpHeaders) throws UnsupportedEncodingException {
-        int indexOfColon = findNext(src, startIndex, endIndex, (byte) ':');
+		while (index < endIndex && !endOfValueFound) {
+			switch (src[index]) {
+				case '0':
+				case '1':
+				case '2':
+				case '3':
+				case '4':
+				case '5':
+				case '6':
+				case '7':
+				case '8':
+				case '9':
+					index++;
+					break;
+				default:
+					endOfValueFound = true;
+					valueEndIndex = index;
+			}
+		}
+		httpHeaders.contentLength = Integer.parseInt(new String(src, valueStartIndex, valueEndIndex - valueStartIndex, "UTF-8"));
+	}
 
-        //skip spaces after colon
-        int index = indexOfColon +1;
-        while(src[index] == ' '){
-            index++;
-        }
+	public static int findNext(byte[] src, int startIndex, int endIndex, byte value) {
+		for (int index = startIndex; index < endIndex; index++)
+			if (src[index] == value) return index;
+		return -1;
+	}
 
-        int valueStartIndex = index;
-        int valueEndIndex   = index;
-        boolean endOfValueFound = false;
+	public static int findNextLineBreak(byte[] src, int startIndex, int endIndex) {
+		for (int index = startIndex; index < endIndex; index++)
+			if (src[index] == '\n') if (src[index - 1] == '\r') return index;
+		return -1;
+	}
 
-        while(index < endIndex && !endOfValueFound){
-            switch(src[index]){
-                case '0' : ;
-                case '1' : ;
-                case '2' : ;
-                case '3' : ;
-                case '4' : ;
-                case '5' : ;
-                case '6' : ;
-                case '7' : ;
-                case '8' : ;
-                case '9' : { index++;  break; }
+	public static void resolveHttpMethod(byte[] src, int startIndex, HttpHeaders httpHeaders) {
+		if (matches(src, startIndex, GET)) {
+			httpHeaders.httpMethod = HttpHeaders.HTTP_METHOD_GET;
+			return;
+		}
+		if (matches(src, startIndex, POST)) {
+			httpHeaders.httpMethod = HttpHeaders.HTTP_METHOD_POST;
+			return;
+		}
+		if (matches(src, startIndex, PUT)) {
+			httpHeaders.httpMethod = HttpHeaders.HTTP_METHOD_PUT;
+			return;
+		}
+		if (matches(src, startIndex, HEAD)) {
+			httpHeaders.httpMethod = HttpHeaders.HTTP_METHOD_HEAD;
+			return;
+		}
+		if (matches(src, startIndex, DELETE)) {
+			httpHeaders.httpMethod = HttpHeaders.HTTP_METHOD_DELETE;
+			return;
+		}
+	}
 
-                default: {
-                    endOfValueFound = true;
-                    valueEndIndex = index;
-                }
-            }
-        }
-
-        httpHeaders.contentLength = Integer.parseInt(new String(src, valueStartIndex, valueEndIndex - valueStartIndex, "UTF-8"));
-
-    }
-
-
-    public static int findNext(byte[] src, int startIndex, int endIndex, byte value){
-        for(int index = startIndex; index < endIndex; index++){
-            if(src[index] == value) return index;
-        }
-        return -1;
-    }
-
-    public static int findNextLineBreak(byte[] src, int startIndex, int endIndex) {
-        for(int index = startIndex; index < endIndex; index++){
-            if(src[index] == '\n'){
-                if(src[index - 1] == '\r'){
-                    return index;
-                }
-            };
-        }
-        return -1;
-    }
-
-    public static void resolveHttpMethod(byte[] src, int startIndex, HttpHeaders httpHeaders){
-        if(matches(src, startIndex, GET)) {
-            httpHeaders.httpMethod = HttpHeaders.HTTP_METHOD_GET;
-            return;
-        }
-        if(matches(src, startIndex, POST)){
-            httpHeaders.httpMethod = HttpHeaders.HTTP_METHOD_POST;
-            return;
-        }
-        if(matches(src, startIndex, PUT)){
-            httpHeaders.httpMethod = HttpHeaders.HTTP_METHOD_PUT;
-            return;
-        }
-        if(matches(src, startIndex, HEAD)){
-            httpHeaders.httpMethod = HttpHeaders.HTTP_METHOD_HEAD;
-            return;
-        }
-        if(matches(src, startIndex, DELETE)){
-            httpHeaders.httpMethod = HttpHeaders.HTTP_METHOD_DELETE;
-            return;
-        }
-    }
-
-    public static boolean matches(byte[] src, int offset, byte[] value){
-        for(int i=offset, n=0; n < value.length; i++, n++){
-            if(src[i] != value[n]) return false;
-        }
-        return true;
-    }
-}
+	public static boolean matches(byte[] src, int offset, byte[] value) {
+		for (int i = offset, n = 0; n < value.length; i++, n++)
+			if (src[i] != value[n]) return false;
+		return true;
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/com.jenkov.nioserver/MessageBufferTest.java b/src/test/java/com.jenkov.nioserver/MessageBufferTest.java
deleted file mode 100644
index b1e1cda..0000000
--- a/src/test/java/com.jenkov.nioserver/MessageBufferTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package com.jenkov.nioserver;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-
-/**
- * Created by jjenkov on 18-10-2015.
- */
-public class MessageBufferTest {
-
-    @Test
-    public void testGetMessage() {
-
-        MessageBuffer messageBuffer = new MessageBuffer();
-
-        Message message = messageBuffer.getMessage();
-
-        assertNotNull(message);
-        assertEquals(0       , message.offset);
-        assertEquals(0       , message.length);
-        assertEquals(4 * 1024, message.capacity);
-
-        Message message2 = messageBuffer.getMessage();
-
-        assertNotNull(message2);
-        assertEquals(4096    , message2.offset);
-        assertEquals(0       , message2.length);
-        assertEquals(4 * 1024, message2.capacity);
-
-        //todo test what happens if the small buffer space is depleted of messages.
-
-    }
-
-
-    @Test
-    public void testExpandMessage(){
-        MessageBuffer messageBuffer = new MessageBuffer();
-
-        Message message = messageBuffer.getMessage();
-
-        byte[] smallSharedArray = message.sharedArray;
-
-        assertNotNull(message);
-        assertEquals(0       , message.offset);
-        assertEquals(0       , message.length);
-        assertEquals(4 * 1024, message.capacity);
-
-        messageBuffer.expandMessage(message);
-        assertEquals(0         , message.offset);
-        assertEquals(0         , message.length);
-        assertEquals(128 * 1024, message.capacity);
-
-        byte[] mediumSharedArray = message.sharedArray;
-        assertNotSame(smallSharedArray, mediumSharedArray);
-
-        messageBuffer.expandMessage(message);
-        assertEquals(0          , message.offset);
-        assertEquals(0          , message.length);
-        assertEquals(1024 * 1024, message.capacity);
-
-        byte[] largeSharedArray = message.sharedArray;
-        assertNotSame(smallSharedArray, largeSharedArray);
-        assertNotSame(mediumSharedArray, largeSharedArray);
-
-        //next expansion should not be possible.
-        assertFalse(messageBuffer.expandMessage(message));
-        assertEquals(0          , message.offset);
-        assertEquals(0          , message.length);
-        assertEquals(1024 * 1024, message.capacity);
-        assertSame(message.sharedArray, largeSharedArray);
-
-
-
-    }
-}
diff --git a/src/test/java/com.jenkov.nioserver/MessageTest.java b/src/test/java/com.jenkov.nioserver/MessageTest.java
deleted file mode 100644
index dcc070f..0000000
--- a/src/test/java/com.jenkov.nioserver/MessageTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.jenkov.nioserver;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-
-import java.nio.ByteBuffer;
-
-
-/**
- * Created by jjenkov on 18-10-2015.
- */
-public class MessageTest {
-
-
-    @Test
-    public void testWriteToMessage() {
-        MessageBuffer messageBuffer = new MessageBuffer();
-
-        Message    message    = messageBuffer.getMessage();
-        ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 1024);
-
-        fill(byteBuffer, 4096);
-
-        int written = message.writeToMessage(byteBuffer);
-        assertEquals(4096, written);
-        assertEquals(4096, message.length);
-        assertSame(messageBuffer.smallMessageBuffer, message.sharedArray);
-
-        fill(byteBuffer, 124 * 1024);
-        written = message.writeToMessage(byteBuffer);
-        assertEquals(124 * 1024, written);
-        assertEquals(128 * 1024, message.length);
-        assertSame(messageBuffer.mediumMessageBuffer, message.sharedArray);
-
-        fill(byteBuffer, (1024-128) * 1024);
-        written = message.writeToMessage(byteBuffer);
-        assertEquals(896  * 1024, written);
-        assertEquals(1024 * 1024, message.length);
-        assertSame(messageBuffer.largeMessageBuffer, message.sharedArray);
-
-        fill(byteBuffer, 1);
-        written = message.writeToMessage(byteBuffer);
-        assertEquals(-1, written);
-
-    }
-
-    private void fill(ByteBuffer byteBuffer, int length){
-        byteBuffer.clear();
-        for(int i=0; ijava-nio-server
+ * File: MessageBufferTest.java
+ * Created: 18 Oct 2015
+ *
+ * @author jjenkov
+ */
+public class MessageBufferTest {
+
+	@Test
+	public void testGetMessage() {
+
+		MessageBuffer messageBuffer = new MessageBuffer();
+
+		Message message = messageBuffer.getMessage();
+
+		assertNotNull(message);
+		assertEquals(0, message.offset);
+		assertEquals(0, message.length);
+		assertEquals(4 * 1024, message.capacity);
+
+		Message message2 = messageBuffer.getMessage();
+
+		assertNotNull(message2);
+		assertEquals(4096, message2.offset);
+		assertEquals(0, message2.length);
+		assertEquals(4 * 1024, message2.capacity);
+
+		// TODO: test what happens if the small buffer space is depleted of messages.
+	}
+
+	@Test
+	public void testExpandMessage() {
+		MessageBuffer messageBuffer = new MessageBuffer();
+
+		Message message = messageBuffer.getMessage();
+
+		byte[] smallSharedArray = message.sharedArray;
+
+		assertNotNull(message);
+		assertEquals(0, message.offset);
+		assertEquals(0, message.length);
+		assertEquals(4 * 1024, message.capacity);
+
+		messageBuffer.expandMessage(message);
+		assertEquals(0, message.offset);
+		assertEquals(0, message.length);
+		assertEquals(128 * 1024, message.capacity);
+
+		byte[] mediumSharedArray = message.sharedArray;
+		assertNotSame(smallSharedArray, mediumSharedArray);
+
+		messageBuffer.expandMessage(message);
+		assertEquals(0, message.offset);
+		assertEquals(0, message.length);
+		assertEquals(1024 * 1024, message.capacity);
+
+		byte[] largeSharedArray = message.sharedArray;
+		assertNotSame(smallSharedArray, largeSharedArray);
+		assertNotSame(mediumSharedArray, largeSharedArray);
+
+		// next expansion should not be possible.
+		assertFalse(messageBuffer.expandMessage(message));
+		assertEquals(0, message.offset);
+		assertEquals(0, message.length);
+		assertEquals(1024 * 1024, message.capacity);
+		assertSame(message.sharedArray, largeSharedArray);
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/com/jenkov/nioserver/MessageTest.java b/src/test/java/com/jenkov/nioserver/MessageTest.java
new file mode 100644
index 0000000..4e838dc
--- /dev/null
+++ b/src/test/java/com/jenkov/nioserver/MessageTest.java
@@ -0,0 +1,56 @@
+package com.jenkov.nioserver;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+import java.nio.ByteBuffer;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Project: java-nio-server
+ * File: MessageTest.java
+ * Created: 18 Oct 2015
+ *
+ * @author jjenkov
+ */
+public class MessageTest {
+
+	@Test
+	public void testWriteToMessage() {
+		MessageBuffer messageBuffer = new MessageBuffer();
+
+		Message		message		= messageBuffer.getMessage();
+		ByteBuffer	byteBuffer	= ByteBuffer.allocate(1024 * 1024);
+
+		fill(byteBuffer, 4096);
+
+		int written = message.writeToMessage(byteBuffer);
+		assertEquals(4096, written);
+		assertEquals(4096, message.length);
+		assertSame(messageBuffer.smallMessageBuffer, message.sharedArray);
+
+		fill(byteBuffer, 124 * 1024);
+		written = message.writeToMessage(byteBuffer);
+		assertEquals(124 * 1024, written);
+		assertEquals(128 * 1024, message.length);
+		assertSame(messageBuffer.mediumMessageBuffer, message.sharedArray);
+
+		fill(byteBuffer, (1024 - 128) * 1024);
+		written = message.writeToMessage(byteBuffer);
+		assertEquals(896 * 1024, written);
+		assertEquals(1024 * 1024, message.length);
+		assertSame(messageBuffer.largeMessageBuffer, message.sharedArray);
+
+		fill(byteBuffer, 1);
+		written = message.writeToMessage(byteBuffer);
+		assertEquals(-1, written);
+	}
+
+	private void fill(ByteBuffer byteBuffer, int length) {
+		byteBuffer.clear();
+		for (int i = 0; i < length; i++)
+			byteBuffer.put((byte) (i % 128));
+		byteBuffer.flip();
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/com.jenkov.nioserver/SelectorTest.java b/src/test/java/com/jenkov/nioserver/SelectorTest.java
similarity index 78%
rename from src/test/java/com.jenkov.nioserver/SelectorTest.java
rename to src/test/java/com/jenkov/nioserver/SelectorTest.java
index 497f5d5..e8bc589 100644
--- a/src/test/java/com.jenkov.nioserver/SelectorTest.java
+++ b/src/test/java/com/jenkov/nioserver/SelectorTest.java
@@ -1,15 +1,19 @@
 package com.jenkov.nioserver;
 
-import org.junit.Test;
-
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
 import java.nio.channels.SocketChannel;
 
+import org.junit.jupiter.api.Test;
+
 /**
- * Created by jjenkov on 21-10-2015.
+ * Project: java-nio-server
+ * File: SelectorTest.java
+ * Created: 21 Oct 2015
+ *
+ * @author jjenkov
  */
 public class SelectorTest {
 
@@ -27,10 +31,5 @@ public class SelectorTest {
 
         SelectionKey key2 = socketChannel.register(selector, SelectionKey.OP_WRITE);
         key2.cancel();
-
-
-
     }
-
-
-}
+}
\ No newline at end of file
diff --git a/src/test/java/com/jenkov/nioserver/http/HttpUtilTest.java b/src/test/java/com/jenkov/nioserver/http/HttpUtilTest.java
new file mode 100644
index 0000000..83c0d50
--- /dev/null
+++ b/src/test/java/com/jenkov/nioserver/http/HttpUtilTest.java
@@ -0,0 +1,67 @@
+package com.jenkov.nioserver.http;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.UnsupportedEncodingException;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Project: java-nio-server
+ * File: HttpUtilTest.java
+ * Created: 19 Oct 2015
+ *
+ * @author jjenkov
+ */
+public class HttpUtilTest {
+
+	@Test
+	public void testResolveHttpMethod() throws UnsupportedEncodingException {
+		assertHttpMethod("GET / HTTP/1.1\r\n", HttpHeaders.HTTP_METHOD_GET);
+		assertHttpMethod("POST / HTTP/1.1\r\n", HttpHeaders.HTTP_METHOD_POST);
+		assertHttpMethod("PUT / HTTP/1.1\r\n", HttpHeaders.HTTP_METHOD_PUT);
+		assertHttpMethod("HEAD / HTTP/1.1\r\n", HttpHeaders.HTTP_METHOD_HEAD);
+		assertHttpMethod("DELETE / HTTP/1.1\r\n", HttpHeaders.HTTP_METHOD_DELETE);
+	}
+
+	private void assertHttpMethod(String httpRequest, int httpMethod) throws UnsupportedEncodingException {
+		byte[]		source		= httpRequest.getBytes("UTF-8");
+		HttpHeaders	httpHeaders	= new HttpHeaders();
+
+		HttpUtil.resolveHttpMethod(source, 0, httpHeaders);
+		assertEquals(httpMethod, httpHeaders.httpMethod);
+	}
+
+	@Test
+	public void testParseHttpRequest() throws UnsupportedEncodingException {
+		String httpRequest = "GET / HTTP/1.1\r\n\r\n";
+
+		byte[]		source		= httpRequest.getBytes("UTF-8");
+		HttpHeaders	httpHeaders	= new HttpHeaders();
+
+		HttpUtil.parseHttpRequest(source, 0, source.length, httpHeaders);
+
+		assertEquals(0, httpHeaders.contentLength);
+
+		httpRequest	= "GET / HTTP/1.1\r\n" + "Content-Length: 5\r\n" + "\r\n1234";
+		source		= httpRequest.getBytes("UTF-8");
+
+		assertEquals(-1, HttpUtil.parseHttpRequest(source, 0, source.length, httpHeaders));
+		assertEquals(5, httpHeaders.contentLength);
+
+		httpRequest	= "GET / HTTP/1.1\r\n" + "Content-Length: 5\r\n" + "\r\n12345";
+		source		= httpRequest.getBytes("UTF-8");
+
+		assertEquals(42, HttpUtil.parseHttpRequest(source, 0, source.length, httpHeaders));
+		assertEquals(5, httpHeaders.contentLength);
+
+		httpRequest = "GET / HTTP/1.1\r\n" + "Content-Length: 5\r\n" + "\r\n12345" + "GET / HTTP/1.1\r\n" + "Content-Length: 5\r\n" + "\r\n12345";
+
+		source = httpRequest.getBytes("UTF-8");
+
+		assertEquals(42, HttpUtil.parseHttpRequest(source, 0, source.length, httpHeaders));
+		assertEquals(5, httpHeaders.contentLength);
+		assertEquals(37, httpHeaders.bodyStartIndex);
+		assertEquals(42, httpHeaders.bodyEndIndex);
+	}
+}
\ No newline at end of file