diff --git a/include/class.auth.php b/include/class.auth.php
index 4a97ab01adb25d60a6bfb74f69628de824772c4a..f67b01237c0ce1a8cb13b935a7e35e68ef177007 100644
--- a/include/class.auth.php
+++ b/include/class.auth.php
@@ -32,6 +32,10 @@ abstract class AuthenticatedUser {
 
         return false;
     }
+
+    // Signal method to allow performing extra things when a user is logged
+    // into the sysem
+    function onLogin($bk) {}
 }
 
 interface AuthDirectorySearch {
@@ -427,14 +431,10 @@ abstract class StaffAuthenticationBackend  extends AuthenticationBackend {
             sprintf(_S("%s logged in [%s], via %s"), $staff->getUserName(),
                 $_SERVER['REMOTE_ADDR'], get_class($bk))); //Debug.
 
-        $sql='UPDATE '.STAFF_TABLE.' SET lastlogin=NOW() '
-            .' WHERE staff_id='.db_input($staff->getId());
-        db_query($sql);
-
-        //Tag the authkey.
+        // Tag the authkey.
         $authkey = $bk::$id.':'.$authkey;
 
-        //Now set session crap and lets roll baby!
+        // Now set session crap and lets roll baby!
         $authsession = &$_SESSION['_auth']['staff'];
 
         $authsession = array(); //clear.
@@ -452,6 +452,9 @@ abstract class StaffAuthenticationBackend  extends AuthenticationBackend {
         if ($bk->supportsInteractiveAuthentication())
             $staff->cancelResetTokens();
 
+        // Update last-used language, login time, etc
+        $staff->onLogin($bk);
+
         return true;
     }
 
@@ -628,6 +631,9 @@ abstract class UserAuthenticationBackend  extends AuthenticationBackend {
         if ($bk->supportsInteractiveAuthentication() && ($acct=$user->getAccount()))
             $acct->cancelResetTokens();
 
+        // Update last-used language, login time, etc
+        $user->onLogin($bk);
+
         return true;
     }
 
diff --git a/include/class.client.php b/include/class.client.php
index 21d230047358f63a561ec1a7888f2ffae1945a77..cfa492bfc2474af087b2e69406019908847d636a 100644
--- a/include/class.client.php
+++ b/include/class.client.php
@@ -314,10 +314,17 @@ class  EndUser extends AuthenticatedUser {
 
         return $stats;
     }
+
+    function onLogin($bk) {
+        if ($account = $this->getAccount())
+            $account->onLogin($bk);
+    }
 }
 
 class ClientAccount extends UserAccount {
 
+    var $_extra;
+
     function checkPassword($password, $autoupdate=true) {
 
         /*bcrypt based password match*/
@@ -353,6 +360,32 @@ class ClientAccount extends UserAccount {
         unset($_SESSION['_client']['reset-token']);
     }
 
+    function getExtraAttr($attr=false) {
+        if (!isset($this->_extra))
+            $this->_extra = JsonDataParser::decode($this->ht['extra']);
+
+        return $attr ? $this->_extra[$attr] : $this->_extra;
+    }
+
+    function setExtraAttr($attr, $value) {
+        $this->getExtraAttr();
+        $this->_extra[$attr] = $value;
+    }
+
+    function onLogin($bk) {
+        $this->setExtraAttr('browser_lang',
+            Internationalization::getCurrentLanguage());
+        $this->save();
+    }
+
+    function save($refetch=false) {
+        // Serialize the extra column on demand
+        if (isset($this->_extra)) {
+            $this->extra = JsonDataEncoder::encode($this->_extra);
+        }
+        return parent::save($refetch);
+    }
+
     function update($vars, &$errors) {
         global $cfg;
 
diff --git a/include/class.i18n.php b/include/class.i18n.php
index 2f5619c05f405e986374b5525e5c276e7d5c478a..bcaf6a4eccf0b94ca2923d3304b9e855e68e9897 100644
--- a/include/class.i18n.php
+++ b/include/class.i18n.php
@@ -363,10 +363,11 @@ class Internationalization {
 
         $user = $user ?: $thisstaff ?: $thisclient;
         if ($user && method_exists($user, 'getLanguage'))
-            return $user->getLanguage();
+            if ($lang = $user->getLanguage())
+                return $lang;
 
         // Support the flag buttons for guests
-        if ((!$user || $user != $thisstaff) && isset($session))
+        if ((!$user || $user != $thisstaff) && $session)
             return $session;
 
         return self::getDefaultLanguage();
diff --git a/include/class.staff.php b/include/class.staff.php
index b9b50ce10892cc62bfbc3d34d4db697371deb625..9738abf2842551defd0d0cf71915e0e498cfbfed 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -67,7 +67,6 @@ class Staff extends AuthenticatedUser {
         $this->teams = $this->ht['teams'] = array();
         $this->group = $this->dept = null;
         $this->departments = $this->stats = array();
-        $this->config = new Config('staff.'.$this->id);
 
         //WE have to patch info here to support upgrading from old versions.
         if(($time=strtotime($this->ht['passwdreset']?$this->ht['passwdreset']:$this->ht['added'])))
@@ -98,7 +97,7 @@ class Staff extends AuthenticatedUser {
     }
 
     function getInfo() {
-        return $this->config->getInfo() + $this->getHashtable();
+        return $this->getHashtable();
     }
 
     // AuthenticatedUser implementation...
@@ -278,13 +277,15 @@ class Staff extends AuthenticatedUser {
     }
 
     function getLanguage() {
+        // XXX: This should just return the language preference. Caching
+        //      should be done elsewhere
         static $cached = false;
         if (!$cached)
             $cached = &$_SESSION['staff:lang'];
 
         if (!$cached) {
-            $cached = $this->config->get('lang',
-                Internationalization::getDefaultLanguage());
+            $cached = $this->ht['lang']
+                ?: Internationalization::getDefaultLanguage();
         }
         return $cached;
     }
@@ -434,6 +435,39 @@ class Staff extends AuthenticatedUser {
         return ($stats=$this->getTicketsStats())?$stats['closed']:0;
     }
 
+    function getExtraAttr($attr=false) {
+        if (!isset($this->extra))
+            $this->extra = JsonDataParser::decode($this->ht['extra']);
+
+        return $attr ? $this->extra[$attr] : $this->extra;
+    }
+
+    function setExtraAttr($attr, $value, $commit=true) {
+        $this->getExtraAttr();
+        $this->extra[$attr] = $value;
+
+        if ($commit) {
+            $sql='UPDATE '.STAFF_TABLE.' SET '
+                .'`extra`='.db_input(JsonDataEncoder::encode($this->extra))
+                .' WHERE staff_id='.db_input($this->getId());
+            db_query($sql);
+        }
+    }
+
+    function onLogin($bk) {
+        // Update last apparent language preference
+        $this->setExtraAttr('browser_lang',
+            Internationalization::getCurrentLanguage(),
+            false);
+
+        $sql='UPDATE '.STAFF_TABLE.' SET '
+            // Update time of last login
+            .'  `lastlogin`=NOW() '
+            .', `extra`='.db_input(JsonDataEncoder::encode($this->extra))
+            .' WHERE staff_id='.db_input($this->getId());
+         db_query($sql);
+    }
+
     //Staff profile update...unfortunately we have to separate it from admin update to avoid potential issues
     function updateProfile($vars, &$errors) {
         global $cfg;
@@ -498,7 +532,6 @@ class Staff extends AuthenticatedUser {
 
         if($errors) return false;
 
-        $this->config->set('lang', $vars['lang']);
         $_SESSION['staff:lang'] = null;
         TextDomain::configureForUser($this);
 
@@ -516,8 +549,8 @@ class Staff extends AuthenticatedUser {
             .' ,max_page_size='.db_input($vars['max_page_size'])
             .' ,auto_refresh_rate='.db_input($vars['auto_refresh_rate'])
             .' ,default_signature_type='.db_input($vars['default_signature_type'])
-            .' ,default_paper_size='.db_input($vars['default_paper_size']);
-
+            .' ,default_paper_size='.db_input($vars['default_paper_size'])
+            .' ,lang='.db_input($vars['lang']);
 
         if($vars['passwd1']) {
             $sql.=' ,change_passwd=0, passwdreset=NOW(), passwd='.db_input(Passwd::hash($vars['passwd1']));
@@ -586,9 +619,6 @@ class Staff extends AuthenticatedUser {
 
             //Cleanup Team membership table.
             db_query('DELETE FROM '.TEAM_MEMBER_TABLE.' WHERE staff_id='.db_input($this->getId()));
-
-            // Destrory config settings
-            $this->config->destroy();
         }
 
         Signal::send('model.deleted', $this);
diff --git a/include/staff/system.inc.php b/include/staff/system.inc.php
index 4238e3dbeced405a5662c96a01598aa9764086e6..2e21c21a67527331b228f673fc2b80974bc11e73 100644
--- a/include/staff/system.inc.php
+++ b/include/staff/system.inc.php
@@ -33,6 +33,10 @@ $extensions = array(
             'name' => 'phar',
             'desc' => __('Highly recommended for plugins and language packs')
             ),
+        'intl' => array(
+            'name' => 'intl',
+            'desc' => __('Highly recommended for non western european language content')
+            ),
         );
 
 ?>