diff --git a/lib/Ratchet/Protocol/WebSocket.php b/lib/Ratchet/Protocol/WebSocket.php
index 2d41df4..ddb80bf 100644
--- a/lib/Ratchet/Protocol/WebSocket.php
+++ b/lib/Ratchet/Protocol/WebSocket.php
@@ -1,6 +1,13 @@
 <?php
 namespace Ratchet\Protocol;
+use Ratchet\Server;
+use Ratchet\Server\Client;
+use Ratchet\Server\Message;
+use Ratchet\Socket;
 
+/**
+ * @link http://ca.php.net/manual/en/ref.http.php
+ */
 class WebSocket implements ProtocolInterface {
     /**
      * @return Array
@@ -20,15 +27,18 @@ class WebSocket implements ProtocolInterface {
      * @return string
      */
     function getName() {
-        return __CLASS__;
+        return 'WebSocket';
     }
 
-    function handleConnect() {
+    public function setUp(Server $server) {
     }
 
-    function handleMessage() {
+    function handleConnect(Socket $client) {
     }
 
-    function handleClose() {
+    function handleMessage($message, Socket $from) {
+    }
+
+    function handleClose(Socket $client) {
     }
 }
\ No newline at end of file
diff --git a/lib/Ratchet/ReceiverInterface.php b/lib/Ratchet/ReceiverInterface.php
index feadd46..8f2d3b3 100644
--- a/lib/Ratchet/ReceiverInterface.php
+++ b/lib/Ratchet/ReceiverInterface.php
@@ -1,5 +1,8 @@
 <?php
 namespace Ratchet;
+use Ratchet\Server;
+use Ratchet\Server\Client;
+use Ratchet\Server\Message;
 
 interface ReceiverInterface {
     /**
@@ -7,9 +10,11 @@ interface ReceiverInterface {
      */
     function getName();
 
-    function handleConnect();
+    function setUp(Server $server);
 
-    function handleMessage();
+    function handleConnect(Socket $client);
 
-    function handleClose();
+    function handleMessage($message, Socket $from);
+
+    function handleClose(Socket $client);
 }
\ No newline at end of file
diff --git a/lib/Ratchet/Server.php b/lib/Ratchet/Server.php
index 570f4da..c8de64b 100644
--- a/lib/Ratchet/Server.php
+++ b/lib/Ratchet/Server.php
@@ -1,56 +1,124 @@
 <?php
 namespace Ratchet;
+use Ratchet\Server\Aggregator;
 use Ratchet\Protocol\ProtocolInterface;
 
 class Server implements ServerInterface {
+    /**
+     * The master socket, receives all connections
+     * @type Socket
+     */
     protected $_master = null;
-    protected $_debug  = false;
 
-    protected $_receivers   = Array();
-    protected $_connections = Array();
+    /**
+     * @todo This needs to implement the composite pattern
+     * @var array of ReceiverInterface
+     */
+    protected $_receivers   = array();
+
+    protected $_resources   = array();
+
+    /**
+     * @type array of Ratchet\Server\Client
+     */
+    protected $_connections = array();
 
     /**
      * @param Ratchet\Socket
      * @param boolean True, enables debug mode and the server doesn't infiniate loop
      */
-    public function __construct(Socket $socket, $debug = false) {
-        $this->_master = $socket;
-        $this->_debug  = (boolean)$debug;
+    public function __construct(Socket $host) {
+        $this->_master = $host;
+
+        $socket = $host->getResource();
+
+        $this->_resources[]          = $socket;
+        $this->_connections[$socket] = $host;
+    }
+
+    /**
+     * @todo Receive an interface that creates clients based on interface, decorator pattern for Socket
+     */
+    public function setClientFactory($s) {
     }
 
     public function attatchReceiver(ReceiverInterface $receiver) {
+        $receiver->setUp($this);
         $this->_receivers[spl_object_hash($receiver)] = $receiver;
     }
 
+    public function getMaster() {
+        return $this->_master;
+    }
+
+    public function getClients() {
+        return $this->_connections;
+    }
+
     /*
      * @param mixed
      * @param int
-     * @throws Ratchet\Exception
+     * @throws Exception
+     * @todo Validate address.  Use socket_get_option, if AF_INET must be IP, if AF_UNIX must be path
      */
     public function run($address = '127.0.0.1', $port = 1025) {
         if (count($this->_receivers) == 0) {
-            throw new \RuntimeException("No receiver has been attatched to the server");
+            throw new \RuntimeException("No receiver has been attached to the server");
         }
 
         set_time_limit(0);
         ob_implicit_flush();
 
+// socket_create_listen($port); instead of create, bind, listen
+
         if (false === ($this->_master->bind($address, (int)$port))) { // perhaps I should do some checks here...
-            throw new Exception();
+            throw new Exception;
         }
 
         if (false === ($this->_master->listen())) {
-            throw new Exception();
+            throw new Exception;
         }
 
         do {
-			$changed     = $this->_connections;
-			$num_changed = socket_select($changed_sockets, $write = NULL, $except = NULL, NULL);
-//			foreach($changed as $) 
+			$changed     = $this->_resources;
+			$num_changed = @socket_select($changed, $write = NULL, $except = NULL, NULL);
+			foreach($changed as $resource) {
+                if ($this->_master->getResource() == $resource) {
+                    $new_connection     = clone $this->_master;
+                    $this->_resources[] = $new_connection->getResource();
+                    $this->_connections[$new_connection->getResource()] = $new_connection;
 
-        } while (!$this->_debug);
+                    // /here $this->_receivers->handleConnection($new_connection);
+                    $this->tmpRIterator('handleConnect', $new_connection);
+                } else {
+                    $conn  = $this->_connections[$resource];
+                    $data  = null;
+                    $bytes = $conn->recv($data, 4096, 0);
+
+                    if ($bytes == 0) {
+                        $this->tmpRIterator('handleClose', $conn);
+                        // $this->_receivers->handleDisconnect($conn);
+
+                        unset($this->_connections[$resource]);
+                        unset($this->_resources[array_search($resource, $this->_resources)]);
+                    } else {
+                        $this->tmpRIterator('handleMessage', $data, $conn);
+                        // new Message
+                        // $this->_receivers->handleMessage($msg, $conn);
+                    }
+                }
+            }
+        } while (true);
 
 //        $this->_master->set_nonblock();
 //        declare(ticks = 1); 
     }
+
+    protected function tmpRIterator() {
+        $args = func_get_args();
+        $fn   = array_shift($args);
+        foreach ($this->_receivers as $app) {
+            call_user_func_array(array($app, $fn), $args);
+        }
+    }
 }
\ No newline at end of file
diff --git a/lib/Ratchet/Server/Aggregator.php b/lib/Ratchet/Server/Aggregator.php
new file mode 100644
index 0000000..1396701
--- /dev/null
+++ b/lib/Ratchet/Server/Aggregator.php
@@ -0,0 +1,69 @@
+<?php
+namespace Ratchet\Server;
+use Ratchet\Socket;
+use Ratchet\Exception;
+
+class Aggregator implements \IteratorAggregator {
+    /**
+     * @var Ratchet\Socket
+     */
+    protected $_master;
+
+    /**
+     * @var SplObjectStorage
+     */
+    protected $_sockets;
+
+    protected $_resources = array();
+
+    /**
+     * @param Ratchet\Socket
+     * @throws Ratchet\Exception
+     */
+    public function __construct(Socket $master) {
+        $this->_sockets = new \SplObjectStorage;
+
+        $this->_master = $master;
+        $this->insert($this->_master);
+    }
+
+    /**
+     * @return Socket
+     */
+    public function getMaster() {
+        return $this->_master;
+    }
+
+    /**
+     * @param resource
+     * @return Socket
+     */
+    public function getClientByResource($resource) {
+        if ($this->_sockets->contains($resource)) {
+            return $this->_sockets[$resource];
+        }
+
+        throw new Exception("Resource not found");
+    }
+
+    protected function insert(Socket $socket) {
+        $resource = $socket->getResource();
+
+        $this->_sockets[$socket] = $resource;
+        $this->_resources[]      = $resource;
+    }
+
+    /**
+     * @return SplObjectStorage
+     */
+    public function getIterator() {
+        return $this->_sockets;
+    }
+
+    /**
+     * @return array
+     */
+    public function asArray() {
+        return $this->_resources;
+    }
+}
\ No newline at end of file
diff --git a/lib/Ratchet/Server/Client.php b/lib/Ratchet/Server/Client.php
new file mode 100644
index 0000000..2bfcc6e
--- /dev/null
+++ b/lib/Ratchet/Server/Client.php
@@ -0,0 +1,13 @@
+<?php
+namespace Ratchet\Server;
+use Ratchet\Socket;
+
+class Client {
+    protected $_socket;
+
+    public function __construct(Socket $socket) {
+        $this->_socket = $socket;
+    }
+
+    
+}
\ No newline at end of file
diff --git a/lib/Ratchet/Socket.php b/lib/Ratchet/Socket.php
index 263bf9a..9b01e89 100644
--- a/lib/Ratchet/Socket.php
+++ b/lib/Ratchet/Socket.php
@@ -10,7 +10,7 @@ class Socket {
     /**
      * @type resource
      */
-    public $_resource;
+    protected $_resource;
 
     public static $_defaults = Array(
         'domain'   => AF_INET
@@ -34,6 +34,17 @@ class Socket {
         }
     }
 
+    /**
+     * @return resource (Socket)
+     */
+    public function getResource() {
+        return $this->_resource;
+    }
+
+    public function __clone() {
+        $this->_resource = @socket_accept($this->_resource);
+    }
+
     /**
      * @param Ratchet\Protocol\ProtocolInterface
      * @return Ratchet\Socket
@@ -70,7 +81,7 @@ class Socket {
             }
         }
 
-        return Array($domain, $type, $protocol);
+        return array($domain, $type, $protocol);
     }
 
     /**
@@ -88,7 +99,17 @@ class Socket {
         $write  = static::mungForSelect($write);
         $except = static::mungForSelect($except);
 
-        socket_select($read, $write, $except, $tv_sec, $tv_usec);
+        return socket_select($read, $write, $except, $tv_sec, $tv_usec);
+    }
+
+    /**
+     * @param string
+     * @param int
+     * @param int
+     * @return int
+     */
+    public function recv(&$buf, $len, $flags) {
+        return socket_recv($this->_resource, $buf, $len, $flags);
     }
 
     /**
@@ -105,9 +126,9 @@ class Socket {
             throw new \InvalidArgumentException('Object pass is not traversable');
         }
 
-        $return = Array();
+        $return = array();
         foreach ($collection as $key => $socket) {
-            $return[$key] = ($socket instanceof \Ratchet\Socket ? $socket->_resource : $socket);
+            $return[$key] = ($socket instanceof \Ratchet\Socket ? $socket->getResource() : $socket);
         }
 
         return $return;
@@ -118,12 +139,19 @@ class Socket {
      * @param string
      * @param Array
      * @return mixed
+     * @throws Exception
      * @throws \BadMethodCallException
      */
     public function __call($method, $arguments) {
         if (function_exists('socket_' . $method)) {
             array_unshift($arguments, $this->_resource);
-            return call_user_func_array('socket_' . $method, $arguments);
+            $result = @call_user_func_array('socket_' . $method, $arguments);
+
+            if (false === $result) {
+                throw new Exception;
+            }
+
+            return $result;
         }
 
         throw new \BadMethodCallException("{$method} is not a valid socket function");
diff --git a/tests/Ratchet/Tests/Mock/Application.php b/tests/Ratchet/Tests/Mock/Application.php
index 08e8c79..7848b37 100644
--- a/tests/Ratchet/Tests/Mock/Application.php
+++ b/tests/Ratchet/Tests/Mock/Application.php
@@ -1,18 +1,24 @@
 <?php
 namespace Ratchet\Tests\Mock;
 use Ratchet\ReceiverInterface;
+use Ratchet\Server;
+use Ratchet\Tests\Mock\Socket as MockSocket;
+use Ratchet\Socket;
 
 class Application implements ReceiverInterface {
     public function getName() {
         return 'mock_application';
     }
 
-    public function handleConnect() {
+    public function setUp(Server $server) {
     }
 
-    public function handleMessage() {
+    public function handleConnect(Socket $client) {
     }
 
-    public function handleClose() {
+    public function handleMessage($msg, Socket $from) {
+    }
+
+    public function handleClose(Socket $client) {
     }
 }
\ No newline at end of file
diff --git a/tests/Ratchet/Tests/Mock/Socket.php b/tests/Ratchet/Tests/Mock/FakeSocket.php
similarity index 96%
rename from tests/Ratchet/Tests/Mock/Socket.php
rename to tests/Ratchet/Tests/Mock/FakeSocket.php
index 9cf8eea..51aa973 100644
--- a/tests/Ratchet/Tests/Mock/Socket.php
+++ b/tests/Ratchet/Tests/Mock/FakeSocket.php
@@ -2,7 +2,7 @@
 namespace Ratchet\Tests\Mock;
 use Ratchet\Socket as RealSocket;
 
-class Socket extends RealSocket {
+class FakeSocket extends RealSocket {
     protected $_arguments = Array();
     protected $_options   = Array();
 
diff --git a/tests/Ratchet/Tests/Mock/Protocol.php b/tests/Ratchet/Tests/Mock/Protocol.php
index 636ee0b..5c7a673 100644
--- a/tests/Ratchet/Tests/Mock/Protocol.php
+++ b/tests/Ratchet/Tests/Mock/Protocol.php
@@ -1,6 +1,8 @@
 <?php
 namespace Ratchet\Tests\Mock;
 use Ratchet\Protocol\ProtocolInterface;
+use Ratchet\Server;
+use Ratchet\Socket;
 
 class Protocol implements ProtocolInterface {
     public static function getDefaultConfig() {
@@ -18,12 +20,15 @@ class Protocol implements ProtocolInterface {
         return 'mock_protocol';
     }
 
-    public function handleConnect() {
+    public function setUp(Server $server) {
     }
 
-    public function handleMessage() {
+    public function handleConnect(Socket $client) {
     }
 
-    public function handleClose() {
+    public function handleMessage($msg, Socket $client) {
+    }
+
+    public function handleClose(Socket $client) {
     }
 }
\ No newline at end of file
diff --git a/tests/Ratchet/Tests/Mock/SocketAggregator.php b/tests/Ratchet/Tests/Mock/SocketAggregator.php
new file mode 100644
index 0000000..c9488f1
--- /dev/null
+++ b/tests/Ratchet/Tests/Mock/SocketAggregator.php
@@ -0,0 +1,42 @@
+<?php
+namespace Ratchet\Tests\Mock;
+use Ratchet\SocketAggregator as RealSocketAggregator;
+
+class SocketAggregator extends RealSocketAggregator {
+    protected $_arguments = Array();
+    protected $_options   = Array();
+
+    public function __construct($domain = null, $type = null, $protocol = null) {
+        list($this->_arguments['domain'], $this->_arguments['type'], $this->_arguments['protocol']) = static::getConfig($domain, $type, $protocol);
+    }
+
+    public function accept() {
+    }
+
+    public function bind($address, $port) {
+    }
+
+    public function close() {
+    }
+
+    public function get_option($level, $optname) {
+        return $this->_options[$level][$optname];
+    }
+
+    public function listen($backlog) {
+    }
+
+    public function recv($buf, $len, $flags) {
+    }
+
+    public function set_option($level, $optname, $optval) {
+        if (!isset($this->_options[$level])) {
+            $this->_options[$level] = Array();
+        }
+
+        $this->_options[$level][$optname] = $optval;
+    }
+
+    public function write($buffer, $length = 0) {
+    }
+}
\ No newline at end of file
diff --git a/tests/Ratchet/Tests/ServerTest.php b/tests/Ratchet/Tests/ServerTest.php
index b7d193e..d1fe6a5 100644
--- a/tests/Ratchet/Tests/ServerTest.php
+++ b/tests/Ratchet/Tests/ServerTest.php
@@ -1,7 +1,7 @@
 <?php
 namespace Ratchet\Tests;
 use Ratchet\Server;
-use Ratchet\Tests\Mock\Socket;
+use Ratchet\Tests\Mock\FakeSocket as Socket;
 use Ratchet\Tests\Mock\Application as TestApp;
 
 /**
diff --git a/tests/Ratchet/Tests/SocketAggregatorTest.php b/tests/Ratchet/Tests/SocketAggregatorTest.php
new file mode 100644
index 0000000..2f3fce0
--- /dev/null
+++ b/tests/Ratchet/Tests/SocketAggregatorTest.php
@@ -0,0 +1,94 @@
+<?php
+namespace Ratchet\Tests;
+use Ratchet\Tests\Mock\FakeSocket as Socket;
+use Ratchet\Socket as RealSocket;
+use Ratchet\Tests\Mock\Protocol;
+
+/**
+ * @covers Ratchet\SocketAggregator
+ */
+class SocketAggregatorTest extends \PHPUnit_Framework_TestCase {
+    protected $_socket;
+
+    protected static function getMethod($name) {
+        $class  = new \ReflectionClass('\\Ratchet\\Tests\\Mock\\Socket');
+        $method = $class->getMethod($name);
+        $method->setAccessible(true);
+
+        return $method;
+    }
+
+    public function setUp() {
+        $this->_socket = new Socket();
+    }
+
+/*
+    public function testWhatGoesInConstructComesOut() {
+        $this->assertTrue(false);
+    }
+*/
+
+    public function testGetDefaultConfigForConstruct() {
+        $ref_conf = static::getMethod('getConfig');
+        $config   = $ref_conf->invokeArgs($this->_socket, Array());
+
+        $this->assertEquals(array_values(Socket::$_defaults), $config);
+    }
+
+    public function testInvalidConstructorArguments() {
+        $this->setExpectedException('\\Ratchet\\Exception');
+        $socket = new RealSocket('invalid', 'param', 'derp');
+    }
+
+    public function testConstructAndCallByOpenAndClose() {
+        $socket = new RealSocket();
+        $socket->close();
+    }
+
+    public function testInvalidSocketCall() {
+        $this->setExpectedException('\\BadMethodCallException');
+        $this->_socket->fake_method();
+    }
+
+    public function testConstructionFromProtocolInterfaceConfig() {
+        $protocol = new Protocol();
+        $socket   = Socket::createFromConfig($protocol);
+
+        $this->assertInstanceOf('\\Ratchet\\Socket', $socket);
+    }
+
+    public function testCreationFromConfigOutputMatchesInput() {
+        $protocol = new Protocol();
+        $socket   = Socket::createFromConfig($protocol);
+        $config   = $protocol::getDefaultConfig();
+
+        // change this to array_filter late
+        unset($config['options']);
+
+        $this->assertAttributeEquals($config, '_arguments', $socket);
+    }
+
+    public function asArrayProvider() {
+        return Array(
+            Array(Array('hello' => 'world'), Array('hello' => 'world'))
+          , Array(null, null)
+          , Array(Array('hello' => 'world'), new \ArrayObject(Array('hello' => 'world')))
+        );
+    }
+
+    /**
+     * @dataProvider asArrayProvider
+     */
+    public function testMethodMungforselectReturnsExpectedValues($output, $input) {
+        $method = static::getMethod('mungForSelect');
+        $return = $method->invokeArgs($this->_socket, Array($input));
+
+        $this->assertEquals($return, $output);
+    }
+
+    public function testMethodMungforselectRejectsNonTraversable() {
+        $this->setExpectedException('\\InvalidArgumentException');
+        $method = static::getMethod('mungForSelect');
+        $method->invokeArgs($this->_socket, Array('I am upset with PHP ATM'));
+    }
+}
\ No newline at end of file
diff --git a/tests/Ratchet/Tests/SocketTest.php b/tests/Ratchet/Tests/SocketTest.php
index e9f9e9e..cce6619 100644
--- a/tests/Ratchet/Tests/SocketTest.php
+++ b/tests/Ratchet/Tests/SocketTest.php
@@ -1,6 +1,6 @@
 <?php
 namespace Ratchet\Tests;
-use Ratchet\Tests\Mock\Socket;
+use Ratchet\Tests\Mock\FakeSocket as Socket;
 use Ratchet\Socket as RealSocket;
 use Ratchet\Tests\Mock\Protocol;