diff --git a/lib/SimpleSAML/Locale/Localization.php b/lib/SimpleSAML/Locale/Localization.php
new file mode 100644
index 0000000000000000000000000000000000000000..7fbef2b3af7d8e2cba0e8ec68ec876ffbca85474
--- /dev/null
+++ b/lib/SimpleSAML/Locale/Localization.php
@@ -0,0 +1,78 @@
+<?php
+
+/**
+ * Glue to connect one or more translation/locale systems to the rest
+ *
+ * @author Hanne Moa, UNINETT AS. <hanne.moa@uninett.no>
+ * @package SimpleSAMLphp
+ */
+
+namespace SimpleSAML\Locale;
+
+class Localization
+{
+
+    /**
+     * The configuration to use.
+     *
+     * @var \SimpleSAML_Configuration
+     */
+    private $configuration;
+
+    /**
+     * The default gettext domain.
+     */
+    private $domain = 'ssp';
+
+    /*
+     * The locale directory
+     */
+    private $localeDir;
+
+    /**
+     * Constructor
+     *
+     * @param \SimpleSAML_Configuration $configuration Configuration object
+     */
+    public function __construct(\SimpleSAML_Configuration $configuration)
+    {
+        $this->configuration = $configuration;
+        $this->localeDir = $this->configuration->resolvePath('locales');
+        $this->language = new Language($configuration);
+        $this->i18nBackend = $this->configuration->getString('language.i18n.backend', null);
+        $this->setupL10N();
+    }
+
+    private function setupL10N() {
+        // use old system
+        if (is_null($this->i18nBackend)) {
+            return;
+        }
+        $encoding = "UTF-8";
+        $langcode = $this->language->getPosixLanguage($this->language->getLanguage());
+        // use gettext and Twig.I18n
+        if ($this->i18nBackend == 'twig.i18n') {
+            putenv('LC_ALL='.$langcode);
+            setlocale(LC_ALL, $langcode);
+            bindtextdomain($this->domain, $this->localeDir);
+            bind_textdomain_codeset($this->domain, $encoding);
+        }
+    }
+
+
+    public function activateDomain($domain)
+    {
+        if ($this->i18nBackend == 'twig.i18n') {
+            textdomain($domain);
+        }
+    }
+
+
+    public function restoreDefaultDomain()
+    {
+        if ($this->i18nBackend == 'twig.i18n') {
+            textdomain($this->domain);
+        }
+    }
+}
+
diff --git a/locales/.gitkeep b/locales/.gitkeep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/locales/en/LC_MESSAGES/ssp.mo b/locales/en/LC_MESSAGES/ssp.mo
new file mode 100644
index 0000000000000000000000000000000000000000..c4931e30dedab05eaff5b91b41e4d67256cf716a
Binary files /dev/null and b/locales/en/LC_MESSAGES/ssp.mo differ
diff --git a/locales/en/LC_MESSAGES/ssp.po b/locales/en/LC_MESSAGES/ssp.po
new file mode 100644
index 0000000000000000000000000000000000000000..70a64a7b7d2dfcf0d9934bd1c44a8805d1dcde64
--- /dev/null
+++ b/locales/en/LC_MESSAGES/ssp.po
@@ -0,0 +1,17 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"POT-Creation-Date: 2016-03-01 14:40+0100\n"
+"PO-Revision-Date: 2016-03-01 14:42+0100\n"
+"Last-Translator: Hanne Moa <hanne.moa@uninett.no>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.8.4\n"
+"X-Poedit-Basepath: .\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Language: en\n"
+
+msgid "Hello, Untranslated World!"
+msgstr "Hello, Translated World!"
diff --git a/locales/en_US b/locales/en_US
new file mode 120000
index 0000000000000000000000000000000000000000..2c4c454fdd2fd2902cc43a87d26851282de294f1
--- /dev/null
+++ b/locales/en_US
@@ -0,0 +1 @@
+en
\ No newline at end of file
diff --git a/locales/nb/LC_MESSAGES/ssp.mo b/locales/nb/LC_MESSAGES/ssp.mo
new file mode 100644
index 0000000000000000000000000000000000000000..e0b0fd1ff49d8bfbe9fea4f2b3e9a4dfcbee76c6
Binary files /dev/null and b/locales/nb/LC_MESSAGES/ssp.mo differ
diff --git a/locales/nb/LC_MESSAGES/ssp.po b/locales/nb/LC_MESSAGES/ssp.po
new file mode 100644
index 0000000000000000000000000000000000000000..f4e73b33321e2a05c4a057797323305822e81219
--- /dev/null
+++ b/locales/nb/LC_MESSAGES/ssp.po
@@ -0,0 +1,18 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"POT-Creation-Date: 2016-03-01 14:40+0100\n"
+"PO-Revision-Date: 2016-03-01 14:45+0100\n"
+"Last-Translator: Hanne Moa <hanne.moa@uninett.no>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.8.4\n"
+"X-Poedit-Basepath: .\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Language: nb\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+
+msgid "Hello, Untranslated World!"
+msgstr "Hallo, oversatte verden!"
diff --git a/locales/nb_NO b/locales/nb_NO
new file mode 120000
index 0000000000000000000000000000000000000000..6c2c32f1bdbc8bd08c444ea0bd76a967b043e5b0
--- /dev/null
+++ b/locales/nb_NO
@@ -0,0 +1 @@
+nb
\ No newline at end of file
diff --git a/locales/nn/LC_MESSAGES/ssp.mo b/locales/nn/LC_MESSAGES/ssp.mo
new file mode 100644
index 0000000000000000000000000000000000000000..6e442efe212da853ebd67796b8a8a0ca19c78aa6
Binary files /dev/null and b/locales/nn/LC_MESSAGES/ssp.mo differ
diff --git a/locales/nn/LC_MESSAGES/ssp.po b/locales/nn/LC_MESSAGES/ssp.po
new file mode 100644
index 0000000000000000000000000000000000000000..0ce9baabbd87da1e647ea6a9f57fb3518ff3e47a
--- /dev/null
+++ b/locales/nn/LC_MESSAGES/ssp.po
@@ -0,0 +1,18 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"POT-Creation-Date: 2016-03-01 14:40+0100\n"
+"PO-Revision-Date: 2016-03-01 14:45+0100\n"
+"Last-Translator: Hanne Moa <hanne.moa@uninett.no>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.8.4\n"
+"X-Poedit-Basepath: .\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Language: nn\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+
+msgid "Hello, Untranslated World!"
+msgstr "Hallo, oversatte verd!"