diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/Listener.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/Listener.cs
new file mode 100644
index 0000000000..720db481fe
--- /dev/null
+++ b/src/Microsoft.AspNet.Server.Kestrel/Http/Listener.cs
@@ -0,0 +1,83 @@
+using Microsoft.AspNet.Server.Kestrel.Networking;
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Microsoft.AspNet.Server.Kestrel
+{
+ ///
+ /// Summary description for Accept
+ ///
+ public class Listener : IDisposable
+ {
+ private readonly KestrelThread _thread;
+ UvTcpHandle _socket;
+ private readonly Action _connectionCallback = ConnectionCallback;
+
+ private static void ConnectionCallback(UvStreamHandle stream, int status, object state)
+ {
+ ((Listener)state).OnConnection(stream, status);
+ }
+
+ public Listener(KestrelThread thread)
+ {
+ _thread = thread;
+ }
+
+ public Task StartAsync()
+ {
+ var tcs = new TaskCompletionSource();
+ _thread.Post(OnStart, tcs);
+ return tcs.Task;
+ }
+
+ public void OnStart(object parameter)
+ {
+ var tcs = (TaskCompletionSource)parameter;
+ try
+ {
+ _socket = new UvTcpHandle();
+ _socket.Init(_thread.Loop);
+ _socket.Bind(new IPEndPoint(IPAddress.Any, 4001));
+ _socket.Listen(10, _connectionCallback, this);
+ tcs.SetResult(0);
+ }
+ catch (Exception ex)
+ {
+ tcs.SetException(ex);
+ }
+ }
+
+ private void OnConnection(UvStreamHandle socket, int status)
+ {
+ var connection = new UvTcpHandle();
+ connection.Init(_thread.Loop);
+ socket.Accept(connection);
+ connection.ReadStart(OnRead, null);
+ }
+
+ private void OnRead(UvStreamHandle socket, int count, byte[] data, object _)
+ {
+ var text = Encoding.UTF8.GetString(data);
+ if (count <= 0)
+ {
+ socket.Close();
+ }
+ }
+
+ public void Dispose()
+ {
+ var socket = _socket;
+ _socket = null;
+ _thread.Post(OnDispose, socket);
+ }
+
+ private void OnDispose(object socket)
+ {
+ ((UvHandle)socket).Close();
+ }
+ }
+}
diff --git a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/Disposable.cs b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/Disposable.cs
new file mode 100644
index 0000000000..9bb2a7f4bd
--- /dev/null
+++ b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/Disposable.cs
@@ -0,0 +1,43 @@
+using System;
+
+namespace Microsoft.AspNet.Server.Kestrel
+{
+ ///
+ /// Summary description for Disposable
+ ///
+ public class Disposable : IDisposable
+ {
+ private Action _dispose;
+
+ public Disposable(Action dispose)
+ {
+ _dispose = dispose;
+ }
+
+ #region IDisposable Support
+ private bool disposedValue = false; // To detect redundant calls
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ _dispose.Invoke();
+ }
+
+ _dispose = null;
+ disposedValue = true;
+ }
+ }
+
+ // This code added to correctly implement the disposable pattern.
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs
new file mode 100644
index 0000000000..83dd84a4a5
--- /dev/null
+++ b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs
@@ -0,0 +1,130 @@
+using Microsoft.AspNet.Server.Kestrel.Networking;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Microsoft.AspNet.Server.Kestrel
+{
+ ///
+ /// Summary description for KestrelThread
+ ///
+ public class KestrelThread
+ {
+ KestrelEngine _engine;
+ Thread _thread;
+ UvLoopHandle _loop;
+ UvAsyncHandle _post;
+ Queue _workAdding = new Queue();
+ Queue _workRunning = new Queue();
+ object _workSync = new Object();
+ bool _stopImmediate = false;
+
+ public KestrelThread(KestrelEngine engine)
+ {
+ _engine = engine;
+ _loop = new UvLoopHandle();
+ _post = new UvAsyncHandle();
+ _thread = new Thread(ThreadStart);
+ }
+
+ public UvLoopHandle Loop { get { return _loop; } }
+
+ public Task StartAsync()
+ {
+ var tcs = new TaskCompletionSource();
+ _thread.Start(tcs);
+ return tcs.Task;
+ }
+
+ public void Stop(TimeSpan timeout)
+ {
+ Post(OnStop, null);
+ if (!_thread.Join(timeout))
+ {
+ Post(OnStopImmediate, null);
+ if (!_thread.Join(timeout))
+ {
+ _thread.Abort();
+ }
+ }
+ }
+
+ private void OnStop(object obj)
+ {
+ _post.Unreference();
+ }
+
+ private void OnStopImmediate(object obj)
+ {
+ _stopImmediate = true;
+ _loop.Stop();
+ }
+
+ public void Post(Action