Index: kernel/common/i18n.php
===================================================================
--- kernel/common/i18n.php	(revision 22645)
+++ kernel/common/i18n.php	(working copy)
@@ -31,8 +31,7 @@
 */
 function ezcurrentLanguage()
 {
-    $locale = eZLocale::instance();
-    return $locale->translationCode();
+    return eZLocale::instance()->localeFullCode();
 }
 
 /*!
@@ -68,54 +67,8 @@
  will only return the source text.
 */
 $ini = eZINI::instance();
-$useTextTranslation = false;
-$hasFallback = false;
-if ( $ini->variable( 'RegionalSettings', 'TextTranslation' ) != 'disabled' )
-{
-    $language = ezcurrentLanguage();
-    $iniI18N = eZINI::instance( "i18n.ini" );
-    $fallbacks = $iniI18N->variable( 'TranslationSettings', 'FallbackLanguages' );
+$useTextTranslation = $ini->variable( 'RegionalSettings', 'TextTranslation' ) != 'disabled';
 
-    $extensionBase = eZExtension::baseDirectory();
-    $translationExtensions = $ini->variable( 'RegionalSettings', 'TranslationExtensions' );
-
-    if ( array_key_exists( $language,  $fallbacks ) and $fallbacks[$language] )
-    {
-        if ( file_exists( 'share/translations/' . $fallbacks[$language] . '/translation.ts' ) )
-        {
-            $hasFallback = true;
-        }
-        else
-        {
-            foreach ( $translationExtensions as $translationExtension )
-            {
-                $extensionPath = $extensionBase . '/' . $translationExtension . '/translations/' . $fallbacks[$language] . '/translation.ts';
-                if ( file_exists( $extensionPath ) )
-                {
-                    $hasFallback = true;
-                    break;
-                }
-            }
-        }
-    }
-    if ( file_exists( 'share/translations/' . $language . '/translation.ts' ) || $hasFallback )
-    {
-        $useTextTranslation = true;
-    }
-    else
-    {
-        foreach ( $translationExtensions as $translationExtension )
-        {
-            $extensionPath = $extensionBase . '/' . $translationExtension . '/translations/' . $language . '/translation.ts';
-            if ( file_exists( $extensionPath ) )
-            {
-                $useTextTranslation = true;
-                break;
-            }
-        }
-    }
-}
-
 if ( $useTextTranslation || eZTranslatorManager::dynamicTranslationsEnabled() )
 {
     function ezi18n( $context, $source, $comment = null, $arguments = null )
@@ -130,21 +83,16 @@
 
     function eZTranslateText( $context, $source, $comment = null, $arguments = null )
     {
-        $ini = eZINI::instance();
-        if ( $ini->variable( 'RegionalSettings', 'Locale' ) == 'eng-GB' )
+        $localeCode = eZLocale::instance()->localeFullCode();
+        if ( $localeCode == 'eng-GB' )
         {
             // we don't have ts-file for 'eng-GB'.
-            // NOTE: don't remove this 'if'. it's needed to support dynamic switch between translations.
             return ezinsertarguments( $source, $arguments );
         }
 
-        $language = ezcurrentLanguage();
-
-        $file = 'translation.ts';
-
-        // translation.ts translation
+        $ini = eZINI::instance();
         $useCache = $ini->variable( 'RegionalSettings', 'TranslationCache' ) != 'disabled';
-        eZTSTranslator::initialize( $context, $language, $file, $useCache );
+        eZTSTranslator::initialize( $context, $localeCode, 'translation.ts', $useCache );
 
         // Bork translation: Makes it easy to see what is not translated.
         // If no translation is found in the eZTSTranslator, a Bork translation will be returned.
Index: lib/ezi18n/classes/eztstranslator.php
===================================================================
--- lib/ezi18n/classes/eztstranslator.php	(revision 22645)
+++ lib/ezi18n/classes/eztstranslator.php	(working copy)
@@ -226,70 +226,103 @@
         }
 
         $status = false;
-        foreach ( $roots as $root )
+
+        // first process country translation files
+        // then process country variation translation files
+        $localeParts = explode( '@', $locale );
+
+        $triedPaths = array();
+        $loadedPaths = array();
+
+        $ini = eZINI::instance( "i18n.ini" );
+        $fallbacks = $ini->variable( 'TranslationSettings', 'FallbackLanguages' );
+
+        foreach ( $localeParts as $localePart )
         {
-            if ( !file_exists( $root ) )
+            $localeCodeToProcess = isset( $localeCodeToProcess ) ? $localeCodeToProcess . '@' . $localePart: $localePart;
+
+            // array with alternative subdirs to check
+            $alternatives = array(
+                array( $localeCodeToProcess, $charset, $filename ),
+                array( $localeCodeToProcess, $filename ),
+            );
+
+            if ( array_key_exists( $localeCodeToProcess,  $fallbacks ) and $fallbacks[$localeCodeToProcess] )
             {
-                continue;
+                $alternatives[] = array( $fallbacks[$localeCodeToProcess], $charset, $filename );
+                $alternatives[] = array( $fallbacks[$localeCodeToProcess], $filename );
             }
-            $path = eZDir::path( array( $root, $locale, $charset, $filename ) );
-            if ( !file_exists( $path ) )
+
+            foreach ( $roots as $root )
             {
-                $path = eZDir::path( array( $root, $locale, $filename ) );
+                if ( !file_exists( $root ) )
+                {
+                    continue;
+                }
 
-                $ini = eZINI::instance( "i18n.ini" );
-                $fallbacks = $ini->variable( 'TranslationSettings', 'FallbackLanguages' );
+                unset( $path );
 
-                if ( array_key_exists( $locale,  $fallbacks ) and $fallbacks[$locale] )
+                foreach ( $alternatives as $alternative )
                 {
-                    $fallbackpath = eZDir::path( array( $root, $fallbacks[$locale], $filename ) );
-                    if ( !file_exists( $path ) and file_exists( $fallbackpath ) )
-                        $path = $fallbackpath;
+                    $pathParts = $alternative;
+                    array_unshift( $pathParts, $root );
+                    $pathToTry = eZDir::path( $pathParts );
+                    $triedPaths[] = $pathToTry;
+
+                    if ( file_exists( $pathToTry ) )
+                    {
+                        $path = $pathToTry;
+                        break;
+                    }
                 }
 
-                if ( !file_exists( $path ) )
+                if ( !isset( $path ) )
                 {
-                    eZDebug::writeError( "Could not load translation file: $path", "eZTSTranslator::loadTranslationFile" );
                     continue;
                 }
-            }
 
-            eZDebug::accumulatorStart( 'tstranslator_load', 'tstranslator', 'TS load' );
+                eZDebug::accumulatorStart( 'tstranslator_load', 'tstranslator', 'TS load' );
 
-            $doc = new DOMDocument( '1.0', 'utf-8' );
-            $success = $doc->load( $path );
+                $doc = new DOMDocument( '1.0', 'utf-8' );
+                $success = $doc->load( $path );
 
-            if ( !$success )
-            {
-                eZDebug::writeWarning( "Unable to load XML from file $path", 'eZTSTranslator::loadTranslationFile' );
-                continue;
-            }
+                if ( !$success )
+                {
+                    eZDebug::writeWarning( "Unable to load XML from file $path", 'eZTSTranslator::loadTranslationFile' );
+                    continue;
+                }
 
-            if ( !$this->validateDOMTree( $doc ) )
-            {
-                eZDebug::writeWarning( "XML text for file $path did not validate", 'eZTSTranslator::loadTranslationFile' );
-                continue;
-            }
+                if ( !$this->validateDOMTree( $doc ) )
+                {
+                    eZDebug::writeWarning( "XML text for file $path did not validate", 'eZTSTranslator::loadTranslationFile' );
+                    continue;
+                }
 
-            $status = true;
+                $loadedPaths[] = $path;
 
-            $treeRoot = $doc->documentElement;
-            $children = $treeRoot->childNodes;
-            for ($i = 0; $i < $children->length; $i++ )
-            {
-                $child = $children->item( $i );
+                $status = true;
 
-                if ( $child->nodeType == XML_ELEMENT_NODE )
+                $treeRoot = $doc->documentElement;
+                $children = $treeRoot->childNodes;
+                for ($i = 0; $i < $children->length; $i++ )
                 {
-                    if ( $child->tagName == "context" )
+                    $child = $children->item( $i );
+
+                    if ( $child->nodeType == XML_ELEMENT_NODE )
                     {
-                        $this->handleContextNode( $child );
+                        if ( $child->tagName == "context" )
+                        {
+                            $this->handleContextNode( $child );
+                        }
                     }
                 }
+                eZDebug::accumulatorStop( 'tstranslator_load' );
             }
-            eZDebug::accumulatorStop( 'tstranslator_load' );
         }
 
+        eZDebug::writeDebug( implode( PHP_EOL, $triedPaths ), __METHOD__ . ': tried paths' );
+        eZDebug::writeDebug( implode( PHP_EOL, $loadedPaths ), __METHOD__ . ': loaded paths' );
+
         // Save translation cache
         if ( $this->UseCache == true && $this->BuildCache == true )
         {
Index: lib/eztemplate/classes/eztemplatecompiler.php
===================================================================
--- lib/eztemplate/classes/eztemplatecompiler.php	(revision 22645)
+++ lib/eztemplate/classes/eztemplatecompiler.php	(working copy)
@@ -345,7 +345,7 @@
         if ( isset( $GLOBALS['eZCurrentAccess']['name'] ) )
             $accessText = '-' . $GLOBALS['eZCurrentAccess']['name'];
         $locale = eZLocale::instance();
-        $language = $locale->translationCode();
+        $language = $locale->localeFullCode();
         $http = eZHTTPTool::instance();
         $useFullUrlText = $http->UseFullUrl ? 'full' : 'relative';
 
