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..b3b152c820a686a68b21243bd0137840691fef77
--- /dev/null
+++ b/system/libraries/network/notifications/class.apns.inc.php
@@ -0,0 +1,335 @@
+<?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;
+
+    /**
+     * The process ID of the push.
+     * @var Integer
+     */
+    private $process_id;
+
+    /**
+     * The expiry time for the push im seconds.
+     * @var Integer
+     */
+    private $expiry;
+
+    /**
+     * 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;
+
+    /**
+     * Constructor.
+     *
+     * @param StreamSocketClient &$stream_socket_client Reference to the stream used for push
+     * @param Integer            $expiry                Expiration time of the push in seconds, default 300
+     * @param Integer            $process_id            Process Identifier of the push, default current UNIX timestamp
+     */
+    public function __construct(&$stream_socket_client, $expiry=300, $process_id=NULL)
+    {
+        $this->stream_socket_client =& $stream_socket_client;
+
+        $this->result = '';
+        $this->response_code = '';
+
+        if(is_int($expiry))
+        {
+            $this->expiry = $expiry;
+        }
+        else
+        {
+            $this->expiry = $expiry;
+        }
+
+        if($process_id !== NULL && is_int($process_id))
+        {
+            $this->process_id = $process_id;
+        }
+        else
+        {
+            $this->process_id = mktime();
+        }
+    }
+
+    /**
+     * Destructor
+     */
+    public function __destruct()
+    {
+        unset($this->result);
+        unset($this->response_code);
+        unset($this->process_id);
+        unset($this->expiry);
+    }
+
+    /**
+     * Push the notification to remote devices.
+     *
+     * @param String $destination The destination of the message,
+     *                            e.g the device token
+     * @param String $message     The message to be pushed,
+     *                            e.g the payload
+     *
+     * @return Boolean TRUE in case of success, FALSE otherwise
+     */
+    public function push($destination, $message)
+    {
+        $data = $this->pack_data($destination, $message);
+
+        $write = $this->stream_socket_client->write($data);
+
+        return $this->parse_result($write) ;
+    }
+
+    /**
+     * 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_data($destination, $message)
+    {
+        return chr(1).
+               pack("N",  $this->process_id).
+               pack("N",  $this->expiry).
+               pack("n",  32).
+               pack('H*', $destination).
+               pack("n",  strlen($message)).
+               $message;
+    }
+
+    /**
+     * 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)
+        {
+            $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;
+            }
+        }
+        else
+        {
+            $this->result = 'Unable to send data.';
+            $this->response_code = '';
+            return FALSE;
+        }
+    }
+
+    /**
+     * 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(APNS_RESPONSE_SIZE);
+
+        if($apns_status_message === FALSE)
+        {
+            $this->result = 'Failed to read response code.';
+            $this->response_code = '';
+            $this->stream_socket_client->close();
+            return FALSE;
+        }
+        else
+        {
+            $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)
+        {
+            $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 = $status_code;
+            //Close the connection as it was also closed by APNS
+            $this->stream_socket_client->close();
+
+            return FALSE;
+        }
+        else
+        {
+            $this->result = 'Push successful.';
+            $this->response_code = '0';
+            return TRUE;
+        }
+    }
+
+    /**
+     * 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..9bb255d89b20217a9a6d1e4d1489232a8c311289
--- /dev/null
+++ b/system/libraries/network/notifications/interface.pushnotification.inc.php
@@ -0,0 +1,57 @@
+<?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.
+     *
+     * @param String $destination The destination of the message
+     * @param String $message     The message to be pushed
+     *
+     * @return Boolean TRUE in case of success, FALSE otherwise
+     */
+    public function push($destination, $message);
+
+    /**
+     * 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();
+
+}
+
+?>
