diff --git a/system/libraries/network/notifications/class.apns.inc.php b/system/libraries/network/notifications/class.apns.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..ecfab1ae73ad16d85608b15797191734de45bc9f
--- /dev/null
+++ b/system/libraries/network/notifications/class.apns.inc.php
@@ -0,0 +1,412 @@
+<?php
+
+/**
+ * This file contains the push notification class
+ * for Apple Push Notification Service.
+ *
+ * @category   Libraries
+ * @package    Network
+ * @subpackage Core
+ * @author     Olivier wizen <olivier@m2mobi.com>
+ * @copyright  2011-2012, M2Mobi BV, Amsterdam, The Netherlands
+ * @license    http://lunr.nl/LICENSE MIT License
+ */
+
+namespace Lunr\Libraries\Core\Network\PushNotification;
+use Lunr\Libraries\Network\Curl;
+
+/**
+ * Apple Push Notification Service class.
+ *
+ * @category   Libraries
+ * @package    Network
+ * @subpackage Core
+ * @author     M2Mobi <info@m2mobi.com>
+ * @author     Olivier wizen <olivier@m2mobi.com>
+ */
+class APNS implements PushNotification
+{
+
+    /**
+     * Reference to the stream used to push to APNS.
+     * @var StreamSocketClient
+     */
+    private $stream_socket_client;
+
+    /**
+     * The result of the push as message.
+     * @var String
+     */
+    private $result;
+
+    /**
+     * The response code/status code of APNS
+     * @var String
+     */
+    private $response_code;
+
+    /**
+     * Process Identifier of the push, default current UNIX timestamp
+     * @var Integer
+     */
+    private $process_id;
+
+    /**
+     * Expiration time of the push in seconds, default 300
+     * @var Integer
+     */
+    private $expiry;
+
+    /**
+     * The header of the push,
+     * e.g the command code, the expiry and the process_id packed.
+     * @var String
+     */
+    private $push_header;
+
+    /**
+     * The device token to push to.
+     * @var String
+     */
+    private $device_token;
+
+    /**
+     * The payload of the push.
+     * @var String
+     */
+    private $payload;
+
+    /**
+     * The APNS status code 0, No errors encountered.
+     * @var Integer
+     */
+    const NO_ERRORS_ENCOUNTERED = 0;
+
+    /**
+     * The APNS status code 1, Processing error.
+     * @var Integer
+     */
+    const PROCESSING_ERROR = 1;
+
+    /**
+     * The APNS status code 2, Missing device token.
+     * @var Integer
+     */
+    const MISSING_DEVICE_TOKEN = 2;
+
+    /**
+     * The APNS status code 3, Missing topic.
+     * @var Integer
+     */
+    const MISSING_TOPIC = 3;
+
+    /**
+     * The APNS status code 4, Missing payload.
+     * @var Integer
+     */
+    const MISSING_PAYLOAD = 4;
+
+    /**
+     * The APNS status code 5, Invalid token size.
+     * @var Integer
+     */
+    const INVALID_TOKEN_SIZE = 5;
+
+    /**
+     * The APNS status code 6, Invalid topic size.
+     * @var Integer
+     */
+    const INVALID_TOPIC_SIZE = 6;
+
+    /**
+     * The APNS status code 7, Invalid payload size.
+     * @var Integer
+     */
+    const INVALID_PAYLOAD_SIZE = 7;
+
+    /**
+     * The APNS status code 8, Invalid token.
+     * @var Integer
+     */
+    const INVALID_TOKEN = 8;
+
+    /**
+     * The APNS status code 255, UNKNOWN ERROR.
+     * @var Integer
+     */
+    const UNKNOWN_ERROR = 255;
+
+    /**
+     * The APNS response size constante.
+     * @var Integer
+     */
+    const APNS_RESPONSE_SIZE = 6;
+
+    /**
+     * The APNS token size.
+     * @var Integer
+     */
+    const APNS_TOKEN_SIZE = 32;
+
+    /**
+     * Constructor.
+     *
+     * @param StreamSocketClient &$stream_socket_client Reference to the stream used for push
+     */
+    public function __construct(&$stream_socket_client)
+    {
+        $this->stream_socket_client =& $stream_socket_client;
+
+        $this->result = '';
+        $this->response_code = '';
+        $this->expiry = 300;
+        $this->process_id = mktime();
+        $this->device_token = NULL;
+
+        $this->pack_push_header();
+    }
+
+    /**
+     * Destructor
+     */
+    public function __destruct()
+    {
+        unset($this->result);
+        unset($this->response_code);
+        unset($this->process_id);
+        unset($this->expiry);
+        unset($this->device_token);
+    }
+
+    /**
+     * Sets the expiry for this push notification. Note that a value
+     * equal to or less than zero indicates to apple that the notification
+     * must not be stored.
+     *
+     * @param Integer $expiry The expiry of this push notification
+     *
+     * @return APNS $self Self reference
+     */
+    public function set_expiry($expiry)
+    {
+        if(is_int($expiry))
+        {
+            $this->expiry = $expiry;
+            $this->push_pack_header();
+        }
+        return $this;
+    }
+
+    /**
+     * Sets the process ID of this push. must be greater than zero
+     *
+     * @param Integer $pid the process ID of this push
+     *
+     * @return APNS $self Self reference
+     */
+    public function set_process_id($pid)
+    {
+        if(is_int($pid) && $pid > 0)
+        {
+            $this->process_id = $pid;
+            $this->push_pack_header();
+        }
+        return $this;
+    }
+    /**
+     * Push the notification to remote devices.
+     *
+     * @return Boolean TRUE in case of success, FALSE otherwise
+     */
+    public function push()
+    {
+        if($this->device_token ===NULL)
+        {
+            $this->result = 'No destination provided.';
+            $this->response_code = '-1';
+            return FALSE;
+        }
+        $data = $this->push_header.$token.$payload;
+
+        $write = $this->stream_socket_client->write($data);
+
+        return $this->parse_result($write) ;
+    }
+
+    /**
+     * Sets the payload of this push.
+     *
+     * @param String $payload the payload for this push
+     *
+     * @return APNS $self Self reference
+     */
+    public function set_payload($payload)
+    {
+        $this->payload = $payload;
+
+        return $this;
+    }
+
+    /**
+     * Set the device token to push to.
+     *
+     * @param String $device_token The device token to be added,
+     *                             32 characters long, ignored otherwise.
+     *
+     * @return APNS $self Self reference
+     */
+    public function set_destination($device_token)
+    {
+        if(strlen($device_token) !== self::APNS_TOKEN_SIZE)
+        {
+            $this->device_token = NULL;
+
+            return $this;
+        }
+
+        $this->device_token = $device_token;
+
+        return $this;
+    }
+
+    /**
+     * The result of the push as a string.
+     *
+     * @return String The result of the push
+     */
+    public function get_result()
+    {
+        return $this->result;
+    }
+
+    /**
+     * The result code of the push.
+     *
+     * @return mixed The result of the push
+    */
+    public function get_response_code()
+    {
+        return $this->response_code;
+    }
+
+    /**
+     * Packs the data of the push, e-g the $destination and the message
+     *
+     * @param String $destination The destination to pack
+     * @param String $message     The message to pack
+     *
+     * @return $return The packed token and payload to send to APNS
+     */
+    private function pack_push_header()
+    {
+        $this->push_header= chr(1).
+                            pack("N",  $this->process_id).
+                            pack("N",  $this->expiry).
+                            pack("n",  self::APNS_TOKEN_SIZE) ;
+    }
+
+    /**
+     * Get the result of the push according to the raw write result.
+     *
+     * @param Boolean $write The result of the write operation on the stream
+     *
+     * @return Boolean $return Wether the push was succcessful or not.
+     */
+    private function parse_result($write)
+    {
+        if(!$write)
+        {
+            $this->result = 'Unable to send data.';
+            $this->response_code = '-1';
+
+            $this->stream_socket_client->close();
+
+            return FALSE;
+        }
+
+        $changed = $this->stream_socket_client->is_readable();
+
+        if($changed === NULL)
+        {
+            $this->result = 'Failed to get stream status.';
+            $this->response_code = '';
+            return FALSE;
+        }
+        elseif($changed === TRUE)
+        {
+            return $this->parse_response_message();
+        }
+        elseif($changed === FALSE)
+        {   //infer that response code = 0
+            $this->result = 'Push successful.';
+            $this->response_code = '0';
+            return TRUE;
+        }
+    }
+
+    /**
+     * Parse the response message fromn APNS.
+     *
+     * @return Boolean $return Wether the push was successful or not
+     */
+    private function parse_response_message()
+    {
+        $apns_status_message = $this->stream_socket_client->read(self::APNS_RESPONSE_SIZE);
+
+        if($apns_status_message === FALSE)
+        {
+            $this->result = 'Failed to read response code.';
+            $this->response_code = '-1';
+
+            return FALSE;
+        }
+
+        $response = $this->unpack_status_message($apns_status_message);
+
+        return $this->parse_status_code($response);
+    }
+
+    /**
+     * Parse the status code received from APNS.
+     *
+     * @param array $response The array of unpacked informations returned by apple
+     *
+     * @return Boolean $return Wether the push was successful or not
+     */
+    private function parse_status_code($response)
+    {
+        if($response['status_code'] = 0)
+        {
+            $this->result = 'Push successful.';
+            $this->response_code = '0';
+            return TRUE;
+        }
+
+        $command     = $error['command'];
+        $status_code = $error['status_code'];
+        $identifier  = $error['identifier'];
+
+        $this->result = "ERROR: APNS responded with command($command) and status($status_code) for pid($identifier).";
+        $this->response_code = strval($status_code);
+        //Close the connection as it was also closed by APNS
+        $this->stream_socket_client->close();
+
+        return FALSE;
+    }
+
+    /**
+     * Returns an unpacked array from the byte string gotten from APNS
+     *
+     *  @param String $status_message The raw status message as retrieved from APNS
+     *
+     *  @return array $return The array of unpacked data with command,
+     *                        status code and process identifier
+     */
+    private function unpack_status_message($status_message)
+    {
+        return unpack('Ccommand/Cstatus_code/Nidentifier', $status_message);
+    }
+
+}
+
+?>
diff --git a/system/libraries/network/notifications/interface.pushnotification.inc.php b/system/libraries/network/notifications/interface.pushnotification.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..fea89b4a41d6000cf9a00e984a9305cd6c47482d
--- /dev/null
+++ b/system/libraries/network/notifications/interface.pushnotification.inc.php
@@ -0,0 +1,72 @@
+<?php
+
+/**
+  * This file contains the PushNotification interface which
+  * is the base of all push notifications.
+  *
+  * PHP Version 5.3
+  *
+  * @category   Libraries
+  * @package    Network
+  * @subpackage Core
+  * @author     Olivier wizen <olivier@m2mobi.com>
+  * @copyright  2011-2012, M2Mobi BV, Amsterdam, The Netherlands
+  * @license    http://lunr.nl/LICENSE MIT License
+  */
+
+namespace Lunr\Libraries\Core\Network\PushNotification;
+
+/**
+ * Push notification interface.
+ *
+ * @category   Libraries
+ * @package    Network
+ * @subpackage Core
+ * @author     M2Mobi <info@m2mobi.com>
+ * @author     Olivier wizen <olivier@m2mobi.com>
+ */
+interface PushNotification
+{
+
+    /**
+     * Push the notification.
+     *
+     * @return Boolean TRUE in case of success, FALSE otherwise
+     */
+    public function push();
+
+    /**
+     * Set the destination of the push.
+     *
+     * @param String $destination The destination of the push
+     *
+     * @return PushNotification $self Self reference
+     */
+    public function set_destination($destination);
+
+    /**
+     * Set the payload of the push.
+     *
+     * @param String $payload The payload of the push
+     *
+     * @return PushNotification $self Self reference
+     */
+    public function set_payload($payload);
+
+    /**
+     * The result of the push as a string.
+     *
+     * @return String The result of the push
+     */
+    public function get_result();
+
+    /**
+     * The result code of the push.
+     *
+     * @return mixed The result of the push
+     */
+    public function get_response_code();
+
+}
+
+?>
