diff --git a/layouts/v7/modules/Mobile/simple/Users/Login.tpl b/layouts/v7/modules/Mobile/simple/Users/Login.tpl
index 60f644951a3baea9e1afb184dea57b89957baa58..65f67456ef30d2d235facd76a11866d22433d589 100644
--- a/layouts/v7/modules/Mobile/simple/Users/Login.tpl
+++ b/layouts/v7/modules/Mobile/simple/Users/Login.tpl
@@ -25,7 +25,7 @@
             <form name="loginForm" ng-submit="login()" class="login-form" ng-validate>
                 <md-input-container  md-no-float class="md-hue-1">
                     <label for="username" >User name</label>
-                    <input type="email" autoFilled="true" id="user-name" name="username" ng-model="auth.username" ng-required="true">
+                    <input type="text" autoFilled="true" id="user-name" name="username" ng-model="auth.username" ng-required="true">
                     <div class="form-errors" ng-message="required" ng-show="loginForm.username.$invalid && loginForm.username.$touched">User Name required!</div>
                 </md-input-container>
                 <md-input-container class="md-hue-1">
diff --git a/libraries/HTTP_Session/Session.php b/libraries/HTTP_Session/Session.php
new file mode 100644
index 0000000000000000000000000000000000000000..c811c0ba78230ce37b42a4b34c3821f654ca1cba
--- /dev/null
+++ b/libraries/HTTP_Session/Session.php
@@ -0,0 +1,804 @@
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Class for managing HTTP sessions
+ *
+ * Provides access to session-state values as well as session-level
+ * settings and lifetime management methods.
+ * Based on the standart PHP session handling mechanism
+ * it provides for you more advanced features such as
+ * database container, idle and expire timeouts, etc.
+ *
+ * PHP version 4
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  HTTP
+ * @package   HTTP_Session
+ * @author    David Costa <gurugeek@php.net>
+ * @author    Michael Metz <pear.metz@speedpartner.de>
+ * @author    Stefan Neufeind <pear.neufeind@speedpartner.de>
+ * @author    Torsten Roehr <torsten.roehr@gmx.de>
+ * @copyright 1997-2005 The PHP Group
+ * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
+ * @version   CVS: $Id: Session.php,v 1.15 2007/07/14 12:11:54 troehr Exp $
+ * @link      http://pear.php.net/package/HTTP_Session
+ * @since     File available since Release 0.4.0
+ */
+
+// @const HTTP_SESSION_STARTED - The session was started with the current request
+define("HTTP_SESSION_STARTED", 1);
+// @const HTTP_SESSION_STARTED - No new session was started with the current request
+define("HTTP_SESSION_CONTINUED", 2);
+
+/**
+ * Class for managing HTTP sessions
+ *
+ * Provides access to session-state values as well as session-level
+ * settings and lifetime management methods.
+ * Based on the standart PHP session handling mechanism
+ * it provides for you more advanced features such as
+ * database container, idle and expire timeouts, etc.
+ *
+ * Example 1:
+ *
+ * <code>
+ * // Setting some options and detecting of a new session
+ * HTTP_Session::setCookieless(false);
+ * HTTP_Session::start('MySessionID');
+ * HTTP_Session::set('variable', 'Tet string');
+ * if (HTTP_Session::isNew()) {
+ *     echo('new session was created with the current request');
+ *     $visitors++; // Increase visitors count
+ * }
+ *
+ * //HTTP_Session::regenerateId();
+ * </code>
+ *
+ * Example 2:
+ *
+ * <code>
+ * // Using database container
+ * HTTP_Session::setContainer('DB');
+ * HTTP_Session::start();
+ * </code>
+ *
+ * Example 3:
+ *
+ * <code>
+ * // Setting timeouts
+ * HTTP_Session::start();
+ * HTTP_Session::setExpire(time() + 60 * 60); // expires in one hour
+ * HTTP_Session::setIdle(time()+ 10 * 60);    // idles in ten minutes
+ * if (HTTP_Session::isExpired()) {
+ *     // expired
+ *     echo('Your session is expired!');
+ *     HTTP_Session::destroy();
+ * }
+ * if (HTTP_Session::isIdle()) {
+ *     // idle
+ *     echo('You've been idle for too long!');
+ *     HTTP_Session::destroy();
+ * }
+ * HTTP_Session::updateIdle();
+ * </code>
+ *
+ * @category  HTTP
+ * @package   HTTP_Session
+ * @author    David Costa <gurugeek@php.net>
+ * @author    Michael Metz <pear.metz@speedpartner.de>
+ * @author    Stefan Neufeind <pear.neufeind@speedpartner.de>
+ * @author    Torsten Roehr <torsten.roehr@gmx.de>
+ * @copyright 1997-2005 The PHP Group
+ * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
+ * @version   Release: @package_version@
+ * @link      http://pear.php.net/package/HTTP_Session
+ * @since     Class available since Release 0.4.0
+ */
+class HTTP_Session
+{
+    /**
+     * Sets user-defined session storage functions
+     *
+     * Sets the user-defined session storage functions which are used
+     * for storing and retrieving data associated with a session.
+     * This is most useful when a storage method other than
+     * those supplied by PHP sessions is preferred.
+     * i.e. Storing the session data in a local database.
+     *
+     * @param string $container         Container name
+     * @param array  $container_options Container options
+     *
+     * @static
+     * @access public
+     * @return void
+     * @see    session_set_save_handler()
+     */
+    function setContainer($container, $container_options = null)
+    {
+        $container_class     = 'HTTP_Session_Container_' . $container;
+        $container_classfile = 'HTTP/Session/Container/' . $container . '.php';
+
+        include_once $container_classfile;
+        $container = new $container_class($container_options);
+
+        $container->set();
+    }
+
+    /**
+     * Initializes session data
+     *
+     * Creates a session (or resumes the current one
+     * based on the session id being passed
+     * via a GET variable or a cookie).
+     * You can provide your own name and/or id for a session.
+     *
+     * @param string $name string Name of a session, default is 'SessionID'
+     * @param string $id   string Id of a session which will be used
+     *                            only when the session is new
+     *
+     * @static
+     * @access public
+     * @return void
+     * @see    session_name()
+     * @see    session_id()
+     * @see    session_start()
+     */
+    function start($name = 'SessionID', $id = null)
+    {
+        HTTP_Session::name($name);
+        if ($id) {
+            HTTP_Session::id($id);
+        } elseif (is_null(HTTP_Session::detectID())) {
+            HTTP_Session::id($id ? $id : uniqid(dechex(rand())));
+        }
+        session_start();
+        if (!isset($_SESSION['__HTTP_Session_Info'])) {
+            $_SESSION['__HTTP_Session_Info'] = HTTP_SESSION_STARTED;
+        } else {
+            $_SESSION['__HTTP_Session_Info'] = HTTP_SESSION_CONTINUED;
+        }
+    }
+
+    /**
+     * Writes session data and ends session
+     *
+     * Session data is usually stored after your script
+     * terminated without the need to call HTTP_Session::stop(),
+     * but as session data is locked to prevent concurrent
+     * writes only one script may operate on a session at any time.
+     * When using framesets together with sessions you will
+     * experience the frames loading one by one due to this
+     * locking. You can reduce the time needed to load all the
+     * frames by ending the session as soon as all changes
+     * to session variables are done.
+     *
+     * @static
+     * @access public
+     * @return void
+     * @see    session_write_close()
+     */
+    function pause()
+    {
+        session_write_close();
+    }
+
+    /**
+     * Frees all session variables and destroys all data
+     * registered to a session
+     *
+     * This method resets the $_SESSION variable and
+     * destroys all of the data associated
+     * with the current session in its storage (file or DB).
+     * It forces new session to be started after this method
+     * is called. It does not unset the session cookie.
+     *
+     * @static
+     * @access public
+     * @return void
+     * @see    session_unset()
+     * @see    session_destroy()
+     */
+    function destroy()
+    {
+        session_unset();
+        session_destroy();
+
+        // set session handlers again to avoid fatal error in case
+        // HTTP_Session::start() will be called afterwards
+        if (isset($GLOBALS['HTTP_Session_Container']) &&
+            is_a($GLOBALS['HTTP_Session_Container'], 'HTTP_Session_Container')) {
+            $GLOBALS['HTTP_Session_Container']->set();
+        }
+    }
+
+    /**
+     * Calls session_regenerate_id() if available
+     *
+     * @param bool $deleteOldSessionData Whether to delete data of old session
+     *
+     * @static
+     * @access public
+     * @return bool
+     */
+    function regenerateId($deleteOldSessionData = false)
+    {
+        if (function_exists('session_regenerate_id')) {
+            return session_regenerate_id($deleteOldSessionData);
+
+            // emulate session_regenerate_id()
+        } else {
+
+            do {
+                $newId = uniqid(dechex(rand()));
+            } while ($newId === session_id());
+
+            if ($deleteOldSessionData) {
+                session_unset();
+            }
+
+            session_id($newId);
+
+            return true;
+        }
+    }
+
+    /**
+     * This function copies session data of specified id to specified table
+     *
+     * @param string $targetTable Table to replicate data to
+     * @param string $id          ID of the session
+     *
+     * @static
+     * @access public
+     * @return bool
+     */
+    function replicate($targetTable, $id = null)
+    {
+        return $GLOBALS['HTTP_Session_Container']->replicate($targetTable, $id);
+    }
+
+    /**
+     * Free all session variables
+     *
+     * @todo   TODO Save expire and idle timestamps?
+     * @static
+     * @access public
+     * @return void
+     */
+    function clear()
+    {
+        $info = $_SESSION['__HTTP_Session_Info'];
+        session_unset();
+        $_SESSION['__HTTP_Session_Info'] = $info;
+    }
+
+    /**
+     * Tries to find any session id in $_GET, $_POST or $_COOKIE
+     *
+     * @static
+     * @access private
+     * @return string Session ID (if exists) or null
+     */
+    function detectID()
+    {
+        if (HTTP_Session::useCookies()) {
+            if (isset($_COOKIE[HTTP_Session::name()])) {
+                return $_COOKIE[HTTP_Session::name()];
+            }
+        } else {
+            if (isset($_GET[HTTP_Session::name()])) {
+                return $_GET[HTTP_Session::name()];
+            }
+            if (isset($_POST[HTTP_Session::name()])) {
+                return $_POST[HTTP_Session::name()];
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Sets new name of a session
+     *
+     * @param string $name New name of a session
+     *
+     * @static
+     * @access public
+     * @return string Previous name of a session
+     * @see    session_name()
+     */
+    function name($name = null)
+    {
+        return isset($name) ? session_name($name) : session_name();
+    }
+
+    /**
+     * Sets new ID of a session
+     *
+     * @param string $id New ID of a session
+     *
+     * @static
+     * @access public
+     * @return string Previous ID of a session
+     * @see    session_id()
+     */
+    function id($id = null)
+    {
+        return isset($id) ? session_id($id) : session_id();
+    }
+
+    /**
+     * Sets the maximum expire time
+     *
+     * @param integer $time Time in seconds
+     * @param bool    $add  Add time to current expire time or not
+     *
+     * @static
+     * @access public
+     * @return void
+     */
+    function setExpire($time, $add = false)
+    {
+        if ($add) {
+            if (!isset($_SESSION['__HTTP_Session_Expire_TS'])) {
+                $_SESSION['__HTTP_Session_Expire_TS'] = time() + $time;
+            }
+
+            // update session.gc_maxlifetime
+            $currentGcMaxLifetime = HTTP_Session::setGcMaxLifetime(null);
+            HTTP_Session::setGcMaxLifetime($currentGcMaxLifetime + $time);
+
+        } elseif (!isset($_SESSION['__HTTP_Session_Expire_TS'])) {
+            $_SESSION['__HTTP_Session_Expire_TS'] = $time;
+        }
+    }
+
+    /**
+     * Sets the maximum idle time
+     *
+     * Sets the time-out period allowed
+     * between requests before the session-state
+     * provider terminates the session.
+     *
+     * @param int  $time Time in seconds
+     * @param bool $add  Add time to current maximum idle time or not
+     *
+     * @static
+     * @access public
+     * @return void
+     */
+    function setIdle($time, $add = false)
+    {
+        if ($add) {
+            $_SESSION['__HTTP_Session_Idle'] = $time;
+        } else {
+            // substract time again because it doesn't make any sense to provide
+            // the idle time as a timestamp
+            // keep $add functionality to provide BC
+            $_SESSION['__HTTP_Session_Idle'] = $time - time();
+        }
+    }
+
+    /**
+     * Returns the time up to the session is valid
+     *
+     * @static
+     * @access public
+     * @return integer Time when the session idles
+     */
+    function sessionValidThru()
+    {
+        if (!isset($_SESSION['__HTTP_Session_Idle_TS']) ||
+            !isset($_SESSION['__HTTP_Session_Idle'])) {
+            return 0;
+        } else {
+            return $_SESSION['__HTTP_Session_Idle_TS'] +
+                   $_SESSION['__HTTP_Session_Idle'];
+        }
+    }
+
+    /**
+     * Check if session is expired
+     *
+     * @static
+     * @access public
+     * @return bool
+     */
+    function isExpired()
+    {
+        if (isset($_SESSION['__HTTP_Session_Expire_TS']) &&
+            $_SESSION['__HTTP_Session_Expire_TS'] < time()) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Check if session is idle
+     *
+     * @static
+     * @access public
+     * @return bool
+     */
+    function isIdle()
+    {
+        if (isset($_SESSION['__HTTP_Session_Idle_TS']) &&
+            (($_SESSION['__HTTP_Session_Idle_TS'] +
+              $_SESSION['__HTTP_Session_Idle']) < time())) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Updates the idletime
+     *
+     * @static
+     * @access public
+     * @return void
+     */
+    function updateIdle()
+    {
+        $_SESSION['__HTTP_Session_Idle_TS'] = time();
+    }
+
+    /**
+     * If optional parameter is specified it indicates
+     * whether the module will use cookies to store
+     * the session id on the client side
+     *
+     * It returns the previous value of this property
+     *
+     * @param bool $useCookies If specified it will replace the previous value
+     *                         of this property
+     *
+     * @static
+     * @access public
+     *
+     * @return bool The previous value of the property
+     */
+    function useCookies($useCookies = null)
+    {
+        $return = ini_get('session.use_cookies') ? true : false;
+        if (isset($useCookies)) {
+            ini_set('session.use_cookies', $useCookies ? 1 : 0);
+        }
+        return $return;
+    }
+
+    /**
+     * Gets a value indicating whether the session
+     * was created with the current request
+     *
+     * You MUST call this method only after you have started
+     * the session with the HTTP_Session::start() method.
+     *
+     * @static
+     * @access public
+     * @return bool   True if the session was created
+     *                with the current request, false otherwise
+     */
+    function isNew()
+    {
+        // The best way to check if a session is new is to check
+        // for existence of a session data storage
+        // with the current session id, but this is impossible
+        // with the default PHP module wich is 'files'.
+        // So we need to emulate it.
+        return !isset($_SESSION['__HTTP_Session_Info']) ||
+            $_SESSION['__HTTP_Session_Info'] == HTTP_SESSION_STARTED;
+    }
+
+    /**
+     * Register variable with the current session
+     *
+     * @param string $name Name of a global variable
+     *
+     * @deprecated Use set()/setRef() instead
+     *
+     * @static
+     * @access public
+     * @return bool
+     * @see    session_register()
+     */
+    function register($name)
+    {
+        return session_register($name);
+    }
+
+    /**
+     * Unregister a variable from the current session
+     *
+     * @param string $name Name of a global variable
+     *
+     * @deprecated Use get()/getRef() instead
+     *
+     * @static
+     * @access public
+     * @return bool
+     * @see    session_unregister()
+     */
+    function unregister($name)
+    {
+        return session_unregister($name);
+    }
+
+    /**
+     * Checks if a session variable is registered
+     *
+     * @param string $name Variable name
+     *
+     * @deprecated Use is_set() instead
+     *
+     * @static
+     * @access public
+     * @return bool
+     */
+    function registered($name)
+    {
+        return session_is_registered($name);
+    }
+
+    /**
+     * Returns session variable
+     *
+     * @param string $name    Name of a variable
+     * @param mixed  $default Default value of a variable if not set
+     *
+     * @static
+     * @access public
+     * @return mixed  Value of a variable
+     */
+    function get($name, $default = null)
+    {
+        if (!isset($_SESSION[$name]) && isset($default)) {
+            $_SESSION[$name] = $default;
+        }
+        $return = (isset($_SESSION[$name])) ? $_SESSION[$name] : null;
+        return $return;
+    }
+
+    /**
+     * Returns session variable by reference
+     *
+     * @param string $name Name of a variable
+     *
+     * @static
+     * @access public
+     * @return mixed  Value of a variable
+     */
+    function &getRef($name)
+    {
+        if (isset($_SESSION[$name])) {
+            $return =& $_SESSION[$name];
+        } else {
+            $return = null;
+        }
+
+        return $return;
+    }
+
+    /**
+     * Sets session variable
+     *
+     * @param string $name  Name of a variable
+     * @param mixed  $value Value of a variable
+     *
+     * @static
+     * @access public
+     * @return mixed  Old value of a variable
+     */
+    function set($name, $value)
+    {
+        $return = (isset($_SESSION[$name])) ? $_SESSION[$name] : null;
+        if (null === $value) {
+            unset($_SESSION[$name]);
+        } else {
+            $_SESSION[$name] = $value;
+        }
+        return $return;
+    }
+
+    /**
+     * Sets session variable by reference
+     *
+     * @param string $name  Name of a variable
+     * @param mixed  $value Value of a variable
+     *
+     * @static
+     * @access public
+     * @return mixed  Old value of a variable
+     */
+    function setRef($name, &$value)
+    {
+        $return = (isset($_SESSION[$name])) ? $_SESSION[$name] : null;
+
+        $_SESSION[$name] =& $value;
+
+        return $return;
+    }
+
+    /**
+     * Checks if a session variable is set
+     *
+     * @param string $name Variable name
+     *
+     * @static
+     * @access public
+     * @return bool
+     */
+    function is_set($name)
+    {
+        return isset($_SESSION[$name]);
+    }
+
+    /**
+     * Returns local variable of a script
+     *
+     * Two scripts can have local variables with the same names
+     *
+     * @param string $name    Name of a variable
+     * @param mixed  $default Default value of a variable if not set
+     *
+     * @static
+     * @access public
+     * @return mixed  Value of a local variable
+     */
+    function &getLocal($name, $default = null)
+    {
+        $local = md5(HTTP_Session::localName());
+        if (!isset($_SESSION[$local]) || !is_array($_SESSION[$local])) {
+            $_SESSION[$local] = array();
+        }
+        if (!isset($_SESSION[$local][$name]) && isset($default)) {
+            $_SESSION[$local][$name] = $default;
+        }
+        return $_SESSION[$local][$name];
+    }
+
+    /**
+     * Sets local variable of a script.
+     * Two scripts can have local variables with the same names.
+     *
+     * @param string $name  Name of a local variable
+     * @param mixed  $value Value of a local variable
+     *
+     * @static
+     * @access public
+     * @return mixed  Old value of a local variable
+     */
+    function setLocal($name, $value)
+    {
+        $local = md5(HTTP_Session::localName());
+        if (!isset($_SESSION[$local]) || !is_array($_SESSION[$local])) {
+            $_SESSION[$local] = array();
+        }
+        $return = (isset($_SESSION[$local][$name])) ? $_SESSION[$local][$name]
+                                                    : null;
+
+        if (null === $value) {
+            unset($_SESSION[$local][$name]);
+        } else {
+            $_SESSION[$local][$name] = $value;
+        }
+        return $return;
+    }
+
+    /**
+     * Sets new local name
+     *
+     * @param string $name New local name
+     *
+     * @static
+     * @access public
+     * @return string Previous local name
+     */
+    function localName($name = null)
+    {
+        $return = (isset($GLOBALS['__HTTP_Session_Localname'])) ? $GLOBALS['__HTTP_Session_Localname']
+                                                                : null;
+
+        if (!empty($name)) {
+            $GLOBALS['__HTTP_Session_Localname'] = $name;
+        }
+        return $return;
+    }
+
+    /**
+     * Initialize
+     *
+     * @static
+     * @access private
+     * @return void
+     */
+    function _init()
+    {
+        // Disable auto-start of a sesion
+        ini_set('session.auto_start', 0);
+
+        // Set local name equal to the current script name
+        HTTP_Session::localName($_SERVER['PHP_SELF']);
+    }
+
+    /**
+     * If optional parameter is specified it indicates
+     * whether the session id will automatically be appended to
+     * all links
+     *
+     * It returns the previous value of this property
+     *
+     * @param bool $useTransSID If specified it will replace the previous value
+     *                          of this property
+     *
+     * @static
+     * @access public
+     * @return bool   The previous value of the property
+     */
+    function useTransSID($useTransSID = null)
+    {
+        $return = ini_get('session.use_trans_sid') ? true : false;
+        if (isset($useTransSID)) {
+            ini_set('session.use_trans_sid', $useTransSID ? 1 : 0);
+        }
+        return $return;
+    }
+
+    /**
+     * If optional parameter is specified it determines the number of seconds
+     * after which session data will be seen as 'garbage' and cleaned up
+     *
+     * It returns the previous value of this property
+     *
+     * @param bool $gcMaxLifetime If specified it will replace the previous value
+     *                            of this property
+     *
+     * @static
+     * @access public
+     * @return bool   The previous value of the property
+     */
+    function setGcMaxLifetime($gcMaxLifetime = null)
+    {
+        $return = ini_get('session.gc_maxlifetime');
+        if (isset($gcMaxLifetime) && is_int($gcMaxLifetime) && $gcMaxLifetime >= 1) {
+            ini_set('session.gc_maxlifetime', $gcMaxLifetime);
+        }
+        return $return;
+    }
+
+    /**
+     * If optional parameter is specified it determines the
+     * probability that the gc (garbage collection) routine is started
+     * and session data is cleaned up
+     *
+     * It returns the previous value of this property
+     *
+     * @param bool $gcProbability If specified it will replace the previous value
+     *                            of this property
+     *
+     * @static
+     * @access public
+     * @return bool   The previous value of the property
+     */
+    function setGcProbability($gcProbability = null)
+    {
+        $return = ini_get('session.gc_probability');
+        if (isset($gcProbability)  &&
+            is_int($gcProbability) &&
+            $gcProbability >= 1    &&
+            $gcProbability <= 100) {
+            ini_set('session.gc_probability', $gcProbability);
+        }
+        return $return;
+    }
+}
+
+HTTP_Session::_init();
+?>
\ No newline at end of file
diff --git a/libraries/HTTP_Session/Session/Container.php b/libraries/HTTP_Session/Session/Container.php
new file mode 100644
index 0000000000000000000000000000000000000000..ba85fa2a7a94e6625820431dc7ca8b93291b6cf4
--- /dev/null
+++ b/libraries/HTTP_Session/Session/Container.php
@@ -0,0 +1,280 @@
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Container class for storing session data
+ *
+ * PHP version 4
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  HTTP
+ * @package   HTTP_Session
+ * @author    Alexander Radivanovich <info@wwwlab.net>
+ * @author    David Costa <gurugeek@php.net>
+ * @author    Michael Metz <pear.metz@speedpartner.de>
+ * @author    Stefan Neufeind <pear.neufeind@speedpartner.de>
+ * @author    Torsten Roehr <torsten.roehr@gmx.de>
+ * @copyright 1997-2005 The PHP Group
+ * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
+ * @version   CVS: $Id: Container.php,v 1.8 2007/07/14 12:11:54 troehr Exp $
+ * @link      http://pear.php.net/package/HTTP_Session
+ * @since     File available since Release 0.4.0
+ */
+
+/**
+ * Container class for storing session data
+ *
+ * @category  HTTP
+ * @package   HTTP_Session
+ * @author    David Costa <gurugeek@php.net>
+ * @author    Michael Metz <pear.metz@speedpartner.de>
+ * @author    Stefan Neufeind <pear.neufeind@speedpartner.de>
+ * @author    Torsten Roehr <torsten.roehr@gmx.de>
+ * @copyright 1997-2005 The PHP Group
+ * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
+ * @version   Release: @package_version@
+ * @link      http://pear.php.net/package/HTTP_Session
+ * @since     Class available since Release 0.4.0
+ */
+class HTTP_Session_Container
+{
+    /**
+     * Additional options for the container object
+     *
+     * @var array
+     * @access private
+     */
+    var $options = array();
+
+    /**
+     * Constrtuctor method
+     *
+     * @param array $options Additional options for the container object
+     *
+     * @access public
+     * @return object
+     */
+    function HTTP_Session_Container($options = null)
+    {
+        $this->_setDefaults();
+        if (is_array($options)) {
+            $this->_parseOptions();
+        }
+    }
+
+    /**
+     * Set some default options
+     *
+     * @access private
+     * @return void
+     */
+    function _setDefaults()
+    {
+    }
+
+    /**
+     * Parse options passed to the container class
+     *
+     * @param array $options Options
+     *
+     * @access private
+     * @return void
+     */
+    function _parseOptions($options)
+    {
+        foreach ($options as $option => $value) {
+            if (in_array($option, array_keys($this->options))) {
+                $this->options[$option] = $value;
+            }
+        }
+    }
+
+    /**
+     * This function is called by the session handler to initialize things
+     *
+     * @param string $save_path    Save path
+     * @param string $session_name Session name
+     *
+     * @access public
+     * @return bool
+     */
+    function open($save_path, $session_name)
+    {
+        return true;
+    }
+
+    /**
+     * This function is called when the page is finished
+     * executing and the session handler needs to close things off
+     *
+     * Has to be overwritten by each container class
+     *
+     * @access public
+     * @return bool
+     */
+    function close()
+    {
+        return true;
+    }
+
+    /**
+     * This function is called by the session handler
+     * to read the data associated with a given session ID.
+     * This function must retrieve and return the session data
+     * for the session identified by $id.
+     *
+     * Has to be overwritten by each container class
+     *
+     * @param string $id ID of the session
+     *
+     * @access public
+     * @return string
+     */
+    function read($id)
+    {
+        return '';
+    }
+
+    /**
+     * This function is called when the session handler
+     * has session data to save, which usually happens
+     * at the end of your script
+     *
+     * Has to be overwritten by each container class
+     *
+     * @param string $id   ID of the session
+     * @param mixed  $data The data associated with a given session ID
+     *
+     * @access public
+     * @return bool
+     */
+    function write($id, $data)
+    {
+        return true;
+    }
+
+    /**
+     * This function is called when a session is destroyed.
+     * It is responsible for deleting the session and cleaning things up.
+     *
+     * Has to be overwritten by each container class
+     *
+     * @param string $id ID of the session
+     *
+     * @access public
+     * @return bool
+     */
+    function destroy($id)
+    {
+        return true;
+    }
+
+    /**
+     * This function copies session data of specified id to specified table
+     *
+     * Has to be overwritten by each container class
+     *
+     * @param string $targetTable Table to replicate data to
+     * @param string $id          ID of the session
+     *
+     * @access public
+     * @return bool
+     */
+    function replicate($targetTable, $id = null)
+    {
+        return true;
+    }
+
+    /**
+     * This function is responsible for garbage collection.
+     * In the case of session handling, it is responsible
+     * for deleting old, stale sessions that are hanging around.
+     * The session handler will call this every now and then.
+     *
+     * Has to be overwritten by each container class
+     *
+     * @param integer $maxlifetime Maximum lifetime
+     *
+     * @access public
+     * @return bool
+     */
+    function gc($maxlifetime)
+    {
+        return true;
+    }
+
+    /**
+     * Set session save handler
+     *
+     * @access public
+     * @return void
+     */
+    function set()
+    {
+        $GLOBALS['HTTP_Session_Container'] =& $this;
+        session_module_name('user');
+        session_set_save_handler('HTTP_Session_Open',
+                                 'HTTP_Session_Close',
+                                 'HTTP_Session_Read',
+                                 'HTTP_Session_Write',
+                                 'HTTP_Session_Destroy',
+                                 'HTTP_Session_GC');
+    }
+
+    /**
+     * Destructor for compatibility with PHP >= 5.0.5
+     *
+     * @access private
+     * @return void
+     */
+    function __destruct()
+    {
+        $GLOBALS['HTTP_Session_Container'] =& $this;
+        session_write_close();
+    }
+}
+
+// Delegate function calls to the object's methods
+/** @ignore */
+function HTTP_Session_Open($save_path, $session_name)
+{
+    return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->open($save_path, $session_name)
+                                                       : false;
+}
+/** @ignore */
+function HTTP_Session_Close()
+{
+    return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->close()
+                                                       : false;
+}
+/** @ignore */
+function HTTP_Session_Read($id)
+{
+    return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->read($id)
+                                                       : false;
+}
+/** @ignore */
+function HTTP_Session_Write($id, $data)
+{
+    return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->write($id, $data)
+                                                       : false;
+}
+/** @ignore */
+function HTTP_Session_Destroy($id)
+{
+    return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->destroy($id)
+                                                       : false;
+}
+/** @ignore */
+function HTTP_Session_GC($maxlifetime)
+{
+    return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->gc($maxlifetime)
+                                                       : false;
+}
+?>
\ No newline at end of file
diff --git a/libraries/HTTP_Session/Session/Container/DB.php b/libraries/HTTP_Session/Session/Container/DB.php
new file mode 100644
index 0000000000000000000000000000000000000000..3b6007310afca2e438d00db6d92bbee451cc61f7
--- /dev/null
+++ b/libraries/HTTP_Session/Session/Container/DB.php
@@ -0,0 +1,364 @@
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Database container for session data
+ *
+ * PEAR::DB database container
+ *
+ * PHP version 4
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  HTTP
+ * @package   HTTP_Session
+ * @author    Alexander Radivanovich <info@wwwlab.net>
+ * @author    David Costa <gurugeek@php.net>
+ * @author    Michael Metz <pear.metz@speedpartner.de>
+ * @author    Stefan Neufeind <pear.neufeind@speedpartner.de>
+ * @author    Torsten Roehr <torsten.roehr@gmx.de>
+ * @copyright 1997-2005 The PHP Group
+ * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
+ * @version   CVS: $Id: DB.php,v 1.7 2007/07/14 12:11:54 troehr Exp $
+ * @link      http://pear.php.net/package/HTTP_Session
+ * @since     File available since Release 0.4.0
+ */
+
+require_once 'HTTP/Session/Container.php';
+require_once 'DB.php';
+
+/**
+ * Database container for session data
+ *
+ * Create the following table to store session data
+ * <code>
+ * CREATE TABLE `sessiondata` (
+ *     `id` CHAR(32) NOT NULL,
+ *     `expiry` INT UNSIGNED NOT NULL DEFAULT 0,
+ *     `data` TEXT NOT NULL,
+ *     PRIMARY KEY (`id`)
+ * );
+ * </code>
+ *
+ * @category  HTTP
+ * @package   HTTP_Session
+ * @author    David Costa <gurugeek@php.net>
+ * @author    Michael Metz <pear.metz@speedpartner.de>
+ * @author    Stefan Neufeind <pear.neufeind@speedpartner.de>
+ * @author    Torsten Roehr <torsten.roehr@gmx.de>
+ * @copyright 1997-2005 The PHP Group
+ * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
+ * @version   Release: @package_version@
+ * @link      http://pear.php.net/package/HTTP_Session
+ * @since     Class available since Release 0.4.0
+ */
+class HTTP_Session_Container_DB extends HTTP_Session_Container
+{
+    /**
+     * DB connection object
+     *
+     * @var object DB
+     * @access private
+     */
+    var $db = null;
+
+    /**
+     * Session data cache id
+     *
+     * @var mixed
+     * @access private
+     */
+    var $crc = false;
+
+    /**
+     * Constrtuctor method
+     *
+     * $options is an array with the options.<br>
+     * The options are:
+     * <ul>
+     * <li>'dsn' - The DSN string</li>
+     * <li>'table' - Table with session data, default is 'sessiondata'</li>
+     * <li>'autooptimize' - Boolean, 'true' to optimize
+     * the table on garbage collection, default is 'false'.</li>
+     * </ul>
+     *
+     * @param array $options Options
+     *
+     * @access public
+     * @return object
+     */
+    function HTTP_Session_Container_DB($options)
+    {
+        $this->_setDefaults();
+        if (is_array($options)) {
+            $this->_parseOptions($options);
+        } else {
+            $this->options['dsn'] = $options;
+        }
+    }
+
+    /**
+     * Connect to database by using the given DSN string
+     *
+     * @param string $dsn DSN string
+     *
+     * @access private
+     * @return mixed   Object on error, otherwise bool
+     */
+    function _connect($dsn)
+    {
+        if (is_string($dsn) || is_array($dsn)) {
+            $this->db = DB::connect($dsn);
+        } else if (is_object($dsn) && is_a($dsn, "db_common")) {
+            $this->db = $dsn;
+        } else if (is_object($dsn) && DB::isError($dsn)) {
+            return new DB_Error($dsn->code, PEAR_ERROR_DIE);
+        } else {
+            return new PEAR_Error("The given dsn was not valid in file " . __FILE__
+                                  . " at line " . __LINE__,
+                                  41,
+                                  PEAR_ERROR_RETURN,
+                                  null,
+                                  null
+                                  );
+
+        }
+
+        if (DB::isError($this->db)) {
+            return new DB_Error($this->db->code, PEAR_ERROR_DIE);
+        }
+
+        return true;
+    }
+
+    /**
+     * Set some default options
+     *
+     * @access private
+     * @return void
+     */
+    function _setDefaults()
+    {
+        $this->options['dsn']          = null;
+        $this->options['table']        = 'sessiondata';
+        $this->options['autooptimize'] = false;
+    }
+
+    /**
+     * Establish connection to a database
+     *
+     * @param string $save_path    Save path
+     * @param string $session_name Session name
+     *
+     * @return bool
+     */
+    function open($save_path, $session_name)
+    {
+        if (DB::isError($this->_connect($this->options['dsn']))) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Free resources
+     *
+     * @return void
+     */
+    function close()
+    {
+        return true;
+    }
+
+    /**
+     * Read session data
+     *
+     * @param string $id Session id
+     *
+     * @return void
+     */
+    function read($id)
+    {
+        $query = sprintf("SELECT data FROM %s WHERE id = %s AND expiry >= %d",
+                         $this->options['table'],
+                         $this->db->quoteSmart(md5($id)),
+                         time());
+        $result = $this->db->getOne($query);
+        if (DB::isError($result)) {
+            new DB_Error($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+        $this->crc = strlen($result) . crc32($result);
+        return $result;
+    }
+
+    /**
+     * Write session data
+     *
+     * @param string $id   Session id
+     * @param mixed  $data Data
+     *
+     * @return bool
+     */
+    function write($id, $data)
+    {
+        if ((false !== $this->crc) &&
+            ($this->crc === strlen($data) . crc32($data))) {
+            // $_SESSION hasn't been touched, no need to update the blob column
+            $query = sprintf("UPDATE %s SET expiry = %d WHERE id = %s",
+                             $this->options['table'],
+                             time() + ini_get('session.gc_maxlifetime'),
+                             $this->db->quoteSmart(md5($id)));
+        } else {
+            // Check if table row already exists
+            $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
+                             $this->options['table'],
+                             $this->db->quoteSmart(md5($id)));
+            $result = $this->db->getOne($query);
+            if (DB::isError($result)) {
+                new DB_Error($result->code, PEAR_ERROR_DIE);
+                return false;
+            }
+            if (0 == intval($result)) {
+                // Insert new row into table
+                $query = sprintf("INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)",
+                                 $this->options['table'],
+                                 $this->db->quoteSmart(md5($id)),
+                                 time() + ini_get('session.gc_maxlifetime'),
+                                 $this->db->quoteSmart($data));
+            } else {
+                // Update existing row
+                $query = sprintf("UPDATE %s SET expiry = %d, data = %s WHERE id = %s",
+                                 $this->options['table'],
+                                 time() + ini_get('session.gc_maxlifetime'),
+                                 $this->db->quoteSmart($data),
+                                 $this->db->quoteSmart(md5($id)));
+            }
+        }
+        $result = $this->db->query($query);
+        if (DB::isError($result)) {
+            new DB_Error($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Destroy session data
+     *
+     * @param string $id Session id
+     *
+     * @return void
+     */
+    function destroy($id)
+    {
+        $query = sprintf("DELETE FROM %s WHERE id = %s",
+                         $this->options['table'],
+                         $this->db->quoteSmart(md5($id)));
+        $result = $this->db->query($query);
+        if (DB::isError($result)) {
+            new DB_Error($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Replicate session data to table specified in option 'replicateBeforeDestroy'
+     *
+     * @param string $targetTable Table to replicate to
+     * @param string $id          Id of record to replicate
+     *
+     * @access private
+     * @return bool
+     */
+    function replicate($targetTable, $id = null)
+    {
+        if (is_null($id)) {
+            $id = HTTP_Session::id();
+        }
+
+        // Check if table row already exists
+        $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
+                         $targetTable,
+                         $this->db->quoteSmart(md5($id)));
+        $result = $this->db->getOne($query);
+        if (DB::isError($result)) {
+            new DB_Error($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+
+        // Insert new row into dest table
+        if (0 == intval($result)) {
+            $query = sprintf("INSERT INTO %s SELECT * FROM %s WHERE id = %s",
+                             $targetTable,
+                             $this->options['table'],
+                             $this->db->quoteSmart(md5($id)));
+
+        } else {
+            // Update existing row
+            $query = sprintf("UPDATE %s dst, %s src SET dst.expiry = src.expiry, dst.data = src.data WHERE dst.id = src.id AND src.id = %s",
+                             $targetTable,
+                             $this->options['table'],
+                             $this->db->quoteSmart(md5($id)));
+        }
+
+        $result = $this->db->query($query);
+        if (DB::isError($result)) {
+            new DB_Error($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Garbage collection
+     *
+     * @param int $maxlifetime Maximum lifetime
+     *
+     * @return bool
+     */
+    function gc($maxlifetime)
+    {
+        $query = sprintf("DELETE FROM %s WHERE expiry < %d",
+                         $this->options['table'],
+                         time());
+        $result = $this->db->query($query);
+        if (DB::isError($result)) {
+            new DB_Error($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+        if ($this->options['autooptimize']) {
+            switch($this->db->phptype) {
+            case 'mysql':
+                $query = sprintf("OPTIMIZE TABLE %s", $this->options['table']);
+                break;
+            case 'pgsql':
+                $query = sprintf("VACUUM %s", $this->options['table']);
+                break;
+            default:
+                $query = null;
+                break;
+            }
+            if (isset($query)) {
+                $result = $this->db->query($query);
+                if (DB::isError($result)) {
+                    new DB_Error($result->code, PEAR_ERROR_DIE);
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+}
+?>
\ No newline at end of file
diff --git a/libraries/HTTP_Session/Session/Container/MDB.php b/libraries/HTTP_Session/Session/Container/MDB.php
new file mode 100644
index 0000000000000000000000000000000000000000..2a8f54c79697fda569fdb74c217e01200ae0686c
--- /dev/null
+++ b/libraries/HTTP_Session/Session/Container/MDB.php
@@ -0,0 +1,364 @@
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Database container for session data
+ *
+ * PEAR::MDB database container
+ *
+ * PHP version 4
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  HTTP
+ * @package   HTTP_Session
+ * @author    Alexander Radivanovich <info@wwwlab.net>
+ * @author    David Costa <gurugeek@php.net>
+ * @author    Michael Metz <pear.metz@speedpartner.de>
+ * @author    Stefan Neufeind <pear.neufeind@speedpartner.de>
+ * @author    Torsten Roehr <torsten.roehr@gmx.de>
+ * @copyright 1997-2005 The PHP Group
+ * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
+ * @version   CVS: $Id: MDB.php,v 1.5 2007/07/14 12:11:55 troehr Exp $
+ * @link      http://pear.php.net/package/HTTP_Session
+ * @since     File available since Release 0.5.0
+ */
+
+require_once 'HTTP/Session/Container.php';
+require_once 'MDB.php';
+
+/**
+ * Database container for session data
+ *
+ * Create the following table to store session data
+ * <code>
+ * CREATE TABLE `sessiondata` (
+ *     `id` CHAR(32) NOT NULL,
+ *     `expiry` INT UNSIGNED NOT NULL DEFAULT 0,
+ *     `data` TEXT NOT NULL,
+ *     PRIMARY KEY (`id`)
+ * );
+ * </code>
+ *
+ * @category  HTTP
+ * @package   HTTP_Session
+ * @author    David Costa <gurugeek@php.net>
+ * @author    Michael Metz <pear.metz@speedpartner.de>
+ * @author    Stefan Neufeind <pear.neufeind@speedpartner.de>
+ * @author    Torsten Roehr <torsten.roehr@gmx.de>
+ * @copyright 1997-2005 The PHP Group
+ * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
+ * @version   Release: @package_version@
+ * @link      http://pear.php.net/package/HTTP_Session
+ * @since     Class available since Release 0.4.0
+ */
+class HTTP_Session_Container_MDB extends HTTP_Session_Container
+{
+
+    /**
+     * MDB connection object
+     *
+     * @var object MDB
+     * @access private
+     */
+    var $db = null;
+
+    /**
+     * Session data cache id
+     *
+     * @var mixed
+     * @access private
+     */
+    var $crc = false;
+
+    /**
+     * Constructor method
+     *
+     * $options is an array with the options.<br>
+     * The options are:
+     * <ul>
+     * <li>'dsn' - The DSN string</li>
+     * <li>'table' - Table with session data, default is 'sessiondata'</li>
+     * <li>'autooptimize' - Boolean, 'true' to optimize
+     * the table on garbage collection, default is 'false'.</li>
+     * </ul>
+     *
+     * @param array $options Options
+     *
+     * @access public
+     * @return object
+     */
+    function HTTP_Session_Container_MDB($options)
+    {
+        $this->_setDefaults();
+        if (is_array($options)) {
+            $this->_parseOptions($options);
+        } else {
+            $this->options['dsn'] = $options;
+        }
+    }
+
+    /**
+     * Connect to database by using the given DSN string
+     *
+     * @param string $dsn DSN string
+     *
+     * @access private
+     * @return mixed  Object on error, otherwise bool
+     */
+    function _connect($dsn)
+    {
+        if (is_string($dsn) || is_array($dsn)) {
+            $this->db = MDB::connect($dsn);
+        } else if (is_object($dsn) && is_a($dsn, 'mdb_common')) {
+            $this->db = $dsn;
+        } else if (is_object($dsn) && MDB::isError($dsn)) {
+            return new MDB_Error($dsn->code, PEAR_ERROR_DIE);
+        } else {
+            return new PEAR_Error("The given dsn was not valid in file " . __FILE__ 
+                                  . " at line " . __LINE__,
+                                  41,
+                                  PEAR_ERROR_RETURN,
+                                  null,
+                                  null
+                                  );
+
+        }
+
+        if (MDB::isError($this->db)) {
+            return new MDB_Error($this->db->code, PEAR_ERROR_DIE);
+        }
+
+        return true;
+    }
+
+    /**
+     * Set some default options
+     *
+     * @access private
+     * @return void
+     */
+    function _setDefaults()
+    {
+        $this->options['dsn']          = null;
+        $this->options['table']        = 'sessiondata';
+        $this->options['autooptimize'] = false;
+    }
+
+    /**
+     * Establish connection to a database
+     *
+     * @param string $save_path    Save path
+     * @param string $session_name Session name
+     *
+     * @return bool
+     */
+    function open($save_path, $session_name)
+    {
+        if (MDB::isError($this->_connect($this->options['dsn']))) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Free resources
+     *
+     * @return bool
+     */
+    function close()
+    {
+        return true;
+    }
+
+    /**
+     * Read session data
+     *
+     * @param string $id Session id
+     *
+     * @return mixed
+     */
+    function read($id)
+    {
+        $query = sprintf("SELECT data FROM %s WHERE id = %s AND expiry >= %d",
+                         $this->options['table'],
+                         $this->db->getTextValue(md5($id)),
+                         time());
+        $result = $this->db->getOne($query);
+        if (MDB::isError($result)) {
+            new MDB_Error($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+        $this->crc = strlen($result) . crc32($result);
+        return $result;
+    }
+
+    /**
+     * Write session data
+     *
+     * @param string $id   Session id
+     * @param mixed  $data Data
+     *
+     * @return bool
+     */
+    function write($id, $data)
+    {
+        if ((false !== $this->crc) && 
+            ($this->crc === strlen($data) . crc32($data))) {
+            // $_SESSION hasn't been touched, no need to update the blob column
+            $query = sprintf("UPDATE %s SET expiry = %d WHERE id = %s",
+                             $this->options['table'],
+                             time() + ini_get('session.gc_maxlifetime'),
+                             $this->db->getTextValue(md5($id)));
+        } else {
+            // Check if table row already exists
+            $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
+                             $this->options['table'],
+                             $this->db->getTextValue(md5($id)));
+            $result = $this->db->getOne($query);
+            if (MDB::isError($result)) {
+                new MDB_Error($result->code, PEAR_ERROR_DIE);
+                return false;
+            }
+            if (0 == intval($result)) {
+                // Insert new row into table
+                $query = sprintf("INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)",
+                                 $this->options['table'],
+                                 $this->db->getTextValue(md5($id)),
+                                 time() + ini_get('session.gc_maxlifetime'),
+                                 $this->db->getTextValue($data));
+            } else {
+                // Update existing row
+                $query = sprintf("UPDATE %s SET expiry = %d, data = %s WHERE id = %s",
+                                 $this->options['table'],
+                                 time() + ini_get('session.gc_maxlifetime'),
+                                 $this->db->getTextValue($data),
+                                 $this->db->getTextValue(md5($id)));
+            }
+        }
+        $result = $this->db->query($query);
+        if (MDB::isError($result)) {
+            new MDB_Error($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Destroy session data
+     *
+     * @param string $id Session id
+     *
+     * @return bool
+     */
+    function destroy($id)
+    {
+        $query = sprintf("DELETE FROM %s WHERE id = %s",
+                         $this->options['table'],
+                         $this->db->getTextValue(md5($id)));
+        $result = $this->db->query($query);
+        if (MDB::isError($result)) {
+            new MDB_Error($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Replicate session data to table specified in option 'replicateBeforeDestroy'
+     *
+     * @param string $targetTable Table to replicate to
+     * @param string $id          Id of record to replicate
+     *
+     * @access private
+     * @return bool
+     */
+    function replicate($targetTable, $id = null)
+    {
+        if (is_null($id)) {
+            $id = HTTP_Session::id();
+        }
+
+        // Check if table row already exists
+        $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
+                         $targetTable,
+                         $this->db->getTextValue(md5($id)));
+        $result = $this->db->getOne($query);
+        if (MDB::isError($result)) {
+            new MDB_Error($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+
+        // Insert new row into dest table
+        if (0 == intval($result)) {
+            $query = sprintf("INSERT INTO %s SELECT * FROM %s WHERE id = %s",
+                             $targetTable,
+                             $this->options['table'],
+                             $this->db->getTextValue(md5($id)));
+        } else {
+            // Update existing row
+            $query = sprintf("UPDATE %s dst, %s src SET dst.expiry = src.expiry, dst.data = src.data WHERE dst.id = src.id AND src.id = %s",
+                             $targetTable,
+                             $this->options['table'],
+                             $this->db->getTextValue(md5($id)));
+        }
+
+        $result = $this->db->query($query);
+        if (MDB::isError($result)) {
+            new MDB_Error($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Garbage collection
+     *
+     * @param int $maxlifetime Maximum lifetime
+     *
+     * @return bool
+     */
+    function gc($maxlifetime)
+    {
+        $query = sprintf("DELETE FROM %s WHERE expiry < %d",
+                         $this->options['table'],
+                         time());
+        $result = $this->db->query($query);
+        if (MDB::isError($result)) {
+            new MDB_Error($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+        if ($this->options['autooptimize']) {
+            switch($this->db->phptype) {
+            case 'mysql':
+                $query = sprintf("OPTIMIZE TABLE %s", $this->options['table']);
+                break;
+            case 'pgsql':
+                $query = sprintf("VACUUM %s", $this->options['table']);
+                break;
+            default:
+                $query = null;
+                break;
+            }
+            if (isset($query)) {
+                $result = $this->db->query($query);
+                if (MDB::isError($result)) {
+                    new MDB_Error($result->code, PEAR_ERROR_DIE);
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+}
+?>
\ No newline at end of file
diff --git a/libraries/HTTP_Session/Session/Container/MDB2.php b/libraries/HTTP_Session/Session/Container/MDB2.php
new file mode 100644
index 0000000000000000000000000000000000000000..e36616ba5d23bca18e9932e1d0326e670c1c15c1
--- /dev/null
+++ b/libraries/HTTP_Session/Session/Container/MDB2.php
@@ -0,0 +1,364 @@
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Database container for session data
+ *
+ * PEAR::MDB2 database container
+ *
+ * PHP version 4
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  HTTP
+ * @package   HTTP_Session
+ * @author    Alexander Radivanovich <info@wwwlab.net>
+ * @author    David Costa <gurugeek@php.net>
+ * @author    Michael Metz <pear.metz@speedpartner.de>
+ * @author    Stefan Neufeind <pear.neufeind@speedpartner.de>
+ * @author    Torsten Roehr <torsten.roehr@gmx.de>
+ * @copyright 1997-2005 The PHP Group
+ * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
+ * @version   CVS: $Id: MDB2.php,v 1.5 2007/07/14 12:11:55 troehr Exp $
+ * @link      http://pear.php.net/package/HTTP_Session
+ * @since     File available since Release 0.5.0
+ */
+
+require_once 'HTTP/Session/Container.php';
+require_once 'MDB2.php';
+
+/**
+ * Database container for session data
+ *
+ * Create the following table to store session data
+ * <code>
+ * CREATE TABLE `sessiondata` (
+ *     `id` CHAR(32) NOT NULL,
+ *     `expiry` INT UNSIGNED NOT NULL DEFAULT 0,
+ *     `data` TEXT NOT NULL,
+ *     PRIMARY KEY (`id`)
+ * );
+ * </code>
+ *
+ * @category  HTTP
+ * @package   HTTP_Session
+ * @author    David Costa <gurugeek@php.net>
+ * @author    Michael Metz <pear.metz@speedpartner.de>
+ * @author    Stefan Neufeind <pear.neufeind@speedpartner.de>
+ * @author    Torsten Roehr <torsten.roehr@gmx.de>
+ * @copyright 1997-2005 The PHP Group
+ * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
+ * @version   Release: @package_version@
+ * @link      http://pear.php.net/package/HTTP_Session
+ * @since     Class available since Release 0.5.0
+ */
+class HTTP_Session_Container_MDB2 extends HTTP_Session_Container
+{
+    /**
+     * MDB2 connection object
+     *
+     * @var object MDB2
+     * @access private
+     */
+    var $db = null;
+
+    /**
+     * Session data cache id
+     *
+     * @var mixed
+     * @access private
+     */
+    var $crc = false;
+
+    /**
+     * Constructor method
+     *
+     * $options is an array with the options.<br>
+     * The options are:
+     * <ul>
+     * <li>'dsn' - The DSN string</li>
+     * <li>'table' - Table with session data, default is 'sessiondata'</li>
+     * <li>'autooptimize' - Boolean, 'true' to optimize
+     * the table on garbage collection, default is 'false'.</li>
+     * </ul>
+     *
+     * @param array $options Options
+     *
+     * @access public
+     * @return void
+     */
+    function HTTP_Session_Container_MDB2($options)
+    {
+        $this->_setDefaults();
+        if (is_array($options)) {
+            $this->_parseOptions($options);
+        } else {
+            $this->options['dsn'] = $options;
+        }
+    }
+
+    /**
+     * Connect to database by using the given DSN string
+     *
+     * @param string $dsn DSN string
+     *
+     * @access private
+     * @return mixed   Object on error, otherwise bool
+     */
+    function _connect($dsn)
+    {
+        if (is_string($dsn) || is_array($dsn)) {
+            $this->db = MDB2::connect($dsn);
+        } else if (is_object($dsn) && is_a($dsn, 'MDB2_Driver_Common')) {
+            $this->db = $dsn;
+        } else if (is_object($dsn) && MDB2::isError($dsn)) {
+            return $dsn;
+        } else {
+            return new PEAR_Error("The given dsn was not valid in file " . __FILE__
+                                  . " at line " . __LINE__,
+                                  41,
+                                  PEAR_ERROR_RETURN,
+                                  null,
+                                  null
+                                  );
+
+        }
+
+        if (MDB2::isError($this->db)) {
+            return new MDB2_Error($this->db->code, PEAR_ERROR_DIE);
+        }
+
+        return true;
+    }
+
+    /**
+     * Set some default options
+     *
+     * @access private
+     * @return void
+     */
+    function _setDefaults()
+    {
+        $this->options['dsn']          = null;
+        $this->options['table']        = 'sessiondata';
+        $this->options['autooptimize'] = false;
+    }
+
+    /**
+     * Establish connection to a database
+     *
+     * @param string $save_path    Save path
+     * @param string $session_name Session name
+     *
+     * @return bool
+     */
+    function open($save_path, $session_name)
+    {
+        if (MDB2::isError($this->_connect($this->options['dsn']))) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Free resources
+     *
+     * @return bool
+     */
+    function close()
+    {
+        return true;
+    }
+
+    /**
+     * Read session data
+     *
+     * @param string $id Session id
+     *
+     * @return mixed
+     */
+    function read($id)
+    {
+        $query = sprintf("SELECT data FROM %s WHERE id = %s AND expiry >= %d",
+                         $this->options['table'],
+                         $this->db->quote(md5($id), 'text'),
+                         time());
+        $result = $this->db->queryOne($query);
+        if (MDB2::isError($result)) {
+            $this->db->raiseError($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+        $this->crc = strlen($result) . crc32($result);
+        return $result;
+    }
+
+    /**
+     * Write session data
+     *
+     * @param string $id   Session id
+     * @param mixed  $data Data
+     *
+     * @return bool
+     */
+    function write($id, $data)
+    {
+        if ((false !== $this->crc) &&
+            ($this->crc === strlen($data) . crc32($data))) {
+            // $_SESSION hasn't been touched, no need to update the blob column
+            $query = sprintf("UPDATE %s SET expiry = %d WHERE id = %s",
+                             $this->options['table'],
+                             time() + ini_get('session.gc_maxlifetime'),
+                             $this->db->quote(md5($id), 'text'));
+        } else {
+            // Check if table row already exists
+            $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
+                             $this->options['table'],
+                             $this->db->quote(md5($id), 'text'));
+            $result = $this->db->queryOne($query);
+            if (MDB2::isError($result)) {
+                $this->db->raiseError($result->code, PEAR_ERROR_DIE);
+                return false;
+            }
+            if (0 == intval($result)) {
+                // Insert new row into table
+                $query = sprintf("INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)",
+                                 $this->options['table'],
+                                 $this->db->quote(md5($id), 'text'),
+                                 time() + ini_get('session.gc_maxlifetime'),
+                                 $this->db->quote($data, 'text'));
+            } else {
+                // Update existing row
+                $query = sprintf("UPDATE %s SET expiry = %d, data = %s WHERE id = %s",
+                                 $this->options['table'],
+                                 time() + ini_get('session.gc_maxlifetime'),
+                                 $this->db->quote($data, 'text'),
+                                 $this->db->quote(md5($id), 'text'));
+            }
+        }
+        $result = $this->db->query($query);
+        if (MDB2::isError($result)) {
+            $this->db->raiseError($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Destroy session data
+     *
+     * @param string $id Session id
+     *
+     * @return bool
+     */
+    function destroy($id)
+    {
+        $query = sprintf("DELETE FROM %s WHERE id = %s",
+                         $this->options['table'],
+                         $this->db->quote(md5($id), 'text'));
+        $result = $this->db->query($query);
+        if (MDB2::isError($result)) {
+            $this->db->raiseError($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Replicate session data to table specified in option 'replicateBeforeDestroy'
+     *
+     * @param string $targetTable Table to replicate to
+     * @param string $id          Id of record to replicate
+     *
+     * @access private
+     * @return bool
+     */
+    function replicate($targetTable, $id = null)
+    {
+        if (is_null($id)) {
+            $id = HTTP_Session::id();
+        }
+
+        // Check if table row already exists
+        $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
+                         $targetTable,
+                         $this->db->quote(md5($id), 'text'));
+        $result = $this->db->queryOne($query);
+        if (MDB2::isError($result)) {
+            $this->db->raiseError($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+
+        // Insert new row into dest table
+        if (0 == intval($result)) {
+            $query = sprintf("INSERT INTO %s SELECT * FROM %s WHERE id = %s",
+                             $targetTable,
+                             $this->options['table'],
+                             $this->db->quote(md5($id), 'text'));
+
+        } else {
+            // Update existing row
+            $query = sprintf("UPDATE %s dst, %s src SET dst.expiry = src.expiry, dst.data = src.data WHERE dst.id = src.id AND src.id = %s",
+                             $targetTable,
+                             $this->options['table'],
+                             $this->db->quote(md5($id), 'text'));
+        }
+
+        $result = $this->db->query($query);
+        if (MDB2::isError($result)) {
+            $this->db->raiseError($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Garbage collection
+     *
+     * @param int $maxlifetime Maximum lifetime
+     *
+     * @return bool
+     */
+    function gc($maxlifetime)
+    {
+        $query = sprintf("DELETE FROM %s WHERE expiry < %d",
+                         $this->options['table'],
+                         time());
+        $result = $this->db->query($query);
+        if (MDB2::isError($result)) {
+            $this->db->raiseError($result->code, PEAR_ERROR_DIE);
+            return false;
+        }
+        if ($this->options['autooptimize']) {
+            switch($this->db->phptype) {
+            case 'mysql':
+                $query = sprintf("OPTIMIZE TABLE %s", $this->options['table']);
+                break;
+            case 'pgsql':
+                $query = sprintf("VACUUM %s", $this->options['table']);
+                break;
+            default:
+                $query = null;
+                break;
+            }
+            if (isset($query)) {
+                $result = $this->db->query($query);
+                if (MDB2::isError($result)) {
+                    $this->db->raiseError($result->code, PEAR_ERROR_DIE);
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+}
+?>
\ No newline at end of file
diff --git a/libraries/HTTP_Session/Session/Container/Memcache.php b/libraries/HTTP_Session/Session/Container/Memcache.php
new file mode 100644
index 0000000000000000000000000000000000000000..d2889ffcea97476cd791460b314556301031c41d
--- /dev/null
+++ b/libraries/HTTP_Session/Session/Container/Memcache.php
@@ -0,0 +1,202 @@
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Database container for session data
+ *
+ * Memcache database container
+ *
+ * PHP version 4
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  HTTP
+ * @package   HTTP_Session
+ * @author    Chad Wagner <chad.wagner@gmail.com>
+ * @author    Torsten Roehr <torsten.roehr@gmx.de>
+ * @copyright 1997-2007 The PHP Group
+ * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
+ * @version   CVS: $Id: Memcache.php,v 1.3 2007/07/14 12:11:55 troehr Exp $
+ * @link      http://pear.php.net/package/HTTP_Session
+ * @since     File available since Release 0.5.6
+ */
+
+require_once 'HTTP/Session/Container.php';
+
+/**
+ * Database container for session data
+ *
+ * @category  HTTP
+ * @package   HTTP_Session
+ * @author    Chad Wagner <chad.wagner@gmail.com>
+ * @author    Torsten Roehr <torsten.roehr@gmx.de>
+ * @copyright 1997-2007 The PHP Group
+ * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
+ * @version   Release: @package_version@
+ * @link      http://pear.php.net/package/HTTP_Session
+ * @since     Class available since Release 0.5.6
+ */
+class HTTP_Session_Container_Memcache extends HTTP_Session_Container
+{
+    /**
+     * Memcache connection object
+     *
+     * @var     object  Memcache
+     * @access  private
+     */
+    var $mc;
+
+    /**
+     * Constructor method
+     *
+     * $options is an array with the options.<br>
+     * The options are:
+     * <ul>
+     * <li>'memcache' - Memcache object
+     * <li>'prefix' - Key prefix, default is 'sessiondata:'</li>
+     * </ul>
+     *
+     * @param array $options Options
+     *
+     * @access public
+     * @return object
+     */
+    function HTTP_Session_Container_Memcache($options)
+    {
+        $this->_setDefaults();
+
+        if (is_array($options)) {
+            $this->_parseOptions($options);
+        }
+    }
+
+    /**
+     * Connect to database by using the given DSN string
+     *
+     * @param string $mc Memcache object
+     *
+     * @access private
+     * @return mixed   Object on error, otherwise bool
+     */
+    function _connect($mc)
+    {
+        if (is_object($mc) && is_a($mc, 'Memcache')) {
+            $this->mc = $mc;
+
+        } else {
+
+            return new PEAR_Error('The given memcache object was not valid in file '
+                                  . __FILE__ . ' at line ' . __LINE__,
+                                  41,
+                                  PEAR_ERROR_RETURN,
+                                  null,
+                                  null
+                                 );
+        }
+
+        return true;
+    }
+
+    /**
+     * Set some default options
+     *
+     * @access private
+     * @return void
+     */
+    function _setDefaults()
+    {
+        $this->options['prefix']   = 'sessiondata:';
+        $this->options['memcache'] = null;
+    }
+
+    /**
+     * Establish connection to a database
+     *
+     * @param string $save_path    Save path
+     * @param string $session_name Session name
+     *
+     * @access public
+     * @return mixed  Object on error, otherwise bool
+     */
+    function open($save_path, $session_name)
+    {
+        return $this->_connect($this->options['memcache']);
+    }
+
+    /**
+     * Free resources
+     *
+     * @access public
+     * @return bool
+     */
+    function close()
+    {
+        return true;
+    }
+
+    /**
+     * Read session data
+     *
+     * @param string $id Session id
+     *
+     * @access public
+     * @return mixed
+     */
+    function read($id)
+    {
+        $result = $this->mc->get($this->options['prefix'] . $id);
+        return $result;
+    }
+
+    /**
+     * Write session data
+     *
+     * @param string $id   Session id
+     * @param mixed  $data Session data
+     *
+     * @access public
+     * @return bool
+     */
+    function write($id, $data)
+    {
+        $this->mc->set($this->options['prefix'] . $id,
+                       $data,
+                       MEMCACHE_COMPRESSED,
+                       time() + ini_get('session.gc_maxlifetime'));
+
+        return true;
+    }
+
+    /**
+     * Destroy session data
+     *
+     * @param string $id Session id
+     *
+     * @access public
+     * @return bool
+     */
+    function destroy($id)
+    {
+        $this->mc->delete($this->options['prefix'] . $id);
+        return true;
+    }
+
+    /**
+     * Garbage collection
+     *
+     * @param int $maxlifetime Maximum lifetime
+     *
+     * @access public
+     * @return bool
+     */
+    function gc($maxlifetime)
+    {
+        return true;
+    }
+}
+?>
\ No newline at end of file
diff --git a/packages/vtiger/mandatory/Mobile.zip b/packages/vtiger/mandatory/Mobile.zip
index b4ab1fed2ef6cc2fff462de1567710074c912b43..ff87287f49ed87e0e7e3db01e1382a601260a1c1 100644
Binary files a/packages/vtiger/mandatory/Mobile.zip and b/packages/vtiger/mandatory/Mobile.zip differ
diff --git a/pkg/vtiger/modules/Mobile/modules/Mobile/html/Viewer.php b/pkg/vtiger/modules/Mobile/modules/Mobile/html/Viewer.php
index d7735e0c9c1e7d9d36441905086453e745b51872..b8a0176e78bfda38939e6f586d6fc8b535a3a8dc 100644
--- a/pkg/vtiger/modules/Mobile/modules/Mobile/html/Viewer.php
+++ b/pkg/vtiger/modules/Mobile/modules/Mobile/html/Viewer.php
@@ -8,6 +8,7 @@
  * All Rights Reserved.
  ************************************************************************************/
 
+include_once 'includes/Loader.php';
 include_once 'includes/runtime/Viewer.php';
 
 class Mobile_HTML_Viewer extends Vtiger_Viewer{