diff --git a/client.inc.php b/client.inc.php
index bb8e8badbe7fdce1ef104276bff36448aa4126a6..2faee156f11c1c34aebffaf72d13bd15b3dd1655 100644
--- a/client.inc.php
+++ b/client.inc.php
@@ -48,7 +48,7 @@ $nav=null;
 $thisclient = UserAuthenticationBackend::getUser();
 
 if (isset($_GET['lang']) && $_GET['lang']) {
-    $_SESSION['client:lang'] = $_GET['lang'];
+    Internationalization::setCurrentLanguage($_GET['lang']);
 }
 
 // Bootstrap gettext translations as early as possible, but after attempting
diff --git a/include/class.client.php b/include/class.client.php
index bfcffeaca09f2a1251a0d3ae7fd8125cd5d08e1b..21d230047358f63a561ec1a7888f2ffae1945a77 100644
--- a/include/class.client.php
+++ b/include/class.client.php
@@ -271,7 +271,6 @@ class  EndUser extends AuthenticatedUser {
 
     function getLanguage() {
         static $cached = false;
-        if (!$cached) $cached = &$_SESSION['client:lang'];
 
         if (!$cached) {
             if ($acct = $this->getAccount())
@@ -396,7 +395,7 @@ class ClientAccount extends UserAccount {
         $this->set('dst', isset($vars['dst']) ? 1 : 0);
         // Change language
         $this->set('lang', $vars['lang'] ?: null);
-        $_SESSION['client:lang'] = null;
+        Internationalization::setCurrentLanguage(null);
         TextDomain::configureForUser($this);
 
         if ($vars['backend']) {
diff --git a/include/class.i18n.php b/include/class.i18n.php
index d141439d1606f1aa38d81f1d4fff12fbb407af58..2f5619c05f405e986374b5525e5c276e7d5c478a 100644
--- a/include/class.i18n.php
+++ b/include/class.i18n.php
@@ -274,7 +274,7 @@ class Internationalization {
         if (empty($_SERVER["HTTP_ACCEPT_LANGUAGE"]))
             return $cfg->getPrimaryLanguage();
 
-        $languages = self::availableLanguages();
+        $languages = self::getConfiguredSystemLanguages();
 
         // The Accept-Language header contains information about the
         // language preferences configured in the user's browser / operating
@@ -348,18 +348,27 @@ class Internationalization {
           }
         }
 
-        return $best_match_langcode;
+        if (self::isLanguageInstalled($best_match_langcode))
+            return $best_match_langcode;
+        else
+            return $cfg->getPrimaryLanguage();
     }
 
     static function getCurrentLanguage($user=false) {
         global $thisstaff, $thisclient;
+        static $session = null;
+
+        if (!isset($session))
+            $session = &$_SESSION['::lang'];
 
         $user = $user ?: $thisstaff ?: $thisclient;
         if ($user && method_exists($user, 'getLanguage'))
             return $user->getLanguage();
+
         // Support the flag buttons for guests
-        if (isset($_SESSION['client:lang']))
-            return $_SESSION['client:lang'];
+        if ((!$user || $user != $thisstaff) && isset($session))
+            return $session;
+
         return self::getDefaultLanguage();
     }
 
@@ -386,6 +395,14 @@ class Internationalization {
         return $rv;
     }
 
+    static function setCurrentLanguage($lang) {
+        if (!self::isLanguageInstalled($lang))
+            return false;
+
+        $_SESSION['::lang'] = $lang ?: null;
+        return true;
+    }
+
     static function bootstrap() {
 
         require_once INCLUDE_DIR . 'class.translation.php';
diff --git a/include/class.staff.php b/include/class.staff.php
index da2473c0e75d45d05d9d6cf52e05f16c602f3164..b9b50ce10892cc62bfbc3d34d4db697371deb625 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -279,12 +279,12 @@ class Staff extends AuthenticatedUser {
 
     function getLanguage() {
         static $cached = false;
-        if (!$cached) $cached = &$_SESSION['staff:lang'];
+        if (!$cached)
+            $cached = &$_SESSION['staff:lang'];
 
         if (!$cached) {
-            $cached = $this->config->get('lang');
-            if (!$cached)
-                $cached = Internationalization::getDefaultLanguage();
+            $cached = $this->config->get('lang',
+                Internationalization::getDefaultLanguage());
         }
         return $cached;
     }
diff --git a/include/class.translation.php b/include/class.translation.php
index 84570ff53faedb2e47577385aebdcba525ecc1a9..e6fb8301d6b80442257136b7b54ecb21cb079632 100644
--- a/include/class.translation.php
+++ b/include/class.translation.php
@@ -760,8 +760,7 @@ class TextDomain {
 
     static function configureForUser($user=false) {
         $lang = Internationalization::getCurrentLanguage($user);
-
-        $info = Internationalization::getLanguageInfo(strtolower($lang));
+        $info = Internationalization::getLanguageInfo($lang);
         if (!$info)
             // Not a supported language
             return;
diff --git a/setup/setup.inc.php b/setup/setup.inc.php
index 035a8333d8786500f49e622a87763603b70ca52a..68bb943229213c84f3ef85f952498c93cc3218c5 100644
--- a/setup/setup.inc.php
+++ b/setup/setup.inc.php
@@ -68,7 +68,7 @@ require_once INCLUDE_DIR.'class.translation.php';
 
 // Support flags in the setup portal too
 if (isset($_GET['lang']) && $_GET['lang']) {
-    $_SESSION['client:lang'] = $_GET['lang'];
+    Internationalization::setCurrentLanguage($_GET['lang']);
 }
 TextDomain::configureForUser();