protected function getCountries()
    {
        $loadedLanguage = $this->getMetaModel()->getActiveLanguage();
        if (isset($this->countryCache[$loadedLanguage])) {
            return $this->countryCache[$loadedLanguage];
        }

        $languageValues = $this->getCountryNames($loadedLanguage);
        $countries      = $this->getRealCountries();
        $keys           = \array_keys($countries);
        $aux            = [];
        $real           = [];

        // Fetch real language values.
        foreach ($keys as $key) {
            if (isset($languageValues[$key])) {
                $aux[$key]  = Utf8::toAscii($languageValues[$key]);
                $real[$key] = $languageValues[$key];
            }
        }

        // Add needed fallback values.
        $keys = \array_diff($keys, \array_keys($aux));
        if ($keys) {
            $loadedLanguage = $this->getMetaModel()->getFallbackLanguage();
            $fallbackValues = $this->getCountryNames($loadedLanguage);
            foreach ($keys as $key) {
                if (isset($fallbackValues[$key])) {
                    $aux[$key]  = Utf8::toAscii($fallbackValues[$key]);
                    $real[$key] = $fallbackValues[$key];
                }
            }
        }

        $keys = \array_diff($keys, \array_keys($aux));
        if ($keys) {
            foreach ($keys as $key) {
                $aux[$key]  = $countries[$key];
                $real[$key] = $countries[$key];
            }
        }

        \asort($aux);
        $return = [];
        foreach (\array_keys($aux) as $key) {
            $return[$key] = $real[$key];
        }

        $this->restoreLanguage();

        $this->countryCache[$loadedLanguage] = $return;

        return $return;
    }