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
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 += \