201033_04
authorhgs
Tue, 07 Sep 2010 16:39:34 +0800
changeset 59 7d891bb52a7d
parent 53 11e2bb0d14ba
child 64 f66674566702
201033_04
layers.sysdef.xml
package_definition.xml
textandlocutils/nearestlangutils/bwins/langutilu.def
textandlocutils/nearestlangutils/eabi/langutilu.def
textandlocutils/nearestlangutils/group/T_LangUtilsServer.pkg
textandlocutils/nearestlangutils/group/bld.inf
textandlocutils/nearestlangutils/group/langutil.MMP
textandlocutils/nearestlangutils/group/langutilTests.bat
textandlocutils/nearestlangutils/group/langutilTests.iby
textandlocutils/nearestlangutils/group/langutils.iby
textandlocutils/nearestlangutils/group/langutils.mrp
textandlocutils/nearestlangutils/inc/LangUtil.h
textandlocutils/nearestlangutils/src/LangUtil.cpp
textandlocutils/nearestlangutils/src/LangUtilImpl.h
textandlocutils/nearestlangutils/tsrc/T_All_langutils.bat
textandlocutils/nearestlangutils/tsrc/T_All_langutils.script
textandlocutils/nearestlangutils/tsrc/T_LangUtils.MMP
textandlocutils/nearestlangutils/tsrc/T_LangUtils.cpp
textandlocutils/nearestlangutils/tsrc/T_LangUtilsImp.cpp
textandlocutils/nearestlangutils/tsrc/T_LangUtilsImp.mmp
textandlocutils/nearestlangutils/tsrc/T_LangUtilsLang.cpp
textandlocutils/nearestlangutils/tsrc/T_LangUtilsLang.mmp
textandlocutils/nearestlangutils/tsrc/T_LangUtilsServer.mmp
textandlocutils/nearestlangutils/tsrc/T_LangUtilsTestShareFunc.cpp
textandlocutils/nearestlangutils/tsrc/T_LangUtilsTestShareFunc.h
textandlocutils/nearestlangutils/tsrc/T_langutils.script
textandlocutils/nearestlangutils/tsrc/T_langutilsimp.script
textandlocutils/nearestlangutils/tsrc/T_langutilslang.script
textandlocutils/nearestlangutils/tsrc/file1.txt
textandlocutils/nearestlangutils/tsrc/file123456789.txt
textandlocutils/nearestlangutils/tsrc/file2.txt
textandlocutils/nearestlangutils/tsrc/file5.txt
textandlocutils/nearestlangutils/tsrc/t_langutils.h
textandlocutils/nearestlangutils/tsrc/t_langutilsimp.h
textandlocutils/nearestlangutils/tsrc/t_langutilslang.h
textandlocutils/nearestlangutils/tsrc/t_langutilsserver.cpp
textandlocutils/nearestlangutils/tsrc/t_langutilsserver.h
--- a/layers.sysdef.xml	Thu Aug 26 11:46:18 2010 +0800
+++ b/layers.sysdef.xml	Tue Sep 07 16:39:34 2010 +0800
@@ -140,6 +140,9 @@
       <module name="syslibs_fatcharsetconv">
         <unit name="fatcharsetconv" unitID="tls.fatcharsetconv"  bldFile="sf\os\textandloc\charconvfw\fatfilenameconversionplugins\group" mrp="sf\os\textandloc\charconvfw\fatfilenameconversionplugins\group\syslibs_fatcharsetconv.mrp"/>
       </module>
+      <module name="nearestlangutils">
+        <unit name="nearestlangutils" unitID="tls.nearestlangutils"  bldFile="sf\os\textandloc\textandlocutils\nearestlangutils\group" mrp="sf\os\textandloc\textandlocutils\nearestlangutils\group\langutils.mrp"/>
+      </module>
     </layer>
     <layer name="api_test_layer">
       <!--module name="test.app-framework_etext">
--- a/package_definition.xml	Thu Aug 26 11:46:18 2010 +0800
+++ b/package_definition.xml	Tue Sep 07 16:39:34 2010 +0800
@@ -26,13 +26,10 @@
         <unit bldFile="fontservices/textshaperplugin/group" mrp="fontservices/textshaperplugin/group/graphics_iculayoutengine.mrp"/>
       </component>
       <component id="fontstore" name="Font Store" purpose="mandatory" filter="api_test"> <!-- both production and api_test-->
-    	<meta rel="testbuild">
-          <group name="test.graphics_fntstore"/>
-        </meta>
-        <unit bldFile="fontservices/fontstore/group" mrp="fontservices/fontstore/group/graphics_fntstore.mrp"/>
+`        <unit bldFile="fontservices/fontstore/group" mrp="fontservices/fontstore/group/graphics_fntstore.mrp"/>
       </component>
      <component id="textbase" name="Text Base" purpose="mandatory">
-     	<!-- placeholder for text code from GDI -->
+	<unit bldFile="fontservices/textbase/group" mrp="fontservices/textbase/group/textbase.mrp" /> 
      </component>      
       <component id="freetypefontrasteriser" name="FreeType Font Rasteriser" purpose="optional" class="plugin">
         <unit bldFile="fontservices/freetypefontrasteriser/group" mrp="fontservices/freetypefontrasteriser/group/graphics_freetype.mrp"/>
@@ -68,6 +65,9 @@
       <component id="numberformatting" name="Number Formatting" introduced="7.0s" purpose="optional">
         <unit bldFile="textrendering/numberformatting/group" mrp="textrendering/numberformatting/group/app-framework_numberconversion.mrp"/>
       </component>
+      <component id="nearestlangutils" name="Nearest Language Utils">
+        <unit bldFile="textandlocutils/nearestlangutils/group" mrp="textandlocutils/nearestlangutils/group/langutils.mrp"/>
+      </component>
     </collection>
     <collection id="localesupport" name="Locale Support" level="util">
       <component id="reflocales" name="Reference Locales"  purpose="optional" class="plugin">
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/bwins/langutilu.def	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,10 @@
+EXPORTS
+	?IdealLanguage@LangUtil@@SA?AW4TLanguage@@XZ @ 1 NONAME ; enum TLanguage LangUtil::IdealLanguage(void)
+	?NearestLanguageFile@LangUtil@@SAXABVRFs@@AAV?$TBuf@$0BAA@@@AAW4TLanguage@@@Z @ 2 NONAME ; void LangUtil::NearestLanguageFile(class RFs const &, class TBuf<256> &, enum TLanguage &)
+	?ReleaseIdealLanguage@LangUtil@@SAXXZ @ 3 NONAME ; void LangUtil::ReleaseIdealLanguage(void)
+	?GetEquivalentLanguageList@LangUtil@@SAXW4TLanguage@@AAY0BB@W42@@Z @ 4 NONAME ; void LangUtil::GetEquivalentLanguageList(enum TLanguage, enum TLanguage [17] &)
+	?NearestLanguageFile@LangUtil@@SAXABVRFs@@AAV?$TBuf@$0BAA@@@@Z @ 5 NONAME ; void LangUtil::NearestLanguageFile(class RFs const &, class TBuf<256> &)
+	?NearestLanguageFileV2@LangUtil@@SAXABVRFs@@AAV?$TBuf@$0BAA@@@AAW4TLanguage@@@Z @ 6 NONAME ; void LangUtil::NearestLanguageFileV2(class RFs const &, class TBuf<256> &, enum TLanguage &)
+	?SetIdealLanguage@LangUtil@@SAHW4TLanguage@@@Z @ 7 NONAME ; int LangUtil::SetIdealLanguage(enum TLanguage)
+	?GetDowngradePathL@LangUtil@@SAXABVRFs@@W4TLanguage@@AAV?$RArray@W4TLanguage@@@@@Z @ 8 NONAME ; void LangUtil::GetDowngradePathL(class RFs const &, enum TLanguage, class RArray<enum TLanguage> &)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/group/T_LangUtilsServer.pkg	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,29 @@
+;
+; Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http:;www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description: 
+;
+
+;Languages
+&EN
+
+;Localised Vendor name
+%{"t_PTPipsuite EN"}
+
+; Vendor name
+: "t_PTPipsuite"
+
+; test scripts
+"\epoc32\data\z\test\T_langutils.script"-"c:\sys\bin\T_langutils.script"
+"\epoc32\data\z\test\T_langutilsimp.script"-"c:\sys\bin\T_langutilsimp.script"
+"\epoc32\data\z\test\T_langutilslang.script"-"c:\sys\bin\T_langutilslang.script"
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/group/bld.inf	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,66 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+// LangUtils
+// 
+//
+
+/**
+ @file
+*/
+
+
+PRJ_PLATFORMS
+
+DEFAULT
+
+
+PRJ_EXPORTS
+
+../inc/LangUtil.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(bafl/langutil.h)
+
+../group/langutils.iby			/epoc32/rom/include/langutils.iby
+
+PRJ_MMPFILES
+
+../group/langutil.MMP
+
+PRJ_TESTEXPORTS
+../group/langutilTests.bat		/epoc32/data/z/system/test/langutilTests.bat
+../group/langutilTests.iby		/epoc32/rom/include/langutilTests.iby
+
+	../tsrc/T_All_langutils.bat				z:/test/T_All_langutils.bat
+	../tsrc/T_All_langutils.script			z:/test/T_All_langutils.script
+	../tsrc/T_langutils.script				z:/test/T_langutils.script
+	../tsrc/T_langutilsimp.script			z:/test/T_langutilsimp.script
+	../tsrc/T_langutilslang.script			z:/test/T_langutilslang.script
+
+../tsrc/file1.txt		/epoc32/data/z/system/data/file1.txt
+../tsrc/file1.txt		/epoc32/data/z/file1.txt
+../tsrc/file1.txt		/epoc32/data/z/system/data/src/file1.txt
+../tsrc/file2.txt		/epoc32/data/z/system/data/dst/file2.txt
+../tsrc/file123456789.txt	/epoc32/data/z/system/data/file123456789.txt
+../tsrc/file2.txt		/epoc32/data/z/system/data/file2.txt
+../tsrc/file5.txt		/epoc32/data/z/system/data/file5.txt
+
+../tsrc/file1.txt		/epoc32/release/wins/udeb/z/file1.txt
+../tsrc/file1.txt		/epoc32/release/wins/urel/z/file1.txt
+../tsrc/file1.txt		/epoc32/release/winscw/udeb/z/file1.txt
+../tsrc/file1.txt		/epoc32/release/winscw/urel/z/file1.txt
+
+PRJ_TESTMMPFILES
+../tsrc/T_LangUtilsServer.mmp
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/group/langutil.MMP	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,50 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+//   Lang utility functions collection
+// 
+//
+
+/**
+ @file
+*/
+
+
+TARGET          langutil.lib
+CAPABILITY All  -Tcb
+TARGETTYPE      LIB
+UID				0x1000008D
+VENDORID        0x70000001
+
+
+USERINCLUDE     ../inc
+USERINCLUDE 	../src
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+START WINS
+BASEADDRESS     0x41900000
+END
+UNPAGED
+
+
+
+SOURCEPATH ../src
+SOURCE LangUtil.cpp
+
+
+
+
+SMPSAFE
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/group/langutilTests.bat	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,19 @@
+@rem
+@rem Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). 
+@rem All rights reserved.                                                   
+@rem This component and the accompanying materials are made available       
+@rem under the terms of "Eclipse Public License v1.0"                       
+@rem which accompanies this distribution, and is available                  
+@rem at the URL "http://www.eclipse.org/legal/epl-v10.html".                
+@rem                                                                        
+@rem Initial Contributors:                                                  
+@rem Nokia Corporation - initial contribution.                              
+@rem                                                                        
+@rem Contributors:                                                          
+@rem                                                                        
+@rem Description:                                                           
+@rem
+
+T_LangUtils.EXE
+T_LangUtilsImp.EXE
+T_LangUtilsLang.EXE
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/group/langutilTests.iby	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,34 @@
+/*
+* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.                                                   
+* This component and the accompanying materials are made available       
+* under the terms of "Eclipse Public License v1.0"                       
+* which accompanies this distribution, and is available                  
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".                
+*                                                                        
+* Initial Contributors:                                                  
+* Nokia Corporation - initial contribution.                              
+*                                                                        
+* Contributors:                                                          
+*                                                                        
+* Description:                                                           
+*
+*/
+#ifndef __LANGUTILS_TESTS_IBY__
+#define __LANGUTILS_TESTS_IBY__
+
+REM BaflTests
+#include <testbed.iby>
+
+file=ABI_DIR\BUILD_DIR\t_langutilsserver.exe			sys\bin\t_langutilsserver.exe
+
+data=ZSYSTEM\Data\file1.txt                                 \system\data\file1.txt
+data=ZSYSTEM\Data\file1.txt                                 \file1.txt
+data=ZSYSTEM\Data\file1.txt                                 \system\data\src\file1.txt
+data=ZSYSTEM\Data\file2.txt                                 \system\data\dst\file2.txt
+data=ZSYSTEM\Data\file123456789.txt                         \system\data\file123456789.txt
+data=ZSYSTEM\Data\file2.txt                                 \system\data\file2.txt
+data=ZSYSTEM\Data\file5.txt                                 \system\data\file5.txt
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/group/langutils.iby	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,22 @@
+/*
+* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.                                                   
+* This component and the accompanying materials are made available       
+* under the terms of "Eclipse Public License v1.0"                       
+* which accompanies this distribution, and is available                  
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".                
+*                                                                        
+* Initial Contributors:                                                  
+* Nokia Corporation - initial contribution.                              
+*                                                                        
+* Contributors:                                                          
+*                                                                        
+* Description:                                                           
+*
+*/
+#ifndef __LANGUTILS_IBY__
+#define __LANGUTILS_IBY__
+
+file=ABI_DIR\BUILD_DIR\langutil.lib 		System\Libs\langutil.lib
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/group/langutils.mrp	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,10 @@
+component	nearestlangutils
+source	\sf\os\textandloc\textandlocalisationutils\nearestlangutils
+binary	\sf\os\textandloc\textandlocalisationutils\nearestlangutils\group	all
+exports	\sf\os\textandloc\textandlocalisationutils\nearestlangutils\group
+
+notes_source	\component_defs\release.src
+
+
+ipr D
+ipr T \sf\os\textandloc\textandlocalisationutils\nearestlangutils\tsrc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/inc/LangUtil.h	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,38 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+
+#ifndef __LANGUTIL_H__
+#define __LANGUTIL_H__
+
+#include <e32std.h>
+#include <bautils.h>
+
+
+
+class LangUtil
+{
+public:
+     static void GetDowngradePathL(const RFs& aFs, const TLanguage aCurrentLanguage, RArray<TLanguage>& aLanguageArray );
+     static void GetEquivalentLanguageList(TLanguage aLang, TLanguagePath& aEquivalents);
+     static TLanguage IdealLanguage();
+     static void NearestLanguageFile(const RFs& aFs, TFileName& aName);
+     static void NearestLanguageFile(const RFs& aFs, TFileName& aName, TLanguage& aLanguage);
+     static void NearestLanguageFileV2(const RFs& aFs, TFileName& aName, TLanguage& aLanguage);
+     static void ReleaseIdealLanguage();
+     static TInt SetIdealLanguage(TLanguage aLanguage);
+
+};
+#endif // end of __LANGUTIL_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/src/LangUtil.cpp	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,908 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <bafl/langutil.h>
+#include <hal.h>
+#include <hal_data.h>
+#include "LangUtilImpl.h"
+
+
+/**
+Mimimum length of a filename and mimimum length of a suffix.
+Note these two values are tied together.
+*/
+const TInt KInvNameAndMinSuffixLength = 2;
+
+#define ISDIGIT(c) (c-'0' >= 0 && c-'0' <= 9)
+
+_LIT(KAllDrives, "YXWVUTSRQPONMLKJIHGFEDCBAZ");
+
+LOCAL_C const TLanguage dp0[] = { ELangCanadianEnglish, ELangAmerican,ELangEnglish, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangAustralian,ELangNewZealand,ELangInternationalEnglish,ELangSouthAfricanEnglish,ELangNone };
+LOCAL_C const TLanguage dp1[] = { ELangAmerican, ELangEnglish,ELangCanadianEnglish, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangAustralian,ELangNewZealand,ELangInternationalEnglish,ELangSouthAfricanEnglish, ELangNone };
+LOCAL_C const TLanguage dp2[] = { ELangAustralian, ELangEnglish, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangInternationalEnglish,ELangSouthAfricanEnglish, ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp3[] = { ELangSouthAfricanEnglish, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangInternationalEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp4[] = { ELangInternationalEnglish, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp5[] = { ELangEnglish_Apac, ELangEnglish, ELangAustralian, ELangAmerican,ELangInternationalEnglish,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp6[] = { ELangEnglish_Taiwan, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangInternationalEnglish,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp7[] = { ELangEnglish_HongKong, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangInternationalEnglish,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp8[] = { ELangEnglish_Prc, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangInternationalEnglish,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp9[] = { ELangEnglish_Japan, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangInternationalEnglish,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp10[] = { ELangEnglish_Thailand, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangInternationalEnglish,ELangEnglish_India,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp11[] = { ELangEnglish_India, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangInternationalEnglish,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp12[] = { ELangNewZealand, ELangEnglish, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangAustralian,ELangInternationalEnglish,ELangSouthAfricanEnglish, ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp13[] = { ELangInternationalFrench,ELangFrench,ELangSwissFrench,ELangBelgianFrench,ELangCanadianFrench,ELangNone };
+LOCAL_C const TLanguage dp14[] = { ELangBelgianFrench, ELangFrench,ELangInternationalFrench,ELangSwissFrench,ELangCanadianFrench,ELangNone };
+LOCAL_C const TLanguage dp15[] = { ELangCanadianFrench, ELangFrench,ELangInternationalFrench,ELangSwissFrench,ELangBelgianFrench,ELangNone };
+LOCAL_C const TLanguage dp16[] = { ELangFrench,ELangInternationalFrench,ELangSwissFrench,ELangBelgianFrench,ELangCanadianFrench,ELangNone };
+LOCAL_C const TLanguage dp17[] = { ELangSwissFrench,ELangFrench,ELangInternationalFrench,ELangBelgianFrench,ELangCanadianFrench,ELangNone };
+LOCAL_C const TLanguage dp18[] = { ELangSwissGerman,ELangGerman,ELangAustrian,ELangNone };
+LOCAL_C const TLanguage dp19[] = { ELangAustrian,ELangGerman,ELangSwissGerman,ELangNone };
+LOCAL_C const TLanguage dp20[] = { ELangGerman,ELangSwissGerman,ELangAustrian,ELangNone };
+LOCAL_C const TLanguage dp21[] = { ELangSerbian,ELangCroatian,ELangNone };
+LOCAL_C const TLanguage dp22[] = { ELangCroatian,ELangSerbian,ELangNone };
+LOCAL_C const TLanguage dp23[] = { ELangRomanian,ELangMoldavian,ELangNone };
+LOCAL_C const TLanguage dp24[] = { ELangMoldavian,ELangRomanian,ELangNone };
+LOCAL_C const TLanguage dp25[] = { ELangBelgianFlemish,ELangDutch,ELangNone };
+LOCAL_C const TLanguage dp26[] = { ELangDutch,ELangBelgianFlemish,ELangNone };
+LOCAL_C const TLanguage dp27[] = { ELangAfrikaans,ELangDutch,ELangNone };
+LOCAL_C const TLanguage dp28[] = { ELangMalay_Apac,ELangMalay,ELangNone };
+LOCAL_C const TLanguage dp29[] = { ELangIndonesian_Apac,ELangIndonesian,ELangNone };
+LOCAL_C const TLanguage dp30[] = { ELangSpanish,ELangInternationalSpanish,ELangLatinAmericanSpanish,ELangNone };
+LOCAL_C const TLanguage dp31[] = { ELangLatinAmericanSpanish,ELangSpanish,ELangInternationalSpanish,ELangNone };
+LOCAL_C const TLanguage dp32[] = { ELangInternationalSpanish,ELangSpanish,ELangLatinAmericanSpanish,ELangNone };
+LOCAL_C const TLanguage dp33[] = { ELangCyprusGreek,ELangGreek,ELangNone };
+LOCAL_C const TLanguage dp34[] = { ELangGreek,ELangCyprusGreek,ELangNone };
+LOCAL_C const TLanguage dp35[] = { ELangSwissItalian,ELangItalian,ELangNone };
+LOCAL_C const TLanguage dp36[] = { ELangItalian,ELangSwissItalian,ELangNone };
+LOCAL_C const TLanguage dp37[] = { ELangBrazilianPortuguese,ELangPortuguese,ELangNone };
+LOCAL_C const TLanguage dp38[] = { ELangPortuguese,ELangBrazilianPortuguese,ELangNone };
+LOCAL_C const TLanguage dp39[] = { ELangFinlandSwedish,ELangSwedish,ELangNone };
+LOCAL_C const TLanguage dp40[] = { ELangSwedish,ELangFinlandSwedish,ELangNone };
+LOCAL_C const TLanguage dp41[] = { ELangCyprusTurkish,ELangTurkish,ELangNone };
+LOCAL_C const TLanguage dp42[] = { ELangTurkish,ELangCyprusTurkish,ELangNone };
+LOCAL_C const TLanguage dp43[] = { ELangHongKongChinese, ELangTaiwanChinese, ELangPrcChinese,ELangNone };
+LOCAL_C const TLanguage dp44[] = { ELangTaiwanChinese, ELangHongKongChinese,ELangPrcChinese,ELangNone };
+LOCAL_C const TLanguage dp45[] = { ELangPrcChinese, ELangHongKongChinese, ELangTaiwanChinese,ELangNone };
+LOCAL_C const TLanguage * const KEquivalentLists[] = { dp0,  dp1,  dp2,  dp3,  dp4,  dp5,  dp6,  
+		dp7,  dp8,  dp9,  dp10,  dp11,  dp12,  dp13,  dp14,  dp15,  dp16,  dp17,
+		dp18,  dp19,  dp20,  dp21,  dp22,  dp23,  dp24,  dp25,  dp26,  dp27,  
+		dp28,  dp29,  dp30,  dp31,  dp32,  dp33,  dp34,  dp35,  dp36,  dp37,  
+		dp38,  dp39,  dp40,  dp41,  dp42,  dp43,  dp44,  dp45};
+
+
+
+LOCAL_C TBool IsLanguageExtended(const TLanguage aLanguage)
+	{
+	// For compatibility reasons, ELangNone is 0xFFFF. However, it's not an extended language.
+	if ((aLanguage==ELangNone) || ((static_cast<TUint>(aLanguage))<=KDialectMask))
+		return EFalse;
+	else
+		return ETrue;
+	}
+
+
+LOCAL_C TLanguage BaseLanguage(const TLanguage aLanguage)
+	{
+	if (IsLanguageExtended(aLanguage))
+		return static_cast<TLanguage>(aLanguage & KDialectMask);
+	else
+		return aLanguage;
+	}
+
+LOCAL_C TLanguage NextLanguage(TLanguage aLanguage)
+/** Returns the next best language to use after aLanguage,
+based on Symbian's base table of language near-equivalence.
+@internalAll */
+	{
+	switch (aLanguage)
+		{
+		case ELangAustralian:
+		case ELangNewZealand:
+		case ELangSouthAfricanEnglish:
+		case ELangInternationalEnglish:
+		case ELangAmerican:
+		case ELangEnglish_Apac:
+		case ELangEnglish_Taiwan:
+		case ELangEnglish_HongKong:
+		case ELangEnglish_Prc:
+		case ELangEnglish_Japan:
+		case ELangEnglish_Thailand:
+			return ELangEnglish;
+		case ELangCanadianEnglish:
+			return ELangAmerican;	// 2-stage downgrade
+		case ELangSwissFrench:
+		case ELangBelgianFrench:
+		case ELangInternationalFrench:
+		case ELangCanadianFrench:
+			return ELangFrench;
+		case ELangSwissGerman:
+		case ELangAustrian:
+			return ELangGerman;
+		case ELangInternationalSpanish:
+		case ELangLatinAmericanSpanish:
+			return ELangSpanish;
+		case ELangSwissItalian:
+			return ELangItalian;
+		case ELangFinlandSwedish:
+			return ELangSwedish;
+		case ELangCyprusTurkish:
+			return ELangTurkish;
+		case ELangBelgianFlemish:
+			return ELangDutch;
+		case ELangHongKongChinese:
+			return ELangTaiwanChinese;
+		case ELangCyprusGreek:
+			return ELangGreek;
+		case ELangMalay_Apac:
+			return ELangMalay;
+		case ELangBrazilianPortuguese:
+			return ELangPortuguese;
+		default:
+			return ELangNone;	
+		}
+	}
+
+
+void AddLanguage(TLanguagePath& aPath, TLanguage aNewLanguage)
+/** Add language to the language path if there is space.
+The first empty slot must have "ELangNone" in it. This will also be true
+on exit. */ 
+    {
+    TLanguage *p = aPath;
+    const TLanguage *end = &(aPath[KMaxDowngradeLanguages]);
+    while (p != end)
+        {
+        if (*p == aNewLanguage)
+            // language already in list
+            break;
+        if (*p == ELangNone)
+            {
+            // found the end of the list
+            p[0] = aNewLanguage;
+            p[1] = ELangNone;
+            break;
+            }
+        ++p;
+        }
+    return;
+    }
+
+void MakeLanguageDowngradePath(TLanguagePath& aPath,
+    TLanguage aCurrent, TLanguage aIdeal, const TLocale& aLocale)
+    {
+    TInt j = 0;
+    if( aIdeal != ELangNone)
+        {
+        aPath[j++]=aIdeal;  
+        }
+    aPath[j++] = aCurrent;
+    aPath[j++] = ELangNone;
+
+    if (aCurrent & ~KDialectMask)
+        AddLanguage(aPath, static_cast<TLanguage>(aCurrent & KDialectMask));
+
+    for (TInt i=0;i<=2;i++)
+        {
+        AddLanguage(aPath, aLocale.LanguageDowngrade(i));
+        AddLanguage(aPath, BaseLanguage(aLocale.LanguageDowngrade(i)));
+        }
+
+    while (ELangNone != (aCurrent = NextLanguage(BaseLanguage(aCurrent))))  
+        AddLanguage(aPath, aCurrent);
+    }
+
+
+
+//EXPORT_C 
+void LangUtil::GetDowngradePathL(const RFs& aFs, const TLanguage aCurrentLanguage, RArray<TLanguage>& aLanguageArray){
+
+ 	TLocale currentLocale; 
+  	TNearestLanguageFileFinder languageDowngradePath(aFs);
+  	TLanguage idealLanguage=IdealLanguage();
+  	MakeLanguageDowngradePath(languageDowngradePath.iPath,aCurrentLanguage,idealLanguage, currentLocale);
+ 	aLanguageArray.Reset();
+  	const TLanguage* p=languageDowngradePath.iPath;
+  	while (*p != ELangNone)
+  		{
+		User::LeaveIfError(aLanguageArray.Append(*p));
+  		++p;
+  		}
+
+}
+
+
+//EXPORT_C 
+void LangUtil::GetEquivalentLanguageList(TLanguage aLang, TLanguagePath& aEquivalents){
+
+    aEquivalents[0] = aLang;
+	aEquivalents[1] = ELangNone;
+	const TInt len = sizeof(KEquivalentLists) / sizeof(KEquivalentLists[0]);
+	for (TInt i = 0; i < len; ++i)
+		{
+		const TLanguage *ptr = KEquivalentLists[i];
+		if (ptr[0] == aLang)
+			{
+			TInt index = 1;
+			while (ELangNone != *ptr)
+				{
+				aEquivalents[index++] = (TLanguage)*(++ptr);
+				}
+			aEquivalents[index] = ELangNone;
+			break;
+			} // end if ptr[0]
+		} // end for i
+
+}
+
+
+
+//EXPORT_C 
+TLanguage LangUtil::IdealLanguage(){
+
+		TLanguage* langPtr=(TLanguage*)Dll::Tls();
+	
+	if( langPtr==NULL)
+		{
+		return(ELangNone);
+		}
+
+	return(*langPtr);
+
+}
+
+
+//EXPORT_C 
+void LangUtil::NearestLanguageFile(const RFs& aFs, TFileName& aName){
+	
+	TLanguage language;
+	
+	NearestLanguageFile( aFs, aName, language);
+	
+	(void)language;
+
+}
+
+
+//EXPORT_C 
+void LangUtil::NearestLanguageFile(const RFs& aFs, TFileName& aName, TLanguage& aLanguage){
+#if defined(DO_PROFILING)
+	RDebug::ProfileReset(FIRST_PROFILE_INDEX, PROFILE_COUNT);
+	RDebug::ProfileStart(PROFILE_INDEX_1);
+#endif
+	TNearestLanguageFileFinder finder(aFs);
+	TBool goodSuffix=finder.SetFileName(aName);
+	
+	// Only continue if the suffix is good.
+	if(goodSuffix)
+		{
+		// add preset customised resource drive to drive list  
+		// Note that errors returned from AddCustomResourceDrive are ignored. This is because if 
+		// a custom resource drive has not been found we still want to continue on with searching 
+		// other drives according to our algorithm
+		finder.AddCustomResourceDrive();
+		
+		TLocale locale;
+		TLanguage idealLanguage;
+		idealLanguage = IdealLanguage();
+		MakeLanguageDowngradePath(finder.iPath, User::Language(), idealLanguage, locale);
+		if (!finder.FindLanguageAndDrive()
+			&& KErrNone != finder.FindFirstLanguageFileAndDrive())
+			finder.RepairFileName();
+		aLanguage = finder.Language();
+		}
+		
+#if defined(DO_PROFILING)
+	RDebug::ProfileEnd(PROFILE_INDEX_1);
+	TProfile profile[PROFILE_COUNT];
+	RDebug::ProfileResult(&profile[0], FIRST_PROFILE_INDEX, PROFILE_COUNT);
+	if(goodSuffix)
+		{
+		RDebug::Print(_L("BaflUtils::NearestLanguageFile profile info: %d.%03ds"), profile[PROFILE_INDEX_1-FIRST_PROFILE_INDEX].iTime/1000000, profile[PROFILE_INDEX_1-FIRST_PROFILE_INDEX].iTime%1000000);
+		}
+	else
+		{
+		RDebug::Print(_L("BaflUtils::NearestLanguageFile (bad suffix ) profile info: %d.%03ds"), profile[PROFILE_INDEX_1-FIRST_PROFILE_INDEX].iTime/1000000, profile[PROFILE_INDEX_1-FIRST_PROFILE_INDEX].iTime%1000000);
+		}
+#endif
+
+}
+
+
+//EXPORT_C 
+void LangUtil::NearestLanguageFileV2(const RFs& aFs, TFileName& aName, TLanguage& aLanguage){
+	
+	TNearestLanguageFileFinder finder(aFs);
+	TBool goodSuffix=finder.SetFileName(aName);
+	
+	// Continue only if the suffix is good.
+	if(goodSuffix)
+		{
+		// add preset customised resource drive to drive list  
+		// Note that errors returned from AddCustomResourceDrive are ignored. This is because if 
+		// a custom resource drive has not been found we still want to continue on with searching 
+		// other drives according to our algorithm
+		finder.AddCustomResourceDrive();
+		
+		GetEquivalentLanguageList(User::Language(), finder.iPath);
+		if (!finder.FindLanguageAndDrive()
+			&& KErrNone != finder.FindFirstLanguageFileAndDrive())
+			finder.RepairFileName();
+		aLanguage = finder.Language();
+		}
+	else
+		{
+		aLanguage = ELangNone;
+		}
+
+}
+
+
+//EXPORT_C 
+void LangUtil::ReleaseIdealLanguage(){
+
+	TLanguage* aLanguage=(TLanguage*)Dll::Tls();
+	if( aLanguage==NULL)
+		return;
+	
+	delete aLanguage;
+	Dll::FreeTls();
+
+}
+
+
+//EXPORT_C
+TInt LangUtil::SetIdealLanguage(TLanguage aLanguage){
+TLanguage* langPtr=(TLanguage*)Dll::Tls();
+	if( langPtr==NULL)
+		{
+		langPtr=(TLanguage*)User::Alloc(sizeof(TLanguage));
+		
+		if(!langPtr) 
+			return(KErrNoMemory);
+		
+		TInt ret=Dll::SetTls(langPtr);
+		
+		if(ret!=KErrNone)
+			return(ret);
+		}
+	*langPtr=aLanguage;
+	return(KErrNone);
+	
+}
+
+TInt RRealDirectoryScanner::Open(RFs& aFs, const TDesC& aMatchPattern)
+    {
+    return iDir.Open(aFs, aMatchPattern,
+        KEntryAttReadOnly | KEntryAttHidden | KEntryAttSystem | KEntryAttArchive);
+    }
+
+TInt RRealDirectoryScanner::Next(TEntry& aOut)
+    {
+    return iDir.Read(aOut);
+    }
+
+void RRealDirectoryScanner::Close()
+    {
+    iDir.Close();
+    }
+
+/**
+Simply counts the number of numerical characters at the end of the name passed.
+
+@internalComponent
+@param          aFilename The filename to parse
+                
+@return         Count of the numeric digits at the end of the name passed, 
+                e.g. x.r491 gives 3.
+*/
+TInt TNearestLanguageFileFinder::CountDigitsFromEnd(const TDesC& aFilename)
+    {
+    TInt digitCount = 0;
+    
+    for (TInt idx = aFilename.Length()-1; idx>=0 && ISDIGIT (aFilename [idx]); --idx)
+        {
+        ++digitCount;
+        }
+        
+    return digitCount;
+    }
+
+
+/**
+Counts the number of digits at the end of a filename.
+
+@internalComponent
+@param          aFilename The filename to parse
+                
+@return         Count of the numeric digits at the end of the suffix, 
+                e.g. x.r491 gives 3.
+                0 if no numeric end of suffix,
+                KErrBadName for an invalid filename,
+                KErrNotSupported if the filename (minus path) is less
+                than or equal to KInvNameAndMinSuffixLength in length
+*/
+TInt TNearestLanguageFileFinder::CountDigitsFromEndInSuffix (const TDesC& aFilename)
+    {
+    TInt digitCount = 0;
+    TInt slashIdx = 0;
+    TInt len = aFilename.Length ();
+    
+    // NOTE: We didn't use TChar here as they are too slow.
+    // We also didn't use TParse as they are too large.
+    
+    // don't work on the path
+    for (slashIdx=len-1; slashIdx >= 0 && aFilename[slashIdx] != '\\'; --slashIdx)
+    {/*do nothing*/};
+    
+    // Get new length
+    if (slashIdx>=0) {len = len-slashIdx-1;}
+
+    // Initial test to see if filename legal size.
+    if (len > KInvNameAndMinSuffixLength)
+        {
+        digitCount = CountDigitsFromEnd(aFilename);
+
+        // Can't store something bigger or we'll panic!
+        if (digitCount > KMaxSuffixLength)
+            {
+            digitCount = KErrBadName;
+            }
+        else
+        // numeric filename, e.g. "1234". 
+        // No preceeding alpha character
+        if (!(len-digitCount))
+            {
+            digitCount = KErrBadName;
+            }
+        }
+    else
+        {
+        digitCount = KErrNotSupported;
+        }
+        
+    return digitCount;
+    }
+
+RDirectoryScanner& TNearestLanguageFileFinder::DirectoryScanner()
+    {
+    return iDirScanner;
+    }
+
+TBool TNearestLanguageFileFinder::FileExists(const TDesC& aFileName) const
+    {
+    //return BaflUtils::FileExists(iFs, aFileName);
+    TEntry entry;
+    return(iFs.Entry(aFileName,entry)==KErrNone);
+    
+    }
+
+TBool TNearestLanguageFileFinder::FindDrive()
+    {
+    ASSERT(iFileName);
+    TBool found=EFalse;
+    TInt driveLength=iDrives.Length();
+    for (TInt drive = 0; drive!=driveLength; ++drive)
+        {
+        (*iFileName)[0] = iDrives[drive];
+        if (FileExists(*iFileName))
+            {
+            found=ETrue;
+            break;
+            }
+        }
+    return found;
+    }
+
+TBool TNearestLanguageFileFinder::AppendLanguageCode(TLanguage aLanguage)
+    {
+    TInt rest = static_cast<TInt>(aLanguage);
+#ifdef _DEBUG
+    _LIT(KErrorMessage, "Bafl");
+#endif
+    __ASSERT_DEBUG(0 <= rest, User::Panic(KErrorMessage,KErrArgument));
+    iFileName->SetLength(iBaseLength);
+    const TInt remaining = iFileName->MaxLength() - iBaseLength;
+    TInt soFar = 0;
+    TBuf<1> num;
+    num.Append('0');
+    TBool appendLangSuccess = ETrue;
+    TInt digitCount = 0;
+    TInt digit = 0;
+    while (rest)
+        {
+        if (remaining == soFar)
+            {
+            // no more room in descriptor- return rather than panic,
+            // file cannot exist.
+            iFileName->SetLength(iBaseLength);
+            appendLangSuccess= EFalse;
+            break;
+            }
+        // Convert the number to ASCII by consistantly getting the base 10 remainder to convert.
+        // The number is updated minus the remainder for the next iteration.
+        // eg (rest = 123) -> (12, r3) -> (1, r2) -> (0, r1)
+        // Then insert the ASCII representation of the remainder into the filename end
+        // so it appears the correct way round.
+        // eg (filename.r) -> (filename.r3) -> (filename.r23) -> (filename.r123)
+        digit = rest % 10;
+        digitCount++;
+        rest /= 10;
+        num[0] = static_cast<TText16>(digit + '0');
+        iFileName->Insert(iBaseLength, num);
+
+        // Minimum suffix length is KInvNameAndMinSuffixLength
+        // so we have to insert zeros to make this up.
+        while (!rest && digitCount < KInvNameAndMinSuffixLength)
+            {
+            num[0] = static_cast<TText16>('0');
+            iFileName->Insert(iBaseLength, num);
+            ++digitCount;
+            }
+            
+        ++soFar;
+        }
+        
+    return appendLangSuccess;
+    }
+
+
+TBool TNearestLanguageFileFinder::FindLanguageAndDrive()
+/** Search for files across all drives in all languages in the path plus the
+language-neutral file. */
+    {
+    ASSERT(iFileName);
+    // No point appending if the suffix is bad
+    for (const TLanguage* currentLang = iPath; *currentLang != ELangNone; ++currentLang)
+        {
+        if (AppendLanguageCode(*currentLang) && FindDrive())
+            {
+            iLanguage = *currentLang;
+            return ETrue;
+            }
+        }
+    // search for language-neutral file
+    iFileName->SetLength(iBaseLength);
+    iFileName->Append(iSuffix);
+    return FindDrive();
+    }
+
+TInt TNearestLanguageFileFinder::LanguageNumberFromFile(const TDesC& aFileName, const TDesC& aStem)
+    {
+    TInt lang = 0;
+    TInt multiplier = 1;
+    TInt leadingZeroCount = 0;
+    TInt languageNumber = KErrNotFound;
+    const TText* firstChar = aFileName.Ptr();
+    const TText* lastChar = firstChar + aFileName.Length() - 1;
+    const TText* currentChar = lastChar;
+    // string cannot contain only numbers, because it must have a ':' in it
+    while ('0' <= *currentChar && *currentChar <= '9')
+        {
+        if (*currentChar == '0')
+            leadingZeroCount++;
+        else
+            {
+            leadingZeroCount = 0;
+            lang += multiplier * (*currentChar - '0');
+            }
+        multiplier *= 10;
+        --currentChar;
+        }
+    TInt along=lastChar - currentChar;
+    if (2 <= along)
+        {
+        // We have at least 2 digits at the end.
+        // trim of bad leading zeros
+        TInt maxTrim = along - 2;
+        if (maxTrim < leadingZeroCount)
+            {
+            leadingZeroCount = maxTrim;
+            }
+        currentChar += leadingZeroCount;
+        // we have at least 2 digits at the end but does the rest of it match the stem?
+        TPtrC foundStem(firstChar, currentChar - firstChar + 1);
+        //foundStem.CompareF(aStem.Right(foundStem.Length()))
+        if (0 == foundStem.CompareF(aStem))
+            {
+            languageNumber=lang;
+            }
+        }
+    return languageNumber;
+    }
+
+TInt TNearestLanguageFileFinder::FindFirstLanguageFile(RFs& aFs)
+    {
+    ASSERT(iFileName);
+    iFileName->SetLength(iBaseLength);
+    TPtrC name(*iFileName);
+    TParsePtrC nameToParse(name);
+    TPtrC nameStem(nameToParse.NameAndExt());
+    iFileName->Append('*');
+    TInt bestLanguageMatch = KMaxTInt;
+    RDirectoryScanner& scanner = DirectoryScanner();
+    TInt err = scanner.Open(aFs, *iFileName);
+    if (err != KErrNone)
+        {
+        return err;
+        }
+    TEntry entry;
+    while (KErrNone == scanner.Next(entry))
+        {
+        TInt lang = LanguageNumberFromFile(entry.iName, nameStem);
+        if (0 < lang && lang < bestLanguageMatch)
+            {
+            bestLanguageMatch = lang;
+            }
+        }
+    scanner.Close();
+    if (bestLanguageMatch != KMaxTInt)
+        {
+        iLanguage = static_cast<TLanguage>(bestLanguageMatch);
+        AppendLanguageCode(static_cast<TLanguage>(bestLanguageMatch));
+        return KErrNone;
+        }
+    return KErrNotFound;
+    }
+
+// Try each drive for any language files
+// iFileName must have a directory specifier
+TInt TNearestLanguageFileFinder::FindFirstLanguageFileAndDrive()
+    {
+    ASSERT(iFileName);
+    TInt findFirstResult=KErrNotFound;
+    TInt driveLength=iDrives.Length();
+    for (TInt drive = 0; drive != driveLength; ++drive)
+        {
+        (*iFileName)[0] = iDrives[drive];
+        TInt err = FindFirstLanguageFile(CONST_CAST(RFs&,iFs));
+        if (err == KErrNone || err == KErrNoMemory)
+            {
+            findFirstResult=err;
+            break;
+            }
+        }
+    return findFirstResult;
+    }
+
+/**
+Invalid filenames are any filename whose length (minus path) must be greater
+than KInvNameAndMinSuffixLength, and whose form is purely numerical, i.e. '1234' 
+*/
+TBool TNearestLanguageFileFinder::SetFileName(TFileName& aFileName)
+    {
+    iDrives.Zero();
+    iFileName = &aFileName;
+    iOriginalBaseLength = iFileName->Length();
+    
+    TInt suffixLength = CountDigitsFromEndInSuffix (aFileName);
+    
+    // No point trying for filenames thats are badly formed
+    // or that are too large.
+    if (suffixLength >= 0 && 
+        KInvNameAndMinSuffixLength < iOriginalBaseLength)
+        {
+        if (suffixLength > 0)
+            {
+            // all of suffix to be replaced 
+            iSuffix = iFileName->Right(suffixLength);
+            iOriginalBaseLength -= suffixLength;
+            iFileName->SetLength(iOriginalBaseLength);
+            }
+        else
+            { 
+            // No numerical part to suffix
+            TInt periodIdx = 0;
+            
+            // Search for the period within range KInvNameAndMinSuffixLength 
+            // from the end. As this must work for all values of
+            // KInvNameAndMinSuffixLength
+            for (TInt i = iOriginalBaseLength-1; 
+                 !periodIdx && i >= (iOriginalBaseLength-KInvNameAndMinSuffixLength-1);
+                 --i)
+                {
+                if ((*iFileName) [i] == '.')
+                    {
+                    periodIdx = i;
+                    }
+                }
+            
+            // Don't handle files ending in a period.
+            // This is because the behaviour is different between Windows
+            // and Symbian Fs. In Windows it strips the period off.
+            //
+            // However, and this shouldn't happen as it is not shown
+            // (in the documentation) to be valid.
+            // Just try our best.
+            if (periodIdx == iOriginalBaseLength-1)
+                {
+                iSuffix.Zero();
+                return EFalse;
+                }
+            else
+            if (periodIdx)
+                {
+                // If there are KInvNameAndMinSuffixLength chars after the period
+                // simply replace them.
+                TInt right = iOriginalBaseLength-periodIdx-1;
+                iSuffix = iFileName->Right(right);
+                iOriginalBaseLength -= right;
+                iFileName->SetLength(iOriginalBaseLength);                  
+                }
+            else
+                {
+                // Make the suffix start from KInvNameAndMinSuffixLength 
+                // from the right
+                TInt right = KInvNameAndMinSuffixLength;
+                iSuffix = iFileName->Right(right);
+                iOriginalBaseLength -= right;
+                iFileName->SetLength(iOriginalBaseLength);                  
+                }
+            }
+        }
+    else
+        {
+        // bad or no suffix - treat the same
+        iSuffix.Zero();
+        return EFalse;
+        }
+
+    // For filenames with no drive letter prefix and also for filenames
+    // shorter than the drive letter length, i.e. with no drive
+    // information, insert it.
+    // Handles if the user simply enters the drive, e.g. "c:".
+    if (iOriginalBaseLength < KMaxDriveName || (*iFileName)[1] != ':')
+        {
+        // Set up the default if none supplied and make room in the filename 
+        // array to contain a drive specification. Set initial drive letter to -1
+        // so the iFileName is repaired before exited 
+        iInitialDriveLetter = -1;
+        iFileName->Insert(0, _L("_:")); 
+        iDrives.Append('Z');
+        }
+    else
+        {
+       // Use the drive supplied inthe aName to NearestLanguageFile()
+        iInitialDriveLetter = (*iFileName)[0];
+        iDrives.Append(iInitialDriveLetter);
+        }
+    
+    iBaseLength = iFileName->Length();
+    
+    return ETrue;
+    }
+
+
+TLanguage TNearestLanguageFileFinder::Language()
+    {
+    return iLanguage;
+    }
+
+TNearestLanguageFileFinder::TNearestLanguageFileFinder(
+    const RFs& aFs)
+    : iFs(aFs), iFileName(0), iLanguage(ELangNone)
+    {
+    }
+
+void TNearestLanguageFileFinder::RepairFileName()
+    {
+    ASSERT(iFileName);
+    iFileName->SetLength(iBaseLength);
+    if (iInitialDriveLetter == -1)
+        iFileName->Delete(0, 2);
+    else
+        (*iFileName)[0] = static_cast<TText>(iInitialDriveLetter);
+    iFileName->SetLength(iOriginalBaseLength);
+    iFileName->Append(iSuffix);
+    }
+
+
+/**
+Add the custom resource drive to the start of the iDrives string.
+
+The custom resource drive is a preset writeable drive on which customised 
+resource files may be present. This drive takes priority over the other 
+drives when searching for language files.
+
+@return KErrNone if iDrives string was successfully modified; KErrAlreadyExists 
+if the drive is already present in the string; otherwise one of 
+the other system-wide error codes (iDrives will be unmodified). 
+*/
+TInt TNearestLanguageFileFinder::AddCustomResourceDrive()
+    {
+    TInt drive = GetCustomResourceDriveNumber();
+    if (drive<0)
+        return drive;
+    
+    // if drive not already in drive list
+    if (iDrives.LocateF('A' + drive) < 0)
+        {
+        // add it
+        _LIT(KDrivePlaceholder, "_");
+        iDrives.Insert(0, KDrivePlaceholder);
+        iDrives[0] = 'A' + drive;
+        return KErrNone;
+        }
+    else
+        return KErrAlreadyExists;
+    }
+
+
+void TNearestLanguageFileFinder::AddAllDrives()
+    {
+    ASSERT(iDrives.Length() < 2);
+    if (iDrives.Length() == 0)
+        {
+        iDrives = KAllDrives;
+        return;
+        }
+    TInt pos = KAllDrives().LocateF(iDrives[0]);
+    if (pos < 0)
+        {
+        iDrives = KAllDrives;
+        return;
+        }
+    iDrives.Append(KAllDrives().Left(pos));
+    iDrives.Append(KAllDrives().Mid(pos + 1));
+    }
+
+
+/**
+Get the value of the custom resource drive.
+
+The custom resource drive is a preset writeable drive on which customised language resource 
+files can reside. The drive number is accessed via the HAL attribute ECustomResourceDrive. 
+It is then returned if it has been defined as a valid drive no.
+Otherwise for backward compatibility reasons an attempt is then made to access the system 
+drive HAL attribute instead. This drive number is returned if it has been defined as a valid 
+drive number.  
+Otherwise if neither a valid ECustomResourceDrive or ESystemDrive exists then KErrNotFound 
+is returned.
+ 
+Note that the ESystemDrive HAL attribute has been deprecated. It is accessed here to cater 
+for existing implementations which still expect it to be used.
+ 
+@return The drive number (corresponding to a TDriveNumber value) if successful; 
+KErrNotFound if neither a valid ECustomResourceDrive or a valid ESystemDrive HAL attribute 
+is defined;  
+ 
+@see HAL::ECustomResourceDrive
+@see HAL::ESystemDrive
+*/
+TInt TNearestLanguageFileFinder::GetCustomResourceDriveNumber() const
+    {
+    TInt drive = KErrNotFound;
+    
+    // access custom resource drive attribute  
+    if (HAL::Get(HAL::ECustomResourceDrive, drive) == KErrNone)
+        {
+        // check that drive is valid
+        if (drive>=EDriveA && drive<=EDriveZ)
+            return drive;    
+        }
+                        
+    // access system drive attribute  
+    // (Note that ESystemDrive is deprecated. It is checked here 
+    // solely for backward compatibility reasons.)      
+    if (HAL::Get(HAL::ESystemDrive, drive) == KErrNone)
+        {
+        // check that drive is valid
+        if (drive>=EDriveA && drive<=EDriveZ)
+                return drive;
+        }       
+ 
+    return KErrNotFound;
+    }
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/src/LangUtilImpl.h	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,148 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#ifndef __LANGUTILIMPL_H__
+#define __LANGUTILIMPL_H__
+
+
+#include <f32file.h>
+#include <e32std.h>
+
+/**
+Specifies the maximum length of the numerical part of the suffix.
+
+If this is changed the documentation of the following functions 
+must also be updated:
+
+	LangUtil::NearestLanguageFile()
+	TNearestLanguageFileFinder::CountDigitsFromEndInValidSuffix()
+	TNearestLanguageFileFinder::SetFileName()
+*/
+const TInt KMaxSuffixLength = 5;
+
+class RDirectoryScanner
+/**
+@internalAll
+*/
+    {
+public:
+    virtual TInt Open(RFs& aFs, const TDesC& aMatchPattern) = 0;
+    virtual TInt Next(TEntry& aOut) = 0;
+    virtual void Close() = 0;
+    virtual ~RDirectoryScanner() {}
+    };
+
+NONSHARABLE_CLASS(RRealDirectoryScanner) : public RDirectoryScanner
+/**
+@internalAll
+*/
+    {
+public:
+    virtual TInt Open(RFs& aFs, const TDesC& aMatchPattern);
+    virtual TInt Next(TEntry& aOut);
+    virtual void Close();
+private:
+    RDir iDir;
+    };
+
+
+/**
+ * Add a language to the end of the language path, unless it is already
+ * present. On entry, the language path must have an ELangNone entry at its
+ * end. This will be true on exit also.
+ * @internalAll
+ */
+void AddLanguage(TLanguagePath& aPath, TLanguage aNewLanguage);
+
+/**
+ * Create a language path from the current language, ideal language and locale. 
+ * The path may have up to eight entries in it.
+ * @internalAll
+ */
+
+void MakeLanguageDowngradePath(TLanguagePath& aPath,
+	TLanguage aCurrent, TLanguage aIdeal, const TLocale& aLocale);
+
+
+/**
+ * This class contains all the functions for working out the nearest language
+ * file. It can be derived from for test code purposes.
+ * @internalAll
+ */
+NONSHARABLE_CLASS(TNearestLanguageFileFinder)
+	{
+public:
+	TNearestLanguageFileFinder(const RFs& aFs);
+	TBool SetFileName(TFileName& aFileName);
+	TLanguage Language();
+	// put back the original suffix and drive letter
+	void RepairFileName();
+	// add the preset custom resource drive, if any, to iDrives.
+	TInt AddCustomResourceDrive();
+	// add all remaining drives to iDrives. iDrives must not have more than one
+	// drive in it on entry.
+	void AddAllDrives();
+	// Tries to append the language code to iFileName. This is 00..09 or just the number.
+	// If there was not enough space, EFalse is returned.
+	TBool AppendLanguageCode(TLanguage aLanguage);
+	// Search the drives in iDrives for the file named iFileName.
+	// iFileName must have a drive specifier, which will be overwritten.
+	TBool FindDrive();
+	// Search for files across all drives in all languages in the path plus the
+	// language-neutral file.
+	// On entry, iFileName should be the original name with a drive specifier
+	// minus the suffix. On return, iFileName will be untouched if EFalse is
+	// returned, but contain the result if ETrue is returned.
+	TBool FindLanguageAndDrive();
+	// Test whether the filename passed in matches the stem given + numbers
+	// added to the end. Returns the number if it does, or KErrNotFound if not.
+	// aFileName must not end in a digit.
+	static TInt LanguageNumberFromFile(const TDesC& aFileName, const TDesC& aStem);
+	// Find lowest numbered file that matches iFileName, which must be without
+	// its suffix.
+	TInt FindFirstLanguageFile(RFs&);
+	// Try each drive for any language files that match iFileName.
+	// iFileName must have a directory specifier and be without its suffix.
+	// returns KErrNotFound, KErrNone or error code.
+	TInt FindFirstLanguageFileAndDrive();
+
+	virtual TInt GetCustomResourceDriveNumber() const;
+	
+	virtual TInt FileExists(const TDesC& aFileName) const;
+	// return our member that is our directory scanning class
+	virtual RDirectoryScanner& DirectoryScanner();
+	virtual ~TNearestLanguageFileFinder() {}
+	
+private:
+	TInt CountDigitsFromEnd(const TDesC& aFilename);
+	TInt CountDigitsFromEndInSuffix (const TDesC& aFilename);
+
+public:
+	const RFs& iFs;
+	TFileName* iFileName;
+	TLanguage  iLanguage;
+	TBuf<26> iDrives;
+	TLanguagePath iPath;
+	TBuf<KMaxSuffixLength> iSuffix;
+	TInt iInitialDriveLetter;
+	// length minus the removed suffix
+	TInt iOriginalBaseLength;
+	// length plus added drive letter minus removed suffix
+	TInt iBaseLength;
+	RRealDirectoryScanner iDirScanner;
+	};
+
+#endif // __LANGUTILIMPL_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_All_langutils.bat	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,4 @@
+@echo on
+testexecute.exe z:\test\T_All_langutils.script
+@echo off
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_All_langutils.script	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,6 @@
+PRINT Run All T_LangUtilsServer tests
+//
+LOAD_SUITE T_LangUtilsServer
+RUN_TEST_STEP 100 T_LangUtilsServer T_LANGUTILS
+RUN_TEST_STEP 100 T_LangUtilsServer T_LANGUTILSIMP
+RUN_TEST_STEP 100 T_LangUtilsServer T_LANGUTILSLANG
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtils.MMP	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,37 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+// T_CLIPB.MMP for test component T_CLIPB (released in BAFL)
+// 
+//
+
+target          T_LangUtils.exe
+targettype      EXE
+UID		0x1000007a
+
+SOURCEPATH	../tsrc
+userinclude   ../inc
+userinclude ../src
+userinclude ../tsrc
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+source  /T_LangUtils.cpp
+source  /T_LangUtilsTestShareFunc.cpp
+
+STATICLIBRARY  langutil.lib
+library euser.lib hal.lib efsrv.lib estor.lib centralrepository.lib
+
+CAPABILITY WriteDeviceData
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtils.cpp	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,425 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+
+#include <baclipb.h>
+#include <f32file.h>
+#include <s32strm.h>
+#include <s32file.h>
+#include <e32lang.h>
+#include <langutil.h>
+#include "LangUtilImpl.h"
+#include "T_LangUtilsTestShareFunc.h"
+#include "t_langutils.h"
+
+
+
+#define test(cond)                                          \
+    {                                                       \
+    TBool __bb = (cond);                                    \
+    TEST(__bb);                                             \
+    if (!__bb)                                              \
+        {                                                   \
+        ERR_PRINTF1(_L("ERROR: Test Failed"));              \
+        User::Leave(1);                                     \
+        }                                                   \
+    }
+
+// File names for copying
+
+const TPtrC KSystem1Folder              =_L("C:\\System1\\");
+const TPtrC KSystem1Data1Folder         =_L("C:\\System1\\data1\\");
+
+const TPtrC KSystem1Data1File1          =_L("C:\\System1\\data1\\file1.txt");
+const TPtrC KFile1                      =_L("C:\\file1.txt");
+const TPtrC KSystem1Data1SrcFile1       =_L("C:\\System1\\data1\\src\\file1.txt");
+const TPtrC KSystem1Data1DstFile2       =_L("C:\\System1\\data1\\dst\\file2.txt");
+const TPtrC KSystem1Data1File123456789  =_L("C:\\System1\\data1\\file123456789.txt");
+const TPtrC KSystem1Data1File2          =_L("C:\\System1\\data1\\file2.txt");
+const TPtrC KSystem1Data1File5          =_L("C:\\System1\\data1\\file5.txt");
+const TPtrC KSystem1Data1SrcFolder      =_L("C:\\System1\\data1\\src\\");
+const TPtrC KSystem1Data1DstFolder      =_L("C:\\System1\\data1\\dst\\");
+
+const TPtrC KZFile1                     =_L("Z:\\file1.txt");
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////
+//LangUtil::GetEquivalentLanguageList
+//LangUtil::NearestLanguageFileV2 
+//test data
+_LIT (KNullFilename, "");
+_LIT (KRscFilename,  "C:\\geltest.rsc");
+_LIT (KRscFilenameNoSuffix,  "C:\\geltest.");
+
+_LIT (KAmericanLang, "C:\\geltest.r10");
+_LIT (KFrenchLang,   "C:\\geltest.r02");
+_LIT (KJapanEnglishLang, "C:\\geltest.r160");
+_LIT (KEnglishLang, "C:\\geltest.r01");
+_LIT (KInvalidDriveLetterV2, "q:\\geltest.rsc");
+_LIT (KNoSuchLangFile, "c:\\geltest.r54");
+
+
+//Delete "aFullName" file.
+void CT_LANGUTILS::DeleteTestFile(const TDesC& aFullName)
+    {
+    RFs fsSession;
+    TInt err = fsSession.Connect();
+    if(err == KErrNone)
+        {
+        TEntry entry;
+        if(fsSession.Entry(aFullName, entry) == KErrNone)
+            {
+            INFO_PRINTF2(_L("Deleting \"%S\" file.\n"), &aFullName);
+            err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
+            if(err != KErrNone)
+                {
+                INFO_PRINTF3(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
+                }
+            err = fsSession.Delete(aFullName);
+            if(err != KErrNone)
+                {
+                INFO_PRINTF3(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
+                }
+            }
+        fsSession.Close();
+        }
+    else
+        {
+        INFO_PRINTF3(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
+        }
+    }
+
+//Delete "aFullName" dir.
+void CT_LANGUTILS::DeleteTestDir(const TDesC& aFullName)
+    {
+    RFs fsSession;
+    TInt err = fsSession.Connect();
+    if(err == KErrNone)
+        {
+        TEntry entry;
+        if(fsSession.Entry(aFullName, entry) == KErrNone)
+            {
+            INFO_PRINTF2(_L("Deleting \"%S\" dir.\n"), &aFullName);
+            err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
+            if(err != KErrNone)
+                {
+                INFO_PRINTF3(_L("Error %d changing \"%S\" dir attributes.\n"), err, &aFullName);
+                }
+            err = fsSession.RmDir(aFullName);
+            if(err != KErrNone)
+                {
+                INFO_PRINTF3(_L("Error %d deleting \"%S\" dir.\n"), err, &aFullName);
+                }
+            }
+        fsSession.Close();
+        }
+    else
+        {
+        INFO_PRINTF3(_L("Error %d connecting file session. Dir: %S.\n"), err, &aFullName);
+        }
+    }
+
+//Delete data files used by the test
+void CT_LANGUTILS::DeleteTestFiles()
+    {
+        DeleteTestFile(KSystem1Data1File1);
+        DeleteTestFile(KFile1);
+        DeleteTestFile(KSystem1Data1SrcFile1);
+        DeleteTestFile(KSystem1Data1DstFile2);
+        DeleteTestFile(KSystem1Data1File123456789);
+        DeleteTestFile(KSystem1Data1File2);
+        DeleteTestFile(KSystem1Data1File5);
+        DeleteTestDir(KSystem1Data1SrcFolder);
+        DeleteTestDir(KSystem1Data1DstFolder);
+        DeleteTestDir(KSystem1Data1Folder);
+        DeleteTestDir(KSystem1Folder);
+    }
+
+
+
+
+void CT_LANGUTILS::DeleteTestFiles2(RFs &aFs)
+{
+    LangUtilsTest::DeleteFile (aFs, KRscFilename);
+    LangUtilsTest::DeleteFile (aFs, KAmericanLang);
+    LangUtilsTest::DeleteFile (aFs, KFrenchLang);
+    LangUtilsTest::DeleteFile (aFs, KJapanEnglishLang);
+    LangUtilsTest::DeleteFile (aFs, KEnglishLang);
+}
+
+void CT_LANGUTILS::CreateTestFiles2(RFs &aFs)
+{
+    test(LangUtilsTest::FileExists (aFs, KRscFilename) == EFalse);
+    test(LangUtilsTest::FileExists (aFs, KAmericanLang) == EFalse);
+    test(LangUtilsTest::FileExists (aFs, KFrenchLang) == EFalse);
+    test(LangUtilsTest::FileExists (aFs, KJapanEnglishLang) == EFalse);
+    test(LangUtilsTest::FileExists (aFs, KEnglishLang) == EFalse);
+
+    // Create the files...
+    RFile rFile;
+    test(KErrNone == rFile.Create (aFs, KRscFilename, EFileRead));
+    rFile.Close ();
+    test(KErrNone == rFile.Create (aFs, KAmericanLang, EFileRead));
+    rFile.Close ();
+    test (KErrNone == rFile.Create (aFs, KFrenchLang, EFileRead));
+    rFile.Close ();
+    test(KErrNone == rFile.Create (aFs, KEnglishLang, EFileRead));
+    rFile.Close ();
+}
+///////////////////////////////////////////////////////////////////////////////////////
+//Copy test file from Z: to C: drive.
+
+void CT_LANGUTILS::CopyTestFiles()
+    {
+    RFs fsSession;
+    TInt err = fsSession.Connect();
+    if(err == KErrNone)
+        {
+        User::LeaveIfError(fsSession.MkDir(KSystem1Folder));
+        User::LeaveIfError(fsSession.MkDir(KSystem1Data1Folder));
+        test( LangUtilsTest::CopyFile(fsSession, KZFile1, KSystem1Data1File1) == KErrNone);
+        test( LangUtilsTest::CopyFile(fsSession, KZFile1, KFile1) == KErrNone);
+        test( LangUtilsTest::CopyFile(fsSession, KZFile1, KSystem1Data1File123456789) == KErrNone);
+        test( LangUtilsTest::CopyFile(fsSession, KZFile1, KSystem1Data1File2) == KErrNone);
+        test( LangUtilsTest::CopyFile(fsSession, KZFile1, KSystem1Data1File5) == KErrNone);
+        User::LeaveIfError(fsSession.MkDir(KSystem1Data1SrcFolder));
+        User::LeaveIfError(fsSession.MkDir(KSystem1Data1DstFolder));
+        test( LangUtilsTest::CopyFile(fsSession, KZFile1, KSystem1Data1SrcFile1) == KErrNone);
+        test( LangUtilsTest::CopyFile(fsSession, KZFile1, KSystem1Data1DstFile2) == KErrNone);
+
+        fsSession.Close();
+        }
+    else
+        {
+        INFO_PRINTF2(_L("Error %d connecting file session.\n"), err);
+        }
+    }
+
+
+
+
+
+/**
+@SYMTestCaseID TI18N-BAFL-CT-4003
+@SYMTestCaseDesc Tests Baflutils::TestNearestLanguageFileV2.
+@SYMTestPriority Medium
+@SYMTestActions Pass in various resource file names and change system locale setting, check the return values.
+@SYMTestExpectedResults The test must not fail.
+@SYMPREQ 2525 Install device equivalent languages from SIS files
+*/
+void CT_LANGUTILS::TestNearestLanguageFileV2(RFs& aFs)
+    {
+    /* test case ID to be added */
+    INFO_PRINTF1(_L (" @SYMTestCaseID TI18N-BAFL-CT-4003 "));
+    
+    __UHEAP_MARK;
+
+    CleanupClosePushL (aFs);
+    User::LeaveIfError (aFs.Connect ());
+    
+    DeleteTestFiles2(aFs);
+    CreateTestFiles2(aFs);
+
+    TBuf <256> filename;
+    TLanguage lang = ELangNone;
+    INFO_PRINTF2 (_L("lang initial value is %d\n"), lang);
+
+    // Test NearestLanguageFile with empty name
+    TFileName resPath;
+    LangUtil::NearestLanguageFileV2(aFs, resPath, lang);
+    test(resPath.Length()==0);
+    INFO_PRINTF2 (_L("lang returned by NLFV2 is %d\n"), lang);
+    test(ELangNone == lang);
+    INFO_PRINTF3 (_L ("The NearestLanguageFile for the null file - %S - is - %S -\n"), &KNullFilename, &filename);
+    
+    // Test NearestLanguageFile with invalid drive letter
+    filename.Copy (KInvalidDriveLetterV2);
+    LangUtil::NearestLanguageFileV2(aFs, filename, lang);
+    //test(filename==KRscFilenameNoSuffix);
+    INFO_PRINTF4 (_L ("The NearestLanguageFile for %S is %S, lang is %d\n"), &KInvalidDriveLetterV2, &filename, lang);
+    //test(ELangNone == lang);
+    
+    // Test NearestLanguageFile with incorrect ext
+    DeleteTestFiles2(aFs);
+    RFile rFile;
+    test (KErrNone == rFile.Create (aFs, KFrenchLang, EFileRead));
+    rFile.Close ();
+    filename.Copy (KNoSuchLangFile);
+    LangUtil::NearestLanguageFileV2(aFs, filename, lang);
+    //test(filename==KRscFilenameNoSuffix);
+    INFO_PRINTF4 (_L ("The NearestLanguageFile for %S is %S, lang is %d\n"), &KNoSuchLangFile, &filename, lang);
+    //test(ELangNone == lang);
+    LangUtilsTest::DeleteFile (aFs, KFrenchLang);
+    CreateTestFiles2(aFs);
+        
+    // Test NearestLanguageFile with no suffix
+    filename.Copy (KRscFilenameNoSuffix);
+    LangUtil::NearestLanguageFileV2(aFs, filename, lang);
+    test(filename==KRscFilenameNoSuffix);
+    INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilenameNoSuffix, &filename);
+    test(ELangNone == lang);
+    
+    // change locale to American
+	/*
+    TExtendedLocale loc;
+    loc.LoadSystemSettings();
+    TInt ret = loc.LoadLocaleAspect(_L ("elocl_lan.010"));
+    INFO_PRINTF2(_L("LoadLocale returns %d\n"), ret);
+    test(KErrNone == ret);
+    ret = loc.SaveSystemSettings();
+    test(KErrNone == ret);
+    
+    // Test NearestLanguageFile: AmE is supported
+    filename.Copy (KRscFilename);
+    LangUtil::NearestLanguageFileV2(aFs, filename, lang);
+    INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilename, &filename);
+    //test(filename == KEnglishLang);
+    test(filename == KAmericanLang);
+    test(lang == ELangAmerican);
+
+    // Delete geltest.r10, AmE downgrades to En_GB.
+    LangUtilsTest::DeleteFile (aFs, KAmericanLang);
+    filename.Copy (KRscFilename);
+    LangUtil::NearestLanguageFileV2(aFs, filename, lang);
+    INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilename, &filename);
+    test(filename == KEnglishLang);
+    test(lang == ELangEnglish);
+    
+    
+    // Delete geltest.r01, AmE downgrades to en_GB, to ELangNone.
+    LangUtilsTest::DeleteFile (aFs, KEnglishLang);
+    filename.Copy (KRscFilename);
+    LangUtil::NearestLanguageFileV2(aFs, filename, lang);
+    INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilename, &filename);
+    test(filename == KRscFilename); // filename remains unchanged.
+    test(lang == ELangNone);
+
+    // restore locale settings
+    INFO_PRINTF1(_L("Restoring locale settings.\n"));
+    loc.LoadSystemSettings();
+    ret = loc.LoadLocaleAspect(_L("elocl_lan.001"));
+    test(KErrNone == ret);
+    ret = loc.SaveSystemSettings();
+    test(KErrNone == ret);
+	*/
+    
+    CleanupStack::PopAndDestroy (&aFs);
+
+    __UHEAP_MARKEND;
+    }
+
+/**
+@SYMTestCaseID TI18N-BAFL-CT-4004
+@SYMTestCaseDesc Tests Baflutils::TestGetEquivalentLanguageList.
+@SYMTestPriority Medium
+@SYMTestActions Pass in various language ID's and check the returned list.
+@SYMTestExpectedResults The test must not fail.
+@SYMPREQ 2525 Install device equivalent languages from SIS files
+*/
+void CT_LANGUTILS::TestGetEquivalentLanguageList()
+    {
+    /* test case ID to be added */
+    INFO_PRINTF1 (_L (" @SYMTestCaseID TI18N-BAFL-CT-4004 "));
+    
+    __UHEAP_MARK;
+    
+    TLanguagePath lp;
+    // Test GetNearestLanguageFile();
+    // 1- There is an entry in the table for the given language
+    LangUtil::GetEquivalentLanguageList(ELangCyprusGreek, lp);
+    test(ELangCyprusGreek == lp[0]);
+    test(ELangGreek == lp[1]);
+    test(ELangNone == lp[2]);
+    
+    // 2- There is no entry for the given language
+    LangUtil::GetEquivalentLanguageList(ELangFarsi, lp);
+    test(ELangFarsi == lp[0]);
+    test(ELangNone == lp[1]);
+
+    __UHEAP_MARKEND;
+    }
+
+/**
+@SYMTestCaseID TI18N-BAFL-CT-4004
+@SYMTestCaseDesc Tests Baflutils::TestGetDowngradePathL.
+@SYMTestPriority Medium
+@SYMTestActions Pass in various language ID's and check the returned list.
+@SYMTestExpectedResults The test must not fail.
+@SYMPREQ 2525 Install device equivalent languages from SIS files
+*/
+void CT_LANGUTILS::TestGetDowngradePathL()
+    {
+    RFs fsSession;
+    TInt err = fsSession.Connect();
+    if(err == KErrNone)
+        {
+        TLanguage currentLang = ELangPrcChinese;
+        RArray<TLanguage> languageArray;
+        LangUtil::GetDowngradePathL(fsSession, currentLang,languageArray);
+        fsSession.Close();
+        test(ELangPrcChinese == languageArray[0]);
+        test(1 == languageArray.Count());
+        languageArray.Close();
+        }
+    else
+        {
+        INFO_PRINTF2(_L("Error %d connecting file session. "), err);
+        }
+    }
+
+/**
+@SYMTestCaseID SYSLIB-BAFL-CT-0038
+@SYMTestCaseDesc Tests Baflutils.
+@SYMTestPriority Medium
+@SYMTestActions Executes all T_baflutils tests.
+@SYMTestExpectedResults The test must not fail.
+@SYMDEF DEF050397 - Crimson test code improvement to be propagated into MCL
+*/
+void CT_LANGUTILS::TestLANGUTILS()
+    {
+    RFs fs;
+
+    CopyTestFiles();
+    TestNearestLanguageFileV2(fs);
+    TestGetEquivalentLanguageList();
+    TestGetDowngradePathL();
+
+    DeleteTestFiles();
+    }
+
+CT_LANGUTILS::CT_LANGUTILS()
+    {
+    SetTestStepName(KTestStep_T_LANGUTILS);
+    }
+
+TVerdict CT_LANGUTILS::doTestStepL()
+    {
+    SetTestStepResult(EFail);
+
+    __UHEAP_MARK;
+
+    TRAPD(error1, TestLANGUTILS());
+
+    __UHEAP_MARKEND;
+
+    if(error1 == KErrNone )
+        {
+        SetTestStepResult(EPass);
+        }
+
+    return TestStepResult();
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtilsImp.cpp	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,639 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "t_langutilsimp.h"
+
+
+#define test(cond)                                          \
+    {                                                       \
+    TBool __bb = (cond);                                    \
+    TEST(__bb);                                             \
+    if (!__bb)                                              \
+        {                                                   \
+        ERR_PRINTF1(_L("ERROR: Test Failed"));              \
+        User::Leave(1);                                     \
+        }                                                   \
+    }
+
+
+
+void CT_LANGUTILSIMP::TestPath(const TLanguagePath& aPath, const TLanguage* aExpected, TInt aExpectedCount)
+    {
+    for (int i = 0; i != aExpectedCount; ++i)
+        test(aPath[i] == *aExpected++);
+    test(aPath[aExpectedCount] == ELangNone);
+    }
+
+const TLanguage ExpectedPath[] = { ELangFrench, ELangJapanese, ELangGerman, ELangGreek,
+    ELangArabic, ELangEnglish, ELangItalian, ELangHebrew };
+
+/**
+@SYMTestCaseID          SYSLIB-BAFL-CT-0443
+@SYMTestCaseDesc        Tests TLanguagePath class
+@SYMTestPriority        High
+@SYMTestActions         Test for adding different language paths
+@SYMTestExpectedResults Test must not fail
+@SYMREQ                 REQ0000
+*/
+void CT_LANGUTILSIMP::TestAddLanguage()
+    {
+    INFO_PRINTF1(_L(" @SYMTestCaseID:SYSLIB-BAFL-CT-0443 "));
+    TLanguagePath path;
+    path[0] = ELangNone;
+    AddLanguage(path, ELangNone);
+    TestPath(path, ExpectedPath, 0);
+    AddLanguage(path, ELangFrench);
+    TestPath(path, ExpectedPath, 1);
+    AddLanguage(path, ELangFrench);
+    TestPath(path, ExpectedPath, 1);
+    AddLanguage(path, ELangNone);
+    TestPath(path, ExpectedPath, 1);
+    AddLanguage(path, ELangFrench);
+    TestPath(path, ExpectedPath, 1);
+    AddLanguage(path, ELangJapanese);
+    TestPath(path, ExpectedPath, 2);
+    AddLanguage(path, ELangFrench);
+    TestPath(path, ExpectedPath, 2);
+    AddLanguage(path, ELangNone);
+    TestPath(path, ExpectedPath, 2);
+    AddLanguage(path, ELangGerman);
+    TestPath(path, ExpectedPath, 3);
+    AddLanguage(path, ELangGreek);
+    TestPath(path, ExpectedPath, 4);
+    AddLanguage(path, ELangArabic);
+    TestPath(path, ExpectedPath, 5);
+    AddLanguage(path, ELangNone);
+    TestPath(path, ExpectedPath, 5);
+    AddLanguage(path, ELangEnglish);
+    TestPath(path, ExpectedPath, 6);
+    AddLanguage(path, ELangItalian);
+    TestPath(path, ExpectedPath, 7);
+    AddLanguage(path, ELangNone);
+    TestPath(path, ExpectedPath, 7);
+    AddLanguage(path, ELangHebrew);
+    TestPath(path, ExpectedPath, 8);
+    AddLanguage(path, ELangHebrew);
+    TestPath(path, ExpectedPath, 8);
+    AddLanguage(path, ELangEnglish);
+    TestPath(path, ExpectedPath, 8);
+    AddLanguage(path, ELangItalian);
+    TestPath(path, ExpectedPath, 8);
+    AddLanguage(path, ELangNone);
+    TestPath(path, ExpectedPath, 8);
+    AddLanguage(path, ELangFrench);
+    TestPath(path, ExpectedPath, 8);
+    AddLanguage(path, ELangNone);
+    TestPath(path, ExpectedPath, 8);
+    AddLanguage(path, ELangGerman);
+    TestPath(path, ExpectedPath, 8);
+    }
+
+
+
+/**
+@SYMTestCaseID          SYSLIB-BAFL-CT-0444
+@SYMTestCaseDesc        Tests for the functionality of TLocale class
+@SYMTestPriority        High
+@SYMTestActions         Test for language downgrades
+@SYMTestExpectedResults Test must not fail
+@SYMREQ                 REQ0000
+*/
+void CT_LANGUTILSIMP::TestDowngrade(SDowngradeTest& aTest)
+    {
+    INFO_PRINTF1(_L(" @SYMTestCaseID:SYSLIB-BAFL-CT-0444 "));
+    TLocale loc;
+    loc.SetLanguageDowngrade(0, aTest.iIn[1]);
+    loc.SetLanguageDowngrade(1, aTest.iIn[2]);
+    loc.SetLanguageDowngrade(2, aTest.iIn[3]);
+    TLanguagePath path;
+    MakeLanguageDowngradePath(path, aTest.iIn[0], ELangNone, loc);
+    for (int i = 0; ; ++i)
+        {
+        test(i < 9);
+        test(aTest.iOut[i] == path[i]);
+        if (path[i] == ELangNone)
+            return;
+        }
+    
+    MakeLanguageDowngradePath(path, ELangAustralian, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangNewZealand, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangSouthAfricanEnglish, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangInternationalEnglish, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangAmerican, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangEnglish_Apac, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangEnglish_Taiwan, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangEnglish_HongKong, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangEnglish_Prc, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangEnglish_Japan, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangEnglish_Thailand, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangSwissFrench, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangBelgianFrench, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangInternationalFrench, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangCanadianFrench, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangSwissGerman, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangAustrian, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangInternationalSpanish, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangLatinAmericanSpanish, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangSwissItalian, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangFinlandSwedish, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangCyprusTurkish, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangBelgianFlemish, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangHongKongChinese, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangCyprusGreek, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangMalay_Apac, ELangNone, loc);
+    MakeLanguageDowngradePath(path, ELangBrazilianPortuguese, ELangNone, loc);
+    
+    }
+
+
+// Test Dialect enumeration.
+// Each value represents a dialect (variant) of a TLanguage language.
+// E.g. AmericanSprint is represented by ELangAmerican | EDialectSprint
+
+// The dialect location -- top six bits
+const TUint KDialectFactor=0x0400;
+enum TDialect
+    {
+    // The following are example dialects for testing only
+    EDialectSprint = (1*KDialectFactor),
+    EDialectOrange = (2*KDialectFactor),
+    EDialectMaximum = EDialectOrange // This must always be equal to the last TDialect enum.
+    // Up to 63 dialects.
+    };
+
+const TLanguage ELangEnglishOrange = static_cast<TLanguage>(ELangEnglish|EDialectOrange);
+const TLanguage ELangAmericanSprint = static_cast<TLanguage>(ELangAmerican|EDialectSprint);
+
+SDowngradeTest DowngradeData[] =
+    {
+        // 0 = test language
+        // 1-3 = language downgrade for locale
+        // 4- = calculated language downgrade path, terminated with ELangNone.
+        {{ELangEnglishOrange, ELangNone, ELangNone, ELangNone},
+            {ELangEnglishOrange, ELangEnglish, ELangNone}},
+        {{ELangAmericanSprint, ELangNone, ELangNone, ELangNone},
+            {ELangAmericanSprint, ELangAmerican, ELangEnglish, ELangNone}},
+        {{ELangFrench, ELangNone, ELangNone, ELangNone},
+            {ELangFrench, ELangNone}},
+        {{ELangSwissFrench, ELangNone, ELangNone, ELangNone},
+            {ELangSwissFrench, ELangFrench, ELangNone}},
+        {{ELangCanadianEnglish, ELangNone, ELangNone, ELangNone},
+            {ELangCanadianEnglish, ELangAmerican, ELangEnglish, ELangNone}},
+        {{ELangSwissFrench, ELangNone, ELangFrench, ELangNone},
+            {ELangSwissFrench, ELangFrench, ELangNone}},
+        {{ELangCanadianEnglish, ELangEnglish, ELangNone, ELangAmerican},
+            {ELangCanadianEnglish, ELangEnglish, ELangAmerican, ELangNone}},
+        {{ELangCanadianEnglish, ELangNone, ELangNone, ELangSwissFrench},
+            {ELangCanadianEnglish, ELangSwissFrench, ELangAmerican, ELangEnglish, ELangNone}},
+        {{ELangCanadianEnglish, ELangFrench, ELangAmerican, ELangSwissFrench},
+            {ELangCanadianEnglish, ELangFrench, ELangAmerican, ELangSwissFrench, ELangEnglish, ELangNone}},
+        {{ELangCanadianEnglish, ELangNone, ELangGerman, ELangSwissFrench},
+            {ELangCanadianEnglish, ELangGerman, ELangSwissFrench, ELangAmerican, ELangEnglish, ELangNone}},
+        {{ELangCanadianEnglish, ELangFinlandSwedish, ELangGerman, ELangSwissFrench},
+            {ELangCanadianEnglish, ELangFinlandSwedish, ELangGerman, ELangSwissFrench, ELangAmerican, ELangEnglish, ELangNone}},
+        {{ELangFinlandSwedish, ELangFinlandSwedish, ELangFinlandSwedish, ELangFinlandSwedish},
+            {ELangFinlandSwedish, ELangSwedish, ELangNone}},
+    };
+
+/**
+@SYMTestCaseID          SYSLIB-BAFL-CT-0445
+@SYMTestCaseDesc        Tests for language downgrades
+@SYMTestPriority        High
+@SYMTestActions         Call up downgrade path test function
+@SYMTestExpectedResults Test must not fail
+@SYMREQ                 REQ0000
+*/
+void CT_LANGUTILSIMP::TestMakeLanguageDowngradePath()
+    {
+    INFO_PRINTF1(_L(" @SYMTestCaseID:SYSLIB-BAFL-CT-0445 "));
+    for (int i = 0; i != sizeof(DowngradeData)/sizeof(DowngradeData[0]); ++i)
+        TestDowngrade(DowngradeData[i]);
+    }
+
+void CT_LANGUTILSIMP::SetUpFinderForLanguageAndDriveSearchL(
+    TTestNearestLanguageFileFinder& aFinder)
+    {
+    aFinder.iDrives = _L("ZAG");
+    aFinder.iFilesSearchedFor = new(ELeave) CDesCArraySeg(10);
+    aFinder.iFilesSearchedFor->AppendL(_L("z:\\dir\\name.e02"));
+    aFinder.iFilesSearchedFor->AppendL(_L("a:\\dir\\name.e02"));
+    aFinder.iFilesSearchedFor->AppendL(_L("g:\\dir\\name.e02"));
+    aFinder.iFilesSearchedFor->AppendL(_L("z:\\dir\\name.e15702")); //Extended lang
+    aFinder.iFilesSearchedFor->AppendL(_L("a:\\dir\\name.e15702"));
+    aFinder.iFilesSearchedFor->AppendL(_L("g:\\dir\\name.e15702"));
+    aFinder.iFilesSearchedFor->AppendL(_L("z:\\dir\\name.e01"));
+    aFinder.iFilesSearchedFor->AppendL(_L("a:\\dir\\name.e01"));
+    aFinder.iFilesSearchedFor->AppendL(_L("g:\\dir\\name.e01"));
+    aFinder.iFilesSearchedFor->AppendL(_L("z:\\dir\\name.ext"));
+    aFinder.iFilesSearchedFor->AppendL(_L("a:\\dir\\name.ext"));
+    aFinder.iFilesSearchedFor->AppendL(_L("g:\\dir\\name.ext"));
+    aFinder.iDrivesChecked = _L("zagzagzagzagzag");
+    }
+
+_LIT(KTestFileName1, "z:\\dir\\name.ext");
+//_LIT(KTestFileName2, "z:\\dir\\náme.ext");
+_LIT(KTestFileName2, "z:\\dir\\n\u00c1me.ext");
+_LIT(KTestFileName3, "a:\\dir\\name.ext");
+_LIT(KTestFileName4, "c:\\dir\\name.ext");
+_LIT(KTestFileName5, "d:\\dir\\name.ext");
+_LIT(KTestFileName6, "y:\\dir\\name.ext");
+_LIT(KTestFileName7, "A:\\dir\\name.ext");
+_LIT(KTestFileName8, "C:\\dir\\name.ext");
+_LIT(KTestFileName9, "Y:\\dir\\name.ext");
+_LIT(KTestFileName11, "\\abc\\defg.hijkl");
+_LIT(KTestFileName256Chars, "\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz01234\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz01234\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz01234\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz0.ext");
+
+_LIT(KExpectedFileName256Chars, "?:\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz01234\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz01234\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz01234\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz0.e");
+_LIT(KExpectedFileName1, "?:\\dir\\name.e");
+_LIT(KExpectedSuffix1, "xt");
+_LIT(KExpectedFileName2, "?:\\abc\\defg.hij");
+_LIT(KExpectedSuffix2, "kl");
+_LIT(KTestFileName1French, "z:\\dir\\name.e02");
+_LIT(KTestFileName1Japanese, "z:\\dir\\name.e32");
+_LIT(KTestFileName1Mongolian, "z:\\dir\\name.e54321");
+_LIT(KTestFileName1AmericanSprint, "z:\\dir\\name.e1034"); //American=0x0A, Sprint=0x0400. 0x040A=1034.
+_LIT(KCheckedForFrench, "?:\\dir\\name.e02");
+
+/**
+@SYMTestCaseID          SYSLIB-BAFL-CT-0446
+@SYMTestCaseDesc        Nearest language finder test
+@SYMTestPriority        High
+@SYMTestActions         Test drive sequence construction
+                        Test addition of language number
+                        Test searching each drive for the specified file
+                        Test searching language and drive down the language path
+                        Test filename matching
+                        Test searching for any language file within a drive
+                        Test searching all drives for any language
+@SYMTestExpectedResults Test must not fail
+@SYMREQ                 REQ0000
+*/
+void CT_LANGUTILSIMP::TestNearestLanguageFinder()
+    {
+    INFO_PRINTF1(_L(" @SYMTestCaseID:SYSLIB-BAFL-CT-0446 "));
+    RFs dummy;
+    TTestNearestLanguageFileFinder finder(dummy);
+
+    // Test file name setting and disecting
+    // SetFileName
+    // RepairFileName
+    TFileName fileName(KTestFileName1);
+    finder.SetFileName(fileName);
+    test(0 <= finder.iFileName->MatchF(KExpectedFileName1));
+    test(0 == finder.iSuffix.Compare(KExpectedSuffix1));
+    test('z' == finder.iInitialDriveLetter);
+    finder.RepairFileName();
+    test(0 == finder.iFileName->Compare(KTestFileName1));
+    fileName = KTestFileName11;
+    finder.SetFileName(fileName);
+    test(0 <= finder.iFileName->MatchF(KExpectedFileName2));
+    test(0 == finder.iSuffix.Compare(KExpectedSuffix2));
+    test(-1 == finder.iInitialDriveLetter);
+    finder.RepairFileName();
+    test(0 == finder.iFileName->Compare(KTestFileName11));
+    fileName = KTestFileName256Chars;
+    finder.SetFileName(fileName);
+    test(0 <= finder.iFileName->MatchF(KExpectedFileName256Chars));
+    test(0 == finder.iSuffix.Compare(KExpectedSuffix1));
+    test(-1 == finder.iInitialDriveLetter);
+    finder.RepairFileName();
+    test(0 == finder.iFileName->Compare(KTestFileName256Chars));
+
+    // Test drive sequence construction
+    // AddCustomResourceDrive
+    finder.iCustomRscDrive = static_cast<TInt>(EDriveC);    // drive c:
+    fileName = KTestFileName1;
+    finder.SetFileName(fileName);
+    test(finder.AddCustomResourceDrive() == KErrNone);
+    test(0 == finder.iDrives.CompareF(_L("CZ")));
+    fileName = KTestFileName3;
+    finder.SetFileName(fileName);
+    test(finder.AddCustomResourceDrive() == KErrNone);
+    test(0 == finder.iDrives.CompareF(_L("CA")));
+    fileName = KTestFileName4;
+    finder.SetFileName(fileName);
+    test(finder.AddCustomResourceDrive() == KErrAlreadyExists);
+    test(0 == finder.iDrives.CompareF(_L("C")));
+    fileName = KTestFileName5;
+    finder.SetFileName(fileName);
+    test(finder.AddCustomResourceDrive() == KErrNone);
+    test(0 == finder.iDrives.CompareF(_L("CD")));
+    fileName = KTestFileName6;
+    finder.SetFileName(fileName);
+    test(finder.AddCustomResourceDrive() == KErrNone);
+    test(0 == finder.iDrives.CompareF(_L("CY")));
+    fileName = KTestFileName7;
+    finder.SetFileName(fileName);
+    test(finder.AddCustomResourceDrive() == KErrNone);
+    test(0 == finder.iDrives.CompareF(_L("CA")));
+    fileName = KTestFileName8;
+    finder.SetFileName(fileName);
+    test(finder.AddCustomResourceDrive() == KErrAlreadyExists);
+    test(0 == finder.iDrives.CompareF(_L("C")));
+    fileName = KTestFileName9;
+    finder.SetFileName(fileName);
+    test(finder.AddCustomResourceDrive() == KErrNone);
+    test(0 == finder.iDrives.CompareF(_L("CY")));
+    // AddAllDrives
+    fileName = KTestFileName1;
+    finder.SetFileName(fileName);
+    finder.AddAllDrives();
+    test(0 == finder.iDrives.CompareF(_L("ZYXWVUTSRQPONMLKJIHGFEDCBA")));
+    fileName = KTestFileName3;
+    finder.SetFileName(fileName);
+    finder.AddAllDrives();
+    test(0 == finder.iDrives.CompareF(_L("AYXWVUTSRQPONMLKJIHGFEDCBZ")));
+    fileName = KTestFileName4;
+    finder.SetFileName(fileName);
+    finder.AddAllDrives();
+    test(0 == finder.iDrives.CompareF(_L("CYXWVUTSRQPONMLKJIHGFEDBAZ")));
+    fileName = KTestFileName5;
+    finder.SetFileName(fileName);
+    finder.AddAllDrives();
+    test(0 == finder.iDrives.CompareF(_L("DYXWVUTSRQPONMLKJIHGFECBAZ")));
+    fileName = KTestFileName6;
+    finder.SetFileName(fileName);
+    finder.AddAllDrives();
+    test(0 == finder.iDrives.CompareF(_L("YXWVUTSRQPONMLKJIHGFEDCBAZ")));
+    fileName = KTestFileName7;
+    finder.SetFileName(fileName);
+    finder.AddAllDrives();
+    test(0 == finder.iDrives.CompareF(_L("AYXWVUTSRQPONMLKJIHGFEDCBZ")));
+    fileName = KTestFileName8;
+    finder.SetFileName(fileName);
+    finder.AddAllDrives();
+    test(0 == finder.iDrives.CompareF(_L("CYXWVUTSRQPONMLKJIHGFEDBAZ")));
+    fileName = KTestFileName9;
+    finder.SetFileName(fileName);
+    finder.AddAllDrives();
+    test(0 == finder.iDrives.CompareF(_L("YXWVUTSRQPONMLKJIHGFEDCBAZ")));
+
+    // Test addition of language number
+    // AppendLanguageCode
+    fileName = KTestFileName1;
+    finder.SetFileName(fileName);
+    finder.AppendLanguageCode(ELangFrench);
+    test(0 == finder.iFileName->CompareF(KTestFileName1French));
+    finder.SetFileName(fileName);
+    finder.AppendLanguageCode(ELangJapanese);
+    test(0 == finder.iFileName->CompareF(KTestFileName1Japanese));
+    finder.SetFileName(fileName);
+    finder.AppendLanguageCode(ELangAmericanSprint);
+    test(0 == finder.iFileName->CompareF(KTestFileName1AmericanSprint));
+
+    fileName = KTestFileName1;
+    finder.SetFileName(fileName);
+    finder.AppendLanguageCode(static_cast<TLanguage>(54321));
+    test(0 == finder.iFileName->CompareF(KTestFileName1Mongolian));
+    fileName = KTestFileName256Chars;
+    finder.SetFileName(fileName);
+    test(!finder.AppendLanguageCode(ELangFrench));
+
+    // Test searching each drive for the specified file
+    // FindDrive
+    finder.iFileCheckedFor = KCheckedForFrench;
+    finder.iDrivesChecked = _L("D");
+    fileName = KTestFileName5;
+    finder.SetFileName(fileName);
+    finder.AppendLanguageCode(ELangFrench);
+    finder.FindDrive();
+    test(finder.iDrivesChecked.Length() == 0);
+    finder.SetFileName(fileName);
+    finder.AddAllDrives();
+    finder.iDrivesChecked = _L("dyxwvutsrqponmlkjihgfecbaz");
+    finder.AppendLanguageCode(ELangFrench);
+    finder.FindDrive();
+    test(finder.iDrivesChecked.Length() == 0);
+    fileName = KTestFileName5;
+    finder.SetFileName(fileName);
+    finder.AddAllDrives();
+    finder.iDrivesChecked = _L("dyxwvutsrqponmlkjihgfecbaz");
+    finder.AppendLanguageCode(ELangFrench);
+    finder.iFilesThatExist = new (ELeave) CDesCArraySeg(10);
+    finder.iFilesThatExist->AppendL(_L("o:\\dIR\\NAmE.E02"));
+    test(finder.FindDrive());
+    test(0 == finder.iFileName->CompareF(_L("O:\\dir\\name.e02")));
+    fileName = KTestFileName2;
+    finder.SetFileName(fileName);
+    finder.AppendLanguageCode(ELangFrench);
+    finder.AddAllDrives();
+    finder.iDrivesChecked = _L("zyxwvutsrqponmlkjihgfedcba");
+    finder.iFilesThatExist->AppendL(_L("v:\\dIR\\NA\x301mE.E02"));
+    //finder.iFileCheckedFor = _L("?:\\dir\\nÁme.e02");
+    finder.iFileCheckedFor = _L("?:\\dir\\n\u00c1me.e02");
+    test(finder.FindDrive());
+    //test(0 == finder.iFileName->CompareF(_L("v:\\dir\\nÁme.e02")));
+    test(0 == finder.iFileName->CompareF(_L("v:\\dir\\n\u00c1me.e02")));
+    delete finder.iFilesThatExist;
+    finder.iFilesThatExist = 0;
+
+    // Test searching language and drive down the language path
+    // FindLanguageAndDrive
+    finder.iPath[0] = static_cast<TLanguage>(2);
+    finder.iPath[1] = static_cast<TLanguage>(15702);
+    finder.iPath[2] = static_cast<TLanguage>(1);
+    finder.iPath[3] = ELangNone;
+    fileName = KTestFileName1;
+    finder.SetFileName(fileName);
+    SetUpFinderForLanguageAndDriveSearchL(finder);
+    finder.iFileCheckedFor = _L("?:\\dir\\name.e*");
+    test(!finder.FindLanguageAndDrive());
+    // check that iFileName is undamaged
+    finder.RepairFileName();
+    test(0 == finder.iFileName->CompareF(KTestFileName1));
+    delete finder.iFilesSearchedFor;
+    finder.iFilesThatExist = new (ELeave) CDesCArraySeg(10);
+    finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.e15702"));
+    fileName = KTestFileName1;
+    finder.SetFileName(fileName);
+    SetUpFinderForLanguageAndDriveSearchL(finder);
+    test(finder.FindLanguageAndDrive());
+    test(0 == finder.iFileName->CompareF(_L("a:\\dir\\name.e15702")));
+    delete finder.iFilesSearchedFor;
+    finder.iFilesSearchedFor = 0;
+
+    finder.iPath[0] = static_cast<TLanguage>(7);
+    finder.iPath[1] = ELangNone;
+    finder.iFilesThatExist->AppendL(_L("g:\\dir\\name.ext"));
+    fileName = KTestFileName1;
+    finder.SetFileName(fileName);
+    finder.iDrives = _L("ZAG");
+    finder.iDrivesChecked = _L("ZAGZAG");
+    test(finder.FindLanguageAndDrive());
+    test(0 == finder.iFileName->CompareF(_L("g:\\dir\\name.ext")));
+    delete finder.iFilesThatExist;
+    finder.iFilesThatExist = 0;
+
+    // Test filename matching
+    // LanguageNumberFromFile
+    test(4 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb04"), _L("AVB")));
+    //test(4 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("ávb04"), _L("A\x301VB")));
+    //test(4 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("a\x301vb04"), _L("ÁVB")));
+    test(4 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("\u00e1vb04"), _L("A\x301VB")));
+    test(4 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("a\x301vb04"), _L("\u00c1VB")));
+    test(5254 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb5254"), _L("aVb")));
+    test(KErrNotFound == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb04"), _L("avb04")));
+    test(KErrNotFound == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb04"), _L("av")));
+    test(KErrNotFound == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb04"), _L("")));
+    test(0 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb0000000"), _L("AVB00000")));
+    test(4 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb000000004"), _L("AVB0000000")));
+    test(100004 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb000100004"), _L("AVB000")));
+    test(111114 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb0111114"), _L("AVB0")));
+
+    // Test searching for any language file within a drive
+    // FindFirstLanguageFile
+    fileName = KTestFileName3;
+    finder.SetFileName(fileName);
+    finder.iFilesThatExist = new (ELeave) CDesCArraySeg(10);
+    finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.e107"));
+    finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.e07"));
+    finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.e02"));
+    finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.ee01"));
+    finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.01"));
+    finder.iFilesThatExist->AppendL(_L("a:\\dir\\name01"));
+    finder.iFilesThatExist->AppendL(_L("a:\\dir\\name01.e01"));
+    finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.e15108"));
+    finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.e03"));
+    finder.iTestScanner.iDriveError[0] = KErrNoMemory;
+    fileName = KTestFileName3;
+    finder.SetFileName(fileName);
+    test(KErrNotFound == finder.FindFirstLanguageFile(dummy));
+    finder.iTestScanner.iDriveError[0] = KErrAbort;
+    fileName = KTestFileName3;
+    finder.SetFileName(fileName);
+    test(KErrNotFound == finder.FindFirstLanguageFile(dummy));
+    finder.iTestScanner.iDriveError[0] = KErrNone;
+    fileName = KTestFileName3;
+    finder.SetFileName(fileName);
+    test(0 <= finder.FindFirstLanguageFile(dummy));
+    test(0 == finder.iFileName->CompareF(_L("a:\\dir\\name.e02")));
+
+    finder.iFilesThatExist->AppendL(_L("a:\\abaffafg.100"));
+    finder.iFilesThatExist->AppendL(_L("a:\\abcdefg.9539"));
+    finder.iFilesThatExist->AppendL(_L("a:\\abcdefg.19539"));
+    finder.iFilesThatExist->AppendL(_L("a:\\abcdefg.1000"));
+    finder.iFilesThatExist->AppendL(_L("a:\\abaffafg.102"));
+    fileName = _L("a:\\abcdefg.xx");
+    finder.SetFileName(fileName);
+    test(0 <= finder.FindFirstLanguageFile(dummy));
+    test(0 == finder.iFileName->CompareF(_L("a:\\abcdefg.1000")));
+    finder.iFilesThatExist->AppendL(_L("a:\\abaffafg.aaa100"));
+    finder.iFilesThatExist->AppendL(_L("a:\\abcdefg.0523"));    // not well-formed. Will not count.
+    finder.iFilesThatExist->AppendL(_L("a:\\abcdefg.1001"));
+    fileName = _L("a:\\abcdefg.xx");
+    finder.SetFileName(fileName);
+    test(0 <= finder.FindFirstLanguageFile(dummy));
+    test(0 == finder.iFileName->CompareF(_L("a:\\abcdefg.1000")));
+    fileName = _L("a:\\abaffafg.xx");
+    finder.SetFileName(fileName);
+    test(0 <= finder.FindFirstLanguageFile(dummy));
+    test(0 == finder.iFileName->CompareF(_L("a:\\abaffafg.100")));
+    finder.iFilesThatExist->AppendL(_L("a:\\abaffafg.09"));
+    fileName = _L("a:\\abaffafg.xx");
+    finder.SetFileName(fileName);
+    test(0 <= finder.FindFirstLanguageFile(dummy));
+    test(0 == finder.iFileName->CompareF(_L("a:\\abaffafg.09")));
+
+    // Test searching all drives for any language
+    // FindFirstLanguageFileAndDrive
+    finder.iFilesThatExist->AppendL(_L("z:\\abcdefg.05"));
+    fileName = _L("c:\\abcdefg.xx");
+    finder.SetFileName(fileName);
+    finder.iDrives = _L("az");
+    test(0 <= finder.FindFirstLanguageFileAndDrive());
+    test(0 == finder.iFileName->CompareF(_L("a:\\abcdefg.1000")));
+    fileName = _L("c:\\abaffafg.xx");
+    finder.SetFileName(fileName);
+    finder.iDrives = _L("az");
+    test(0 <= finder.FindFirstLanguageFileAndDrive());
+    test(0 == finder.iFileName->CompareF(_L("a:\\abaffafg.09")));
+    fileName = _L("c:\\abcdefg.xx");
+    finder.SetFileName(fileName);
+    finder.iDrives = _L("za");
+    test(0 <= finder.FindFirstLanguageFileAndDrive());
+    test(0 == finder.iFileName->CompareF(_L("z:\\abcdefg.05")));
+    fileName = _L("c:\\xxx.xx");
+    finder.SetFileName(fileName);
+    finder.iDrives = _L("za");
+    test(KErrNotFound == finder.FindFirstLanguageFileAndDrive());
+    finder.iTestScanner.iDriveError[25] = KErrAbort;
+    fileName = _L("c:\\abcdefg.xx");
+    finder.SetFileName(fileName);
+    finder.iDrives = _L("za");
+    test(0 <= finder.FindFirstLanguageFileAndDrive());
+    test(0 == finder.iFileName->CompareF(_L("a:\\abcdefg.1000")));
+    fileName = _L("c:\\abcdefg.xx");
+    finder.SetFileName(fileName);
+    finder.iDrives = _L("za");
+    finder.iTestScanner.iDriveError[0] = KErrNoMemory;
+    test(KErrNotFound == finder.FindFirstLanguageFileAndDrive());
+    fileName = _L("c:\\abcdefg.xx");
+    finder.SetFileName(fileName);
+    finder.iDrives = _L("za");
+    finder.iTestScanner.iDriveError[0] = KErrAbort;
+    test(KErrNotFound == finder.FindFirstLanguageFileAndDrive());
+
+    }
+
+
+
+
+
+void CT_LANGUTILSIMP::TestLANGUTILSIMP()
+    {
+    __UHEAP_MARK;
+
+    INFO_PRINTF1(_L("LangUtils Internal Tests: "));
+
+    TestAddLanguage();
+    TestMakeLanguageDowngradePath();
+    TestNearestLanguageFinder();
+
+
+
+    __UHEAP_MARKENDC(0);
+    }
+
+CT_LANGUTILSIMP::CT_LANGUTILSIMP()
+    {
+    SetTestStepName(KTestStep_T_LANGUTILSIMP);
+    }
+
+TVerdict CT_LANGUTILSIMP::doTestStepL()
+    {
+    SetTestStepResult(EFail);
+
+    __UHEAP_MARK;
+
+    TRAPD(error1, TestLANGUTILSIMP());
+
+    __UHEAP_MARKEND;
+
+    if(error1 == KErrNone )
+        {
+        SetTestStepResult(EPass);
+        }
+
+    return TestStepResult();
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtilsImp.mmp	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,38 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+// Tests some code internal to BaflUtils
+// 
+//
+
+target          T_LangUtilsImp.exe
+targettype      EXE
+
+userinclude ../src 
+userinclude   ../inc
+userinclude ../tsrc
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+sourcepath	../tsrc
+source T_LangUtilsImp.cpp
+source T_LangUtilsTestShareFunc.cpp
+
+STATICLIBRARY  langutil.lib
+library euser.lib hal.lib efsrv.lib estor.lib centralrepository.lib
+
+
+VENDORID 0x70000001
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtilsLang.cpp	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,310 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+#include <f32file.h>
+#include <hal.h>
+#include <e32std.h>
+#include <langutil.h>
+#include "LangUtilImpl.h"
+#include "T_LangUtilsTestShareFunc.h"
+#include "t_langutilslang.h"
+
+#define test(cond)                                          \
+    {                                                       \
+    TBool __bb = (cond);                                    \
+    TEST(__bb);                                             \
+    if (!__bb)                                              \
+        {                                                   \
+        ERR_PRINTF1(_L("ERROR: Test Failed"));              \
+        User::Leave(1);                                     \
+        }                                                   \
+    }
+
+
+LOCAL_D RFs                 TheFs;
+
+// Our test diectory and files...
+
+_LIT (KNullFilename, "");
+_LIT (KRscFilename,  "C:\\abc.rsc");
+_LIT (KRscFilenameNoSuffix,  "C:\\abc.");
+
+_LIT (KAmericanLang, "C:\\abc.r10");
+_LIT (KFrenchLang,   "C:\\abc.r02");
+_LIT (KJapanEnglishLang, "C:\\abc.r160");
+_LIT (KEnglishLang, "C:\\abc.r01");
+
+LOCAL_C void DeleteTestFiles()
+{
+    User::LeaveIfError (TheFs.Connect ());
+    ::CleanupClosePushL (TheFs);
+
+    LangUtilsTest::DeleteFile (TheFs, KRscFilename);
+    LangUtilsTest::DeleteFile (TheFs, KAmericanLang);
+    LangUtilsTest::DeleteFile (TheFs, KFrenchLang);
+    LangUtilsTest::DeleteFile (TheFs, KJapanEnglishLang);
+    LangUtilsTest::DeleteFile (TheFs, KEnglishLang);
+
+    CleanupStack::PopAndDestroy (&::TheFs);
+}
+
+
+
+void CT_LANGUTILSLANG::CreateTestFiles()
+{
+    User::LeaveIfError (TheFs.Connect ());
+    ::CleanupClosePushL (TheFs);
+    test (LangUtilsTest::FileExists (TheFs, KRscFilename) == EFalse);
+    test (LangUtilsTest::FileExists (TheFs, KAmericanLang) == EFalse);
+    test (LangUtilsTest::FileExists (TheFs, KFrenchLang) == EFalse);
+    test (LangUtilsTest::FileExists (TheFs, KJapanEnglishLang) == EFalse);
+    test (LangUtilsTest::FileExists (TheFs, KEnglishLang) == EFalse);
+
+    // Create the files...
+    RFile rFile;
+    // KFilename1 can't be created
+    rFile.Create (TheFs, KRscFilename, EFileRead);
+    rFile.Close ();
+    rFile.Create (TheFs, KAmericanLang, EFileRead);
+    rFile.Close ();
+    rFile.Create (TheFs, KFrenchLang, EFileRead);
+    rFile.Close ();
+
+    CleanupStack::PopAndDestroy (&::TheFs);
+
+}
+
+/**
+@SYMTestCaseID SYSLIB-BAFL-CT-0070
+@SYMTestCaseDesc Tests the configuration of the ideal language.
+@SYMTestPriority High
+@SYMTestActions  Set the ideal language and look for nearest language files.
+@SYMTestExpectedResults The test must not fail.
+@SYMREQ 3770: Configurable "ideal language" in LangUtil::NearestLanguageFile.
+*/
+void CT_LANGUTILSLANG::TestIdeaLang()
+    {
+    INFO_PRINTF1 (_L (" @SYMTestCaseID SYSLIB-BAFL-CT-0070 TestIdeaLang "));
+
+    __UHEAP_MARK;
+
+    User::LeaveIfError (TheFs.Connect ());
+    ::CleanupClosePushL (TheFs);
+
+    TBuf <256> filename;
+    TLanguage language;
+
+    // Test ideal language code
+
+    // Check initial value of ideal language
+
+    language=LangUtil::IdealLanguage();
+    test(language == ELangNone);
+
+    // Set and read back the ideal language
+
+    LangUtil::SetIdealLanguage( ELangGerman);
+    language=LangUtil::IdealLanguage();
+    test(language == ELangGerman);
+
+    LangUtil::SetIdealLanguage( ELangAmerican);
+    language=LangUtil::IdealLanguage();
+    test(language == ELangAmerican);
+
+    // Test NearestLanguageFile with empty name
+    TFileName resPath;
+    LangUtil::NearestLanguageFile (TheFs, resPath);
+    test(resPath.Length()==0);
+    INFO_PRINTF3 (_L ("The NearestLanguageFile for the null file - %S - is - %S -\n"), &KNullFilename, &filename);
+
+    // Test NearestLanguageFile with no suffix
+    filename.Copy (KRscFilenameNoSuffix);
+    LangUtil::NearestLanguageFile (TheFs, filename);
+    test(filename==KRscFilenameNoSuffix);
+    INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilenameNoSuffix, &filename);
+
+    // Test NearestLanguageFile
+    filename.Copy (KRscFilename);
+    LangUtil::NearestLanguageFile (TheFs, filename);
+    INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilename, &filename);
+    test(filename == KAmericanLang);
+
+    // Set ideal language to one we don't have
+    LangUtil::SetIdealLanguage( ELangGerman);
+    language=LangUtil::IdealLanguage();
+    test(language == ELangGerman);
+
+    // Test NearestLanguageFile
+    filename.Copy (KRscFilename);
+    LangUtil::NearestLanguageFile (TheFs, filename);
+    INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilename, &filename);
+    test(filename == KRscFilename);
+
+    // Restore ideal language to default
+    LangUtil::SetIdealLanguage( ELangNone);
+    language=LangUtil::IdealLanguage();
+    test(language == ELangNone);
+
+    // Test NearestLanguageFile
+    filename.Copy (KRscFilename);
+    LangUtil::NearestLanguageFile (TheFs, filename);
+    INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilename, &filename);
+    test(filename == KRscFilename);
+
+    // Set ideal language to French
+
+    LangUtil::SetIdealLanguage( ELangFrench);
+    language=LangUtil::IdealLanguage();
+    test(language == ELangFrench);
+
+    // Test NearestLanguageFile
+    filename.Copy (KRscFilename);
+    LangUtil::NearestLanguageFile (TheFs, filename);
+    INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilename, &filename);
+    test(filename == KFrenchLang);
+
+    // Restore ideal language to default
+    LangUtil::SetIdealLanguage( ELangNone);
+    language=LangUtil::IdealLanguage();
+    test(language == ELangNone);
+
+    // Release ideal language - free's TLS
+
+    LangUtil::ReleaseIdealLanguage();
+
+    CleanupStack::PopAndDestroy (&::TheFs);
+
+    __UHEAP_MARKEND;
+    }
+
+/**
+@SYMTestCaseID SYSLIB-BAFL-CT-0071
+@SYMTestCaseDesc Tests the overload of LangUtil::NearestLanguageFile.
+@SYMTestPriority High
+@SYMTestActions  Calls the overload of LangUtil::NearestLanguageFile and checks the returned language.
+@SYMTestExpectedResults The test must not fail.
+@SYMREQ 3785: Overload of LangUtil::NearestLanguageFile.
+*/
+void CT_LANGUTILSLANG::TestNearestLang()
+    {
+    INFO_PRINTF1 (_L (" @SYMTestCaseID SYSLIB-BAFL-CT-0071 TestNearestLang "));
+
+    __UHEAP_MARK;
+
+    User::LeaveIfError (TheFs.Connect ());
+    ::CleanupClosePushL (TheFs);
+
+    TBuf <256> filename;
+    TLanguage language;
+
+    // Ensure that ideal language is default
+    LangUtil::SetIdealLanguage( ELangNone);
+    language=LangUtil::IdealLanguage();
+    test(language == ELangNone);
+
+    // Test NearestLanguageFile overload with language returned
+    language=ELangAmerican;
+    filename.Copy (KRscFilename);
+    LangUtil::NearestLanguageFile (TheFs, filename, language);
+    INFO_PRINTF4(_L ("The NearestLanguageFile for %S is %S, language = %d\n"), &KRscFilename, &filename, language);
+    test(language == ELangNone);
+    test(filename == KRscFilename);
+
+    // Set ideal language to American
+
+    LangUtil::SetIdealLanguage( ELangAmerican);
+    language=LangUtil::IdealLanguage();
+    test(language == ELangAmerican);
+
+    // Test NearestLanguageFile overload with language returned
+    language=ELangNone;
+    filename.Copy (KRscFilename);
+    LangUtil::NearestLanguageFile (TheFs, filename, language);
+    INFO_PRINTF4 (_L ("The NearestLanguageFile for %S is %S, language = %d\n"), &KRscFilename, &filename, language);
+    test(language == ELangAmerican);
+    test(filename == KAmericanLang);
+
+    // Set ideal language to French
+
+    LangUtil::SetIdealLanguage( ELangFrench);
+    language=LangUtil::IdealLanguage();
+    test(language == ELangFrench);
+
+    // Test NearestLanguageFile overload with language returned
+    language=ELangNone;
+    filename.Copy (KRscFilename);
+    LangUtil::NearestLanguageFile (TheFs, filename, language);
+    INFO_PRINTF4 (_L ("The NearestLanguageFile for %S is %S, language = %d\n"), &KRscFilename, &filename, language);
+    test(language == ELangFrench);
+    test(filename == KFrenchLang);
+
+    // Set ideal language to one we don't have
+    LangUtil::SetIdealLanguage( ELangGerman);
+    language=LangUtil::IdealLanguage();
+    test(language == ELangGerman);
+
+    // Test NearestLanguageFile overload with language returned
+    language=ELangAmerican;
+    filename.Copy (KRscFilename);
+    LangUtil::NearestLanguageFile (TheFs, filename, language);
+    INFO_PRINTF4 (_L ("The NearestLanguageFile for %S is %S, language = %d\n"), &KRscFilename, &filename, language);
+    test(language == ELangNone);
+    test(filename == KRscFilename);
+
+    // Restore ideal language to default
+    LangUtil::SetIdealLanguage( ELangNone);
+    language=LangUtil::IdealLanguage();
+    test(language == ELangNone);
+
+    // Release ideal language - free's TLS
+
+    LangUtil::ReleaseIdealLanguage();
+
+    CleanupStack::PopAndDestroy (&::TheFs);
+
+    __UHEAP_MARKEND;
+    }
+
+
+void CT_LANGUTILSLANG::TestLANGUTILSLANG ()
+    {
+    CreateTestFiles();
+    TestIdeaLang ();
+    TestNearestLang ();
+    DeleteTestFiles();
+    }
+
+CT_LANGUTILSLANG::CT_LANGUTILSLANG()
+    {
+    SetTestStepName(KTestStep_T_LANGUTILSLANG);
+    }
+
+TVerdict CT_LANGUTILSLANG::doTestStepL()
+    {
+    SetTestStepResult(EFail);
+
+    __UHEAP_MARK;
+
+    TRAPD(error1, TestLANGUTILSLANG());
+
+    __UHEAP_MARKEND;
+
+    if(error1 == KErrNone )
+        {
+        SetTestStepResult(EPass);
+        }
+
+    return TestStepResult();
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtilsLang.mmp	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,33 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+//
+
+target		T_LangUtilsLang.exe
+targettype	exe
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+userinclude	../inc
+userinclude ../src
+userinclude ../tsrc
+
+SOURCEPATH	.
+source		T_LangUtilsLang.cpp
+source      T_LangUtilsTestShareFunc.cpp
+
+STATICLIBRARY  langutil.lib
+library euser.lib hal.lib efsrv.lib estor.lib centralrepository.lib
+VENDORID 0x70000001
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtilsServer.mmp	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,31 @@
+TARGET		  t_langutilsserver.exe
+TARGETTYPE	  exe
+UID 0x1000007A 0xE27AD85E
+//UID			 0 0xE27AD85D
+
+CAPABILITY		ProtServ WriteDeviceData
+
+
+SOURCEPATH	../tsrc
+userinclude   ../inc
+userinclude ../src
+userinclude ../tsrc
+
+OS_LAYER_LIBC_SYSTEMINCLUDE 
+APP_LAYER_SYSTEMINCLUDE
+
+SOURCE t_langutilsserver.cpp
+source T_LangUtilsTestShareFunc.cpp
+source T_LangUtils.cpp
+source T_LangUtilsImp.cpp
+source T_LangUtilsLang.cpp
+
+
+STATICLIBRARY  langutil.lib
+library euser.lib hal.lib efsrv.lib estor.lib centralrepository.lib
+LIBRARY	    testexecuteutils.lib 
+LIBRARY	    testexecutelogclient.lib
+
+#ifdef ENABLE_ABIV2_MODE
+DEBUGGABLE_UDEBONLY
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtilsTestShareFunc.cpp	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,408 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <langutil.h>
+#include "T_LangUtilsTestShareFunc.h"
+
+void DoCopyFileL(RFs& aFs, const TDesC& aSourceFullName, const TDesC& aTargetFullName, TUint aSwitch)
+    {
+    CFileMan* fileMan=CFileMan::NewL(aFs);
+    CleanupStack::PushL(fileMan);
+    User::LeaveIfError(fileMan->Copy(aSourceFullName,aTargetFullName,aSwitch));
+    CleanupStack::PopAndDestroy(); // fileMan
+    }
+
+
+TInt LangUtilsTest::CopyFile(RFs& aFs, const TDesC& aSourceFullName, const TDesC& aTargetFullName, TUint aSwitch)
+/** Copies one or more files.
+
+For more details, 
+@see CFileMan::Copy()
+@since     5.1
+@param     aFs File server session
+@param     aSourceFullName Path indicating the file(s) to be copied. Any path
+components that are not specified here will be taken from the session path.
+@param     aTargetFullName Path indicating the directory into which the file(s)
+are to be copied
+@param     aSwitch=CFileMan::EOverWrite Set this to zero for no overwriting and 
+no recursion; CFileMan::EOverWrite to overwrite files with the same name; or 
+CFileMan::ERecurse for recursion.
+@return   KErrNone if successful, otherwise another of the system-wide error 
+codes.*/
+    {
+    TRAPD(err,DoCopyFileL(aFs,aSourceFullName,aTargetFullName,aSwitch));
+    return err;
+    }
+
+TBool LangUtilsTest::FileExists(const RFs& aFileSession,const TDesC& aFileName)
+/** Checks if the specified file exists.
+    
+@param aFs File server session
+@param aFileName File to check
+@return ETrue if the file exists, otherwise EFalse */
+    { // static
+    TEntry entry;
+    return(aFileSession.Entry(aFileName,entry)==KErrNone);
+    }
+
+void DoDeleteFileL(RFs& aFs, const TDesC& aSourceFullName, TUint aSwitch)
+    {
+    CFileMan* fileMan=CFileMan::NewL(aFs);
+    CleanupStack::PushL(fileMan);
+    User::LeaveIfError(fileMan->Delete(aSourceFullName,aSwitch));
+    CleanupStack::PopAndDestroy(); // fileMan
+    }
+
+
+EXPORT_C TInt LangUtilsTest::DeleteFile(RFs& aFs, const TDesC& aSourceFullName, TUint aSwitch)
+/** Deletes one or more files.
+
+For more details,
+@see CFileMan::Delete().
+@since 5.1
+@param aFs File server session
+@param aSourceFullName Path indicating the file(s) to be deleted. May either
+be a full path, or relative to the session path. Use wildcards to specify 
+more than one file.
+@param aSwitch=0  Specify CFileMan::ERecurse for recursion,
+zero for no recursion.
+@return KErrNone if successful, otherwise another of the system-wide error 
+codes. */   
+    {
+    TRAPD(err,DoDeleteFileL(aFs,aSourceFullName,aSwitch));
+    return err;
+    }
+
+NONSHARABLE_CLASS(TKeyDesC16Array) : public TKeyArrayFix
+    {
+public:
+    TKeyDesC16Array(TKeyCmpText aType);
+private: // from TKey
+    TInt Compare(TInt aLeft,TInt aRight) const;
+    };
+
+TKeyDesC16Array::TKeyDesC16Array(TKeyCmpText aType)
+    : TKeyArrayFix(0,aType,0)
+    {
+    }
+
+TInt TKeyDesC16Array::Compare(TInt aLeft,TInt aRight) const
+    {
+    TDesC16* left=(*(TDesC16**)At(aLeft));
+    TDesC16* right=(*(TDesC16**)At(aRight));
+    switch (iCmpType)
+        {
+    case ECmpFolded:
+        return(left->CompareF(*right));
+    case ECmpCollated:
+        return(left->CompareC(*right));
+    default:
+        break;
+        }
+    return(left->Compare(*right));
+    }
+
+EXPORT_C CDesC16Array::CDesC16Array(TBufRep aRep,TInt aGranularity)
+    : CArrayFixBase(aRep,sizeof(HBufC16*),aGranularity)
+    {
+    }
+
+EXPORT_C CDesC16Array::~CDesC16Array()
+/** Frees all resources owned by the object, prior to its destruction. In particular, 
+it deletes all descriptors from the array and frees the memory allocated to 
+the array buffer. */
+    {
+    Reset();
+    }
+
+EXPORT_C void CDesC16Array::Reset()
+/** Deletes all descriptors from the array and frees the memory allocated to the 
+array buffer.
+
+@see CDesC16Array::Delete() */
+    {
+    Delete(0,Count());
+    }
+
+EXPORT_C void CDesC16Array::Delete(TInt aIndex)
+    {
+    Delete(aIndex,1);
+    }
+
+/**
+ *
+ * Deletes one or more logically contiguous descriptor elements from the
+ * array.
+ *
+ * The deletion starts at the specified position.Deleting descriptor
+ * elements from the array frees the memory occupied by the associated
+ * heap descriptors and removes their pointers from the array buffer but
+ * does not cause the array buffer to be automatically compressed. Call
+ * the Compress() function to return excess space in the array buffer to
+ * the heap.
+ *
+ * @param     " TInt aPos "
+ *            The starting position in the array from which
+ *            descriptor elements are to be deleted. The position is
+ *            relative to zero, i.e. zero implies the first
+ *            descriptor element. This value must not be negative
+ *            and must not be greater than the number of descriptor
+ *            elements currently in the array, otherwise the
+ *            functions raise an E32USER-CBase 21 panic.
+ * @param     " TInt aCount "
+ *            If specified, the number of contiguous descriptor
+ *            elements to be deleted from the array. This value must
+ *            not be negative otherwise the function raises an
+ *            E32USER-CBase 22 panic. This value must not be
+ *            negative otherwise the function raises an
+ *            E32USER-CBase 22 panic. This value must not be
+ *            negative otherwise the function raises an
+ *            E32USER-CBase 22 panic. This value plus the value of
+ *            the starting position must not be greater than the
+ *            number of descriptor elements in the array, otherwise
+ *            the function raises an E32USER-CBase 29 panic. If not
+ *            specified, one element is assumed.
+ */
+EXPORT_C void CDesC16Array::Delete(TInt aIndex,TInt aCount)
+    {
+    TInt count=aCount;
+    for (TInt ii=aIndex; count--; ii++)
+        User::Free(*(HBufC16**)At(ii));
+    CArrayFixBase::Delete(aIndex,aCount);
+    }
+
+EXPORT_C TInt CDesC16Array::MdcaCount() const
+/** Returns the number of descriptor elements in the array. The function implements 
+the function interface MDesC16Array::MdcaCount().
+
+@return The number of descriptor elements. */
+    {
+    return Count();
+    }
+
+EXPORT_C TPtrC16 CDesC16Array::MdcaPoint(TInt anIndex) const
+/** Indexes into a descriptor array. The function implements the interface MDesC16Array::MdcaPoint().
+    
+    @param aIndex The position of the descriptor element within the array. The 
+    position is relative to zero; i.e. zero implies the first descriptor element 
+    in the array. This value must be non-negative and less than the number of 
+    descriptors currently within the array otherwise the operator panics with 
+    EArrayIndexOutOfRange. 
+    @return A non-modifiable pointer descriptor representing the descriptor element 
+    located at position aIndex within the array. */ 
+    {
+    HBufC16* temp=(*(HBufC16**)At(anIndex));
+    return (TPtrC16)(*temp);
+    }
+
+EXPORT_C void CDesC16Array::AppendL(const TDesC16& aPtr)
+/** Appends a descriptor onto the end of any existing descriptor elements in the 
+array.
+
+@param aPtr A reference to the descriptor to be appended to the array. */
+    {
+    InsertL(Count(),aPtr);
+    }
+
+EXPORT_C void CDesC16Array::InsertL(TInt aPos,const TDesC16& aPtr)
+/** Inserts a descriptor into the array at the specified position. 
+
+If the specified position is the same as the current number of descriptor 
+elements in the array, this has the effect of appending the element.
+
+@param aPos The position within the array where the descriptor element is 
+to be inserted. The position is relative to zero, i.e. zero implies the first 
+descriptor element. This value must not be negative and must not be greater 
+than the number of descriptor elements currently in the array, otherwise the 
+function raises an E32USER-CBase 21 panic. 
+@param aPtr The descriptor to be inserted into the array. */
+    {
+    HBufC16* bufPtr=aPtr.AllocLC();
+    CArrayFixBase::InsertL(aPos,&bufPtr);
+    CleanupStack::Pop();
+    }
+
+EXPORT_C TInt CDesC16Array::InsertIsqL(const TDesC16& aPtr,TKeyCmpText aTextComparisonType)
+/** Inserts a descriptor into the array at a position which maintains the sequence 
+of the descriptors.
+
+The sequence is determined by comparing descriptors using one of the TDesC 
+comparison functions. The enumeration aTextComparisonType governs how the 
+descriptors are to be compared.
+
+The array should already be in sequence, otherwise the position of the new 
+descriptor element is unpredictable. Descriptor elements which are the same 
+are not permitted.
+
+@param aPtr A reference to the descriptor to be inserted into the array. 
+@param aTextComparisonType An enumeration which determines the type of comparison 
+to be made between descriptors for the purpose of choosing the insertion position. 
+If no parameter is explicitly passed, ECmpFolded is used by default.
+@return The position within the array of the inserted descriptor. */
+    {
+    HBufC16* bufPtr=aPtr.AllocLC();
+    TKeyDesC16Array key(aTextComparisonType);
+    TInt found=CArrayFixBase::InsertIsqL(&bufPtr,key);
+    CleanupStack::Pop();
+    return(found);
+    }
+
+EXPORT_C TInt CDesC16Array::InsertIsqAllowDuplicatesL(const TDesC16& aPtr,TKeyCmpText aTextComparisonType)
+/** Inserts a descriptor into the array at a position which maintains the sequence 
+of the descriptors; allows duplicates.
+
+The sequence is determined by comparing descriptors using one of the TDesC 
+comparison functions. The enumeration aTextComparisonType governs how the 
+descriptors are to be compared.
+
+The array should already be in sequence, otherwise the position of the new 
+descriptor element is unpredictable. Descriptor elements which are the same 
+are permitted; if the descriptor aPtr is a duplicate of an existing descriptor 
+within the array, then the new descriptor element is positioned after the 
+existing descriptor element.
+
+@param aPtr A reference to the descriptor to be inserted into the array. 
+@param aTextComparisonType An enumeration which determines the type of comparison 
+to be made between descriptors for the purpose of choosing the insertion position. 
+If no parameter is explicitly passed, ECmpFolded is used by default.
+@return The position within the array of the inserted descriptor. */
+    {
+    HBufC16* bufPtr=aPtr.AllocLC();
+    TKeyDesC16Array key(aTextComparisonType);
+    TInt found=CArrayFixBase::InsertIsqAllowDuplicatesL(&bufPtr,key);
+    CleanupStack::Pop();
+    return(found);
+    }
+
+EXPORT_C void CDesC16Array::Sort(TKeyCmpText aTextComparisonType)
+/** Sorts the descriptor elements into sequence.
+
+The sequence is determined by comparing descriptors using one of the member 
+functions of the descriptor base class TDesC.
+
+@param aTextComparisonType An enumeration which defines the type of comparison 
+to be made between descriptors. By default the comparison type is ECmpFolded. */
+    {
+    TKeyDesC16Array key(aTextComparisonType);
+    CArrayFixBase::Sort(key);
+    }
+
+EXPORT_C TInt CDesC16Array::Find(const TDesC16& aPtr,TInt& aPos,TKeyCmpText aTextComparisonType) const
+/** Finds the position of a descriptor element within the array which matches the 
+specified descriptor, using a sequential search.
+
+The array is searched sequentially for a matching descriptor element, starting 
+with the first descriptor element in the array. Descriptors are compared using 
+one of the TDesC comparison functions. The enumeration aTextComparisonType 
+governs how the descriptors are to be compared.
+
+Where an array has duplicate descriptor elements, the function only supplies 
+the position of the first descriptor element.
+
+@param aPtr A reference to a descriptor to be used for comparison. 
+@param aPos If the descriptor element is found, this reference is set to the 
+position of that descriptor element within the array. The position is relative 
+to zero, (i.e. the first descriptor element in the array is at position 0). 
+If the descriptor element is not found and the array is not empty, then the 
+value of the reference is set to the number of descriptor elements in the 
+array. If the descriptor element is not found and the array is empty, then 
+the reference is set to zero. 
+@param aTextComparisonType An enumeration which determines the type of comparison 
+to be made between descriptors. If no parameter is explicitly passed,ECmpFolded 
+is used by default. 
+@return Zero, if a matching descriptor element is found. Non-zero, if no matching 
+descriptor element can be found. */
+    {
+    TKeyDesC16Array key(aTextComparisonType);
+    const TDesC16* tmp=(&aPtr);
+    return(CArrayFixBase::Find(&tmp,key,aPos));
+    }
+
+EXPORT_C TInt CDesC16Array::FindIsq(const TDesC16& aPtr,TInt& aPos,TKeyCmpText aTextComparisonType) const
+/** Finds the position of a descriptor element within the array which matches the 
+specified descriptor, using a binary search technique. The array must 
+be in sequence, otherwise the outcome is unpredictable.
+
+Descriptors are compared using one of the TDesC comparison functions. The 
+enumeration aTextComparisonType governs how the descriptors are to be compared.
+
+Where an array has duplicate descriptor elements, the function cannot guarantee 
+which matching descriptor element it will return; except that it will find 
+one of them.
+
+@param aPtr A reference to a descriptor to be used for comparison. 
+@param aPos If the descriptor element is found, the reference is set to the 
+position of that descriptor element within the array. The position is relative 
+to zero, (i.e. the first descriptor element in the array is at position 0). 
+If the descriptor element is not found and the array is not empty, then the 
+reference is set to the position of the first descriptor element in the array 
+whose content is greater than the content of aPtr. If the descriptor element 
+is not found and the array is empty, then the reference is set to zero.
+@param aTextComparisonType An enumeration which determines the type of comparison 
+to be made between descriptors. If no parameter is explicitly passed, ECmpFolded 
+is used by default. 
+@return Zero, if a matching descriptor element is found. Non-zero, if no matching 
+descriptor element can be found. */
+    {
+    TKeyDesC16Array key(aTextComparisonType);
+    const TDesC16* tmp=(&aPtr);
+    return(CArrayFixBase::FindIsq(&tmp,key,aPos));
+    }
+
+
+EXPORT_C CDesC16ArraySeg::CDesC16ArraySeg(TInt aGranularity)
+    : CDesC16Array((TBufRep)CBufSeg::NewL,aGranularity)
+/** Construct a segmented descriptor array with the specified granularity.
+
+No memory is allocated to the array buffer by this C++ constructor.
+
+@param aGranularity The granularity of the array. This value must be positive 
+otherwise the constructor raises an E32USER-CBase 18 panic. */
+    {
+    __DECLARE_NAME(_S("CDesC16ArraySeg"));
+    }
+
+EXPORT_C CDesC16ArraySeg::~CDesC16ArraySeg()
+/** Frees all resources owned by the object, prior to its destruction. */
+    {}
+
+
+/* The following 3 function is defined so that the functions IdealLanguage,
+SetIdealLanguage, ReleaseIdealLanguage will compile as part as an .exe
+These functions use a global TAny* to store the data that would have been
+stored in the TLS under normal compilation (ie If the BaUtils was compilled
+as part of a DLL).
+*/
+
+TAny* ptr(NULL);
+
+TAny* Dll::Tls()
+    {
+    return ptr;
+    }
+
+TInt Dll::SetTls(TAny* aPtr)
+    {
+    ptr = aPtr;
+    return KErrNone;
+    }
+
+void Dll::FreeTls()
+    {
+    ptr = NULL;
+    }
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtilsTestShareFunc.h	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,36 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#ifndef __T_LANGUTILS_TEST_SHAREFUNC_H__
+#define __T_LANGUTILS_TEST_SHAREFUNC_H__
+
+#include <e32std.h>
+#include <f32file.h>
+
+
+
+class LangUtilsTest
+    {
+public:
+    static TInt DeleteFile(RFs& aFs, const TDesC& aSourceFullName, TUint aSwitch = 0);
+    static TBool FileExists(const RFs& aFs,const TDesC& aFileName);
+    static TInt CopyFile(RFs& aFs, const TDesC& aSourceFullName, const TDesC& aTargetFullName, TUint aSwitch = CFileMan::EOverWrite);
+
+    };
+
+
+
+#endif // __T_LANGUTILS_TEST_SHAREFUNC_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_langutils.script	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,4 @@
+PRINT Run T_LANGUTILS tests
+//
+LOAD_SUITE T_LangUtilsServer
+RUN_TEST_STEP 100 T_LangUtilsServer T_LANGUTILS
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_langutilsimp.script	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,4 @@
+PRINT Run T_LANGUTILSIMP tests
+//
+LOAD_SUITE T_LangUtilsServer
+RUN_TEST_STEP 100 T_LangUtilsServer T_LANGUTILSIMP
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_langutilslang.script	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,4 @@
+PRINT Run T_LANGUTILSLANG tests
+//
+LOAD_SUITE T_LangUtilsServer
+RUN_TEST_STEP 100 T_LangUtilsServer T_LANGUTILSLANG
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/file1.txt	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,1 @@
+ 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/file123456789.txt	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,1 @@
+ 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/file2.txt	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,1 @@
+ 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/file5.txt	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,1 @@
+ 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/t_langutils.h	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,36 @@
+#ifndef __T_LANGUTILS_H__
+#define __T_LANGUTILS_H__
+
+//#include <w32std.h>
+#include <test/testexecutestepbase.h>
+#include <baclipb.h>
+#include <f32file.h>
+#include <s32strm.h>
+#include <s32file.h>
+#include <e32lang.h>
+#include <langutil.h>
+#include "LangUtilImpl.h"
+#include "T_LangUtilsTestShareFunc.h"
+
+class CT_LANGUTILS : public CTestStep
+    {
+public:
+    CT_LANGUTILS();
+protected:  
+    TVerdict doTestStepL();
+private:
+    void TestLANGUTILS();
+    void TestGetDowngradePathL();
+    void TestGetEquivalentLanguageList();
+    void TestNearestLanguageFileV2(RFs& aFs);
+    void CopyTestFiles();
+    void CreateTestFiles2(RFs &aFs);
+    void DeleteTestFiles2(RFs &aFs);
+    void DeleteTestFiles();
+    void DeleteTestFile(const TDesC& aFullName);
+    void DeleteTestDir(const TDesC& aFullName);
+    };
+
+_LIT(KTestStep_T_LANGUTILS, "T_LANGUTILS");
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/t_langutilsimp.h	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,136 @@
+#ifndef __T_LANGUTILSIMP_H__
+#define __T_LANGUTILSIMP_H__
+
+//#include <w32std.h>
+#include <test/testexecutestepbase.h>
+#include <langutil.h>
+#include "LangUtilImpl.h"
+#include "T_LangUtilsTestShareFunc.h"
+
+struct SDowngradeTest
+    {
+    TLanguage iIn[4];
+    TLanguage iOut[9];
+    };
+
+class RTestDirectoryScanner : public RDirectoryScanner
+    {
+public:
+    RTestDirectoryScanner(CDesCArray*& aMember)
+        : iOpenError(0), iFilesThatExist(aMember)
+        {
+        for (TInt i = 0; i != 26; ++i)
+            iDriveError[i] = 0;
+        }
+    virtual TInt Open(RFs&, const TDesC& aMatchPattern)
+        {
+        iMatch = aMatchPattern;
+        iIndex = 0;
+        return iOpenError;
+        }
+    virtual TInt Next(TEntry& aOut)
+        {
+        if (!iFilesThatExist)
+            return KErrEof;
+        while (iIndex < iFilesThatExist->Count())
+            {
+            TInt i = iIndex++;
+            if (0 <= (*iFilesThatExist)[i].MatchF(iMatch))
+                {
+                TPtrC fullName=(*iFilesThatExist)[i];
+                TParsePtrC name(fullName);
+                aOut.iName=name.NameAndExt();
+                if (1 < fullName.Length() && fullName[1] == ':')
+                    {
+                    TInt drive = fullName[0];
+                    if ('a' <= drive && drive <= 'z')
+                        drive -= 'a';
+                    else
+                        {
+                        ASSERT('A' <= drive && drive <= 'Z');
+                        drive -= 'A';
+                        }
+                    return iDriveError[drive];
+                    }
+                return KErrNone;
+                }
+            }
+        return KErrEof;
+        }
+    virtual void Close() {}
+    TInt iOpenError;
+    TInt iDriveError[26];
+private:
+    CDesCArray *&iFilesThatExist;
+    TInt iIndex;
+    TFileName iMatch;
+    };
+
+
+class TTestNearestLanguageFileFinder : public TNearestLanguageFileFinder
+    {
+public:
+    TTestNearestLanguageFileFinder(const RFs& aFs)
+        : TNearestLanguageFileFinder(aFs), iTestScanner(iFilesThatExist)
+        {
+        iFilesThatExist = 0;
+        iFilesSearchedFor = 0;
+        }
+    ~TTestNearestLanguageFileFinder()
+        {
+        delete iFilesThatExist;
+        delete iFilesSearchedFor;
+        }
+    virtual TInt GetCustomResourceDriveNumber() const { return iCustomRscDrive; }
+    virtual TBool FileExists(const TDesC& aFileName) const
+        {
+        ASSERT(aFileName[1] == ':');
+        ASSERT(0 == aFileName.Left(1).CompareF(iDrivesChecked.Left(1)));
+        iDrivesChecked.Delete(0, 1);
+        ASSERT(0 <= aFileName.MatchF(iFileCheckedFor));
+        if (iFilesSearchedFor)
+            {
+            ASSERT(0 == aFileName.CompareF((*iFilesSearchedFor)[0]));
+            iFilesSearchedFor->Delete(0);
+            }
+        if (!iFilesThatExist)
+            return EFalse;
+        TInt i;
+        iFilesThatExist->Find(aFileName, i);
+        return (0 <= i && i < iFilesThatExist->Count())? ETrue : EFalse;
+        }
+    virtual RDirectoryScanner& DirectoryScanner() { return iTestScanner; }
+
+    TInt iCustomRscDrive;
+    CDesCArray* iFilesThatExist;
+    // File that is expected to go into FileExists.
+    // Can contain wildcards.
+    TFileName iFileCheckedFor;
+    // Drives expected in calls to FileExists. The first one is checked then
+    // discarded each time FileExists is called.
+    mutable TBuf<26> iDrivesChecked;
+    CDesCArray* iFilesSearchedFor;
+    RTestDirectoryScanner iTestScanner;
+    };
+
+
+class CT_LANGUTILSIMP : public CTestStep
+    {
+public:
+    CT_LANGUTILSIMP();
+protected:  
+    TVerdict doTestStepL();
+private:
+    void TestLANGUTILSIMP();
+    void TestPath(const TLanguagePath& aPath, const TLanguage* aExpected, TInt aExpectedCount);
+    void TestAddLanguage();
+    void TestDowngrade(SDowngradeTest& aTest);
+    void TestMakeLanguageDowngradePath();
+    void SetUpFinderForLanguageAndDriveSearchL(TTestNearestLanguageFileFinder& aFinder);
+    void TestNearestLanguageFinder();
+
+    };
+
+_LIT(KTestStep_T_LANGUTILSIMP, "T_LANGUTILSIMP");
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/t_langutilslang.h	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,22 @@
+#ifndef __T_LANGUTILSLANG_H__
+#define __T_LANGUTILSLANG_H__
+
+//#include <w32std.h>
+#include <test/testexecutestepbase.h>
+
+class CT_LANGUTILSLANG : public CTestStep
+    {
+public:
+    CT_LANGUTILSLANG();
+protected:  
+    TVerdict doTestStepL();
+private:
+    void TestLANGUTILSLANG();
+    void TestNearestLang();
+    void TestIdeaLang();
+    void CreateTestFiles();
+    };
+
+_LIT(KTestStep_T_LANGUTILSLANG, "T_LANGUTILSLANG");
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/t_langutilsserver.cpp	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,118 @@
+/*
+ ============================================================================
+ Name		: t_TEF.cpp
+ Author	  : Yanchun Li
+ Copyright   : Your copyright notice
+ Description : Exe source file
+ ============================================================================
+ */
+
+//  Include Files  
+
+#include "t_langutilsserver.h"
+#include "t_langutils.h"
+#include "t_langutilsimp.h"
+#include "t_langutilslang.h"
+
+
+/* Path to the script
+
+c:\z:\t_TEF\t_TEF_All.script
+
+*/
+
+_LIT(KServerName,"T_LangUtilsServer");
+
+CT_LangUtilsServer *CT_LangUtilsServer::NewL()
+/**
+   @return - Instance of the test server
+   Same code for Secure and non-secure variants
+   Called inside the MainL() function to create and start the
+   CTestServer derived server.
+ */
+    {
+    CT_LangUtilsServer * server = new (ELeave) CT_LangUtilsServer();
+    CleanupStack::PushL(server);
+    // CServer base class call
+    server->StartL(KServerName);
+    CleanupStack::Pop(server);
+    return server;
+    }
+
+
+LOCAL_C void MainL()
+//
+// Secure variant
+// Much simpler, uses the new Rendezvous() call to sync with the client
+//
+    {
+#if (defined __DATA_CAGING__)
+    RProcess().DataCaging(RProcess::EDataCagingOn);
+    RProcess().SecureApi(RProcess::ESecureApiOn);
+#endif
+    CActiveScheduler* sched=NULL;
+    sched=new(ELeave) CActiveScheduler;
+    CActiveScheduler::Install(sched);
+    CT_LangUtilsServer *server = NULL;
+    // Create the CTestServer derived server
+    TRAPD(err,server = CT_LangUtilsServer::NewL());
+    if(!err)
+        {
+        // Sync with the client and enter the active scheduler
+        RProcess::Rendezvous(KErrNone);
+        sched->Start();
+        }
+    delete server;
+    delete sched;
+    }
+
+/** @return - Standard Epoc error code on process exit
+    Secure variant only
+    Process entry point. Called by client using RProcess API
+*/
+GLDEF_C TInt E32Main()
+    {
+    __UHEAP_MARK;
+    CTrapCleanup* cleanup = CTrapCleanup::New();
+    if(cleanup == NULL)
+        {
+        return KErrNoMemory;
+        }
+    TRAPD(err,MainL());
+    // This if statement is here just to shut up RVCT, which would otherwise warn
+    // that err was set but never used
+    if (err)
+        {
+        err = KErrNone;
+        }
+    delete cleanup;
+    __UHEAP_MARKEND;
+    return KErrNone;
+    }
+
+CTestStep *CT_LangUtilsServer::CreateTestStep(const TDesC& aStepName)
+/**
+   @return - A CTestStep derived instance
+   Secure and non-secure variants
+   Implementation of CTestServer pure virtual
+ */
+    {
+    
+    if(aStepName == KTestStep_T_LANGUTILS)
+        {
+        return new CT_LANGUTILS();
+        }
+    else if(aStepName == KTestStep_T_LANGUTILSIMP)
+        {
+        return new CT_LANGUTILSIMP();
+        }
+    else if(aStepName == KTestStep_T_LANGUTILSLANG)
+        {
+        return new CT_LANGUTILSLANG();
+        }
+        
+
+    
+    return NULL;
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/t_langutilsserver.h	Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,26 @@
+/*
+ ============================================================================
+ Name		: T_LangUtilsServer.h
+ Author	  : Yanchun Li
+ Copyright   : Your copyright notice
+ Description : Exe header file
+ ============================================================================
+ */
+
+#ifndef __T_LANGUTILSSERVER_H__
+#define __T_LANGUTILSSERVER_H__
+
+//  Include Files
+
+#include <test/testexecuteserverbase.h>
+
+class CT_LangUtilsServer : public CTestServer
+    {
+public:
+    static CT_LangUtilsServer* NewL();
+//from  CTestServer
+    virtual CTestStep* CreateTestStep(const TDesC& aStepName);
+    };
+
+#endif  // __T_LANGUTILSSERVER_H__
+