Bug 575043: Remove internal uses of nsICaseConversion. r=smontagu sr=roc
authorKyle Huey <me@kylehuey.com>
Thu, 29 Jul 2010 12:22:16 -0700
changeset 48377 e0fa43b96c03fa5bc2653fbe133c1954d3c6c900
parent 48376 3d786e54c7db4ed553a8232b99ab7ba682d233d2
child 48378 64afebe0f45cbecb5eb06faedaf01d37926a5777
push idunknown
push userunknown
push dateunknown
reviewerssmontagu, roc
bugs575043
milestone2.0b3pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 575043: Remove internal uses of nsICaseConversion. r=smontagu sr=roc
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
extensions/spellcheck/hunspell/src/csutil.cpp
extensions/spellcheck/src/mozEnglishWordUtils.cpp
extensions/spellcheck/src/mozEnglishWordUtils.h
intl/build/nsI18nModule.cpp
intl/locale/src/nsCollation.cpp
intl/locale/src/nsCollation.h
intl/unicharutil/src/nsCaseConversionImp2.cpp
intl/unicharutil/src/nsCaseConversionImp2.h
intl/unicharutil/src/nsUcharUtilConstructors.h
intl/unicharutil/util/Makefile.in
intl/unicharutil/util/internal/Makefile.in
intl/unicharutil/util/nsUnicharUtils.cpp
intl/unicharutil/util/nsUnicharUtils.h
layout/generic/nsTextFrameThebes.cpp
layout/generic/nsTextRunTransformations.cpp
toolkit/library/Makefile.in
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -106,17 +106,16 @@ class nsILineBreaker;
 class nsIWordBreaker;
 class nsIJSRuntimeService;
 class nsIEventListenerManager;
 class nsIScriptContext;
 class nsIRunnable;
 class nsIInterfaceRequestor;
 template<class E> class nsCOMArray;
 struct JSRuntime;
-class nsICaseConversion;
 class nsIUGenCategory;
 class nsIWidget;
 class nsIDragSession;
 class nsPIDOMWindow;
 class nsPIDOMEventTarget;
 class nsIPresShell;
 class nsIXPConnectJSObjectHolder;
 class nsPrefOldCallback;
@@ -610,21 +609,16 @@ public:
   {
     return sLineBreaker;
   }
 
   static nsIWordBreaker* WordBreaker()
   {
     return sWordBreaker;
   }
-  
-  static nsICaseConversion* GetCaseConv()
-  {
-    return sCaseConv;
-  }
 
   static nsIUGenCategory* GetGenCat()
   {
     return sGenCat;
   }
 
   /**
    * Regster aObserver as a shutdown observer. A strong reference is held
@@ -1736,17 +1730,16 @@ private:
   static nsIStringBundleService* sStringBundleService;
   static nsIStringBundle* sStringBundles[PropertiesFile_COUNT];
 
   static nsIContentPolicy* sContentPolicyService;
   static PRBool sTriedToGetContentPolicy;
 
   static nsILineBreaker* sLineBreaker;
   static nsIWordBreaker* sWordBreaker;
-  static nsICaseConversion* sCaseConv;
   static nsIUGenCategory* sGenCat;
 
   // Holds pointers to nsISupports* that should be released at shutdown
   static nsTArray<nsISupports**>* sPtrsToPtrsToRelease;
 
   static nsIScriptRuntime* sScriptRuntimes[NS_STID_ARRAY_UBOUND];
   static PRInt32 sScriptRootCount[NS_STID_ARRAY_UBOUND];
   static PRUint32 sJSGCThingRootCount;
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -141,17 +141,16 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
 #include "nsIDOMUserDataHandler.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsTPtrArray.h"
 #include "nsGUIEvent.h"
 #include "nsMutationEvent.h"
 #include "nsIMEStateManager.h"
 #include "nsContentErrors.h"
 #include "nsUnicharUtilCIID.h"
-#include "nsICaseConversion.h"
 #include "nsCompressedCharMap.h"
 #include "nsINativeKeyBindings.h"
 #include "nsIDOMNSUIEvent.h"
 #include "nsIDOMNSEvent.h"
 #include "nsIPrivateDOMEvent.h"
 #include "nsXULPopupManager.h"
 #include "nsIPermissionManager.h"
 #include "nsIScriptObjectPrincipal.h"
@@ -236,17 +235,16 @@ nsDataHashtable<nsISupportsHashKey, Even
 nsDataHashtable<nsStringHashKey, EventNameMapping>* nsContentUtils::sStringEventTable = nsnull;
 nsCOMArray<nsIAtom>* nsContentUtils::sUserDefinedEvents = nsnull;
 nsIStringBundleService *nsContentUtils::sStringBundleService;
 nsIStringBundle *nsContentUtils::sStringBundles[PropertiesFile_COUNT];
 nsIContentPolicy *nsContentUtils::sContentPolicyService;
 PRBool nsContentUtils::sTriedToGetContentPolicy = PR_FALSE;
 nsILineBreaker *nsContentUtils::sLineBreaker;
 nsIWordBreaker *nsContentUtils::sWordBreaker;
-nsICaseConversion *nsContentUtils::sCaseConv;
 nsIUGenCategory *nsContentUtils::sGenCat;
 nsTArray<nsISupports**> *nsContentUtils::sPtrsToPtrsToRelease;
 nsIScriptRuntime *nsContentUtils::sScriptRuntimes[NS_STID_ARRAY_UBOUND];
 PRInt32 nsContentUtils::sScriptRootCount[NS_STID_ARRAY_UBOUND];
 PRUint32 nsContentUtils::sJSGCThingRootCount;
 #ifdef IBMBIDI
 nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nsnull;
 #endif
@@ -398,19 +396,16 @@ nsContentUtils::Init()
     sIOService = nsnull;
   }
 
   rv = CallGetService(NS_LBRK_CONTRACTID, &sLineBreaker);
   NS_ENSURE_SUCCESS(rv, rv);
   
   rv = CallGetService(NS_WBRK_CONTRACTID, &sWordBreaker);
   NS_ENSURE_SUCCESS(rv, rv);
-  
-  rv = CallGetService(NS_UNICHARUTIL_CONTRACTID, &sCaseConv);
-  NS_ENSURE_SUCCESS(rv, rv);
 
   rv = CallGetService(NS_UNICHARCATEGORY_CONTRACTID, &sGenCat);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = CallGetService(NS_IHISTORY_CONTRACTID, &sHistory);
   if (NS_FAILED(rv)) {
     NS_RUNTIMEABORT("Cannot get the history service");
     return rv;
@@ -1078,17 +1073,16 @@ nsContentUtils::Shutdown()
   sXPConnect = nsnull;
   sThreadJSContextStack = nsnull;
   NS_IF_RELEASE(sSecurityManager);
   NS_IF_RELEASE(sNameSpaceManager);
   NS_IF_RELEASE(sParserService);
   NS_IF_RELEASE(sIOService);
   NS_IF_RELEASE(sLineBreaker);
   NS_IF_RELEASE(sWordBreaker);
-  NS_IF_RELEASE(sCaseConv);
   NS_IF_RELEASE(sGenCat);
 #ifdef MOZ_XTF
   NS_IF_RELEASE(sXTFService);
 #endif
   NS_IF_RELEASE(sImgLoader);
   NS_IF_RELEASE(sImgCache);
   NS_IF_RELEASE(sHistory);
   NS_IF_RELEASE(sPrefBranch);
--- a/extensions/spellcheck/hunspell/src/csutil.cpp
+++ b/extensions/spellcheck/hunspell/src/csutil.cpp
@@ -74,17 +74,16 @@
 #  endif
 #endif
 
 #ifdef MOZILLA_CLIENT
 #include "nsCOMPtr.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIUnicodeEncoder.h"
 #include "nsIUnicodeDecoder.h"
-#include "nsICaseConversion.h"
 #include "nsICharsetConverterManager.h"
 #include "nsUnicharUtilCIID.h"
 #include "nsUnicharUtils.h"
 
 static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
 static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID);
 #endif
 
@@ -5206,36 +5205,31 @@ struct cs_info * get_current_cs(const ch
 // XXX This function was rewritten for mozilla. Instead of storing the
 // conversion tables static in this file, create them when needed
 // with help the mozilla backend.
 struct cs_info * get_current_cs(const char * es) {
   struct cs_info *ccs;
 
   nsCOMPtr<nsIUnicodeEncoder> encoder; 
   nsCOMPtr<nsIUnicodeDecoder> decoder; 
-  nsCOMPtr<nsICaseConversion> caseConv;
 
   nsresult rv;
   nsCOMPtr<nsICharsetConverterManager> ccm = do_GetService(kCharsetConverterManagerCID, &rv);
   if (NS_FAILED(rv))
     return nsnull;
 
   rv = ccm->GetUnicodeEncoder(es, getter_AddRefs(encoder));
   if (NS_FAILED(rv))
     return nsnull;
   encoder->SetOutputErrorBehavior(encoder->kOnError_Signal, nsnull, '?');
   rv = ccm->GetUnicodeDecoder(es, getter_AddRefs(decoder));
   if (NS_FAILED(rv))
     return nsnull;
   decoder->SetInputErrorBehavior(decoder->kOnError_Signal);
 
-  caseConv = do_GetService(kUnicharUtilCID, &rv);
-  if (NS_FAILED(rv))
-    return nsnull;
-
   ccs = new cs_info[256];
 
   for (unsigned int i = 0; i <= 0xff; ++i) {
     PRBool success = PR_FALSE;
     // We want to find the upper/lowercase equivalents of each byte
     // in this 1-byte character encoding.  Call our encoding/decoding
     // APIs separately for each byte since they may reject some of the
     // bytes, and we want to handle errors separately for each byte.
@@ -5247,28 +5241,24 @@ struct cs_info * get_current_cs(const ch
       PRUnichar uni, uniCased;
       PRInt32 charLength = 1, uniLength = 1;
 
       rv = decoder->Convert(&source, &charLength, &uni, &uniLength);
       // Explicitly check NS_OK because we don't want to allow
       // NS_OK_UDEC_MOREOUTPUT or NS_OK_UDEC_MOREINPUT.
       if (rv != NS_OK || charLength != 1 || uniLength != 1)
         break;
-      rv = caseConv->ToLower(uni, &uniCased);
-      if (NS_FAILED(rv))
-        break;
+      uniCased = ToLowerCase(uni);
       rv = encoder->Convert(&uniCased, &uniLength, &lower, &charLength);
       // Explicitly check NS_OK because we don't want to allow
       // NS_OK_UDEC_MOREOUTPUT or NS_OK_UDEC_MOREINPUT.
       if (rv != NS_OK || charLength != 1 || uniLength != 1)
         break;
 
-      rv = caseConv->ToUpper(uni, &uniCased);
-      if (NS_FAILED(rv))
-        break;
+      uniCased = ToUpperCase(uni);
       rv = encoder->Convert(&uniCased, &uniLength, &upper, &charLength);
       // Explicitly check NS_OK because we don't want to allow
       // NS_OK_UDEC_MOREOUTPUT or NS_OK_UDEC_MOREINPUT.
       if (rv != NS_OK || charLength != 1 || uniLength != 1)
         break;
 
       success = PR_TRUE;
     } while (0);
@@ -5387,39 +5377,28 @@ int initialize_utf_tbl() {
 void free_utf_tbl() {
   if (utf_tbl_count > 0) utf_tbl_count--;
   if (utf_tbl && (utf_tbl_count == 0)) {
     free(utf_tbl);
     utf_tbl = NULL;
   }
 }
 
-#ifdef MOZILLA_CLIENT
-static nsCOMPtr<nsICaseConversion>& getcaseConv()
-{
-  nsresult rv;
-  static nsCOMPtr<nsICaseConversion> caseConv = do_GetService(kUnicharUtilCID, &rv);
-  return caseConv;
-}
-#endif
-
 unsigned short unicodetoupper(unsigned short c, int langnum)
 {
   // In Azeri and Turkish, I and i dictinct letters:
   // There are a dotless lower case i pair of upper `I',
   // and an upper I with dot pair of lower `i'. 
   if (c == 0x0069 && ((langnum == LANG_az) || (langnum == LANG_tr)))
     return 0x0130;
 #ifdef OPENOFFICEORG
   return u_toupper(c);
 #else
 #ifdef MOZILLA_CLIENT
-  PRUnichar ch2;
-  getcaseConv()->ToUpper((PRUnichar) c, &ch2);
-  return ch2;
+  return ToUpperCase((PRUnichar) c);
 #else
   return (utf_tbl) ? utf_tbl[c].cupper : c;
 #endif
 #endif
 }
 
 unsigned short unicodetolower(unsigned short c, int langnum)
 {
@@ -5427,19 +5406,17 @@ unsigned short unicodetolower(unsigned s
   // There are a dotless lower case i pair of upper `I',
   // and an upper I with dot pair of lower `i'. 
   if (c == 0x0049 && ((langnum == LANG_az) || (langnum == LANG_tr)))
     return 0x0131;
 #ifdef OPENOFFICEORG
   return u_tolower(c);
 #else
 #ifdef MOZILLA_CLIENT
-  PRUnichar ch2;
-  getcaseConv()->ToLower((PRUnichar) c, &ch2);
-  return ch2;
+  return ToLowerCase((PRUnichar) c);
 #else
   return (utf_tbl) ? utf_tbl[c].clower : c;
 #endif
 #endif
 }
 
 int unicodeisalpha(unsigned short c)
 {
--- a/extensions/spellcheck/src/mozEnglishWordUtils.cpp
+++ b/extensions/spellcheck/src/mozEnglishWordUtils.cpp
@@ -34,40 +34,39 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozEnglishWordUtils.h"
 #include "nsICharsetAlias.h"
 #include "nsReadableUtils.h"
 #include "nsIServiceManager.h"
+#include "nsUnicharUtils.h"
 #include "nsUnicharUtilCIID.h"
 #include "nsCRT.h"
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(mozEnglishWordUtils)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(mozEnglishWordUtils)
 
 NS_INTERFACE_MAP_BEGIN(mozEnglishWordUtils)
   NS_INTERFACE_MAP_ENTRY(mozISpellI18NUtil)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozISpellI18NUtil)
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozEnglishWordUtils)
 NS_INTERFACE_MAP_END
 
-NS_IMPL_CYCLE_COLLECTION_3(mozEnglishWordUtils,
-                           mCaseConv,
+NS_IMPL_CYCLE_COLLECTION_2(mozEnglishWordUtils,
                            mCategories,
                            mURLDetector)
 
 mozEnglishWordUtils::mozEnglishWordUtils()
 {
   mLanguage.AssignLiteral("en");
 
   nsresult rv;
   mURLDetector = do_CreateInstance(MOZ_TXTTOHTMLCONV_CONTRACTID, &rv);
-  mCaseConv = do_GetService(NS_UNICHARUTIL_CONTRACTID);
   mCategories = do_GetService(NS_UNICHARCATEGORY_CONTRACTID);
 }
 
 mozEnglishWordUtils::~mozEnglishWordUtils()
 {
 }
 
 /* attribute wstring language; */
@@ -113,25 +112,25 @@ NS_IMETHODIMP mozEnglishWordUtils::GetRo
       tmpPtr = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * 3);
       if (!tmpPtr)
         return NS_ERROR_OUT_OF_MEMORY;
       tmpPtr[0] = ToNewUnicode(word);
       if (!tmpPtr[0]) {
         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(0, tmpPtr);
         return NS_ERROR_OUT_OF_MEMORY;
       }
-      mCaseConv->ToLower(tmpPtr[0], tmpPtr[0], length);
+      ToLowerCase(tmpPtr[0], tmpPtr[0], length);
 
       tmpPtr[1] = ToNewUnicode(word);
       if (!tmpPtr[1]) {
         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(1, tmpPtr);
         return NS_ERROR_OUT_OF_MEMORY;
       }
-      mCaseConv->ToLower(tmpPtr[1], tmpPtr[1], length);
-      mCaseConv->ToUpper(tmpPtr[1], tmpPtr[1], 1);
+      ToLowerCase(tmpPtr[1], tmpPtr[1], length);
+      ToUpperCase(tmpPtr[1], tmpPtr[1], 1);
 
       tmpPtr[2] = ToNewUnicode(word);
       if (!tmpPtr[2]) {
         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(2, tmpPtr);
         return NS_ERROR_OUT_OF_MEMORY;
       }
 
       *words = tmpPtr;
@@ -143,17 +142,17 @@ NS_IMETHODIMP mozEnglishWordUtils::GetRo
       if (!tmpPtr)
         return NS_ERROR_OUT_OF_MEMORY;
 
       tmpPtr[0] = ToNewUnicode(word);
       if (!tmpPtr[0]) {
         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(0, tmpPtr);
         return NS_ERROR_OUT_OF_MEMORY;
       }
-      mCaseConv->ToLower(tmpPtr[0], tmpPtr[0], length);
+      ToLowerCase(tmpPtr[0], tmpPtr[0], length);
 
       tmpPtr[1] = ToNewUnicode(word);
       if (!tmpPtr[1]) {
         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(1, tmpPtr);
         return NS_ERROR_OUT_OF_MEMORY;
       }
 
       *words = tmpPtr;
@@ -240,25 +239,24 @@ NS_IMETHODIMP mozEnglishWordUtils::FindN
     *end = p-word;
   }
   return NS_OK;
 }
 
 mozEnglishWordUtils::myspCapitalization 
 mozEnglishWordUtils::captype(const nsString &word)
 {
-  if(!mCaseConv) return HuhCap; //punt
   PRUnichar* lword=ToNewUnicode(word);  
-  mCaseConv->ToUpper(lword,lword,word.Length());
+  ToUpperCase(lword,lword,word.Length());
   if(word.Equals(lword)){
     nsMemory::Free(lword);
     return AllCap;
   }
 
-  mCaseConv->ToLower(lword,lword,word.Length());
+  ToLowerCase(lword,lword,word.Length());
   if(word.Equals(lword)){
     nsMemory::Free(lword);
     return NoCap;
   }
   PRInt32 length=word.Length();
   if(Substring(word,1,length-1).Equals(lword+1)){
     nsMemory::Free(lword);
     return InitCap;
@@ -293,20 +291,22 @@ NS_IMETHODIMP mozEnglishWordUtils::FromR
     mozEnglishWordUtils::myspCapitalization newCt=captype(capTest);
     if(newCt == NoCap){
       switch(ct) 
         {
         case HuhCap:
         case NoCap:
           break;
         case AllCap:
-          rv = mCaseConv->ToUpper(tmpPtr[i],tmpPtr[i],length);
+          ToUpperCase(tmpPtr[i],tmpPtr[i],length);
+          rv = NS_OK;
           break;
         case InitCap:  
-          rv = mCaseConv->ToUpper(tmpPtr[i],tmpPtr[i],1);
+          ToUpperCase(tmpPtr[i],tmpPtr[i],1);
+          rv = NS_OK;
           break;
         default:
           rv = NS_ERROR_FAILURE; // should never get here;
           break;
 
         }
     }
   }
--- a/extensions/spellcheck/src/mozEnglishWordUtils.h
+++ b/extensions/spellcheck/src/mozEnglishWordUtils.h
@@ -38,17 +38,16 @@
 #ifndef mozEnglishWordUtils_h__
 #define mozEnglishWordUtils_h__
 
 #include "nsCOMPtr.h"
 #include "mozISpellI18NUtil.h"
 #include "nsIUnicodeEncoder.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsString.h"
-#include "nsICaseConversion.h"
 #include "nsIUGenCategory.h"
 
 #include "mozITXTToHTMLConv.h" 
 #include "nsCycleCollectionParticipant.h"
 
 class mozEnglishWordUtils : public mozISpellI18NUtil
 {
 public:
@@ -64,14 +63,13 @@ public:
   };  
 
 protected:
   mozEnglishWordUtils::myspCapitalization captype(const nsString &word);
   PRBool ucIsAlpha(PRUnichar aChar);
 
   nsString mLanguage;
   nsString mCharset;
-  nsCOMPtr<nsICaseConversion> mCaseConv;
   nsCOMPtr<nsIUGenCategory>   mCategories;
   nsCOMPtr<mozITXTToHTMLConv> mURLDetector; // used to detect urls so the spell checker can skip them.
 };
 
 #endif
--- a/intl/build/nsI18nModule.cpp
+++ b/intl/build/nsI18nModule.cpp
@@ -54,17 +54,16 @@
 #include "nsLocaleConstructors.h"
 
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSemanticUnitScanner)
 
 NS_DEFINE_NAMED_CID(NS_LBRK_CID);
 NS_DEFINE_NAMED_CID(NS_WBRK_CID);
 NS_DEFINE_NAMED_CID(NS_SEMANTICUNITSCANNER_CID);
-NS_DEFINE_NAMED_CID(NS_UNICHARUTIL_CID);
 NS_DEFINE_NAMED_CID(NS_UNICHARCATEGORY_CID);
 NS_DEFINE_NAMED_CID(NS_ENTITYCONVERTER_CID);
 NS_DEFINE_NAMED_CID(NS_SAVEASCHARSET_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODE_NORMALIZER_CID);
 NS_DEFINE_NAMED_CID(NS_STRINGBUNDLESERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_STRINGBUNDLETEXTOVERRIDE_CID);
 NS_DEFINE_NAMED_CID(NS_LOCALESERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_COLLATIONFACTORY_CID);
@@ -90,17 +89,16 @@ NS_DEFINE_NAMED_CID(NS_OS2LOCALE_CID);
 NS_DEFINE_NAMED_CID(NS_COLLATION_CID);
 NS_DEFINE_NAMED_CID(NS_DATETIMEFORMAT_CID);
 #endif
 
 static const mozilla::Module::CIDEntry kIntlCIDs[] = {
     { &kNS_LBRK_CID, false, NULL, nsJISx4051LineBreakerConstructor },
     { &kNS_WBRK_CID, false, NULL, nsSampleWordBreakerConstructor },
     { &kNS_SEMANTICUNITSCANNER_CID, false, NULL, nsSemanticUnitScannerConstructor },
-    { &kNS_UNICHARUTIL_CID, false, NULL, nsCaseConversionImp2Constructor },
     { &kNS_UNICHARCATEGORY_CID, false, NULL, nsCategoryImpConstructor },
     { &kNS_ENTITYCONVERTER_CID, false, NULL, nsEntityConverterConstructor },
     { &kNS_SAVEASCHARSET_CID, false, NULL, nsSaveAsCharsetConstructor },
     { &kNS_UNICODE_NORMALIZER_CID, false, NULL, nsUnicodeNormalizerConstructor },
     { &kNS_STRINGBUNDLESERVICE_CID, false, NULL, nsStringBundleServiceConstructor },
     { &kNS_STRINGBUNDLETEXTOVERRIDE_CID, false, NULL, nsStringBundleTextOverrideConstructor },
     { &kNS_LOCALESERVICE_CID, false, NULL, CreateLocaleService },
     { &kNS_COLLATIONFACTORY_CID, false, NULL, nsCollationFactoryConstructor },
@@ -128,17 +126,16 @@ static const mozilla::Module::CIDEntry k
 #endif
     { NULL }
 };
 
 static const mozilla::Module::ContractIDEntry kIntlContracts[] = {
     { NS_LBRK_CONTRACTID, &kNS_LBRK_CID },
     { NS_WBRK_CONTRACTID, &kNS_WBRK_CID },
     { NS_SEMANTICUNITSCANNER_CONTRACTID, &kNS_SEMANTICUNITSCANNER_CID },
-    { NS_UNICHARUTIL_CONTRACTID, &kNS_UNICHARUTIL_CID },
     { NS_UNICHARCATEGORY_CONTRACTID, &kNS_UNICHARCATEGORY_CID },
     { NS_ENTITYCONVERTER_CONTRACTID, &kNS_ENTITYCONVERTER_CID },
     { NS_SAVEASCHARSET_CONTRACTID, &kNS_SAVEASCHARSET_CID },
     { NS_UNICODE_NORMALIZER_CONTRACTID, &kNS_UNICODE_NORMALIZER_CID },
     { NS_STRINGBUNDLE_CONTRACTID, &kNS_STRINGBUNDLESERVICE_CID },
     { NS_STRINGBUNDLETEXTOVERRIDE_CONTRACTID, &kNS_STRINGBUNDLETEXTOVERRIDE_CID },
     { NS_LOCALESERVICE_CONTRACTID, &kNS_LOCALESERVICE_CID },
     { NS_COLLATIONFACTORY_CONTRACTID, &kNS_COLLATIONFACTORY_CID },
--- a/intl/locale/src/nsCollation.cpp
+++ b/intl/locale/src/nsCollation.cpp
@@ -36,17 +36,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIPlatformCharset.h"
 #include "nsIServiceManager.h"
 #include "nsIComponentManager.h"
 #include "nsCollation.h"
 #include "nsCollationCID.h"
-#include "nsUnicharUtilCIID.h"
+#include "nsUnicharUtils.h"
 #include "prmem.h"
 #include "nsReadableUtils.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_DEFINE_CID(kCollationCID, NS_COLLATION_CID);
 
 NS_IMPL_ISUPPORTS1(nsCollationFactory, nsICollationFactory)
@@ -69,49 +69,41 @@ nsresult nsCollationFactory::CreateColla
   return res;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 nsCollation::nsCollation()
 {
   MOZ_COUNT_CTOR(nsCollation);
-  nsresult res;
-  mCaseConversion = do_GetService(NS_UNICHARUTIL_CONTRACTID, &res);
-  NS_ASSERTION(NS_SUCCEEDED(res), "CreateInstance failed for kCaseConversionIID");
 }
 
 nsCollation::~nsCollation()
 {
   MOZ_COUNT_DTOR(nsCollation);
 }
 
 nsresult nsCollation::NormalizeString(const nsAString& stringIn, nsAString& stringOut)
 {
-  if (!mCaseConversion) {
-    stringOut = stringIn;
+  PRInt32 aLength = stringIn.Length();
+
+  if (aLength <= 64) {
+    PRUnichar conversionBuffer[64];
+    ToLowerCase(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
+    stringOut.Assign(conversionBuffer, aLength);
   }
   else {
-    PRInt32 aLength = stringIn.Length();
-
-    if (aLength <= 64) {
-      PRUnichar conversionBuffer[64];
-      mCaseConversion->ToLower(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
-      stringOut.Assign(conversionBuffer, aLength);
+    PRUnichar* conversionBuffer;
+    conversionBuffer = new PRUnichar[aLength];
+    if (!conversionBuffer) {
+      return NS_ERROR_OUT_OF_MEMORY;
     }
-    else {
-      PRUnichar* conversionBuffer;
-      conversionBuffer = new PRUnichar[aLength];
-      if (!conversionBuffer) {
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-      mCaseConversion->ToLower(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
-      stringOut.Assign(conversionBuffer, aLength);
-      delete [] conversionBuffer;
-    }
+    ToLowerCase(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
+    stringOut.Assign(conversionBuffer, aLength);
+    delete [] conversionBuffer;
   }
   return NS_OK;
 }
 
 nsresult nsCollation::SetCharset(const char* aCharset)
 {
   NS_ENSURE_ARG_POINTER(aCharset);
 
--- a/intl/locale/src/nsCollation.h
+++ b/intl/locale/src/nsCollation.h
@@ -36,17 +36,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #ifndef nsCollation_h__
 #define nsCollation_h__
 
 
 #include "nsICollation.h"
-#include "nsICaseConversion.h"
 #include "nsICharsetConverterManager.h"
 #include "nsCOMPtr.h"
 
 
 // Create a collation interface for an input locale.
 // 
 class nsCollationFactory: public nsICollationFactory {
 
@@ -70,13 +69,12 @@ public:
   // normalize string before collation key generation
   nsresult NormalizeString(const nsAString& stringIn, nsAString& stringOut);
 
   // charset conversion util, C string buffer is allocate by PR_Malloc, caller should call PR_Free
   nsresult SetCharset(const char* aCharset);
   nsresult UnicodeToChar(const nsAString& aSrc, char** dst);
 
 protected:
-  nsCOMPtr <nsICaseConversion>            mCaseConversion;
   nsCOMPtr <nsIUnicodeEncoder>            mEncoder;
 };
 
 #endif  /* nsCollation_h__ */
--- a/intl/unicharutil/src/nsCaseConversionImp2.cpp
+++ b/intl/unicharutil/src/nsCaseConversionImp2.cpp
@@ -31,315 +31,65 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "pratom.h"
-#include "nsUUDll.h"
 #include "nsCaseConversionImp2.h"
-#include "casetable.h"
-
-// For gUpperToTitle 
-enum {
-  kUpperIdx =0,
-  kTitleIdx
-};
-
-// For gUpperToTitle
-enum {
-  kLowIdx =0,
-  kSizeEveryIdx,
-  kDiffIdx
-};
-
-#define IS_ASCII(u)       ( 0x0000 == ((u) & 0xFF80))
-#define IS_ASCII_UPPER(u) ((0x0041 <= (u)) && ( (u) <= 0x005a))
-#define IS_ASCII_LOWER(u) ((0x0061 <= (u)) && ( (u) <= 0x007a))
-#define IS_ASCII_ALPHA(u) (IS_ASCII_UPPER(u) || IS_ASCII_LOWER(u))
-#define IS_ASCII_SPACE(u) ( 0x0020 == (u) )
-
-#define IS_NOCASE_CHAR(u)  (0==(1&(gCaseBlocks[(u)>>13]>>(0x001F&((u)>>8)))))
-  
-// Size of Tables
-
-#define CASE_MAP_CACHE_SIZE 0x40
-#define CASE_MAP_CACHE_MASK 0x3F
-
-nsCaseConversionImp2* gCaseConv = nsnull;
-
-struct nsCompressedMap {
-  const PRUnichar *mTable;
-  PRUint32 mSize;
-  PRUint32 mCache[CASE_MAP_CACHE_SIZE];
-  PRUint32 mLastBase;
-
-  PRUnichar Map(PRUnichar aChar)
-  {
-    // no need to worry about thread safety since cached values are
-    // not objects but primitive data types which could be 
-    // accessed in atomic operations. We need to access
-    // the whole 32 bit of cachedData at once in order to make it
-    // thread safe. Never access bits from mCache directly.
-
-    PRUint32 cachedData = mCache[aChar & CASE_MAP_CACHE_MASK];
-    if(aChar == ((cachedData >> 16) & 0x0000FFFF))
-      return (cachedData & 0x0000FFFF);
-
-    // try the last index first
-    // store into local variable so we can be thread safe
-    PRUint32 base = mLastBase; 
-    PRUnichar res = 0;
-    
-    if (( aChar <=  ((mTable[base+kSizeEveryIdx] >> 8) + 
-                  mTable[base+kLowIdx])) &&
-        ( mTable[base+kLowIdx]  <= aChar )) 
-    {
-        // Hit the last base
-        if(((mTable[base+kSizeEveryIdx] & 0x00FF) > 0) && 
-          (0 != ((aChar - mTable[base+kLowIdx]) % 
-                (mTable[base+kSizeEveryIdx] & 0x00FF))))
-        {
-          res = aChar;
-        } else {
-          res = aChar + mTable[base+kDiffIdx];
-        }
-    } else {
-        res = this->Lookup(0, (mSize/2), mSize-1, aChar);
-    }
-
-    mCache[aChar & CASE_MAP_CACHE_MASK] =
-        (((aChar << 16) & 0xFFFF0000) | (0x0000FFFF & res));
-    return res;
-  }
-
-  PRUnichar Lookup(PRUint32 l,
-                   PRUint32 m,
-                   PRUint32 r,
-                   PRUnichar aChar)
-  {
-    PRUint32 base = m*3;
-    if ( aChar >  ((mTable[base+kSizeEveryIdx] >> 8) + 
-                  mTable[base+kLowIdx])) 
-    {
-      if( l > m )
-        return aChar;
-      PRUint32 newm = (m+r+1)/2;
-      if(newm == m)
-        newm++;
-      return this->Lookup(m+1, newm , r, aChar);
-      
-    } else if ( mTable[base+kLowIdx]  > aChar ) {
-      if( r < m )
-        return aChar;
-      PRUint32 newm = (l+m-1)/2;
-      if(newm == m)
-        newm++;
-      return this->Lookup(l, newm, m-1, aChar);
-
-    } else  {
-      if(((mTable[base+kSizeEveryIdx] & 0x00FF) > 0) && 
-        (0 != ((aChar - mTable[base+kLowIdx]) % 
-                (mTable[base+kSizeEveryIdx] & 0x00FF))))
-      {
-        return aChar;
-      }
-      mLastBase = base; // cache the base
-      return aChar + mTable[base+kDiffIdx];
-    }
-  }
-};
-
-static nsCompressedMap gUpperMap = {
-  reinterpret_cast<const PRUnichar*>(&gToUpper[0]),
-  gToUpperItems
-};
-
-static nsCompressedMap gLowerMap = {
-  reinterpret_cast<const PRUnichar*>(&gToLower[0]),
-  gToLowerItems
-};
-
-nsCaseConversionImp2* nsCaseConversionImp2::GetInstance()
-{
-  if (!gCaseConv)
-    gCaseConv = new nsCaseConversionImp2();
-  return gCaseConv;
-}
+#include "nsUnicharUtils.h"
 
 NS_IMETHODIMP_(nsrefcnt) nsCaseConversionImp2::AddRef(void)
 {
   return (nsrefcnt)1;
 }
 
 NS_IMETHODIMP_(nsrefcnt) nsCaseConversionImp2::Release(void)
 {
   return (nsrefcnt)1;
 }
 
 NS_IMPL_THREADSAFE_QUERY_INTERFACE1(nsCaseConversionImp2, nsICaseConversion)
 
-nsresult nsCaseConversionImp2::ToUpper(
-  PRUnichar aChar, PRUnichar* aReturn
-)
+NS_IMETHODIMP nsCaseConversionImp2::ToUpper(PRUnichar aChar, PRUnichar* aReturn)
 {
-  if( IS_ASCII(aChar)) // optimize for ASCII
-  {
-     if(IS_ASCII_LOWER(aChar))
-        *aReturn = aChar - 0x0020;
-     else
-        *aReturn = aChar;
-  } 
-  else if( IS_NOCASE_CHAR(aChar)) // optimize for block which have no case
-  {
-    *aReturn = aChar;
-  } 
-  else 
-  {
-    *aReturn = gUpperMap.Map(aChar);
-  }
+  *aReturn = ToUpperCase(aChar);
   return NS_OK;
 }
 
-// a non-virtual version of ToLower
-static PRUnichar FastToLower(
-  PRUnichar aChar
-)
+NS_IMETHODIMP nsCaseConversionImp2::ToLower(PRUnichar aChar, PRUnichar* aReturn)
 {
-  if( IS_ASCII(aChar)) // optimize for ASCII
-  {
-     if(IS_ASCII_UPPER(aChar))
-        return aChar + 0x0020;
-     else
-        return aChar;
-  }
-  else if( IS_NOCASE_CHAR(aChar)) // optimize for block which have no case
-  {
-     return aChar;
-  }
-
-  return gLowerMap.Map(aChar);
-}
-
-nsresult nsCaseConversionImp2::ToLower(
-  PRUnichar aChar, PRUnichar* aReturn
-)
-{
-  *aReturn = FastToLower(aChar);
+  *aReturn = ToLowerCase(aChar);
   return NS_OK;
 }
 
-nsresult nsCaseConversionImp2::ToTitle(
-  PRUnichar aChar, PRUnichar* aReturn
-)
+NS_IMETHODIMP nsCaseConversionImp2::ToTitle(PRUnichar aChar, PRUnichar* aReturn)
 {
-  if( IS_ASCII(aChar)) // optimize for ASCII
-  {
-    return this->ToUpper(aChar, aReturn);
-  }
-  else if( IS_NOCASE_CHAR(aChar)) // optimize for block which have no case
-  {
-    *aReturn = aChar;
-  } 
-  else
-  {
-    // First check for uppercase characters whose titlecase mapping is
-    //  different, like U+01F1 DZ: they must remain unchanged.
-    if( 0x01C0 == ( aChar & 0xFFC0)) // 0x01Cx - 0x01Fx
-    {
-      for(PRUint32 i = 0 ; i < gUpperToTitleItems; i++) {
-        if ( aChar == gUpperToTitle[(i*2)+kUpperIdx]) {
-          *aReturn = aChar;
-          return NS_OK;
-        }
-      }
-    }
-
-    PRUnichar upper = gUpperMap.Map(aChar);
-    
-    if( 0x01C0 == ( upper & 0xFFC0)) // 0x01Cx - 0x01Fx
-    {
-      for(PRUint32 i = 0 ; i < gUpperToTitleItems; i++) {
-        if ( upper == gUpperToTitle[(i*2)+kUpperIdx]) {
-           *aReturn = gUpperToTitle[(i*2)+kTitleIdx];
-           return NS_OK;
-        }
-      }
-    }
-    *aReturn = upper;
-  }
+  *aReturn = ToTitleCase(aChar);
   return NS_OK;
 }
 
-nsresult nsCaseConversionImp2::ToUpper(
-  const PRUnichar* anArray, PRUnichar* aReturn, PRUint32 aLen
-)
+NS_IMETHODIMP nsCaseConversionImp2::ToUpper(const PRUnichar* anArray,
+                                         PRUnichar* aReturn,
+                                         PRUint32 aLen)
 {
-  PRUint32 i;
-  for(i=0;i<aLen;i++) 
-  {
-    PRUnichar aChar = anArray[i];
-    if( IS_ASCII(aChar)) // optimize for ASCII
-    {
-       if(IS_ASCII_LOWER(aChar))
-          aReturn[i] = aChar - 0x0020;
-       else
-          aReturn[i] = aChar;
-    }
-    else if( IS_NOCASE_CHAR(aChar)) // optimize for block which have no case
-    {
-          aReturn[i] = aChar;
-    } 
-    else 
-    {
-      aReturn[i] = gUpperMap.Map(aChar);
-    }
-  }
+  ToUpperCase(anArray, aReturn, aLen);
   return NS_OK;
 }
 
-nsresult nsCaseConversionImp2::ToLower(
-  const PRUnichar* anArray, PRUnichar* aReturn, PRUint32 aLen
-)
+NS_IMETHODIMP nsCaseConversionImp2::ToLower(const PRUnichar* anArray,
+                                         PRUnichar* aReturn,
+                                         PRUint32 aLen)
 {
-  PRUint32 i;
-  for(i=0;i<aLen;i++) 
-    aReturn[i] = FastToLower(anArray[i]);
+  ToLowerCase(anArray, aReturn, aLen);
   return NS_OK;
 }
 
-
-// implementation moved from the old nsCRT routine
 NS_IMETHODIMP
 nsCaseConversionImp2::CaseInsensitiveCompare(const PRUnichar *aLeft,
                                              const PRUnichar *aRight,
                                              PRUint32 aCount, PRInt32* aResult)
 {
-  if (!aLeft || !aRight)
-    return NS_ERROR_INVALID_POINTER;
-
-  // assume equality. We bail early if no equality
-  *aResult = 0;
-  
-  if (aCount) {
-    do {
-      PRUnichar c1 = *aLeft++;
-      PRUnichar c2 = *aRight++;
-      
-      if (c1 != c2) {
-        c1 = FastToLower(c1);
-        c2 = FastToLower(c2);
-        if (c1 != c2) {
-          if (c1 < c2) {
-            *aResult = -1;
-            return NS_OK;
-          }
-          *aResult = 1;
-          return NS_OK;
-        }
-      }
-    } while (--aCount != 0);
-  }
+  *aResult = ::CaseInsensitiveCompare(aLeft, aRight, aCount);
   return NS_OK;
 }
--- a/intl/unicharutil/src/nsCaseConversionImp2.h
+++ b/intl/unicharutil/src/nsCaseConversionImp2.h
@@ -59,11 +59,9 @@ public:
 
   NS_IMETHOD ToUpper(const PRUnichar* anArray, PRUnichar* aReturn, PRUint32 aLen);
 
   NS_IMETHOD ToLower(const PRUnichar* anArray, PRUnichar* aReturn, PRUint32 aLen);
 
   NS_IMETHOD CaseInsensitiveCompare(const PRUnichar* aLeft, const PRUnichar* aRight, PRUint32 aLength, PRInt32 *aResult);
 };
 
-extern nsCaseConversionImp2* gCaseConv;
-
 #endif
--- a/intl/unicharutil/src/nsUcharUtilConstructors.h
+++ b/intl/unicharutil/src/nsUcharUtilConstructors.h
@@ -34,19 +34,19 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsUcharUtilConstructors_h__
 #define nsUcharUtilConstructors_h__
 
 #include "nsUnicharUtilCIID.h"
-#include "nsCaseConversionImp2.h"
 #include "nsCategoryImp.h"
 #include "nsICaseConversion.h"
+#include "nsCaseConversionImp2.h"
 #include "nsEntityConverter.h"
 #include "nsSaveAsCharset.h"
 #include "nsUUDll.h"
 #include "nsIFile.h"
 #include "nsUnicodeNormalizer.h"
 
 // Functions used to create new instances of a given object by the
 // generic factory.
@@ -71,18 +71,16 @@ CreateNew##_name(nsISupports* aOuter, RE
     rv = inst->QueryInterface(aIID, aResult);                        \
     if (NS_FAILED(rv)) {                                             \
         *aResult = nsnull;                                           \
     }                                                                \
     NS_RELEASE(inst);                /* get rid of extra refcnt */   \
     return rv;                                                       \
 }
 
-
-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsCaseConversionImp2,
-                                         nsCaseConversionImp2::GetInstance)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsCaseConversionImp2)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsCategoryImp,
                                          nsCategoryImp::GetInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsEntityConverter)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSaveAsCharset)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsUnicodeNormalizer)
 
 #endif
--- a/intl/unicharutil/util/Makefile.in
+++ b/intl/unicharutil/util/Makefile.in
@@ -69,16 +69,18 @@ CPPSRCS	= \
 	nsUnicharUtils.cpp \
 	nsBidiUtils.cpp \
 	$(NULL)
 
 FORCE_STATIC_LIB = 1
 FORCE_USE_PIC = 1
 USE_STATIC_LIBS = 1
 
+LOCAL_INCLUDES += -I$(srcdir)/../src
+
 include $(topsrcdir)/config/rules.mk
 
 ifdef _MSC_VER
 # Don't include directives about which CRT to use
 OS_COMPILE_CXXFLAGS += -Zl
 OS_COMPILE_CFLAGS += -Zl
 DEFINES += -D_USE_ANSI_CPP
 endif
--- a/intl/unicharutil/util/internal/Makefile.in
+++ b/intl/unicharutil/util/internal/Makefile.in
@@ -53,16 +53,17 @@ DIST_INSTALL = 1
 EXPORT_LIBRARY = 1
 MOZILLA_INTERNAL_API = 1
 
 include $(srcdir)/../objs.mk
 
 EXTRA_DEPS += $(srcdir)/../objs.mk
 
 LOCAL_INCLUDES	+= -I$(srcdir)/.. \
+  -I$(srcdir)/../../src
 
 
 CPPSRCS	= $(INTL_UNICHARUTIL_UTIL_LCPPSRCS)
 
 FORCE_STATIC_LIB = 1
 FORCE_USE_PIC = 1
 
 include $(topsrcdir)/config/rules.mk
--- a/intl/unicharutil/util/nsUnicharUtils.cpp
+++ b/intl/unicharutil/util/nsUnicharUtils.cpp
@@ -40,187 +40,303 @@
 
 #include "nsUnicharUtils.h"
 #include "nsUnicharUtilCIID.h"
 
 #include "nsCRT.h"
 #include "nsICaseConversion.h"
 #include "nsServiceManagerUtils.h"
 #include "nsXPCOMStrings.h"
+#include "casetable.h"
 
 #include <ctype.h>
 
-static nsICaseConversion* gCaseConv = nsnull;
+// For gUpperToTitle 
+enum {
+  kUpperIdx =0,
+  kTitleIdx
+};
+
+// For gUpperToTitle
+enum {
+  kLowIdx =0,
+  kSizeEveryIdx,
+  kDiffIdx
+};
+
+#define IS_ASCII(u)       ( 0x0000 == ((u) & 0xFF80))
+#define IS_ASCII_UPPER(u) ((0x0041 <= (u)) && ( (u) <= 0x005a))
+#define IS_ASCII_LOWER(u) ((0x0061 <= (u)) && ( (u) <= 0x007a))
+#define IS_ASCII_ALPHA(u) (IS_ASCII_UPPER(u) || IS_ASCII_LOWER(u))
+#define IS_ASCII_SPACE(u) ( 0x0020 == (u) )
+
+#define IS_NOCASE_CHAR(u)  (0==(1&(gCaseBlocks[(u)>>13]>>(0x001F&((u)>>8)))))
+  
+// Size of Tables
+
+#define CASE_MAP_CACHE_SIZE 0x40
+#define CASE_MAP_CACHE_MASK 0x3F
+
+struct nsCompressedMap {
+  const PRUnichar *mTable;
+  PRUint32 mSize;
+  PRUint32 mCache[CASE_MAP_CACHE_SIZE];
+  PRUint32 mLastBase;
+
+  PRUnichar Map(PRUnichar aChar)
+  {
+    // no need to worry about thread safety since cached values are
+    // not objects but primitive data types which could be 
+    // accessed in atomic operations. We need to access
+    // the whole 32 bit of cachedData at once in order to make it
+    // thread safe. Never access bits from mCache directly.
+
+    PRUint32 cachedData = mCache[aChar & CASE_MAP_CACHE_MASK];
+    if(aChar == ((cachedData >> 16) & 0x0000FFFF))
+      return (cachedData & 0x0000FFFF);
 
-nsICaseConversion*
-NS_GetCaseConversion()
-{
-  if (!gCaseConv) {
-    nsresult rv = CallGetService(NS_UNICHARUTIL_CONTRACTID, &gCaseConv);
-    if (NS_FAILED(rv)) {
-      NS_ERROR("Failed to get the case conversion service!");
-      gCaseConv = nsnull;
+    // try the last index first
+    // store into local variable so we can be thread safe
+    PRUint32 base = mLastBase; 
+    PRUnichar res = 0;
+    
+    if (( aChar <=  ((mTable[base+kSizeEveryIdx] >> 8) + 
+                  mTable[base+kLowIdx])) &&
+        ( mTable[base+kLowIdx]  <= aChar )) 
+    {
+        // Hit the last base
+        if(((mTable[base+kSizeEveryIdx] & 0x00FF) > 0) && 
+          (0 != ((aChar - mTable[base+kLowIdx]) % 
+                (mTable[base+kSizeEveryIdx] & 0x00FF))))
+        {
+          res = aChar;
+        } else {
+          res = aChar + mTable[base+kDiffIdx];
+        }
+    } else {
+        res = this->Lookup(0, (mSize/2), mSize-1, aChar);
+    }
+
+    mCache[aChar & CASE_MAP_CACHE_MASK] =
+        (((aChar << 16) & 0xFFFF0000) | (0x0000FFFF & res));
+    return res;
+  }
+
+  PRUnichar Lookup(PRUint32 l,
+                   PRUint32 m,
+                   PRUint32 r,
+                   PRUnichar aChar)
+  {
+    PRUint32 base = m*3;
+    if ( aChar >  ((mTable[base+kSizeEveryIdx] >> 8) + 
+                  mTable[base+kLowIdx])) 
+    {
+      if( l > m )
+        return aChar;
+      PRUint32 newm = (m+r+1)/2;
+      if(newm == m)
+        newm++;
+      return this->Lookup(m+1, newm , r, aChar);
+      
+    } else if ( mTable[base+kLowIdx]  > aChar ) {
+      if( r < m )
+        return aChar;
+      PRUint32 newm = (l+m-1)/2;
+      if(newm == m)
+        newm++;
+      return this->Lookup(l, newm, m-1, aChar);
+
+    } else  {
+      if(((mTable[base+kSizeEveryIdx] & 0x00FF) > 0) && 
+        (0 != ((aChar - mTable[base+kLowIdx]) % 
+                (mTable[base+kSizeEveryIdx] & 0x00FF))))
+      {
+        return aChar;
+      }
+      mLastBase = base; // cache the base
+      return aChar + mTable[base+kDiffIdx];
     }
   }
-  return gCaseConv;
-}
+};
+
+static nsCompressedMap gUpperMap = {
+  reinterpret_cast<const PRUnichar*>(&gToUpper[0]),
+  gToUpperItems
+};
+
+static nsCompressedMap gLowerMap = {
+  reinterpret_cast<const PRUnichar*>(&gToLower[0]),
+  gToLowerItems
+};
 
 void
 ToLowerCase(nsAString& aString)
 {
-  nsICaseConversion* caseConv = NS_GetCaseConversion();
-  if (caseConv) {
-    PRUnichar *buf = aString.BeginWriting();
-    caseConv->ToLower(buf, buf, aString.Length());
-  }
-  else
-    NS_WARNING("No case converter: no conversion done");
+  PRUnichar *buf = aString.BeginWriting();
+  ToLowerCase(buf, buf, aString.Length());
 }
 
 void
 ToLowerCase(const nsAString& aSource,
             nsAString& aDest)
 {
   const PRUnichar *in;
+  PRUnichar *out;
   PRUint32 len = NS_StringGetData(aSource, &in);
-
-  PRUnichar *out;
   NS_StringGetMutableData(aDest, len, &out);
-
-  nsICaseConversion* caseConv = NS_GetCaseConversion();
-  if (out && caseConv)
-    caseConv->ToLower(in, out, len);
-  else {
-    NS_WARNING("No case converter: only copying");
-    aDest.Assign(aSource);
-  }
+  NS_ASSERTION(out, "Uh...");
+  ToLowerCase(in, out, len);
 }
 
 void
 ToUpperCase(nsAString& aString)
 {
-  nsICaseConversion* caseConv = NS_GetCaseConversion();
-  if (caseConv) {
-    PRUnichar *buf = aString.BeginWriting();
-    caseConv->ToUpper(buf, buf, aString.Length());
-  }
-  else
-    NS_WARNING("No case converter: no conversion done");
+  PRUnichar *buf = aString.BeginWriting();
+  ToUpperCase(buf, buf, aString.Length());
 }
 
 void
 ToUpperCase(const nsAString& aSource,
             nsAString& aDest)
 {
   const PRUnichar *in;
+  PRUnichar *out;
   PRUint32 len = NS_StringGetData(aSource, &in);
-
-  PRUnichar *out;
   NS_StringGetMutableData(aDest, len, &out);
-
-  nsICaseConversion* caseConv = NS_GetCaseConversion();
-  if (out && caseConv)
-    caseConv->ToUpper(in, out, len);
-  else {
-    NS_WARNING("No case converter: only copying");
-    aDest.Assign(aSource);
-  }
+  NS_ASSERTION(out, "Uh...");
+  ToUpperCase(in, out, len);
 }
 
 #ifdef MOZILLA_INTERNAL_API
 
 PRInt32
 nsCaseInsensitiveStringComparator::operator()(const PRUnichar* lhs,
                                               const PRUnichar* rhs,
                                               PRUint32 aLength) const
 {
-  PRInt32 result;
-  nsICaseConversion* caseConv = NS_GetCaseConversion();
-  if (caseConv)
-    caseConv->CaseInsensitiveCompare(lhs, rhs, aLength, &result);
-  else {
-    NS_WARNING("No case converter: using default");
-    nsDefaultStringComparator comparator;
-    result = comparator(lhs, rhs, aLength);
-  }
-  return result;
+  return CaseInsensitiveCompare(lhs, rhs, aLength);
 }
 
 PRInt32
 nsCaseInsensitiveStringComparator::operator()(PRUnichar lhs,
                                               PRUnichar rhs) const
 {
   // see if they're an exact match first
   if (lhs == rhs)
     return 0;
   
-  nsICaseConversion* caseConv = NS_GetCaseConversion();
-  if (caseConv) {
-    caseConv->ToLower(lhs, &lhs);
-    caseConv->ToLower(rhs, &rhs);
-  }
-  else {
-    if (lhs < 256)
-      lhs = tolower(char(lhs));
-    if (rhs < 256)
-      rhs = tolower(char(rhs));
-    NS_WARNING("No case converter: no conversion done");
-  }
+  lhs = ToLowerCase(lhs);
+  rhs = ToLowerCase(rhs);
   
   if (lhs == rhs)
     return 0;
   else if (lhs < rhs)
     return -1;
   else
     return 1;
 }
 
-#else // MOZILLA_INTERNAL_API
+#endif // MOZILLA_INTERNAL_API
 
 PRInt32
 CaseInsensitiveCompare(const PRUnichar *a,
                        const PRUnichar *b,
                        PRUint32 len)
 {
-  nsICaseConversion* caseConv = NS_GetCaseConversion();
-  if (!caseConv)
-    return NS_strcmp(a, b);
-
-  PRInt32 result;
-  caseConv->CaseInsensitiveCompare(a, b, len, &result);
-  return result;
+  NS_ASSERTION(a && b, "Do not pass in invalid pointers!");
+  
+  if (len) {
+    do {
+      PRUnichar c1 = *a++;
+      PRUnichar c2 = *b++;
+      
+      if (c1 != c2) {
+        c1 = ToLowerCase(c1);
+        c2 = ToLowerCase(c2);
+        if (c1 != c2) {
+          if (c1 < c2) {
+            return -1;
+          }
+          return 1;
+        }
+      }
+    } while (--len != 0);
+  }
+  return 0;
 }
 
-#endif // MOZILLA_INTERNAL_API
-
 PRUnichar
 ToLowerCase(PRUnichar aChar)
 {
-  PRUnichar result;
-  nsICaseConversion* caseConv = NS_GetCaseConversion();
-  if (caseConv)
-    caseConv->ToLower(aChar, &result);
-  else {
-    NS_WARNING("No case converter: no conversion done");
-    if (aChar < 256)
-      result = tolower(char(aChar));
+  if (IS_ASCII(aChar)) {
+    if (IS_ASCII_UPPER(aChar))
+      return aChar + 0x0020;
     else
-      result = aChar;
+      return aChar;
+  } else if (IS_NOCASE_CHAR(aChar)) {
+     return aChar;
   }
-  return result;
+
+  return gLowerMap.Map(aChar);
+}
+
+void
+ToLowerCase(const PRUnichar *aIn, PRUnichar *aOut, PRUint32 aLen)
+{
+  for (PRUint32 i = 0; i < aLen; i++) {
+    aOut[i] = ToLowerCase(aIn[i]);
+  }
 }
 
 PRUnichar
 ToUpperCase(PRUnichar aChar)
 {
-  PRUnichar result;
-  nsICaseConversion* caseConv = NS_GetCaseConversion();
-  if (caseConv)
-    caseConv->ToUpper(aChar, &result);
-  else {
-    NS_WARNING("No case converter: no conversion done");
-    if (aChar < 256)
-      result = toupper(char(aChar));
+  if (IS_ASCII(aChar)) {
+    if (IS_ASCII_LOWER(aChar))
+      return aChar - 0x0020;
     else
-      result = aChar;
+      return aChar;
+  } else if (IS_NOCASE_CHAR(aChar)) {
+    return aChar;
+  }
+
+  return gUpperMap.Map(aChar);
+}
+
+void
+ToUpperCase(const PRUnichar *aIn, PRUnichar *aOut, PRUint32 aLen)
+{
+  for (PRUint32 i = 0; i < aLen; i++) {
+    aOut[i] = ToUpperCase(aIn[i]);
+  }
+}
+
+PRUnichar
+ToTitleCase(PRUnichar aChar)
+{
+  if (IS_ASCII(aChar)) {
+    return ToUpperCase(aChar);
+  } else if (IS_NOCASE_CHAR(aChar)) {
+    return aChar;
   }
-  return result;
+
+  // First check for uppercase characters whose titlecase mapping is
+  // different, like U+01F1 DZ: they must remain unchanged.
+  if (0x01C0 == (aChar & 0xFFC0)) {
+    for (PRUint32 i = 0; i < gUpperToTitleItems; i++) {
+      if (aChar == gUpperToTitle[(i*2)+kUpperIdx]) {
+        return aChar;
+      }
+    }
+  }
+
+  PRUnichar upper = gUpperMap.Map(aChar);
+  
+  if (0x01C0 == ( upper & 0xFFC0)) {
+    for (PRUint32 i = 0 ; i < gUpperToTitleItems; i++) {
+      if (upper == gUpperToTitle[(i*2)+kUpperIdx]) {
+         return gUpperToTitle[(i*2)+kTitleIdx];
+      }
+    }
+  }
+
+  return upper;
 }
--- a/intl/unicharutil/util/nsUnicharUtils.h
+++ b/intl/unicharutil/util/nsUnicharUtils.h
@@ -51,37 +51,41 @@
    (0xff00u <= (u) && (u) <= 0xffefu) )
 
 void ToLowerCase(nsAString&);
 void ToUpperCase(nsAString&);
 
 void ToLowerCase(const nsAString& aSource, nsAString& aDest);
 void ToUpperCase(const nsAString& aSource, nsAString& aDest);
 
+PRUnichar ToLowerCase(PRUnichar);
 PRUnichar ToUpperCase(PRUnichar);
-PRUnichar ToLowerCase(PRUnichar);
+PRUnichar ToTitleCase(PRUnichar);
+
+void ToLowerCase(const PRUnichar*, PRUnichar*, PRUint32);
+void ToUpperCase(const PRUnichar*, PRUnichar*, PRUint32);
 
 inline PRBool IsUpperCase(PRUnichar c) {
   return ToLowerCase(c) != c;
 }
 
 inline PRBool IsLowerCase(PRUnichar c) {
   return ToUpperCase(c) != c;
 }
 
 #ifdef MOZILLA_INTERNAL_API
 
 class nsCaseInsensitiveStringComparator : public nsStringComparator
 {
 public:
-  virtual int operator() (const PRUnichar*,
-                          const PRUnichar*,
-                          PRUint32 aLength) const;
-  virtual int operator() (PRUnichar,
-                          PRUnichar) const;
+  virtual PRInt32 operator() (const PRUnichar*,
+                              const PRUnichar*,
+                              PRUint32 aLength) const;
+  virtual PRInt32 operator() (PRUnichar,
+                              PRUnichar) const;
 };
 
 class nsCaseInsensitiveStringArrayComparator
 {
 public:
   template<class A, class B>
   PRBool Equals(const A& a, const B& b) const {
     return a.Equals(b, nsCaseInsensitiveStringComparator());
@@ -102,16 +106,14 @@ CaseInsensitiveFindInReadable(const nsAS
                               const nsAString& aHay)
 {
   nsAString::const_iterator searchBegin, searchEnd;
   return FindInReadable(aPattern, aHay.BeginReading(searchBegin),
                         aHay.EndReading(searchEnd),
                         nsCaseInsensitiveStringComparator());
 }
 
-#else // MOZILLA_INTERNAL_API
+#endif // MOZILLA_INTERNAL_API
 
-NS_HIDDEN_(PRInt32)
+PRInt32
 CaseInsensitiveCompare(const PRUnichar *a, const PRUnichar *b, PRUint32 len);
 
-#endif // MOZILLA_INTERNAL_API
-
 #endif  /* nsUnicharUtils_h__ */
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -79,17 +79,16 @@
 #include "nsFrame.h"
 #include "nsPlaceholderFrame.h"
 #include "nsTextFrameUtils.h"
 #include "nsTextRunTransformations.h"
 #include "nsFrameManager.h"
 #include "nsTextFrameTextRunCache.h"
 #include "nsExpirationTracker.h"
 #include "nsTextFrame.h"
-#include "nsICaseConversion.h"
 #include "nsIUGenCategory.h"
 #include "nsUnicharUtilCIID.h"
 
 #include "nsTextFragment.h"
 #include "nsGkAtoms.h"
 #include "nsFrameSelection.h"
 #include "nsISelection.h"
 #include "nsIDOMRange.h"
@@ -6760,24 +6759,24 @@ nsTextFrame::RecomputeOverflowRect()
 static PRUnichar TransformChar(const nsStyleText* aStyle, gfxTextRun* aTextRun,
                                PRUint32 aSkippedOffset, PRUnichar aChar)
 {
   if (aChar == '\n') {
     return aStyle->NewlineIsSignificant() ? aChar : ' ';
   }
   switch (aStyle->mTextTransform) {
   case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
-    nsContentUtils::GetCaseConv()->ToLower(aChar, &aChar);
+    aChar = ToLowerCase(aChar);
     break;
   case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
-    nsContentUtils::GetCaseConv()->ToUpper(aChar, &aChar);
+    aChar = ToUpperCase(aChar);
     break;
   case NS_STYLE_TEXT_TRANSFORM_CAPITALIZE:
     if (aTextRun->CanBreakLineBefore(aSkippedOffset)) {
-      nsContentUtils::GetCaseConv()->ToTitle(aChar, &aChar);
+      aChar = ToTitleCase(aChar);
     }
     break;
   }
 
   return aChar;
 }
 
 nsresult nsTextFrame::GetRenderedText(nsAString* aAppendToString,
--- a/layout/generic/nsTextRunTransformations.cpp
+++ b/layout/generic/nsTextRunTransformations.cpp
@@ -35,21 +35,21 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsTextRunTransformations.h"
 
 #include "nsTextFrameUtils.h"
 #include "gfxSkipChars.h"
 
-#include "nsICaseConversion.h"
 #include "nsStyleConsts.h"
 #include "nsStyleContext.h"
 #include "gfxContext.h"
 #include "nsContentUtils.h"
+#include "nsUnicharUtils.h"
 
 #define SZLIG 0x00DF
 
 nsTransformedTextRun *
 nsTransformedTextRun::Create(const gfxTextRunFactory::Parameters* aParams,
                              nsTransformingTextRunFactory* aFactory,
                              gfxFontGroup* aFontGroup,
                              const PRUnichar* aString, PRUint32 aLength,
@@ -229,20 +229,16 @@ GetParametersForInner(nsTransformedTextR
   *aFlags = aTextRun->GetFlags() & ~gfxFontGroup::TEXT_IS_PERSISTENT;
   return params;
 }
 
 void
 nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
     gfxContext* aRefContext)
 {
-  nsICaseConversion* converter = nsContentUtils::GetCaseConv();
-  if (!converter)
-    return;
-
   gfxFontGroup* fontGroup = aTextRun->GetFontGroup();
   gfxFontStyle fontStyle = *fontGroup->GetStyle();
   fontStyle.size *= 0.8;
   nsRefPtr<gfxFontGroup> smallFont = fontGroup->Copy(&fontStyle);
   if (!smallFont)
     return;
 
   PRUint32 flags;
@@ -274,17 +270,17 @@ nsFontVariantTextRunFactory::RebuildText
       // Characters that aren't the start of a cluster are ignored here. They
       // get added to whatever lowercase/non-lowercase run we're in.
       if (!inner->IsClusterStart(i)) {
         isLowercase = runIsLowercase;
       } else {
         if (styles[i]->GetStyleFont()->mFont.variant == NS_STYLE_FONT_VARIANT_SMALL_CAPS) {
           PRUnichar ch = str[i];
           PRUnichar ch2;
-          converter->ToUpper(ch, &ch2);
+          ch2 = ToUpperCase(ch);
           isLowercase = ch != ch2 || ch == SZLIG;
         } else {
           // Don't transform the character! I.e., pretend that it's not lowercase
         }
       }
     }
 
     if ((i == length || runIsLowercase != isLowercase) && runStart < i) {
@@ -327,20 +323,16 @@ nsFontVariantTextRunFactory::RebuildText
     }
   }
 }
 
 void
 nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
     gfxContext* aRefContext)
 {
-  nsICaseConversion* converter = nsContentUtils::GetCaseConv();
-  if (!converter)
-    return;
-
   PRUint32 length = aTextRun->GetLength();
   const PRUnichar* str = aTextRun->GetTextUnicode();
   nsRefPtr<nsStyleContext>* styles = aTextRun->mStyles.Elements();
 
   nsAutoString convertedString;
   nsAutoTArray<PRPackedBool,50> charsToMergeArray;
   nsAutoTArray<nsStyleContext*,50> styleArray;
   nsAutoTArray<PRPackedBool,50> canBreakBeforeArray;
@@ -355,35 +347,35 @@ nsCaseTransformTextRunFactory::RebuildTe
     canBreakBeforeArray.AppendElement(aTextRun->CanBreakLineBefore(i));
 
     PRUint8 style = mAllUppercase ? NS_STYLE_TEXT_TRANSFORM_UPPERCASE
       : styles[i]->GetStyleText()->mTextTransform;
     PRBool extraChar = PR_FALSE;
 
     switch (style) {
     case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
-      converter->ToLower(ch, &ch);
+      ch = ToLowerCase(ch);
       break;
     case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
       if (ch == SZLIG) {
         convertedString.Append('S');
         extraChar = PR_TRUE;
         ch = 'S';
       } else {
-        converter->ToUpper(ch, &ch);
+        ch = ToUpperCase(ch);
       }
       break;
     case NS_STYLE_TEXT_TRANSFORM_CAPITALIZE:
       if (i < aTextRun->mCapitalize.Length() && aTextRun->mCapitalize[i]) {
         if (ch == SZLIG) {
           convertedString.Append('S');
           extraChar = PR_TRUE;
           ch = 'S';
         } else {
-          converter->ToTitle(ch, &ch);
+          ch = ToTitleCase(ch);
         }
       }
       break;
     default:
       break;
     }
 
     convertedString.Append(ch);
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -133,17 +133,18 @@ CPPSRCS += \
 	$(NULL)
 
 GARBAGE	+= \
 	$(INTL_UNICHARUTIL_UTIL_LCPPSRCS) \
 	$(wildcard *.$(OBJ_SUFFIX)) \
 	dlldeps-javaxpcom.cpp \
 	$(NULL)
 
-LOCAL_INCLUDES += -I$(topsrcdir)/intl/unicharutil/util
+LOCAL_INCLUDES += -I$(topsrcdir)/intl/unicharutil/util \
+  -I$(topsrcdir)/intl/unicharutil/src
 
 ifdef MOZ_RDF
 EXTRA_DEPS += \
 	$(topsrcdir)/rdf/util/src/objs.mk \
 	$(NULL)
 
 
 CPPSRCS += \