diff --git a/html/class_passwordRecovery.inc b/html/class_passwordRecovery.inc
index b1df2ec180043b26bc1b42a50abec52971dcc50b..569fdb62c5a69a91364a288c34ba91e799c79177 100644
--- a/html/class_passwordRecovery.inc
+++ b/html/class_passwordRecovery.inc
@@ -95,7 +95,7 @@ class standAlonePage {
     }
 
     if ($this->interactive) {
-      initLanguage();
+      Language::init();
 
       if (session::global_is_set('plist')) {
         session::global_un_set('plist');
@@ -345,7 +345,7 @@ class passwordRecovery extends standAlonePage {
     $smarty->append('css_files',    get_template_path('login.css'));
     $lang = session::global_get('lang');
     $smarty->assign('lang', preg_replace('/_.*$/', '', $lang));
-    $smarty->assign('rtl', language_is_rtl($lang));
+    $smarty->assign('rtl', Language::isRTL($lang));
     $smarty->display(get_template_path('headers.tpl'));
 
     $smarty->assign('version',        FD_VERSION);
diff --git a/html/index.php b/html/index.php
index 88803a518eb68feadb84ef0c9ec1bb2868121f6a..bfed93af400f078bef92b2df64939dc844c0edbd 100644
--- a/html/index.php
+++ b/html/index.php
@@ -90,7 +90,7 @@ function displayLogin()
   $smarty->assign("usePrototype", "false");
   $smarty->assign("date", date("l, dS F Y H:i:s O"));
   $smarty->assign("lang", preg_replace('/_.*$/', '', $lang));
-  $smarty->assign("rtl", language_is_rtl($lang));
+  $smarty->assign("rtl",  Language::isRTL($lang));
 
   $smarty->display (get_template_path('headers.tpl'));
   $smarty->assign("version", FD_VERSION);
@@ -180,7 +180,7 @@ if (!(is_dir($smarty->compile_dir) && is_writable($smarty->compile_dir))) {
 /* Check for old files in compile directory */
 clean_smarty_compile_dir($smarty->compile_dir);
 
-initLanguage();
+Language::init();
 
 $smarty->assign ('focusfield', 'username');
 
@@ -318,7 +318,7 @@ class Index {
     session::global_set('ui', $ui);
 
     /* User might have its own language, re-run initLanguage */
-    $plistReloaded = initLanguage();
+    $plistReloaded = Language::init();
 
     /* We need a fully loaded plist and config to test account expiration */
     if (!$plistReloaded) {
diff --git a/html/main.php b/html/main.php
index 856a64e6bc97dacbb263c7d086c997db46597529..33ee1bfe8a05cc9f4f084392ed093023a6e6b833 100644
--- a/html/main.php
+++ b/html/main.php
@@ -98,7 +98,7 @@ if (!session::global_is_set('CurrentMainBase')) {
   session::global_set('CurrentMainBase', get_base_from_people($ui->dn));
 }
 
-initLanguage();
+Language::init();
 
 /* Prepare plugin list */
 $plist = load_plist();
@@ -232,9 +232,9 @@ if (isset($_GET['reset'])) {
 /* show web frontend */
 $smarty->assign ("date", date("l, dS F Y H:i:s O"));
 $lang = session::global_get('lang');
-$smarty->assign ("lang", preg_replace('/_.*$/', '', $lang));
-$smarty->assign ("rtl", language_is_rtl($lang));
-$smarty->assign ("must", '<span class="must">*</span>');
+$smarty->assign ('lang',  preg_replace('/_.*$/', '', $lang));
+$smarty->assign ('rtl',   Language::isRTL($lang));
+$smarty->assign ('must',  '<span class="must">*</span>');
 if (isset($plug)) {
   $plug = "?plug=$plug";
 } else {
diff --git a/html/setup.php b/html/setup.php
index 6c77f663c1bb307f367a83e07f6cdd6fa990bb02..183840d0c1f609a3127e91d591b984f3d56f4c27 100644
--- a/html/setup.php
+++ b/html/setup.php
@@ -78,12 +78,12 @@ if (isset($_POST['lang_selected']) && $_POST['lang_selected'] != '') {
     $lang .= '.UTF-8';
   }
 } else {
-  $lang = get_browser_language();
+  $lang = Language::detect();
 }
 
-initLanguage($lang);
+Language::init($lang);
 
-$smarty->assign("rtl", language_is_rtl($lang));
+$smarty->assign("rtl",  Language::isRTL($lang));
 $smarty->assign("must", '<span class="must">*</span>');
 
 /* Minimal config */
@@ -99,7 +99,6 @@ $ui = new fake_userinfo();
 $display = "";
 require_once("../setup/main.inc");
 
-$smarty->assign("rtl", language_is_rtl($lang));
 $smarty->assign("date", date("l, dS F Y H:i:s O"));
 $header = $smarty->fetch(get_template_path('headers.tpl'));
 
diff --git a/include/accept-to-gettext.inc b/include/accept-to-gettext.inc
index 259510bb1b0aad7684785acbb7310b06f16158af..3f2a3b23d64857758cac9c1357c564588464d3ea 100644
--- a/include/accept-to-gettext.inc
+++ b/include/accept-to-gettext.inc
@@ -3,7 +3,7 @@
  * accept-to-gettext.inc -- convert information in 'Accept-*' headers to
  * gettext language identifiers.
  * Copyright (c) 2003, Wouter Verhelst <wouter@debian.org>
- * Copyright (c) 2012-2016, FusionDirectory
+ * Copyright (c) 2012-2018, FusionDirectory
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -115,7 +115,7 @@ function parse_gettext_lang ($str)
   }
 }
 
-function al2gt($gettextlangs, $mime)
+function al2gt($gettextlangs)
 {
   /* Check if ACCEPT_LANGUAGE isset */
   if (empty($_SERVER["HTTP_ACCEPT_LANGUAGE"])) {
@@ -177,15 +177,6 @@ function al2gt($gettextlangs, $mime)
     return NULL;
   }
 
-  /* We must re-parse the gettext-string now, since we may have found it
-   * through a "*" qualifier.*/
-  list ($lang, $country, $char) = parse_gettext_lang($max_lang);
-  if (!headers_sent()) {
-    header("Content-Language: $lang".(empty($country) ? "" : "-$country"));
-    if (!empty($char)) {
-      header("Content-Type: $mime; charset=$char");
-    }
-  }
   return $max_lang;
 }
 ?>
diff --git a/include/class_Language.inc b/include/class_Language.inc
new file mode 100644
index 0000000000000000000000000000000000000000..dba0321e38de732bff51c1ed12ab5f418927fb28
--- /dev/null
+++ b/include/class_Language.inc
@@ -0,0 +1,250 @@
+<?php
+
+/*
+  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
+  Copyright (C) 2017-2018  FusionDirectory
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+/*!
+ * \file class_Language.inc
+ * Source code for the class Language
+ */
+
+/*!
+ * \brief This class contains all the function needed to manage languages
+ */
+class Language
+{
+  /*!
+   * \brief Initialize language configuration
+   *
+   * \param string $lang Language locale to use, defaults to self::detect()
+   */
+  public static function init($lang = NULL)
+  {
+    global $BASE_DIR;
+
+    if ($lang === NULL) {
+      $lang = static::detect();
+    }
+
+    putenv('LANGUAGE=');
+    putenv("LANG=$lang");
+    $langset = setlocale(LC_ALL, $lang);
+    if ($langset === FALSE) {
+      trigger_error('Setting locale to '.$lang.' failed');
+    }
+    $GLOBALS['t_language']            = $lang;
+    $GLOBALS['t_gettext_message_dir'] = $BASE_DIR.'/locale/';
+    static::setHeaders($lang, 'text/html');
+
+    /* Set the text domain as 'fusiondirectory' */
+    $domain = 'fusiondirectory';
+    bindtextdomain($domain, LOCALE_DIR);
+    textdomain($domain);
+    if ($_SERVER['REQUEST_METHOD'] != 'POST') {
+      @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $lang, 'Setting language to');
+    }
+
+    $ret = FALSE;
+
+    /* Reset plist cache if language changed */
+    if ((!session::global_is_set('lang')) || (session::global_get('lang') != $lang)) {
+      $ret = TRUE;
+      if (session::global_is_set('plist')) {
+        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
+          @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, session::global_get('lang'), 'Plist already loaded with language');
+        }
+        session::global_un_set('plist');
+        session::global_set('lang', $lang);
+        load_plist();
+      }
+    }
+
+    session::global_set('lang', $lang);
+    return $ret;
+  }
+
+  /*!
+   * \brief Determine which language to show to the user
+   *
+   * Determines which language should be used to present fusiondirectory content
+   * to the user. It does so by looking at several possibilites and returning
+   * the first setting that can be found.
+   *
+   * -# Language configured by the user
+   * -# Global configured language
+   * -# Language as returned by al2gt (as configured in the browser)
+   *
+   * \return string gettext locale string
+   */
+  public static function detect()
+  {
+    global $config;
+
+    /* Try to use users primary language */
+    $ui = get_userinfo();
+    if (isset($ui) && ($ui !== NULL) && ($ui->language != '')) {
+      return $ui->language.'.UTF-8';
+    }
+
+    /* Check for global language settings in configuration */
+    if (isset($config) && ($config->get_cfg_value('language') != '')) {
+      $lang = $config->get_cfg_value('language');
+      if (!preg_match('/utf/i', $lang)) {
+        $lang .= '.UTF-8';
+      }
+      return $lang;
+    }
+
+    /* Load supported languages */
+    $languages = static::list();
+
+    /* Move supported languages to flat list */
+    $langs = array();
+    foreach (array_keys($languages) as $lang) {
+      $langs[] = $lang.'.UTF-8';
+    }
+
+    /* Return gettext based string */
+    return al2gt($langs);
+  }
+
+  /*!
+   * \brief Get the language for the user connecting
+   *
+   * \param boolean $languages_in_own_language FALSE
+   *
+   * \param boolean $strip_region_tag FALSE
+   */
+  public static function list($languages_in_own_language = FALSE, $strip_region_tag = FALSE)
+  {
+    /* locales in english */
+    $tmp_english = array(
+      'ar'    => 'Arabic',
+      'ca_ES' => 'Catalan',
+      'cs_CZ' => 'Czech',
+      'de_DE' => 'German',
+      'el_GR' => 'Greek',
+      'en_US' => 'English',
+      'es_CO' => 'Colombian Spanish',
+      'es_ES' => 'Spanish',
+      'es_VE' => 'Venezuelan',
+      'fa_IR' => 'Persian',
+      'fi_FI' => 'Finnish',
+      'fr_FR' => 'French',
+      'hu_HU' => 'Hungarian',
+      'id'    => 'Indonesian',
+      'it_IT' => 'Italian',
+      'ja'    => 'Japanese',
+      'ko'    => 'Korean',
+      'lv'    => 'Latvian',
+      'nb'    => 'Norwegian Bokmål',
+      'nl_NL' => 'Dutch',
+      'pl_PL' => 'Polish',
+      'pt'    => 'Portuguese',
+      'pt_BR' => 'Brazilian',
+      'ru_RU' => 'Russian',
+      'tr_TR' => 'Turkish',
+      'vi_VN' => 'Vietnamese',
+      'sv_SE' => 'Swedish',
+      'zh_CN' => 'Chinese',
+    );
+
+    $ret = array();
+    if ($languages_in_own_language) {
+      /* locales in their own language */
+      $tmp_ownlang = array(
+        'ar'    => 'عربية',
+        'ca_ES' => 'Català',
+        'cs_CZ' => 'ÄŒesky',
+        'de_DE' => 'Deutsch',
+        'el_GR' => 'ελληνικά',
+        'en_US' => 'English',
+        'es_CO' => 'Español Colombiano',
+        'es_ES' => 'Español',
+        'es_VE' => 'Castellano',
+        'fa_IR' => 'پارسی',
+        'fi_FI' => 'Suomi',
+        'fr_FR' => 'Français',
+        'hu_HU' => 'Magyar',
+        'id'    => 'Bahasa Indonesia',
+        'it_IT' => 'Italiano',
+        'ja'    => '日本語',
+        'ko'    => '한국어',
+        'lv'    => 'Latviešu valoda',
+        'nb'    => 'Norsk bokmål',
+        'nl_NL' => 'Nederlands',
+        'pl_PL' => 'Polski',
+        'pt'    => 'Português',
+        'pt_BR' => 'Português (Brasil)',
+        'ru_RU' => 'русский язык',
+        'tr_TR' => 'Türkçe',
+        'vi_VN' => 'Tiếng Việt',
+        'sv_SE' => 'Svenska',
+        'zh_CN' => '中文, 汉语, 漢語',
+      );
+
+      foreach ($tmp_english as $key => $name) {
+        $label = _($name)." (".$tmp_ownlang[$key].")";
+        if ($strip_region_tag) {
+          $ret[preg_replace("/^([^_]*).*$/", "\\1", $key)] = $label;
+        } else {
+          $ret[$key] = $label;
+        }
+      }
+    } else {
+      foreach ($tmp_english as $key => $name) {
+        if ($strip_region_tag) {
+          $ret[preg_replace("/^([^_]*).*/", "\\1", $key)] = _($name);
+        } else {
+          $ret[$key] = _($name);
+        }
+      }
+    }
+
+    asort($ret);
+    return $ret;
+  }
+
+  /*!
+   * \brief Returns TRUE if $lang is a right to left language ($lang should match /.._..(\.UTF-8)?/)
+   */
+  public static function isRTL ($lang)
+  {
+    $lang = preg_replace('/\.UTF-8$/', '', $lang);
+
+    if (preg_match('/^fa_/', $lang)) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  public static function setHeaders($language, $mime)
+  {
+    list ($lang, $country, $char) = parse_gettext_lang($language);
+
+    if (!headers_sent()) {
+      header("Content-Language: $lang".(empty($country) ? '' : "-$country"));
+      if (!empty($char)) {
+        header("Content-Type: $mime; charset=$char");
+      }
+    } else {
+      trigger_error('Could not set language '.$lang.' header, headers already sent');
+    }
+  }
+}
diff --git a/include/class_config.inc b/include/class_config.inc
index 7f094e8c5ef56dc5ed27118410cab639764a0eec..6251bb6369ffc5ded10b4eab41c1e0f338482d24 100644
--- a/include/class_config.inc
+++ b/include/class_config.inc
@@ -419,7 +419,7 @@ class config
 
     timezone::setDefaultTimezoneFromConfig();
 
-    initLanguage();
+    Language::init();
   }
 
   /*!
diff --git a/include/functions.inc b/include/functions.inc
index 5cb77efbf7bf5dcae8cd41b9fd94671bc0c0b390..0a025c0011db90b2243cd4fe716798ae126405ff 100644
--- a/include/functions.inc
+++ b/include/functions.inc
@@ -248,50 +248,6 @@ function DEBUG($level, $line, $function, $file, $data, $info = '')
   }
 }
 
-
-/*!
- * \brief Determine which language to show to the user
- *
- * Determines which language should be used to present fusiondirectory content
- * to the user. It does so by looking at several possibilites and returning
- * the first setting that can be found.
- *
- * -# Language configured by the user
- * -# Global configured language
- * -# Language as returned by al2gt (as configured in the browser)
- *
- * \return string gettext locale string
- */
-function get_browser_language()
-{
-  /* Try to use users primary language */
-  global $config;
-  $ui = get_userinfo();
-  if (isset($ui) && ($ui !== NULL) && ($ui->language != '')) {
-    return $ui->language.'.UTF-8';
-  }
-
-  /* Check for global language settings in configuration */
-  if (isset($config) && ($config->get_cfg_value('language') != '')) {
-    $lang = $config->get_cfg_value('language');
-    if (!preg_match('/utf/i', $lang)) {
-      $lang .= '.UTF-8';
-    }
-    return $lang;
-  }
-
-  /* Load supported languages */
-  $gosa_languages = get_languages();
-
-  /* Move supported languages to flat list */
-  $langs = array();
-  foreach (array_keys($gosa_languages) as $lang) {
-    $langs[] = $lang.'.UTF-8';
-  }
-  /* Return gettext based string */
-  return al2gt($langs, 'text/html');
-}
-
 /*!
  * \brief Return themed path for specified base file
  *
@@ -2107,116 +2063,6 @@ function check_schema($cfg)
   return $checks;
 }
 
-/*!
- * \brief Get the language for the user connecting
- *
- * \param boolean $languages_in_own_language FALSE
- *
- * \param boolean $strip_region_tag FALSE
- */
-function get_languages($languages_in_own_language = FALSE, $strip_region_tag = FALSE)
-{
-  /* locales in english */
-  $tmp_english = array(
-    "ar"    => "Arabic",
-    "ca_ES" => "Catalan",
-    "cs_CZ" => "Czech",
-    "de_DE" => "German",
-    "el_GR" => "Greek",
-    "en_US" => "English",
-    "es_CO" => "Colombian Spanish",
-    "es_ES" => "Spanish",
-    "es_VE" => "Venezuelan",
-    "fa_IR" => "Persian",
-    "fi_FI" => "Finnish",
-    "fr_FR" => "French",
-    "hu_HU" => "Hungarian",
-    "id"    => "Indonesian",
-    "it_IT" => "Italian",
-    "ja"    => "Japanese",
-    "ko"    => "Korean",
-    "lv"    => "Latvian",
-    "nb"    => "Norwegian Bokmål",
-    "nl_NL" => "Dutch",
-    "pl_PL" => "Polish",
-    "pt"    => "Portuguese",
-    "pt_BR" => "Brazilian",
-    "ru_RU" => "Russian",
-    "tr_TR" => "Turkish",
-    "vi_VN" => "Vietnamese",
-    "sv_SE" => "Swedish",
-    "zh_CN" => "Chinese",
-  );
-
-  $ret = array();
-  if ($languages_in_own_language) {
-    /* locales in their own language */
-    $tmp_ownlang = array(
-      "ar"    => "عربية",
-      "ca_ES" => "Català",
-      "cs_CZ" => "ÄŒesky",
-      "de_DE" => "Deutsch",
-      "el_GR" => "ελληνικά",
-      "en_US" => "English",
-      "es_CO" => "Español Colombiano",
-      "es_ES" => "Español",
-      "es_VE" => "Castellano",
-      "fa_IR" => "پارسی",
-      "fi_FI" => "Suomi",
-      "fr_FR" => "Français",
-      "hu_HU" => "Magyar",
-      "id"    => "Bahasa Indonesia",
-      "it_IT" => "Italiano",
-      "ja"    => "日本語",
-      "ko"    => "한국어",
-      "lv"    => "Latviešu valoda",
-      "nb"    => "Norsk bokmål",
-      "nl_NL" => "Nederlands",
-      "pl_PL" => "Polski",
-      "pt"    => "Português",
-      "pt_BR" => "Português (Brasil)",
-      "ru_RU" => "русский язык",
-      "tr_TR" => "Türkçe",
-      "vi_VN" => "Tiếng Việt",
-      "sv_SE" => "Svenska",
-      "zh_CN" => "中文, 汉语, 漢語",
-    );
-
-    foreach ($tmp_english as $key => $name) {
-      $label = _($name)." (".$tmp_ownlang[$key].")";
-      if ($strip_region_tag) {
-        $ret[preg_replace("/^([^_]*).*$/", "\\1", $key)] = $label;
-      } else {
-        $ret[$key] = $label;
-      }
-    }
-  } else {
-    foreach ($tmp_english as $key => $name) {
-      if ($strip_region_tag) {
-        $ret[preg_replace("/^([^_]*).*/", "\\1", $key)] = _($name);
-      } else {
-        $ret[$key] = _($name);
-      }
-    }
-  }
-
-  asort($ret);
-  return $ret;
-}
-
-/*!
- * \brief Returns TRUE if $lang is a right to left language ($lang should match /.._..(\.UTF-8)?/)
- */
-function language_is_rtl ($lang)
-{
-  $lang = preg_replace('/\.UTF-8$/', '', $lang);
-
-  if (preg_match('/^fa_/', $lang)) {
-    return TRUE;
-  }
-  return FALSE;
-}
-
 
 /*!
  * \brief Returns contents of the given POST variable and check magic quotes settings
@@ -2567,52 +2413,6 @@ function load_all_classes()
   }
 }
 
-
-/*!
- * \brief Initialize language configuration
- *
- * \param string $lang Language locale to use, defaults to get_browser_language
- */
-function initLanguage($lang = NULL)
-{
-  global $BASE_DIR;
-  if ($lang === NULL) {
-    $lang = get_browser_language();
-  }
-
-  putenv('LANGUAGE=');
-  putenv("LANG=$lang");
-  setlocale(LC_ALL, $lang);
-  $GLOBALS['t_language']            = $lang;
-  $GLOBALS['t_gettext_message_dir'] = $BASE_DIR.'/locale/';
-
-  /* Set the text domain as 'fusiondirectory' */
-  $domain = 'fusiondirectory';
-  bindtextdomain($domain, LOCALE_DIR);
-  textdomain($domain);
-  if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-    @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $lang, 'Setting language to');
-  }
-
-  $ret = FALSE;
-
-  /* Reset plist cache if language changed */
-  if ((!session::global_is_set('lang')) || (session::global_get('lang') != $lang)) {
-    $ret = TRUE;
-    if (session::global_is_set('plist')) {
-      if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-        @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, session::global_get('lang'), 'Plist already loaded with language');
-      }
-      session::global_un_set('plist');
-      session::global_set('lang', $lang);
-      load_plist();
-    }
-  }
-
-  session::global_set('lang', $lang);
-  return $ret;
-}
-
 if (!function_exists('ldap_escape')) {
   /* This bloc is for PHP<5.6 */
   define('LDAP_ESCAPE_FILTER', 0x01);
diff --git a/plugins/config/class_configInLdap.inc b/plugins/config/class_configInLdap.inc
index 336b64ce94f99fa6b3a248f0fc1ae68975e6e035..8d7731196c16f4724a09c92204b3e0a8e5891b88 100644
--- a/plugins/config/class_configInLdap.inc
+++ b/plugins/config/class_configInLdap.inc
@@ -451,7 +451,7 @@ class configInLdap extends simplePlugin
     global $config;
     $attributesInfo = static::getAttributesInfo();
     /* Languages */
-    $languages = get_languages(TRUE);
+    $languages = Language::list(TRUE);
     $languages = array_merge(array("" => _("Automatic")), $languages);
     $attributesInfo['look_n_feel']['attrs'][0]->setChoices(array_keys($languages), array_values($languages));
     /* Timezones */
diff --git a/plugins/personal/generic/class_user.inc b/plugins/personal/generic/class_user.inc
index 231cf96f6b385ade56f1edd3d273df3d25edb0a5..b57fc5c18b252c8e1c68618e7df6b71c1000ac06 100644
--- a/plugins/personal/generic/class_user.inc
+++ b/plugins/personal/generic/class_user.inc
@@ -304,7 +304,7 @@ class user extends simplePlugin
   static function getAttributesInfo ()
   {
     global $config;
-    $languages = array_merge(array('' => ''), get_languages(TRUE));
+    $languages = array_merge(array('' => ''), Language::list(TRUE));
     $attributesInfo = array(
       'perso' => array(
         'name'  => _('Personal information'),
diff --git a/setup/class_setupStepLanguage.inc b/setup/class_setupStepLanguage.inc
index 7e5b666cf2d6948afa33103a41af7f04be26b51d..16fed600b545356758327ade3a38aca79b5ecde4 100644
--- a/setup/class_setupStepLanguage.inc
+++ b/setup/class_setupStepLanguage.inc
@@ -50,7 +50,7 @@ class setupStepLanguage extends setupStep
   function __construct($parent)
   {
     parent::__construct($parent);
-    $this->lang = get_browser_language();
+    $this->lang = Language::detect();
     $this->attributesAccess['lang_selected']->setSize(20);
   }
 
@@ -64,7 +64,7 @@ class setupStepLanguage extends setupStep
 
   function execute()
   {
-    $languages = get_languages(TRUE);
+    $languages = Language::list(TRUE);
     $languages = array_merge(array("" => _("Automatic")), $languages);
     $this->attributesAccess['lang_selected']->setChoices(array_keys($languages), array_values($languages));
     return parent::execute();