/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_editeng.hxx"

#include <map>
#include <set>
#include <vector>
#include <slist>
#include <memory>
#include <editeng/unolingu.hxx>
#include <tools/debug.hxx>
#include <tools/urlobj.hxx>
#include <rtl/logfile.hxx>
#include <unotools/pathoptions.hxx>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/lang/XEventListener.hpp>
#include <com/sun/star/linguistic2/XAvailableLocales.hpp>
#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
#include <com/sun/star/ucb/XContentAccess.hpp>
#include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp>
#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
#include <com/sun/star/ucb/XContentAccess.hpp>
#include <com/sun/star/sdbc/XResultSet.hpp>
#include <com/sun/star/sdbc/XRow.hpp>
#include <com/sun/star/util/DateTime.hpp>

#include <comphelper/processfactory.hxx>
#include <cppuhelper/implbase1.hxx>	// helper for implementations
#include <i18npool/mslangid.hxx>
#include <unotools/lingucfg.hxx>
#include <unotools/ucbhelper.hxx>
#include <unotools/localfilehelper.hxx>
#include <ucbhelper/commandenvironment.hxx>
#include <ucbhelper/content.hxx>
#include <comphelper/processfactory.hxx>
#include <vcl/msgbox.hxx>
#include <tools/shl.hxx>
#include <linguistic/misc.hxx>
#include <editeng/eerdll.hxx>
#include <editeng/editrids.hrc>

using namespace ::rtl;
using namespace ::comphelper;
using namespace ::linguistic;
using namespace ::com::sun::star;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::linguistic2;

#define CSS com::sun::star

///////////////////////////////////////////////////////////////////////////


static uno::Reference< XLinguServiceManager > GetLngSvcMgr_Impl()
{
	uno::Reference< XLinguServiceManager > xRes;
	uno::Reference< XMultiServiceFactory >  xMgr = getProcessServiceFactory();
	if (xMgr.is())
	{
		xRes = uno::Reference< XLinguServiceManager > ( xMgr->createInstance(
				OUString( RTL_CONSTASCII_USTRINGPARAM(
					"com.sun.star.linguistic2.LinguServiceManager" ) ) ), UNO_QUERY ) ;
	}
	return xRes;
}

///////////////////////////////////////////////////////////////////////////

sal_Bool lcl_FindEntry( const OUString &rEntry, const Sequence< OUString > &rCfgSvcs )
{
    sal_Int32 nRes = -1;
    sal_Int32 nEntries = rCfgSvcs.getLength();
    const OUString *pEntry = rCfgSvcs.getConstArray();
    for (sal_Int32 i = 0;  i < nEntries && nRes == -1;  ++i)
    {
        if (rEntry == pEntry[i])
            nRes = i;
    }
    return nRes != -1;
}


Sequence< OUString > lcl_RemoveMissingEntries(
        const Sequence< OUString > &rCfgSvcs,
        const Sequence< OUString > &rAvailSvcs )
{
    Sequence< OUString > aRes( rCfgSvcs.getLength() );
    OUString *pRes = aRes.getArray();
    sal_Int32 nCnt = 0;

    sal_Int32 nEntries = rCfgSvcs.getLength();
    const OUString *pEntry = rCfgSvcs.getConstArray();
    for (sal_Int32 i = 0;  i < nEntries;  ++i)
    {
        if (pEntry[i].getLength() && lcl_FindEntry( pEntry[i], rAvailSvcs ))
            pRes[ nCnt++ ] = pEntry[i];
    }

    aRes.realloc( nCnt );
    return aRes;
}


Sequence< OUString > lcl_GetLastFoundSvcs(
        SvtLinguConfig &rCfg,
        const OUString &rLastFoundList ,
        const Locale &rAvailLocale )
{
    Sequence< OUString > aRes;

    OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
                                SvxLocaleToLanguage( rAvailLocale ) ) );

    Sequence< OUString > aNodeNames( rCfg.GetNodeNames(rLastFoundList) );
    sal_Bool bFound = lcl_FindEntry( aCfgLocaleStr, aNodeNames);

    if (bFound)
    {
        Sequence< OUString > aNames(1);
        OUString &rNodeName = aNames.getArray()[0];
        rNodeName = rLastFoundList;
        rNodeName += OUString::valueOf( (sal_Unicode)'/' );
        rNodeName += aCfgLocaleStr;
        Sequence< Any > aValues( rCfg.GetProperties( aNames ) );
#if OSL_DEBUG_LEVEL > 1
        const Any *pValue;
        pValue = aValues.getConstArray();
#endif
        if (aValues.getLength())
        {
            DBG_ASSERT( aValues.getLength() == 1, "unexpected length of sequence" );
            Sequence< OUString > aSvcImplNames;
            if (aValues.getConstArray()[0] >>= aSvcImplNames)
                aRes = aSvcImplNames;
            else
            {
                DBG_ERROR( "type mismatch" );
            }
        }
    }

    return aRes;
}


Sequence< OUString > lcl_GetNewEntries(
        const Sequence< OUString > &rLastFoundSvcs,
        const Sequence< OUString > &rAvailSvcs )
{
    sal_Int32 nLen = rAvailSvcs.getLength();
    Sequence< OUString > aRes( nLen );
    OUString *pRes = aRes.getArray();
    sal_Int32 nCnt = 0;

    const OUString *pEntry = rAvailSvcs.getConstArray();
    for (sal_Int32 i = 0;  i < nLen;  ++i)
    {
        if (pEntry[i].getLength() && !lcl_FindEntry( pEntry[i], rLastFoundSvcs ))
            pRes[ nCnt++ ] = pEntry[i];
    }

    aRes.realloc( nCnt );
    return aRes;
}


Sequence< OUString > lcl_MergeSeq(
        const Sequence< OUString > &rCfgSvcs,
        const Sequence< OUString > &rNewSvcs )
{
    Sequence< OUString > aRes( rCfgSvcs.getLength() + rNewSvcs.getLength() );
    OUString *pRes = aRes.getArray();
    sal_Int32 nCnt = 0;

    for (sal_Int32 k = 0;  k < 2;  ++k)
    {
		// add previously configured service first and append
		// new found services at the end
        const Sequence< OUString > &rSeq = k == 0 ? rCfgSvcs : rNewSvcs;

		sal_Int32 nLen = rSeq.getLength();
        const OUString *pEntry = rSeq.getConstArray();
        for (sal_Int32 i = 0;  i < nLen;  ++i)
        {
            if (pEntry[i].getLength() && !lcl_FindEntry( pEntry[i], aRes ))
                pRes[ nCnt++ ] = pEntry[i];
        }
    }

    aRes.realloc( nCnt );
    return aRes;
}

///////////////////////////////////////////////////////////////////////////

// static member initialization
sal_Int16 SvxLinguConfigUpdate::nNeedUpdating = -1;
sal_Int32 SvxLinguConfigUpdate::nCurrentDataFilesChangedCheckValue = -1;

void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
{
    RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll" );

    if (IsNeedUpdateAll( bForceCheck ))
    {
        typedef OUString OUstring_t;
        typedef Sequence< OUString > Sequence_OUString_t;
        typedef std::vector< OUstring_t > OUString_vector_t;
        typedef std::set< OUstring_t > OUString_set_t;
        std::vector< OUString_vector_t > aVector;
        typedef std::map< OUstring_t, Sequence_OUString_t > list_entry_map_t;

        RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll - updating..." );

        DBG_ASSERT( nNeedUpdating == 1, "SvxLinguConfigUpdate::UpdateAll already updated!" );

        uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
        DBG_ASSERT( xLngSvcMgr.is(), "service manager missing");
        if (!xLngSvcMgr.is())
            return;

        SvtLinguConfig aCfg;

		const int nNumServices = 4;
        const sal_Char * apServices[nNumServices]       =  { SN_SPELLCHECKER, SN_GRAMMARCHECKER, SN_HYPHENATOR, SN_THESAURUS };
        const sal_Char * apCurLists[nNumServices]       =  { "ServiceManager/SpellCheckerList",       "ServiceManager/GrammarCheckerList",       "ServiceManager/HyphenatorList",       "ServiceManager/ThesaurusList" };
        const sal_Char * apLastFoundLists[nNumServices] =  { "ServiceManager/LastFoundSpellCheckers", "ServiceManager/LastFoundGrammarCheckers", "ServiceManager/LastFoundHyphenators", "ServiceManager/LastFoundThesauri" };

        // usage of indices as above: 0 = spell checker, 1 = grammar checker, 2 = hyphenator, 3 = thesaurus
        std::vector< list_entry_map_t > aLastFoundSvcs(nNumServices);
        std::vector< list_entry_map_t > aCurSvcs(nNumServices);

        for (int k = 0;  k < nNumServices;  ++k)
        {
            OUString aService( A2OU( apServices[k] ) );
            OUString aActiveList( A2OU( apCurLists[k] ) );
            OUString aLastFoundList( A2OU( apLastFoundLists[k] ) );
            sal_Int32 i;

            //
            // remove configured but not available language/services entries
            //
            Sequence< OUString > aNodeNames( aCfg.GetNodeNames( aActiveList ) );   // list of configured locales
            sal_Int32 nNodeNames = aNodeNames.getLength();
            const OUString *pNodeName = aNodeNames.getConstArray();
            for (i = 0;  i < nNodeNames;  ++i)
            {
                Locale aLocale( SvxCreateLocale( MsLangId::convertIsoStringToLanguage(pNodeName[i]) ) );
                Sequence< OUString > aCfgSvcs(
                        xLngSvcMgr->getConfiguredServices( aService, aLocale ));
                Sequence< OUString > aAvailSvcs(
                        xLngSvcMgr->getAvailableServices( aService, aLocale ));
#if OSL_DEBUG_LEVEL > 1
                const OUString * pCfgSvcs   = aCfgSvcs.getConstArray();
                const OUString * pAvailSvcs = aAvailSvcs.getConstArray();
                (void) pCfgSvcs;
                (void) pAvailSvcs;
#endif
                aCfgSvcs = lcl_RemoveMissingEntries( aCfgSvcs, aAvailSvcs );

                aCurSvcs[k][ pNodeName[i] ] = aCfgSvcs;
            }

            //
            // add new available language/service entries
            //
            uno::Reference< XAvailableLocales > xAvail( xLngSvcMgr, UNO_QUERY );
            Sequence< Locale > aAvailLocales( xAvail->getAvailableLocales(aService) );
            sal_Int32 nAvailLocales = aAvailLocales.getLength();
            const Locale *pAvailLocale = aAvailLocales.getConstArray();
            for (i = 0;  i < nAvailLocales;  ++i)
            {
                Sequence< OUString > aAvailSvcs(
                        xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] ));
                Sequence< OUString > aLastSvcs(
                        lcl_GetLastFoundSvcs( aCfg, aLastFoundList , pAvailLocale[i] ));
                Sequence< OUString > aNewSvcs =
                        lcl_GetNewEntries( aLastSvcs, aAvailSvcs );
#if OSL_DEBUG_LEVEL > 1
                const OUString * pAvailSvcs = aAvailSvcs.getConstArray();
                const OUString * pLastSvcs  = aLastSvcs.getConstArray();
                const OUString * pNewSvcs   = aNewSvcs.getConstArray();
                (void) pAvailSvcs;
                (void) pLastSvcs;
                (void) pNewSvcs;
#endif

                OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
                                            SvxLocaleToLanguage( pAvailLocale[i] ) ) );
                Sequence< OUString > aCfgSvcs( aCurSvcs[k][ aCfgLocaleStr ] );

                // merge services list (previously configured to be listed first).
				aCfgSvcs = lcl_MergeSeq( aCfgSvcs, aNewSvcs );

/*
				// there is at most one Hyphenator per language allowed
				// to be configured, thus we only use the first one found.
				if (k == 2 && aCfgSvcs.getLength() > 1)
					aCfgSvcs.realloc(1);
*/
                aCurSvcs[k][ aCfgLocaleStr ] = aCfgSvcs;
            }

            //
            // set last found services to currently available ones
            //
            for (i = 0;  i < nAvailLocales;  ++i)
            {
                Sequence< OUString > aSvcImplNames(
                        xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] ) );

#if OSL_DEBUG_LEVEL > 1
                sal_Int32 nSvcs = aSvcImplNames.getLength();
                const OUString *pSvcImplName = aSvcImplNames.getConstArray();
                for (sal_Int32 j = 0;  j < nSvcs;  ++j)
                {
                    OUString aImplName( pSvcImplName[j] );
                }
#endif

                OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
                                            SvxLocaleToLanguage( pAvailLocale[i] ) ) );
				aLastFoundSvcs[k][ aCfgLocaleStr ] = aSvcImplNames;
            }
        }

        //
        // write new data back to configuration
        //
        for (int k = 0;  k < nNumServices;  ++k)
        {
            for (int i = 0;  i < 2;  ++i)
            {
                const sal_Char *pSubNodeName = (i == 0) ? apCurLists[k] : apLastFoundLists[k];
                OUString aSubNodeName( A2OU(pSubNodeName) );

				list_entry_map_t &rCurMap = (i == 0) ? aCurSvcs[k] : aLastFoundSvcs[k];
                list_entry_map_t::const_iterator aIt( rCurMap.begin() );
                sal_Int32 nVals = static_cast< sal_Int32 >( rCurMap.size() );
                Sequence< PropertyValue > aNewValues( nVals );
                PropertyValue *pNewValue = aNewValues.getArray();
                while (aIt != rCurMap.end())
                {
					OUString aCfgEntryName( aSubNodeName );
	                aCfgEntryName += OUString::valueOf( (sal_Unicode) '/' );
					aCfgEntryName += (*aIt).first;

#if OSL_DEBUG_LEVEL > 1
                    Sequence< OUString > aSvcImplNames( (*aIt).second );
                    sal_Int32 nSvcs = aSvcImplNames.getLength();
                    const OUString *pSvcImplName = aSvcImplNames.getConstArray();
                    for (sal_Int32 j = 0;  j < nSvcs;  ++j)
                    {
                        OUString aImplName( pSvcImplName[j] );
                    }
#endif
                    pNewValue->Name  = aCfgEntryName;
                    pNewValue->Value <<= (*aIt).second;
                    ++pNewValue;
                    ++aIt;
                }
                DBG_ASSERT( pNewValue - aNewValues.getArray() == nVals,
                        "possible mismatch of sequence size and property number" );

                {
                    RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll - ReplaceSetProperties" );
                    // add new or replace existing entries.
                    sal_Bool bRes = aCfg.ReplaceSetProperties( aSubNodeName, aNewValues );
                    if (!bRes)
                    {
#if OSL_DEBUG_LEVEL > 1
                        DBG_ERROR( "failed to set new configuration values" );
#endif
                    }
                }
            }
        }
		DBG_ASSERT( nCurrentDataFilesChangedCheckValue != -1, "SvxLinguConfigUpdate::UpdateAll DataFilesChangedCheckValue not yet calculated!" );
		Any aAny;

		// for the time being (developer builds until OOo 3.0)
		// we should always check for everything available
		// otherwise we may miss a new installed extension dictionary
		// just because e.g. the spellchecker is not asked what
		// languages it does support currently...
		// Since the check is on-demand occurring and executed once it should
		// not be too troublesome.
		// In OOo 3.0 we will not need the respective code anymore at all.
//		aAny <<= nCurrentDataFilesChangedCheckValue;
		aAny <<= (sal_Int32) -1;	// keep the value set to 'need to check'

		aCfg.SetProperty( A2OU( "DataFilesChangedCheckValue" ), aAny );

		//! Note 1: the new values are committed when the 'aCfg' object
		//!		gets destroyed.
		//! Note 2: the new settings in the configuration get applied
		//!		because the 'LngSvcMgr' (in linguistic/source/lngsvcmgr.hxx)
		//!		listens to the configuration for changes of the relevant
		//!		properties and then applies the new settings.

		// nothing needs to be done anymore
        nNeedUpdating = 0;
    }
}


sal_Int32 SvxLinguConfigUpdate::CalcDataFilesChangedCheckValue()
{
    RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::CalcDataFilesChangedCheckValue" );

    sal_Int32 nHashVal = 0;
    // nothing to be checked anymore since those old directory paths are gone by now
    return nHashVal;
}


sal_Bool SvxLinguConfigUpdate::IsNeedUpdateAll( sal_Bool bForceCheck )
{
    RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::IsNeedUpdateAll" );
    if (nNeedUpdating == -1 || bForceCheck )    // need to check if updating is necessary
    {
        // calculate hash value for current data files
        nCurrentDataFilesChangedCheckValue = CalcDataFilesChangedCheckValue();

        // compare hash value and check value to see if anything has changed
        // and thus the configuration needs to be updated
        SvtLinguOptions aLinguOpt;
        SvtLinguConfig aCfg;
        aCfg.GetOptions( aLinguOpt );
        nNeedUpdating = (nCurrentDataFilesChangedCheckValue == aLinguOpt.nDataFilesChangedCheckValue) ? 0 : 1;
    }
    DBG_ASSERT( nNeedUpdating != -1,
            "need for linguistic configuration update should have been already checked." );

    return nNeedUpdating == 1;
}

///////////////////////////////////////////////////////////////////////////


//! Dummy implementation in order to avoid loading of lingu DLL
//! when only the XSupportedLocales interface is used.
//! The dummy accesses the real implementation (and thus loading the DLL)
//! when "real" work needs to be done only.
class ThesDummy_Impl :
    public cppu::WeakImplHelper1< XThesaurus >
{
    uno::Reference< XThesaurus >     xThes;      // the real one...
    Sequence< Locale >         *pLocaleSeq;

    void GetCfgLocales();

    void GetThes_Impl();

public:
    ThesDummy_Impl() : pLocaleSeq(0)  {}
    ~ThesDummy_Impl();

    // XSupportedLocales
    virtual ::com::sun::star::uno::Sequence<
			::com::sun::star::lang::Locale > SAL_CALL
		getLocales()
			throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL
        hasLocale( const ::com::sun::star::lang::Locale& rLocale )
			throw(::com::sun::star::uno::RuntimeException);

	// XThesaurus
    virtual ::com::sun::star::uno::Sequence<
			::com::sun::star::uno::Reference<
				::com::sun::star::linguistic2::XMeaning > > SAL_CALL
        queryMeanings( const ::rtl::OUString& rTerm,
                const ::com::sun::star::lang::Locale& rLocale,
                const ::com::sun::star::beans::PropertyValues& rProperties )
			throw(::com::sun::star::lang::IllegalArgumentException,
				  ::com::sun::star::uno::RuntimeException);
};


ThesDummy_Impl::~ThesDummy_Impl()
{
    delete pLocaleSeq;
}


void ThesDummy_Impl::GetCfgLocales()
{
    if (!pLocaleSeq)
    {
        SvtLinguConfig aCfg;
        String  aNode( A2OU( "ServiceManager/ThesaurusList" ) );
        Sequence < OUString > aNodeNames( aCfg.GetNodeNames( aNode ) );
        const OUString *pNodeNames = aNodeNames.getConstArray();
        sal_Int32 nLen = aNodeNames.getLength();
        pLocaleSeq = new Sequence< Locale >( nLen );
        Locale *pLocale = pLocaleSeq->getArray();
        for (sal_Int32 i = 0;  i < nLen;  ++i)
        {
            pLocale[i] = SvxCreateLocale(
                            MsLangId::convertIsoStringToLanguage( pNodeNames[i] ) );
        }
    }
}


void ThesDummy_Impl::GetThes_Impl()
{
    // update configuration before accessing the service
    if (SvxLinguConfigUpdate::IsNeedUpdateAll())
        SvxLinguConfigUpdate::UpdateAll();

    if (!xThes.is())
    {
        uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
        if (xLngSvcMgr.is())
            xThes = xLngSvcMgr->getThesaurus();

        if (xThes.is())
        {
            // no longer needed...
            delete pLocaleSeq;    pLocaleSeq = 0;
        }
    }
}


uno::Sequence< lang::Locale > SAL_CALL
        ThesDummy_Impl::getLocales()
            throw(uno::RuntimeException)
{
    if (!SvxLinguConfigUpdate::IsNeedUpdateAll())   // configuration already update and thus lingu DLL's already loaded ?
        GetThes_Impl();
    if (xThes.is())
        return xThes->getLocales();
    else if (!pLocaleSeq)       // if not already loaded save startup time by avoiding loading them now
        GetCfgLocales();
    return *pLocaleSeq;
}


sal_Bool SAL_CALL
        ThesDummy_Impl::hasLocale( const lang::Locale& rLocale )
            throw(uno::RuntimeException)
{
    if (!SvxLinguConfigUpdate::IsNeedUpdateAll())   // configuration already update and thus lingu DLL's already loaded ?
        GetThes_Impl();
    if (xThes.is())
        return xThes->hasLocale( rLocale );
    else if (!pLocaleSeq)       // if not already loaded save startup time by avoiding loading them now
        GetCfgLocales();
        GetCfgLocales();
    sal_Bool bFound = sal_False;
    sal_Int32 nLen = pLocaleSeq->getLength();
    const Locale *pLocale = pLocaleSeq->getConstArray();
    const Locale *pEnd = pLocale + nLen;
    for ( ;  pLocale < pEnd  &&  !bFound;  ++pLocale)
    {
        bFound = pLocale->Language == rLocale.Language  &&
                 pLocale->Country  == rLocale.Country   &&
                 pLocale->Variant  == rLocale.Variant;
    }
    return bFound;
}


uno::Sequence< uno::Reference< linguistic2::XMeaning > > SAL_CALL
        ThesDummy_Impl::queryMeanings(
                const rtl::OUString& rTerm,
                const lang::Locale& rLocale,
                const beans::PropertyValues& rProperties )
            throw(lang::IllegalArgumentException,
                  uno::RuntimeException)
{
    GetThes_Impl();
    uno::Sequence< uno::Reference< linguistic2::XMeaning > > aRes;
    DBG_ASSERT( xThes.is(), "Thesaurus missing" );
    if (xThes.is())
        aRes = xThes->queryMeanings( rTerm, rLocale, rProperties );
    return aRes;
}


///////////////////////////////////////////////////////////////////////////


//! Dummy implementation in order to avoid loading of lingu DLL.
//! The dummy accesses the real implementation (and thus loading the DLL)
//! when it needs to be done only.
class SpellDummy_Impl :
    public cppu::WeakImplHelper1< XSpellChecker1 >
{
    uno::Reference< XSpellChecker1 >     xSpell;      // the real one...

    void    GetSpell_Impl();

public:

	// XSupportedLanguages (for XSpellChecker1)
    virtual ::com::sun::star::uno::Sequence< sal_Int16 > SAL_CALL
		getLanguages()
			throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL
		hasLanguage( sal_Int16 nLanguage )
			throw(::com::sun::star::uno::RuntimeException);

	// XSpellChecker1 (same as XSpellChecker but sal_Int16 for language)
	virtual sal_Bool SAL_CALL
        isValid( const ::rtl::OUString& rWord, sal_Int16 nLanguage,
                const ::com::sun::star::beans::PropertyValues& rProperties )
			throw(::com::sun::star::lang::IllegalArgumentException,
				  ::com::sun::star::uno::RuntimeException);
	virtual ::com::sun::star::uno::Reference<
			::com::sun::star::linguistic2::XSpellAlternatives > SAL_CALL
        spell( const ::rtl::OUString& rWord, sal_Int16 nLanguage,
                const ::com::sun::star::beans::PropertyValues& rProperties )
			throw(::com::sun::star::lang::IllegalArgumentException,
				  ::com::sun::star::uno::RuntimeException);
};


void SpellDummy_Impl::GetSpell_Impl()
{
    // update configuration before accessing the service
    if (SvxLinguConfigUpdate::IsNeedUpdateAll())
        SvxLinguConfigUpdate::UpdateAll();

    if (!xSpell.is())
    {
        uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
        if (xLngSvcMgr.is())
            xSpell = uno::Reference< XSpellChecker1 >( xLngSvcMgr->getSpellChecker(), UNO_QUERY );
    }
}


uno::Sequence< sal_Int16 > SAL_CALL
    SpellDummy_Impl::getLanguages()
        throw(uno::RuntimeException)
{
    GetSpell_Impl();
    if (xSpell.is())
        return xSpell->getLanguages();
    else
        return uno::Sequence< sal_Int16 >();
}


sal_Bool SAL_CALL
    SpellDummy_Impl::hasLanguage( sal_Int16 nLanguage )
        throw(uno::RuntimeException)
{
    GetSpell_Impl();
    sal_Bool bRes = sal_False;
    if (xSpell.is())
        bRes = xSpell->hasLanguage( nLanguage );
    return bRes;
}


sal_Bool SAL_CALL
    SpellDummy_Impl::isValid( const rtl::OUString& rWord, sal_Int16 nLanguage,
            const beans::PropertyValues& rProperties )
        throw(lang::IllegalArgumentException,
              uno::RuntimeException)
{
    GetSpell_Impl();
    sal_Bool bRes = sal_True;
    if (xSpell.is())
        bRes = xSpell->isValid( rWord, nLanguage, rProperties );
    return bRes;
}


uno::Reference< linguistic2::XSpellAlternatives > SAL_CALL
    SpellDummy_Impl::spell( const rtl::OUString& rWord, sal_Int16 nLanguage,
            const beans::PropertyValues& rProperties )
        throw(lang::IllegalArgumentException,
              uno::RuntimeException)
{
    GetSpell_Impl();
    uno::Reference< linguistic2::XSpellAlternatives > xRes;
    if (xSpell.is())
        xRes = xSpell->spell( rWord, nLanguage, rProperties );
    return xRes;
}


///////////////////////////////////////////////////////////////////////////


//! Dummy implementation in order to avoid loading of lingu DLL.
//! The dummy accesses the real implementation (and thus loading the DLL)
//! when it needs to be done only.
class HyphDummy_Impl :
    public cppu::WeakImplHelper1< XHyphenator >
{
    uno::Reference< XHyphenator >     xHyph;      // the real one...

    void    GetHyph_Impl();

public:

    // XSupportedLocales
    virtual ::com::sun::star::uno::Sequence<
			::com::sun::star::lang::Locale > SAL_CALL
		getLocales()
			throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL
        hasLocale( const ::com::sun::star::lang::Locale& rLocale )
			throw(::com::sun::star::uno::RuntimeException);

    // XHyphenator
    virtual ::com::sun::star::uno::Reference<
			::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL
        hyphenate( const ::rtl::OUString& rWord,
                const ::com::sun::star::lang::Locale& rLocale,
				sal_Int16 nMaxLeading,
                const ::com::sun::star::beans::PropertyValues& rProperties )
			throw(::com::sun::star::lang::IllegalArgumentException,
				  ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference<
			::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL
        queryAlternativeSpelling( const ::rtl::OUString& rWord,
                const ::com::sun::star::lang::Locale& rLocale,
				sal_Int16 nIndex,
                const ::com::sun::star::beans::PropertyValues& rProperties )
			throw(::com::sun::star::lang::IllegalArgumentException,
				  ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference<
			::com::sun::star::linguistic2::XPossibleHyphens > SAL_CALL
		createPossibleHyphens(
                const ::rtl::OUString& rWord,
                const ::com::sun::star::lang::Locale& rLocale,
                const ::com::sun::star::beans::PropertyValues& rProperties )
			throw(::com::sun::star::lang::IllegalArgumentException,
				  ::com::sun::star::uno::RuntimeException);
};


void HyphDummy_Impl::GetHyph_Impl()
{
    // update configuration before accessing the service
    if (SvxLinguConfigUpdate::IsNeedUpdateAll())
        SvxLinguConfigUpdate::UpdateAll();

    if (!xHyph.is())
    {
        uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
        if (xLngSvcMgr.is())
            xHyph = xLngSvcMgr->getHyphenator();
    }
}


uno::Sequence< lang::Locale > SAL_CALL
    HyphDummy_Impl::getLocales()
        throw(uno::RuntimeException)
{
    GetHyph_Impl();
    if (xHyph.is())
        return xHyph->getLocales();
    else
        return uno::Sequence< lang::Locale >();
}


sal_Bool SAL_CALL
    HyphDummy_Impl::hasLocale( const lang::Locale& rLocale )
        throw(uno::RuntimeException)
{
    GetHyph_Impl();
    sal_Bool bRes = sal_False;
    if (xHyph.is())
        bRes = xHyph->hasLocale( rLocale );
    return bRes;
}


uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL
    HyphDummy_Impl::hyphenate(
            const rtl::OUString& rWord,
            const lang::Locale& rLocale,
            sal_Int16 nMaxLeading,
            const beans::PropertyValues& rProperties )
        throw(lang::IllegalArgumentException,
              uno::RuntimeException)
{
    GetHyph_Impl();
    uno::Reference< linguistic2::XHyphenatedWord > xRes;
    if (xHyph.is())
        xRes = xHyph->hyphenate( rWord, rLocale, nMaxLeading, rProperties );
    return xRes;
}


uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL
    HyphDummy_Impl::queryAlternativeSpelling(
            const rtl::OUString& rWord,
            const lang::Locale& rLocale,
            sal_Int16 nIndex,
            const PropertyValues& rProperties )
        throw(lang::IllegalArgumentException,
              uno::RuntimeException)
{
    GetHyph_Impl();
    uno::Reference< linguistic2::XHyphenatedWord > xRes;
    if (xHyph.is())
        xRes = xHyph->queryAlternativeSpelling( rWord, rLocale, nIndex, rProperties );
    return xRes;
}


uno::Reference< linguistic2::XPossibleHyphens > SAL_CALL
    HyphDummy_Impl::createPossibleHyphens(
            const rtl::OUString& rWord,
            const lang::Locale& rLocale,
            const beans::PropertyValues& rProperties )
        throw(lang::IllegalArgumentException,
              uno::RuntimeException)
{
    GetHyph_Impl();
    uno::Reference< linguistic2::XPossibleHyphens > xRes;
    if (xHyph.is())
        xRes = xHyph->createPossibleHyphens( rWord, rLocale, rProperties );
    return xRes;
}


///////////////////////////////////////////////////////////////////////////


typedef cppu::WeakImplHelper1 < XEventListener > LinguMgrAppExitLstnrBaseClass;

class LinguMgrAppExitLstnr : public LinguMgrAppExitLstnrBaseClass
{
	uno::Reference< XComponent > 		xDesktop;

public:
	LinguMgrAppExitLstnr();
	virtual ~LinguMgrAppExitLstnr();

	virtual	void	AtExit() = 0;


	// lang::XEventListener
    virtual void 	SAL_CALL disposing(const EventObject& rSource)
			throw( RuntimeException );
};

LinguMgrAppExitLstnr::LinguMgrAppExitLstnr()
{
	// add object to frame::Desktop EventListeners in order to properly call
	// the AtExit function at application exit.

	uno::Reference< XMultiServiceFactory >  xMgr = getProcessServiceFactory();
	if ( xMgr.is() )
	{
		xDesktop = uno::Reference< XComponent > ( xMgr->createInstance(
				OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) ) ), UNO_QUERY ) ;
		if (xDesktop.is())
			xDesktop->addEventListener( this );
	}
}

LinguMgrAppExitLstnr::~LinguMgrAppExitLstnr()
{
	if (xDesktop.is())
	{
		xDesktop->removeEventListener( this );
		xDesktop = NULL;	//! release reference to desktop
	}
	DBG_ASSERT(!xDesktop.is(), "reference to desktop should be released");
}

void LinguMgrAppExitLstnr::disposing(const EventObject& rSource)
		throw( RuntimeException )
{
	if (xDesktop.is()  &&  rSource.Source == xDesktop)
	{
		xDesktop->removeEventListener( this );
		xDesktop = NULL;	//! release reference to desktop

		AtExit();
	}
}

///////////////////////////////////////////////////////////////////////////

class LinguMgrExitLstnr : public LinguMgrAppExitLstnr
{
public:
	virtual	void	AtExit();
};

void LinguMgrExitLstnr::AtExit()
{
	// release references
	LinguMgr::xLngSvcMgr	= 0;
	LinguMgr::xSpell		= 0;
	LinguMgr::xHyph			= 0;
	LinguMgr::xThes			= 0;
	LinguMgr::xDicList		= 0;
	LinguMgr::xProp			= 0;
	LinguMgr::xIgnoreAll	= 0;
	LinguMgr::xChangeAll	= 0;

	LinguMgr::bExiting		= sal_True;

	//TL:TODO: MBA fragen wie ich ohne Absturz hier meinen Speicher
	//  wieder freibekomme...
	//delete LinguMgr::pExitLstnr;
	LinguMgr::pExitLstnr	= 0;
}

///////////////////////////////////////////////////////////////////////////


// static member initialization
LinguMgrExitLstnr * 			LinguMgr::pExitLstnr	= 0;
sal_Bool						LinguMgr::bExiting		= sal_False;
uno::Reference< XLinguServiceManager >	LinguMgr::xLngSvcMgr	= 0;
uno::Reference< XSpellChecker1 > 	LinguMgr::xSpell		= 0;
uno::Reference< XHyphenator > 		LinguMgr::xHyph			= 0;
uno::Reference< XThesaurus > 		LinguMgr::xThes			= 0;
uno::Reference< XDictionaryList > 	LinguMgr::xDicList		= 0;
uno::Reference< XPropertySet > 		LinguMgr::xProp			= 0;
uno::Reference< XDictionary >       LinguMgr::xIgnoreAll    = 0;
uno::Reference< XDictionary >       LinguMgr::xChangeAll    = 0;


uno::Reference< XLinguServiceManager > LinguMgr::GetLngSvcMgr()
{
	if (bExiting)
		return 0;

	if (!pExitLstnr)
		pExitLstnr = new LinguMgrExitLstnr;

	if (!xLngSvcMgr.is())
		xLngSvcMgr = GetLngSvcMgr_Impl();

	return xLngSvcMgr;
}


uno::Reference< XSpellChecker1 > LinguMgr::GetSpellChecker()
{
	return xSpell.is() ? xSpell : GetSpell();
}

uno::Reference< XHyphenator > LinguMgr::GetHyphenator()
{
	return xHyph.is() ? xHyph : GetHyph();
}

uno::Reference< XThesaurus > LinguMgr::GetThesaurus()
{
	return xThes.is() ? xThes : GetThes();
}

uno::Reference< XDictionaryList > LinguMgr::GetDictionaryList()
{
	return xDicList.is() ? xDicList : GetDicList();
}

uno::Reference< XPropertySet > LinguMgr::GetLinguPropertySet()
{
	return xProp.is() ? xProp : GetProp();
}

uno::Reference< XDictionary > LinguMgr::GetStandardDic()
{
	//! don't hold reference to this
	//! (it may be removed from dictionary list and needs to be
	//! created empty if accessed again)
	return GetStandard();
}

uno::Reference< XDictionary > LinguMgr::GetIgnoreAllList()
{
	return xIgnoreAll.is() ? xIgnoreAll : GetIgnoreAll();
}

uno::Reference< XDictionary > LinguMgr::GetChangeAllList()
{
	return xChangeAll.is() ? xChangeAll : GetChangeAll();
}

uno::Reference< XSpellChecker1 > LinguMgr::GetSpell()
{
	if (bExiting)
		return 0;

	if (!pExitLstnr)
		pExitLstnr = new LinguMgrExitLstnr;

    //! use dummy implementation in order to avoid loading of lingu DLL
    xSpell = new SpellDummy_Impl;

/*    if (!xLngSvcMgr.is())
		xLngSvcMgr = GetLngSvcMgr_Impl();

	if (xLngSvcMgr.is())
	{
		xSpell = uno::Reference< XSpellChecker1 > (
						xLngSvcMgr->getSpellChecker(), UNO_QUERY );
	}
*/
	return xSpell;
}

uno::Reference< XHyphenator > LinguMgr::GetHyph()
{
	if (bExiting)
		return 0;

	if (!pExitLstnr)
		pExitLstnr = new LinguMgrExitLstnr;

    //! use dummy implementation in order to avoid loading of lingu DLL
    xHyph = new HyphDummy_Impl;

/*
	if (!xLngSvcMgr.is())
		xLngSvcMgr = GetLngSvcMgr_Impl();

	if (xLngSvcMgr.is())
	{
		xHyph = xLngSvcMgr->getHyphenator();
	}
*/
	return xHyph;
}

uno::Reference< XThesaurus > LinguMgr::GetThes()
{
	if (bExiting)
		return 0;

	if (!pExitLstnr)
		pExitLstnr = new LinguMgrExitLstnr;

    //! use dummy implementation in order to avoid loading of lingu DLL
    //! when only the XSupportedLocales interface is used.
    //! The dummy accesses the real implementation (and thus loading the DLL)
    //! when "real" work needs to be done only.
    xThes = new ThesDummy_Impl;
/*
	if (!xLngSvcMgr.is())
		xLngSvcMgr = GetLngSvcMgr_Impl();

	if (xLngSvcMgr.is())
	{
		xThes = xLngSvcMgr->getThesaurus();
	}
*/
	return xThes;
}


void LinguMgr::UpdateAll()
{
}


uno::Reference< XDictionaryList > LinguMgr::GetDicList()
{
	if (bExiting)
		return 0;

	if (!pExitLstnr)
		pExitLstnr = new LinguMgrExitLstnr;

	uno::Reference< XMultiServiceFactory >  xMgr( getProcessServiceFactory() );
	if (xMgr.is())
	{
		xDicList = uno::Reference< XDictionaryList > ( xMgr->createInstance(
                    A2OU("com.sun.star.linguistic2.DictionaryList") ), UNO_QUERY );
	}
	return xDicList;
}

uno::Reference< XPropertySet > LinguMgr::GetProp()
{
	if (bExiting)
		return 0;

	if (!pExitLstnr)
		pExitLstnr = new LinguMgrExitLstnr;

	uno::Reference< XMultiServiceFactory >  xMgr( getProcessServiceFactory() );
	if (xMgr.is())
	{
		xProp = uno::Reference< XPropertySet > ( xMgr->createInstance(
                    A2OU("com.sun.star.linguistic2.LinguProperties") ), UNO_QUERY );
	}
	return xProp;
}

uno::Reference< XDictionary > LinguMgr::GetIgnoreAll()
{
	if (bExiting)
		return 0;

	if (!pExitLstnr)
		pExitLstnr = new LinguMgrExitLstnr;

	uno::Reference< XDictionaryList >  xTmpDicList( GetDictionaryList() );
	if (xTmpDicList.is())
	{
        xIgnoreAll = uno::Reference< XDictionary > ( xTmpDicList->getDictionaryByName(
                    A2OU("IgnoreAllList") ), UNO_QUERY );
	}
	return xIgnoreAll;
}

uno::Reference< XDictionary > LinguMgr::GetChangeAll()
{
	if (bExiting)
		return 0;

	if (!pExitLstnr)
		pExitLstnr = new LinguMgrExitLstnr;

	uno::Reference< XDictionaryList > _xDicList( GetDictionaryList() , UNO_QUERY );
	if (_xDicList.is())
	{
        xChangeAll = uno::Reference< XDictionary > (
						_xDicList->createDictionary(
                            A2OU("ChangeAllList"),
							SvxCreateLocale( LANGUAGE_NONE ),
							DictionaryType_NEGATIVE, String() ), UNO_QUERY );
	}
	return xChangeAll;
}

uno::Reference< XDictionary > LinguMgr::GetStandard()
{
	// Tries to return a dictionary which may hold positive entries is
	// persistent and not read-only.

	if (bExiting)
		return 0;

	uno::Reference< XDictionaryList >  xTmpDicList( GetDictionaryList() );
	if (!xTmpDicList.is())
		return NULL;

	const OUString aDicName( RTL_CONSTASCII_USTRINGPARAM( "standard.dic" ) );
    uno::Reference< XDictionary >   xDic( xTmpDicList->getDictionaryByName( aDicName ),
									  UNO_QUERY );
    if (!xDic.is())
    {
        // try to create standard dictionary
        uno::Reference< XDictionary >    xTmp;
        try
        {
            xTmp =  xTmpDicList->createDictionary( aDicName,
                        SvxCreateLocale( LANGUAGE_NONE ),
                        DictionaryType_POSITIVE,
                        linguistic::GetWritableDictionaryURL( aDicName ) );
        }
        catch(com::sun::star::uno::Exception &)
        {
        }

        // add new dictionary to list
        if (xTmp.is())
        {
            xTmpDicList->addDictionary( xTmp );
            xTmp->setActive( sal_True );
        }
        xDic = uno::Reference< XDictionary > ( xTmp, UNO_QUERY );
    }
#if OSL_DEBUG_LEVEL > 1
    uno::Reference< XStorable >      xStor( xDic, UNO_QUERY );
    DBG_ASSERT( xDic.is() && xDic->getDictionaryType() == DictionaryType_POSITIVE,
            "wrong dictionary type");
    DBG_ASSERT( xDic.is() && SvxLocaleToLanguage( xDic->getLocale() ) == LANGUAGE_NONE,
            "wrong dictionary language");
    DBG_ASSERT( !xStor.is() || (xStor->hasLocation() && !xStor->isReadonly()),
            "dictionary not editable" );
#endif

	return xDic;
}

///////////////////////////////////////////////////////////////////////////

uno::Reference< XSpellChecker1 >  SvxGetSpellChecker()
{
	return LinguMgr::GetSpellChecker();
}

uno::Reference< XHyphenator >  SvxGetHyphenator()
{
	return LinguMgr::GetHyphenator();
}

uno::Reference< XThesaurus >  SvxGetThesaurus()
{
	return LinguMgr::GetThesaurus();
}

uno::Reference< XDictionaryList >  SvxGetDictionaryList()
{
	return LinguMgr::GetDictionaryList();
}

uno::Reference< XPropertySet > 	SvxGetLinguPropertySet()
{
	return LinguMgr::GetLinguPropertySet();
}

//TL:TODO: remove argument or provide SvxGetIgnoreAllList with the same one
uno::Reference< XDictionary >  SvxGetOrCreatePosDic(
		uno::Reference< XDictionaryList >  /* xDicList */ )
{
	return LinguMgr::GetStandardDic();
}

uno::Reference< XDictionary >  SvxGetIgnoreAllList()
{
	return LinguMgr::GetIgnoreAllList();
}

uno::Reference< XDictionary >  SvxGetChangeAllList()
{
	return LinguMgr::GetChangeAllList();
}

///////////////////////////////////////////////////////////////////////////


#include <com/sun/star/linguistic2/XHyphenatedWord.hpp>

SvxAlternativeSpelling SvxGetAltSpelling(
		const ::com::sun::star::uno::Reference<
			::com::sun::star::linguistic2::XHyphenatedWord > & rHyphWord )
{
	SvxAlternativeSpelling aRes;
	if (rHyphWord.is() && rHyphWord->isAlternativeSpelling())
	{
		OUString aWord( rHyphWord->getWord() ),
                 aAltWord( rHyphWord->getHyphenatedWord() );
		sal_Int16	nHyphenationPos		= rHyphWord->getHyphenationPos(),
				nHyphenPos			= rHyphWord->getHyphenPos();
        sal_Int16   nLen    = (sal_Int16)aWord.getLength();
        sal_Int16   nAltLen = (sal_Int16)aAltWord.getLength();
		const sal_Unicode *pWord	= aWord.getStr(),
                          *pAltWord = aAltWord.getStr();

        // count number of chars from the left to the
        // hyphenation pos / hyphen pos that are equal
        sal_Int16 nL = 0;
        while (nL <= nHyphenationPos && nL <= nHyphenPos
               && pWord[ nL ] == pAltWord[ nL ])
            ++nL;
        // count number of chars from the right to the
        // hyphenation pos / hyphen pos that are equal
        sal_Int16 nR = 0;
        sal_Int32 nIdx    = nLen - 1;
        sal_Int32 nAltIdx = nAltLen - 1;
        while (nIdx > nHyphenationPos && nAltIdx > nHyphenPos
               && pWord[ nIdx-- ] == pAltWord[ nAltIdx-- ])
            ++nR;

        aRes.aReplacement       = OUString( aAltWord.copy( nL, nAltLen - nL - nR ) );
        aRes.nChangedPos        = (sal_Int16) nL;
        aRes.nChangedLength     = nLen - nL - nR;
		aRes.bIsAltSpelling		= sal_True;
		aRes.xHyphWord			= rHyphWord;
	}
	return aRes;
}


///////////////////////////////////////////////////////////////////////////

SvxDicListChgClamp::SvxDicListChgClamp( uno::Reference< XDictionaryList >  &rxDicList ) :
	xDicList	( rxDicList )
{
	if (xDicList.is())
	{
		xDicList->beginCollectEvents();
	}
}

SvxDicListChgClamp::~SvxDicListChgClamp()
{
	if (xDicList.is())
	{
		xDicList->endCollectEvents();
	}
}

///////////////////////////////////////////////////////////////////////////

short SvxDicError( Window *pParent, sal_Int16 nError )
{
	short nRes = 0;
	if (DIC_ERR_NONE != nError)
	{
		int nRid;
		switch (nError)
		{
			case DIC_ERR_FULL	  : nRid = RID_SVXSTR_DIC_ERR_FULL;  break;
			case DIC_ERR_READONLY : nRid = RID_SVXSTR_DIC_ERR_READONLY;  break;
			default:
				nRid = RID_SVXSTR_DIC_ERR_UNKNOWN;
				DBG_ASSERT(0, "unexpected case");
		}
		nRes = InfoBox( pParent, EE_RESSTR( nRid ) ).Execute();
	}
	return nRes;
}

LanguageType SvxLocaleToLanguage( const Locale& rLocale )
{
	//	empty Locale -> LANGUAGE_NONE
	if ( rLocale.Language.getLength() == 0 )
		return LANGUAGE_NONE;

	return MsLangId::convertLocaleToLanguage( rLocale );
}

Locale& SvxLanguageToLocale( Locale& rLocale, LanguageType eLang )
{
	if ( eLang != LANGUAGE_NONE	/* &&  eLang != LANGUAGE_SYSTEM */)
		MsLangId::convertLanguageToLocale( eLang, rLocale );
    else
        rLocale = Locale();

	return rLocale;
}

Locale SvxCreateLocale( LanguageType eLang )
{
	Locale aLocale;
	if ( eLang != LANGUAGE_NONE /* &&  eLang != LANGUAGE_SYSTEM */)
		MsLangId::convertLanguageToLocale( eLang, aLocale );

	return aLocale;
}
