Bug 377319 Convert mailnews/compose to the external API r=Neil sr=bienvenu
authorJan Horak <jhorak@redhat.com>
Sat, 19 Jun 2010 11:45:19 +0100
changeset 5732 cd4402569153c86725797c26ae610cc85064dba6
parent 5731 4e969d819c3a965d11df0f34aa5c109af3171c8d
child 5733 18235de07174fe0984c929101cbab85f1fe148b8
push idunknown
push userunknown
push dateunknown
reviewersNeil, bienvenu
bugs377319
Bug 377319 Convert mailnews/compose to the external API r=Neil sr=bienvenu
mailnews/compose/src/nsMsgAttachmentHandler.cpp
mailnews/compose/src/nsMsgCompFields.cpp
mailnews/compose/src/nsMsgCompFields.h
mailnews/compose/src/nsMsgCompUtils.cpp
mailnews/compose/src/nsMsgCompose.cpp
mailnews/compose/src/nsMsgCompose.h
mailnews/compose/src/nsMsgComposeParams.h
mailnews/compose/src/nsMsgComposeService.cpp
mailnews/compose/src/nsMsgCopy.cpp
mailnews/compose/src/nsMsgPrompts.cpp
mailnews/compose/src/nsMsgSend.cpp
mailnews/compose/src/nsMsgSend.h
mailnews/compose/src/nsSmtpProtocol.cpp
mailnews/compose/src/nsSmtpServer.cpp
mailnews/compose/src/nsSmtpService.cpp
mailnews/compose/src/nsSmtpUrl.cpp
mailnews/compose/src/nsURLFetcher.cpp
--- a/mailnews/compose/src/nsMsgAttachmentHandler.cpp
+++ b/mailnews/compose/src/nsMsgAttachmentHandler.cpp
@@ -42,24 +42,22 @@
 #include "nsIPrefBranch.h"
 #include "nsMsgSend.h"
 #include "nsMsgCompUtils.h"
 #include "nsMsgEncoders.h"
 #include "nsMsgI18N.h"
 #include "nsURLFetcher.h"
 #include "nsMimeTypes.h"
 #include "nsMsgCompCID.h"
-#include "nsReadableUtils.h"
 #include "nsIMsgMessageService.h"
 #include "nsMsgUtils.h"
 #include "nsMsgPrompts.h"
 #include "nsTextFormatter.h"
 #include "nsIPrompt.h"
 #include "nsITextToSubURI.h"
-#include "nsEscape.h"
 #include "nsIURL.h"
 #include "nsIFileURL.h"
 #include "nsNetCID.h"
 #include "nsIMimeStreamConverter.h"
 #include "nsMsgMimeCID.h"
 #include "nsNetUtil.h"
 #include "nsNativeCharsetUtils.h"
 #include "nsComposeStrings.h"
@@ -99,17 +97,18 @@ nsresult nsSimpleZipper::Zip(nsIFile *aI
 /* static */
 nsresult nsSimpleZipper::AddToZip(nsIZipWriter *aZipWriter, 
                                   nsIFile *aFile,
                                   const nsACString &aPath)
 {
   // find out the path this file/dir should have in the zip
   nsCString leafName;
   aFile->GetNativeLeafName(leafName);
-  nsCString currentPath(aPath + leafName);
+  nsCString currentPath(aPath);
+  currentPath += leafName;
     
   PRBool isDirectory;
   aFile->IsDirectory(&isDirectory);
   // append slash for a directory entry
   if (isDirectory)
     currentPath.Append('/');
   
   // add the file or directory entry to the zip
@@ -587,17 +586,17 @@ nsMsgAttachmentHandler::SnarfMsgAttachme
       goto done;
     }
 
     rv = fetcher->Initialize(mTmpFile, mOutFile, FetcherURLDoneCallback, this);
     rv = GetMessageServiceFromURI(nsDependentCString(m_uri), getter_AddRefs(messageService));
     if (NS_SUCCEEDED(rv) && messageService)
     {
       nsCAutoString uri(m_uri);
-      uri += (uri.FindChar('?') == kNotFound) ? "?" : "&";
+      uri += (uri.FindChar('?') == kNotFound) ? '?' : '&';
       uri.Append("fetchCompleteMessage=true");
       nsCOMPtr<nsIStreamListener> strListener;
       fetcher->QueryInterface(NS_GET_IID(nsIStreamListener), getter_AddRefs(strListener));
 
       // initialize a new stream converter, that uses the strListener as its input
       // obtain the input stream listener from the new converter,
       // and pass the converter's input stream listener to DisplayMessage
 
@@ -706,32 +705,33 @@ nsMsgAttachmentHandler::SnarfAttachment(
   nsCString sourceURISpec;
   mURL->GetSpec(sourceURISpec);
 #ifdef XP_MACOSX
   if (!m_bogus_attachment && StringBeginsWith(sourceURISpec, NS_LITERAL_CSTRING("file://")))
   {
     // Unescape the path (i.e. un-URLify it) before making a FSSpec
     nsCAutoString filePath;
     filePath.Adopt(nsMsgGetLocalFileFromURL(sourceURISpec.get()));
-    nsUnescape(filePath.BeginWriting());
+    nsCAutoString unescapedFilePath;
+    MsgUnescapeString(filePath, 0, unescapedFilePath);
 
     nsCOMPtr<nsILocalFile> sourceFile;
-    NS_NewNativeLocalFile(filePath, PR_TRUE, getter_AddRefs(sourceFile));
+    NS_NewNativeLocalFile(unescapedFilePath, PR_TRUE, getter_AddRefs(sourceFile));
     if (!sourceFile)
       return NS_ERROR_FAILURE;
       
     // check if it is a bundle. if it is, we'll zip it. 
     // if not, we'll apple encode it (applesingle or appledouble)
     nsCOMPtr<nsILocalFileMac> macFile(do_QueryInterface(sourceFile));
     PRBool isPackage;
     macFile->IsPackage(&isPackage);
     if (isPackage)
       rv = ConvertToZipFile(macFile);
     else
-      rv = ConvertToAppleEncoding(sourceURISpec, filePath, macFile);
+      rv = ConvertToAppleEncoding(sourceURISpec, unescapedFilePath, macFile);
     
     NS_ENSURE_SUCCESS(rv, rv);
   }
 #endif /* XP_MACOSX */
 
   //
   // Ok, here we are, we need to fire the URL off and get the data
   // in the temp file
@@ -1014,23 +1014,24 @@ nsMsgAttachmentHandler::LoadDataFromFile
   if (!readBuf)
     return NS_ERROR_OUT_OF_MEMORY;
   memset(readBuf, 0, readSize + 1);
 
   PRUint32 bytesRead;
   inputFile->Read(readBuf, readSize, &bytesRead);
   inputFile->Close();
 
+  nsDependentCString cstringReadBuf(readBuf, bytesRead);
   if (charsetConversion)
   {
-    if (NS_FAILED(ConvertToUnicode(m_charset, nsDependentCString(readBuf), sigData)))
-      CopyASCIItoUTF16(readBuf, sigData);
+    if (NS_FAILED(ConvertToUnicode(m_charset, cstringReadBuf, sigData)))
+      CopyASCIItoUTF16(cstringReadBuf, sigData);
   }
   else
-    CopyASCIItoUTF16(readBuf, sigData);
+    CopyASCIItoUTF16(cstringReadBuf, sigData);
 
   PR_FREEIF(readBuf);
   return NS_OK;
 }
 
 nsresult
 nsMsgAttachmentHandler::Abort()
 {
@@ -1121,22 +1122,22 @@ nsMsgAttachmentHandler::UrlExit(nsresult
       bundle->GetStringFromID(NS_MSG_FAILURE_ON_OBJ_EMBED_WHILE_SAVING, getter_Copies(msg));
     else
       bundle->GetStringFromID(NS_MSG_FAILURE_ON_OBJ_EMBED_WHILE_SENDING, getter_Copies(msg));
     if (m_real_name && *m_real_name)
       printfString = nsTextFormatter::smprintf(msg.get(), m_real_name);
     else
     if (NS_SUCCEEDED(mURL->GetSpec(turl)) && !turl.IsEmpty())
       {
-        nsCAutoString unescapeUrl(turl);
-        nsUnescape(unescapeUrl.BeginWriting());
-        if (unescapeUrl.IsEmpty())
+        nsCAutoString unescapedUrl;
+        MsgUnescapeString(turl, 0, unescapedUrl);
+        if (unescapedUrl.IsEmpty())
           printfString = nsTextFormatter::smprintf(msg.get(), turl.get());
         else
-          printfString = nsTextFormatter::smprintf(msg.get(), unescapeUrl.get());
+          printfString = nsTextFormatter::smprintf(msg.get(), unescapedUrl.get());
       }
     else
       printfString = nsTextFormatter::smprintf(msg.get(), "?");
 
     nsCOMPtr<nsIPrompt> aPrompt;
     if (m_mime_delivery_state)
       m_mime_delivery_state->GetDefaultPrompt(getter_AddRefs(aPrompt));
     nsMsgAskBooleanQuestionByString(aPrompt, printfString, &keepOnGoing);
--- a/mailnews/compose/src/nsMsgCompFields.cpp
+++ b/mailnews/compose/src/nsMsgCompFields.cpp
@@ -44,16 +44,17 @@
 #include "nsMsgUtils.h"
 #include "prmem.h"
 #include "nsIFileChannel.h"
 #include "nsIMsgMdnGenerator.h"
 #include "nsServiceManagerUtils.h"
 #include "nsMsgMimeCID.h"
 #include "nsIMimeConverter.h"
 #include "nsArrayEnumerator.h"
+#include "nsMemory.h"
 
 /* the following macro actually implement addref, release and query interface for our component. */
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsMsgCompFields, nsIMsgCompFields)
 
 nsMsgCompFields::nsMsgCompFields()
 {
   PRInt16 i;
   for (i = 0; i < MSG_MAX_HEADERS; i ++)
--- a/mailnews/compose/src/nsMsgCompFields.h
+++ b/mailnews/compose/src/nsMsgCompFields.h
@@ -39,16 +39,17 @@
 #ifndef _MsgCompFields_H_
 #define _MsgCompFields_H_
 
 #include "nsIMsgCompFields.h"
 #include "msgCore.h"
 #include "nsIAbCard.h"
 #include "nsTArray.h"
 #include "nsCOMArray.h"
+#include "nsCOMPtr.h"
 
 struct nsMsgRecipient
 {
   nsMsgRecipient() : mPreferFormat(nsIAbPreferMailFormat::unknown),
                      mProcessed(PR_FALSE) {}
 
   nsMsgRecipient(const nsMsgRecipient &other)
   {
--- a/mailnews/compose/src/nsMsgCompUtils.cpp
+++ b/mailnews/compose/src/nsMsgCompUtils.cpp
@@ -35,35 +35,38 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #include "nsCOMPtr.h"
 #include "nsMsgCompUtils.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "prmem.h"
-#include "nsEscape.h"
 #include "nsMsgSend.h"
 #include "nsIIOService.h"
 #include "nsIHttpProtocolHandler.h"
 #include "nsMailHeaders.h"
 #include "nsMsgI18N.h"
 #include "nsIMsgHeaderParser.h"
 #include "nsINntpService.h"
 #include "nsMimeTypes.h"
-#include "nsReadableUtils.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsIDocumentEncoder.h"    // for editor output flags
 #include "nsIURI.h"
 #include "nsNetCID.h"
 #include "nsMsgPrompts.h"
 #include "nsMsgUtils.h"
 #include "nsComposeStrings.h"
 #include "nsIMsgCompUtils.h"
 #include "nsIMsgMdnGenerator.h"
+#include "nsServiceManagerUtils.h"
+#include "nsComponentManagerUtils.h"
+#include "nsMemory.h"
+#include "nsCRTGlue.h"
+#include <ctype.h>
 
 NS_IMPL_ISUPPORTS1(nsMsgCompUtils, nsIMsgCompUtils)
 
 nsMsgCompUtils::nsMsgCompUtils()
 {
 }
 
 nsMsgCompUtils::~nsMsgCompUtils()
@@ -631,25 +634,21 @@ mime_generate_headers (nsMsgCompFields *
           nsCOMPtr<nsIStringBundle> composeStringBundle;
           rv = stringService->CreateBundle("chrome://messenger/locale/messengercompose/composeMsgs.properties", getter_AddRefs(composeStringBundle));
           if (NS_SUCCEEDED(rv))
           {
             nsString undisclosedRecipients;
             rv = composeStringBundle->GetStringFromID(NS_MSG_UNDISCLOSED_RECIPIENTS, getter_Copies(undisclosedRecipients));
             if (NS_SUCCEEDED(rv) && !undisclosedRecipients.IsEmpty())
             {
-              char * cstr = ToNewCString(undisclosedRecipients);
-              if (cstr) {
                 PUSH_STRING("To: ");
-                PUSH_STRING(cstr);
+              PUSH_STRING(NS_LossyConvertUTF16toASCII(undisclosedRecipients).get());
                 PUSH_STRING(":;");
                 PUSH_NEWLINE ();
               }
-              PR_Free(cstr);
-            }
           }
         }
       }
     }
   }
 
   if (pSubject && *pSubject)
     ENCODE_AND_PUSH("Subject: ", PR_FALSE, pSubject, charset, usemime);
@@ -801,17 +800,17 @@ mime_generate_attachment_headers (const 
   /* Let's encode the real name */
   char *encodedRealName = nsnull;
   nsCString charset;   // actual charset used for MIME encode
   nsAutoString realName;
   if (real_name)
   {
     // first try main body's charset to encode the file name,
     // then try local file system charset if fails
-    CopyUTF8toUTF16(real_name, realName);
+    CopyUTF8toUTF16(nsDependentCString(real_name), realName);
     if (bodyCharset && *bodyCharset &&
         nsMsgI18Ncheck_data_in_charset_range(bodyCharset, realName.get()))
       charset.Assign(bodyCharset);
     else
     {
       charset.Assign(nsMsgI18NFileSystemCharset());
       if (!nsMsgI18Ncheck_data_in_charset_range(charset.get(), realName.get()))
         charset.Assign("UTF-8"); // set to UTF-8 if fails again
@@ -1170,36 +1169,36 @@ inline static PRBool is7bitCharset(const
                                   // never be greater than 78 = 75 + CRLFLWSP
 /*static */ char *
 RFC2231ParmFolding(const char *parmName, const nsCString& charset,
                    const char *language, const nsString& parmValue)
 {
   NS_ENSURE_TRUE(parmName && *parmName && !parmValue.IsEmpty(), nsnull);
 
   PRBool needEscape;
-  char *dupParm = nsnull;
+  nsCString dupParm;
 
-  if (!IsASCII(parmValue) || is7bitCharset(charset)) {
+  if (!NS_IsAscii(parmValue.get()) || is7bitCharset(charset)) {
     needEscape = PR_TRUE;
     nsCAutoString nativeParmValue;
     ConvertFromUnicode(charset.get(), parmValue, nativeParmValue);
-    dupParm = nsEscape(nativeParmValue.get(), url_All);
+    MsgEscapeString(nativeParmValue, nsINetUtil::ESCAPE_ALL, dupParm);
   }
   else {
     needEscape = PR_FALSE;
-    dupParm =
+    dupParm.Adopt(
       msg_make_filename_qtext(NS_LossyConvertUTF16toASCII(parmValue).get(),
-                              PR_TRUE);
+                              PR_TRUE));
   }
 
-  if (!dupParm)
+  if (dupParm.IsEmpty())
     return nsnull;
 
   PRInt32 parmNameLen = PL_strlen(parmName);
-  PRInt32 parmValueLen = PL_strlen(dupParm);
+  PRInt32 parmValueLen = dupParm.Length();
 
   if (needEscape)
     parmNameLen += 5;   // *=__'__'___ or *[0]*=__'__'__ or *[1]*=___
   else
     parmNameLen += 5;   // *[0]="___";
 
   PRInt32 languageLen = language ?  PL_strlen(language) : 0;
   PRInt32 charsetLen = charset.Length();
@@ -1216,27 +1215,26 @@ RFC2231ParmFolding(const char *parmName,
         NS_MsgSACat(&foldedParm, charset.get());
       NS_MsgSACat(&foldedParm, "'");
       if (languageLen)
         NS_MsgSACat(&foldedParm, language);
       NS_MsgSACat(&foldedParm, "'");
     }
     else
       NS_MsgSACat(&foldedParm, "=\"");
-    NS_MsgSACat(&foldedParm, dupParm);
+    NS_MsgSACat(&foldedParm, dupParm.get());
     if (!needEscape)
       NS_MsgSACat(&foldedParm, "\"");
-    goto done;
   }
   else
   {
     int curLineLen = 0;
     int counter = 0;
     char digits[32];
-    char *start = dupParm;
+    char *start = dupParm.BeginWriting();
     char *end = NULL;
     char tmp = 0;
 
     while (parmValueLen > 0)
     {
       curLineLen = 0;
       if (counter == 0) {
         PR_FREEIF(foldedParm)
@@ -1307,21 +1305,16 @@ RFC2231ParmFolding(const char *parmName,
 
       parmValueLen -= (end-start);
       if (tmp)
         *end = tmp;
       start = end;
     }
   }
 
-done:
-  if (needEscape)
-    nsMemory::Free(dupParm);
-  else
-    PR_Free(dupParm);
   return foldedParm;
 }
 
 /*static */ char *
 LegacyParmFolding(const nsCString& aCharset,
                   const nsCString& aFileName, PRInt32 aParmFolding)
 {
   PRBool usemime = nsMsgMIMEGetConformToStandard();
@@ -1645,17 +1638,20 @@ msg_pick_real_name (nsMsgAttachmentHandl
   attachment->m_real_name = PL_strdup (s);
   /* Now trim off any named anchors or search data. */
   s3 = PL_strchr (attachment->m_real_name, '?');
   if (s3) *s3 = 0;
   s3 = PL_strchr (attachment->m_real_name, '#');
   if (s3) *s3 = 0;
 
   /* Now lose the %XX crap. */
-  nsUnescape (attachment->m_real_name);
+  nsCString unescaped_real_name;
+  MsgUnescapeString(nsDependentCString(attachment->m_real_name), 0, unescaped_real_name);
+  NS_Free(attachment->m_real_name);
+  attachment->m_real_name = ToNewCString(unescaped_real_name);
   }
 
   /* Now a special case for attaching uuencoded files...
 
    If we attach a file "foo.txt.uu", we will send it out with
    Content-Type: text/plain; Content-Transfer-Encoding: x-uuencode.
    When saving such a file, a mail reader will generally decode it first
    (thus removing the uuencoding.)  So, let's make life a little easier by
@@ -1718,17 +1714,18 @@ nsMsgNewURL(nsIURI** aInstancePtrResult,
   if (nsnull == aInstancePtrResult)
     return NS_ERROR_NULL_POINTER;
   nsCOMPtr<nsIIOService> pNetService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
   if (NS_SUCCEEDED(rv) && pNetService)
   {
     if (PL_strstr(aSpec, "://") == nsnull && strncmp(aSpec, "data:", 5))
     {
       //XXXjag Temporary fix for bug 139362 until the real problem(bug 70083) get fixed
-      nsCAutoString uri(NS_LITERAL_CSTRING("http://") + nsDependentCString(aSpec));
+      nsCAutoString uri(NS_LITERAL_CSTRING("http://"));
+      uri.Append(aSpec);
       rv = pNetService->NewURI(uri, nsnull, nsnull, aInstancePtrResult);
     }
     else
       rv = pNetService->NewURI(nsDependentCString(aSpec), nsnull, nsnull, aInstancePtrResult);
   }
   return rv;
 }
 
@@ -1923,17 +1920,17 @@ GetFolderURIFromUserPrefs(nsMsgDeliverMo
     rv = prefs->GetCharPref("mail.default_sendlater_uri", getter_Copies(uri));
     if (NS_FAILED(rv) || uri.IsEmpty())
       uri.AssignLiteral(ANY_SERVER);
     else
     {
       // check if uri is unescaped, and if so, escape it and reset the pef.
       if (uri.FindChar(' ') != kNotFound)
       {
-        uri.ReplaceSubstring(" ", "%20");
+        MsgReplaceSubstring(uri, " ", "%20");
         prefs->SetCharPref("mail.default_sendlater_uri", uri.get());
       }
     }
     return;
   }
 
   if (!identity)
     return;
--- a/mailnews/compose/src/nsMsgCompose.cpp
+++ b/mailnews/compose/src/nsMsgCompose.cpp
@@ -66,17 +66,16 @@
 #include "nsMailHeaders.h"
 #include "nsMsgPrompts.h"
 #include "nsMimeTypes.h"
 #include "nsICharsetConverterManager.h"
 #include "nsTextFormatter.h"
 #include "nsIPlaintextEditor.h"
 #include "nsIHTMLEditor.h"
 #include "nsIEditorMailSupport.h"
-#include "nsEscape.h"
 #include "plstr.h"
 #include "prmem.h"
 #include "nsIDocShell.h"
 #include "nsIRDFService.h"
 #include "nsRDFCID.h"
 #include "nsAbBaseCID.h"
 #include "nsIAbMDBDirectory.h"
 #include "nsCExternalHandlerService.h"
@@ -1131,17 +1130,17 @@ NS_IMETHODIMP nsMsgCompose::SendMsg(MSG_
             if (prefBranch)
             {
               nsCString prefName("mailnews.disable_fallback_to_utf8.");
               prefName.Append(m_compFields->GetCharacterSet());
               prefBranch->GetBoolPref(prefName.get(), &disableFallback);
             }
             if (!disableFallback)
             {
-              CopyUTF16toUTF8(msgBody.get(), outCString);
+              CopyUTF16toUTF8(msgBody, outCString);
               m_compFields->SetCharacterSet("UTF-8");
             }
           }
         }
         else if (!fallbackCharset.IsEmpty())
         {
           // re-label to the fallback charset
           m_compFields->SetCharacterSet(fallbackCharset.get());
@@ -1201,45 +1200,42 @@ NS_IMETHODIMP nsMsgCompose::SendMsg(MSG_
       nsCString escapedVCard;
       // make sure, if there is no card, this returns an empty string, or NS_ERROR_FAILURE
       rv = identity->GetEscapedVCard(escapedVCard);
 
       if (NS_SUCCEEDED(rv) && !escapedVCard.IsEmpty())
       {
           nsCString vCardUrl;
           vCardUrl = "data:text/x-vcard;charset=utf-8;base64,";
-          char *unescapedData = ToNewCString(escapedVCard);
-          if (!unescapedData)
-              return NS_ERROR_OUT_OF_MEMORY;
-          nsUnescape(unescapedData);
-          char *result = PL_Base64Encode(unescapedData, 0, nsnull);
+          nsCString unescapedData;
+          MsgUnescapeString(escapedVCard, 0, unescapedData);
+          char *result = PL_Base64Encode(unescapedData.get(), 0, nsnull);
           vCardUrl += result;
           PR_Free(result);
-          PR_Free(unescapedData);
 
           nsCOMPtr<nsIMsgAttachment> attachment = do_CreateInstance(NS_MSGATTACHMENT_CONTRACTID, &rv);
           if (NS_SUCCEEDED(rv) && attachment)
           {
               // [comment from 4.x]
               // Send the vCard out with a filename which distinguishes this user. e.g. jsmith.vcf
               // The main reason to do this is for interop with Eudora, which saves off
               // the attachments separately from the message body
               nsCString userid;
               (void)identity->GetEmail(userid);
               PRInt32 index = userid.FindChar('@');
               if (index != kNotFound)
-                  userid.Truncate(index);
+                  userid.SetLength(index);
 
               if (userid.IsEmpty())
                   attachment->SetName(NS_LITERAL_STRING("vcard.vcf"));
               else
               {
                   // Replace any dot with underscore to stop vCards
                   // generating false positives with some heuristic scanners
-                  userid.ReplaceChar('.', '_');
+                  MsgReplaceChar(userid, '.', '_');
                   userid.AppendLiteral(".vcf");
                   attachment->SetName(NS_ConvertASCIItoUTF16(userid));
               }
 
               attachment->SetUrl(vCardUrl);
               m_compFields->AddAttachment(attachment);
           }
       }
@@ -2006,18 +2002,18 @@ nsresult nsMsgCompose::CreateMessage(con
                     nsCOMPtr<nsIMsgIdentity> lookupIdentity2;
                     rv = identities->QueryElementAt(j, NS_GET_IID(nsIMsgIdentity),
                                                     getter_AddRefs(lookupIdentity2));
                     if (NS_FAILED(rv))
                       continue;
 
                     nsCString curIdentityEmail2;
                     lookupIdentity2->GetEmail(curIdentityEmail2);
-                    if (FindInReadable(curIdentityEmail2, recipientsEmailAddresses) ||
-                        FindInReadable(curIdentityEmail2, ccListEmailAddresses))
+                    if (recipientsEmailAddresses.Find(curIdentityEmail2) != kNotFound ||
+                        ccListEmailAddresses.Find(curIdentityEmail2) != kNotFound)
                     {
                       // An identity among the recipients -> not reply-to-self.
                       isReplyToOwnMsg = PR_FALSE;
                       break;
                     }
                   }
                   break;
                 }
@@ -2067,18 +2063,20 @@ nsresult nsMsgCompose::CreateMessage(con
                 NS_ENSURE_SUCCESS(rv, rv);
                 composeBundle->GetStringFromName(NS_LITERAL_STRING("messageAttachmentSafeName").get(),
                                                  getter_Copies(sanitizedSubj));
               }
               else
                 sanitizedSubj.Assign(subject);
 
               // change all '.' to '_'  see bug #271211
-              sanitizedSubj.ReplaceChar('.', '_');
-              attachment->SetName(addExtension ? sanitizedSubj + NS_LITERAL_STRING(".eml") : sanitizedSubj);
+              MsgReplaceChar(sanitizedSubj, ".", '_');
+              if (addExtension)
+                sanitizedSubj.AppendLiteral(".eml");
+              attachment->SetName(sanitizedSubj);
               attachment->SetUrl(nsDependentCString(uri));
               m_compFields->AddAttachment(attachment);
             }
 
             if (isFirstPass)
             {
               nsCString fwdPrefix;
               prefs->GetCharPref("mail.forward_subject_prefix", getter_Copies(fwdPrefix));
@@ -2202,18 +2200,20 @@ QuotingOutputStreamListener::QuotingOutp
       // Setup the cite information....
       nsCString myGetter;
       if (NS_SUCCEEDED(originalMsgHdr->GetMessageId(getter_Copies(myGetter))))
       {
         if (!myGetter.IsEmpty())
         {
           nsCAutoString buf;
           mCiteReference.AssignLiteral("mid:");
-          AppendASCIItoUTF16(NS_EscapeURL(myGetter, esc_FileBaseName | esc_Forced, buf),
-                             mCiteReference);
+          MsgEscapeURL(myGetter,
+                       nsINetUtil::ESCAPE_URL_FILE_BASENAME | nsINetUtil::ESCAPE_URL_FORCED,
+                       buf);
+          mCiteReference.Append(NS_ConvertASCIItoUTF16(buf));
         }
       }
 
       PRInt32 reply_on_top = 0;
       mIdentity->GetReplyOnTop(&reply_on_top);
       if (reply_on_top == 1)
       {
         // add one newline if a signature comes before the quote, two otherwise
@@ -2432,22 +2432,18 @@ NS_IMETHODIMP QuotingOutputStreamListene
 {
   nsresult rv = NS_OK;
   nsAutoString aCharset;
 
   if (!mHtmlToQuote.IsEmpty())
   {
     // If we had a selection in the original message to quote, we can add
     // it now that we are done ignoring the original body of the message
-    nsCOMPtr<nsIInputStream> stream;
-    rv = NS_NewCStringInputStream(getter_AddRefs(stream), mHtmlToQuote);
-    NS_ENSURE_SUCCESS(rv, rv);
-
     mHeadersOnly = PR_FALSE;
-    rv = OnDataAvailable(request, ctxt, stream, 0, mHtmlToQuote.Length());
+    rv = AppendToMsgBody(mHtmlToQuote);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   nsCOMPtr<nsIMsgCompose> compose = do_QueryReferent(mWeakComposeObj);
   if (compose)
   {
     MSG_ComposeType type;
     compose->GetType(&type);
@@ -2553,17 +2549,17 @@ NS_IMETHODIMP QuotingOutputStreamListene
         mHeaders->ExtractHeader(HEADER_LIST_POST, PR_TRUE, getter_Copies(outCString));
         if (!outCString.IsEmpty())
           mMimeConverter->DecodeMimeHeader(outCString.get(), charset.get(),
                                            PR_FALSE, PR_TRUE, listPost);
 
         if (!listPost.IsEmpty())
         {
           PRInt32 startPos = listPost.Find("<mailto:");
-          PRInt32 endPos = listPost.Find(">", PR_FALSE, startPos);
+          PRInt32 endPos = listPost.FindChar('>', startPos);
           // Extract the e-mail address.
           if (endPos > startPos)
           {
             const PRUint32 mailtoLen = strlen("<mailto:");
             listPost = Substring(listPost, startPos + mailtoLen, endPos - (startPos + mailtoLen));
             compFields->SetListReply(listPost);
             if (type == nsIMsgCompType::ReplyToList)
               compFields->SetTo(listPost);
@@ -2763,20 +2759,20 @@ NS_IMETHODIMP QuotingOutputStreamListene
     // just get lots of HTML text in the message...not good.
     //
     // XXX not m_composeHTML? /BenB
     PRBool composeHTML = PR_TRUE;
     compose->GetComposeHTML(&composeHTML);
     if (!composeHTML)
     {
       // Downsampling. The charset should only consist of ascii.
-      char *target_charset = ToNewCString(aCharset);
-      PRBool formatflowed = UseFormatFlowed(target_charset);
+
+      PRBool formatflowed =
+        UseFormatFlowed(NS_LossyConvertUTF16toASCII(aCharset).get());
       ConvertToPlainText(formatflowed);
-      Recycle(target_charset);
     }
 
     compose->ProcessSignature(mIdentity, PR_TRUE, &mSignature);
 
     nsCOMPtr<nsIEditor> editor;
     if (NS_SUCCEEDED(compose->GetEditor(getter_AddRefs(editor))) && editor)
     {
       if (mQuoteOriginal)
@@ -2809,33 +2805,46 @@ NS_IMETHODIMP QuotingOutputStreamListene
 
   PRUint32 numWritten = 0;
   rv = inStr->Read(newBuf, count, &numWritten);
   if (rv == NS_BASE_STREAM_WOULD_BLOCK)
     rv = NS_OK;
   newBuf[numWritten] = '\0';
   if (NS_SUCCEEDED(rv) && numWritten > 0)
   {
+    rv = AppendToMsgBody(nsDependentCString(newBuf, numWritten));
+  }
+
+  PR_FREEIF(newBuf);
+  return rv;
+}
+
+NS_IMETHODIMP QuotingOutputStreamListener::AppendToMsgBody(const nsCString &inStr)
+{
+  nsresult rv = NS_OK;
+
+  if (!inStr.IsEmpty())
+  {
     // Create unicode decoder.
     if (!mUnicodeDecoder)
     {
       nsCOMPtr<nsICharsetConverterManager> ccm =
                do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
       if (NS_SUCCEEDED(rv))
       {
         rv = ccm->GetUnicodeDecoderRaw("UTF-8",
                                        getter_AddRefs(mUnicodeDecoder));
       }
     }
 
     if (NS_SUCCEEDED(rv))
     {
       PRInt32 unicharLength;
-      PRInt32 inputLength = (PRInt32) numWritten;
-      rv = mUnicodeDecoder->GetMaxLength(newBuf, numWritten, &unicharLength);
+      PRInt32 inputLength = inStr.Length();
+      rv = mUnicodeDecoder->GetMaxLength(inStr.get(), inStr.Length(), &unicharLength);
       if (NS_SUCCEEDED(rv))
       {
         // Use this local buffer if possible.
         const PRInt32 kLocalBufSize = 4096;
         PRUnichar localBuf[kLocalBufSize];
         PRUnichar *unichars = localBuf;
 
         if (unicharLength > kLocalBufSize)
@@ -2845,27 +2854,26 @@ NS_IMETHODIMP QuotingOutputStreamListene
               unicharLength > mUnicodeBufferCharacterLength)
           {
             if (mUnicodeConversionBuffer)
               nsMemory::Free(mUnicodeConversionBuffer);
             mUnicodeConversionBuffer = (PRUnichar *) nsMemory::Alloc(unicharLength * sizeof(PRUnichar));
             if (!mUnicodeConversionBuffer)
             {
               mUnicodeBufferCharacterLength = 0;
-              PR_Free(newBuf);
               return NS_ERROR_OUT_OF_MEMORY;
             }
             mUnicodeBufferCharacterLength = unicharLength;
           }
           unichars = mUnicodeConversionBuffer;
         }
 
         PRInt32 consumedInputLength = 0;
         PRInt32 originalInputLength = inputLength;
-        char *inputBuffer = newBuf;
+        const char *inputBuffer = inStr.get();
         PRInt32 convertedOutputLength = 0;
         PRInt32 outputBufferLength = unicharLength;
         PRUnichar *originalOutputBuffer = unichars;
         do
         {
           rv = mUnicodeDecoder->Convert(inputBuffer, &inputLength, unichars, &unicharLength);
           if (NS_SUCCEEDED(rv))
           {
@@ -2893,17 +2901,16 @@ NS_IMETHODIMP QuotingOutputStreamListene
                  (outputBufferLength > convertedOutputLength));
 
         if (convertedOutputLength > 0)
           mMsgBody.Append(originalOutputBuffer, convertedOutputLength);
       }
     }
   }
 
-  PR_FREEIF(newBuf);
   return rv;
 }
 
 nsresult
 QuotingOutputStreamListener::SetComposeObj(nsIMsgCompose *obj)
 {
   mWeakComposeObj = do_GetWeakReference(obj);
   return NS_OK;
@@ -3756,17 +3763,17 @@ nsMsgComposeSendListener::RemoveCurrentD
         NS_ASSERTION(imapFolder, "The draft folder MUST be an imap folder in order to mark the msg delete!");
         if (NS_SUCCEEDED(rv) && imapFolder)
         {
           const char * str = PL_strchr(curDraftIdURL.get(), '#');
           NS_ASSERTION(str, "Failed to get current draft id url");
           if (str)
           {
             nsCAutoString srcStr(str+1);
-            PRInt32 err;
+            nsresult err;
             nsMsgKey messageID = srcStr.ToInteger(&err, 10);
             if (messageID != nsMsgKey_None)
             {
               rv = imapFolder->StoreImapFlags(kImapMsgDeletedFlag, PR_TRUE,
                                               &messageID, 1, nsnull);
             }
           }
         }
@@ -3912,17 +3919,17 @@ nsMsgCompose::ConvertTextToHTML(nsILocal
 
   rv = LoadDataFromFile(aSigFile, origBuf);
   if (NS_FAILED(rv))
     return rv;
 
   // Ok, once we are here, we need to escape the data to make sure that
   // we don't do HTML stuff with plain text sigs.
   //
-  PRUnichar *escaped = nsEscapeHTML2(origBuf.get());
+  PRUnichar *escaped = MsgEscapeHTML2(origBuf.get(), origBuf.Length());
   if (escaped)
   {
     aSigData.Append(escaped);
     NS_Free(escaped);
   }
   else
     aSigData.Append(origBuf);
   return NS_OK;
@@ -3972,17 +3979,17 @@ nsMsgCompose::LoadDataFromFile(nsILocalF
   inputFile->Close();
 
   readSize = (PRUint32) fileSize;
 
   nsCAutoString sigEncoding(nsMsgI18NParseMetaCharset(file));
   PRBool removeSigCharset = !sigEncoding.IsEmpty() && m_composeHTML;
 
   if (sigEncoding.IsEmpty()) {
-    if (aAllowUTF8 && IsUTF8(nsDependentCString(readBuf))) {
+    if (aAllowUTF8 && MsgIsUTF8(nsDependentCString(readBuf))) {
       sigEncoding.Assign("UTF-8");
     }
     else if (sigEncoding.IsEmpty() && aAllowUTF16 &&
              readSize % 2 == 0 && readSize >= 2 &&
              ((readBuf[0] == char(0xFE) && readBuf[1] == char(0xFF)) ||
               (readBuf[0] == char(0xFF) && readBuf[1] == char(0xFE)))) {
       sigEncoding.Assign("UTF-16");
     }
@@ -3998,29 +4005,21 @@ nsMsgCompose::LoadDataFromFile(nsILocalF
   PR_FREEIF(readBuf);
 
   if (NS_FAILED(ConvertToUnicode(sigEncoding.get(), readStr, sigData)))
     CopyASCIItoUTF16(readStr, sigData);
 
   //remove sig meta charset to allow user charset override during composition
   if (removeSigCharset)
   {
-    nsAutoString metaCharset(NS_LITERAL_STRING("charset="));
-    AppendASCIItoUTF16(sigEncoding, metaCharset);
-    // When we move to frozen linkage, this should become:
-    // PRInt32 offset = sigData.Find(metaCharset, CaseInsensitiveCompare) ;
-    //  if (offset >= 0)
-    //    sigData.Cut(offset, metaCharset.Length());
-    nsAString::const_iterator realstart, start, end;
-    sigData.BeginReading(start);
-    sigData.EndReading(end);
-    realstart = start;
-    if (FindInReadable(metaCharset, start, end,
-                       nsCaseInsensitiveStringComparator()))
-      sigData.Cut(Distance(realstart, start), Distance(start, end));
+    nsCAutoString metaCharset("charset=");
+    metaCharset.Append(sigEncoding);
+    PRInt32 pos = sigData.Find(metaCharset.BeginReading(), PR_TRUE);
+    if (pos != kNotFound)
+      sigData.Cut(pos, metaCharset.Length());
   }
 
   return NS_OK;
 }
 
 nsresult
 nsMsgCompose::BuildQuotedMessageAndSignature(void)
 {
@@ -4191,17 +4190,17 @@ nsMsgCompose::ProcessSignature(nsIMsgIde
       if (htmlSig)
         ConvertBufToPlainText(prefSigText, PR_FALSE);
       sigData.Append(prefSigText);
     }
     else
     {
       if (!htmlSig)
       {
-        PRUnichar* escaped = nsEscapeHTML2(prefSigText.get());
+        PRUnichar* escaped = MsgEscapeHTML2(prefSigText.get(), prefSigText.Length());
         if (escaped)
         {
           sigData.Append(escaped);
           NS_Free(escaped);
         }
         else
           sigData.Append(prefSigText);
       }
@@ -4224,17 +4223,17 @@ nsMsgCompose::ProcessSignature(nsIMsgIde
   if (!sigData.IsEmpty())
   {
     if (m_composeHTML)
     {
       sigOutput.AppendLiteral(htmlBreak);
       if (htmlSig)
         sigOutput.AppendLiteral(htmlsigopen);
       else
-        sigOutput.AppendASCII(preopen);
+        sigOutput.Append(NS_ConvertASCIItoUTF16(preopen));
     }
     else
       sigOutput.AppendLiteral(CRLF);
 
     if ((reply_on_top != 1 || sig_bottom || !aQuoted) &&
         sigData.Find("\r-- \r", PR_TRUE) < 0 &&
         sigData.Find("\n-- \n", PR_TRUE) < 0 &&
         sigData.Find("\n-- \r", PR_TRUE) < 0)
@@ -4327,17 +4326,17 @@ nsMsgCompose::BuildBodyMessageAndSignatu
   nsAutoString tSignature;
   if (addSignature)
     ProcessSignature(m_identity, addDashes, &tSignature);
 
   // if type is new, but we have body, this is probably a mapi send, so we need to
   // replace '\n' with <br> so that the line breaks won't be lost by html.
   // if mailtourl, do the same.
   if (m_composeHTML && (mType == nsIMsgCompType::New || mType == nsIMsgCompType::MailToUrl))
-    body.ReplaceSubstring(NS_LITERAL_STRING("\n").get(), NS_LITERAL_STRING("<br>").get());
+    MsgReplaceSubstring(body, NS_LITERAL_STRING("\n"), NS_LITERAL_STRING("<br>"));
 
   // Restore flowed text wrapping for Drafts/Templates.
   // Look for unquoted lines - if we have an unquoted line
   // that ends in a space, join this line with the next one
   // by removing the end of line char(s).
   PRInt32 wrapping_enabled = 0;
   GetWrapLength(&wrapping_enabled);
   if (!m_composeHTML && !addSignature && wrapping_enabled)
@@ -4428,19 +4427,17 @@ nsresult nsMsgCompose::NotifyStateListen
 
   return NS_OK;
 }
 
 nsresult nsMsgCompose::AttachmentPrettyName(const nsACString & scheme, const char* charset, nsACString& _retval)
 {
   nsresult rv;
 
-  nsCAutoString utf8Scheme;
-
-  if (StringHead(scheme, 5).LowerCaseEqualsLiteral("file:"))
+  if (MsgLowerCaseEqualsLiteral(StringHead(scheme, 5), "file:"))
   {
     nsCOMPtr<nsIFile> file;
     rv = NS_GetFileFromURLSpec(scheme,
                                getter_AddRefs(file));
     NS_ENSURE_SUCCESS(rv, rv);
     nsAutoString leafName;
     rv = file->GetLeafName(leafName);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -4457,17 +4454,17 @@ nsresult nsMsgCompose::AttachmentPrettyN
   nsAutoString retUrl;
   rv = textToSubURI->UnEscapeURIForUI(nsDependentCString(cset), scheme, retUrl);
 
   if (NS_SUCCEEDED(rv)) {
     CopyUTF16toUTF8(retUrl, _retval);
   } else {
     _retval.Assign(scheme);
   }
-  if (StringHead(scheme, 5).LowerCaseEqualsLiteral("http:"))
+  if (MsgLowerCaseEqualsLiteral(StringHead(scheme, 5), "http:"))
     _retval.Cut(0, 7);
 
   return NS_OK;
 }
 
 nsresult nsMsgCompose::GetABDirectories(const nsACString& aDirUri,
                                         nsIRDFService *aRDFService,
                                         nsCOMArray<nsIAbDirectory> &aDirArray)
@@ -4878,39 +4875,35 @@ nsMsgCompose::CheckAndPopulateRecipients
   PRBool atLeastOneRecipientPrefersPlainText = PR_FALSE;
   PRBool atLeastOneRecipientPrefersHTML = PR_FALSE;
 
   for (i = 0; i < MAX_OF_RECIPIENT_ARRAY; ++i)
   {
     PRUint32 nbrRecipients = recipientsList[i].Length();
     if (nbrRecipients == 0)
       continue;
-    recipientsStr.SetLength(0);
+    recipientsStr.Truncate();
 
     for (j = 0; j < nbrRecipients; ++j)
     {
       nsMsgRecipient &recipient = recipientsList[i][j];
 
       // if we don't have a prefer format for a recipient, check the domain in
       // case we have a format defined for it
       if (recipient.mPreferFormat == nsIAbPreferMailFormat::unknown &&
           (plaintextDomains.Length() || htmlDomains.Length()))
       {
         PRInt32 atPos = recipient.mEmail.FindChar('@');
         if (atPos >= 0)
         {
-          recipient.mEmail.Right(domain, recipient.mEmail.Length() - atPos - 1);
-          // when we move to frozen linkage this should be:
-          // if (plaintextDomains.Find(domain, CaseInsensitiveCompare) >= 0)
-          if (FindInReadable(domain, plaintextDomains, nsCaseInsensitiveStringComparator()))
+          domain = Substring(recipient.mEmail, atPos + 1);
+          if (CaseInsensitiveFindInReadable(domain, plaintextDomains))
             recipient.mPreferFormat = nsIAbPreferMailFormat::plaintext;
           else
-            // when we move to frozen linkage this should be:
-            // if (htmlDomains.Find(domain, CaseInsensitiveCompare) >= 0)
-            if (FindInReadable(domain, htmlDomains, nsCaseInsensitiveStringComparator()))
+            if (CaseInsensitiveFindInReadable(domain, htmlDomains))
               recipient.mPreferFormat = nsIAbPreferMailFormat::html;
         }
       }
 
       switch (recipient.mPreferFormat)
       {
       case nsIAbPreferMailFormat::html:
         atLeastOneRecipientPrefersHTML = PR_TRUE;
@@ -5124,18 +5117,18 @@ nsresult nsMsgCompose::TagConvertible(ns
         nsAutoString className;
         className.AssignLiteral("class");
         if (NS_SUCCEEDED(pAttributes->GetNamedItem(className,
                                                    getter_AddRefs(pItem)))
             && pItem)
         {
           nsAutoString classValue;
           if (NS_SUCCEEDED(pItem->GetNodeValue(classValue))
-              && (classValue.EqualsIgnoreCase("moz-txt", 7) ||
-                  classValue.EqualsIgnoreCase("\"moz-txt", 8)))
+              && (StringBeginsWith(classValue, NS_LITERAL_STRING("moz-txt"), nsCaseInsensitiveStringComparator()) ||
+                  StringBeginsWith(classValue, NS_LITERAL_STRING("\"moz-txt"), nsCaseInsensitiveStringComparator())))
           {
             *_retval = nsIMsgCompConvertible::Plain;
             return rv;  // Inconsistent :-(
           }
         }
       }
 
       // Maybe, it's an <a> element inserted by another recognizer (e.g. 4.x')
--- a/mailnews/compose/src/nsMsgCompose.h
+++ b/mailnews/compose/src/nsMsgCompose.h
@@ -179,16 +179,17 @@ public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIREQUESTOBSERVER
     NS_DECL_NSISTREAMLISTENER
     NS_DECL_NSIMSGQUOTINGOUTPUTSTREAMLISTENER
 
     NS_IMETHOD  SetComposeObj(nsIMsgCompose *obj);
 	  NS_IMETHOD  ConvertToPlainText(PRBool formatflowed = PR_FALSE);
     NS_IMETHOD InsertToCompose(nsIEditor *aEditor, PRBool aHTMLEditor);
+    NS_IMETHOD AppendToMsgBody(const nsCString &inStr);
 
 private:
     nsWeakPtr                 mWeakComposeObj;
     nsString       				    mMsgBody;
     nsString       				    mCitePrefix;
     nsString       				    mSignature;
     PRBool						        mQuoteHeaders;
     PRBool						        mHeadersOnly;
--- a/mailnews/compose/src/nsMsgComposeParams.h
+++ b/mailnews/compose/src/nsMsgComposeParams.h
@@ -34,16 +34,17 @@
  * 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 "nsIMsgComposeParams.h"
 #include "nsStringGlue.h"
 #include "nsIMsgHdr.h"
+#include "nsCOMPtr.h"
 class nsMsgComposeParams : public nsIMsgComposeParams
 {
 public: 
   nsMsgComposeParams();
   virtual ~nsMsgComposeParams();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIMSGCOMPOSEPARAMS
--- a/mailnews/compose/src/nsMsgComposeService.cpp
+++ b/mailnews/compose/src/nsMsgComposeService.cpp
@@ -52,17 +52,16 @@
 #include "nsISmtpUrl.h"
 #include "nsIURI.h"
 #include "nsMsgI18N.h"
 #include "nsIMsgComposeParams.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIWindowWatcher.h"
 #include "nsIDOMWindow.h"
-#include "nsEscape.h"
 #include "nsIContentViewer.h"
 #include "nsIMsgWindow.h"
 #include "nsIDocShell.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMElement.h"
 #include "nsIXULWindow.h"
@@ -100,16 +99,17 @@
 // <for functions="HTMLSantinize">
 #include "nsIParser.h"
 #include "nsParserCIID.h"
 #include "nsIContentSink.h"
 #include "mozISanitizingSerializer.h"
 
 #include "nsICommandLine.h"
 #include "nsIAppStartup.h"
+#include "nsMsgUtils.h"
 
 #ifdef XP_WIN32
 #include <windows.h>
 #include <shellapi.h>
 #include "nsIWidget.h"
 #endif
 
 static NS_DEFINE_CID(kParserCID, NS_PARSER_CID);
@@ -489,19 +489,18 @@ nsMsgComposeService::GetOrigWindowSelect
     // If "mailnews.reply_quoting_selection.multi_word" is on, then there must be at least
     // two words selected in order to quote just the selected text
     if (requireMultipleWords)
     {
       nsCOMPtr<nsILineBreaker> lineBreaker = do_GetService(NS_LBRK_CONTRACTID, &rv);
 
       if (NS_SUCCEEDED(rv))
       {
-        const nsPromiseFlatString& tString = PromiseFlatString(selPlain);
-        const PRUint32 length = tString.Length();
-        const PRUnichar* unicodeStr = tString.get();
+        const PRUint32 length = selPlain.Length();
+        const PRUnichar* unicodeStr = selPlain.get();
         PRInt32 endWordPos = lineBreaker->Next(unicodeStr, length, 0);
         
         // If there's not even one word, then there's not multiple words
         if (endWordPos == NS_LINEBREAKER_NEED_MORE_TEXT)
           return NS_ERROR_ABORT;
 
         // If after the first word is only space, then there's not multiple words
         const PRUnichar* end;
@@ -509,17 +508,17 @@ nsMsgComposeService::GetOrigWindowSelect
           ;
         if (!*end)
           return NS_ERROR_ABORT;
       }
     }
 
     if (!charsOnlyIf.IsEmpty())
     {
-      if (selPlain.FindCharInSet(NS_ConvertUTF8toUTF16(charsOnlyIf)) < 0)
+      if (MsgFindCharInSet(selPlain, charsOnlyIf.get()) < 0)
         return NS_ERROR_ABORT;
     }
   }
 
   nsCOMPtr<nsIContentViewer> contentViewer;
   rv = docShell->GetContentViewer(getter_AddRefs(contentViewer));
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -556,17 +555,17 @@ nsMsgComposeService::OpenComposeWindow(c
 
   /* Actually, the only way to implement forward inline is to simulate a template message.
      Maybe one day when we will have more time we can change that
   */
   if (type == nsIMsgCompType::ForwardInline || type == nsIMsgCompType::Draft || type == nsIMsgCompType::Template
     || type == nsIMsgCompType::ReplyWithTemplate || type == nsIMsgCompType::Redirect)
   {
     nsCAutoString uriToOpen(originalMsgURI);
-    uriToOpen += (uriToOpen.FindChar('?') == kNotFound) ? "?" : "&";
+    uriToOpen += (uriToOpen.FindChar('?') == kNotFound) ? '?' : '&';
     uriToOpen.Append("fetchCompleteMessage=true");
     if (type == nsIMsgCompType::Redirect)
       uriToOpen.Append("&redirect=true");
 
     aMsgWindow->SetCharsetOverride(true);
     return LoadDraftOrTemplate(uriToOpen, type == nsIMsgCompType::ForwardInline || type == nsIMsgCompType::Draft ?
                                nsMimeOutput::nsMimeMessageDraftOrTemplate : nsMimeOutput::nsMimeMessageEditorTemplate,
                                identity, originalMsgURI, origMsgHdr, type == nsIMsgCompType::ForwardInline,
@@ -603,26 +602,27 @@ nsMsgComposeService::OpenComposeWindow(c
           nsCAutoString newsURI(originalMsgURI);
           nsCAutoString group;
           nsCAutoString host;
 
           PRInt32 slashpos = newsURI.RFindChar('/');
           if (slashpos > 0 )
           {
             // uri is "[s]news://host[:port]/group"
-            newsURI.Left(host, slashpos);
-            newsURI.Right(group, newsURI.Length() - slashpos - 1);
+            host = StringHead(newsURI, slashpos);
+            group = Substring(newsURI, slashpos + 1);
+
           }
           else
             group = originalMsgURI;
 
           nsCAutoString unescapedName;
-          NS_UnescapeURL(group,
-                         esc_FileBaseName|esc_Forced|esc_AlwaysCopy,
-                         unescapedName);
+          MsgUnescapeString(group,
+                            nsINetUtil::ESCAPE_URL_FILE_BASENAME | nsINetUtil::ESCAPE_URL_FORCED,
+                            unescapedName);
           pMsgCompFields->SetNewsgroups(NS_ConvertUTF8toUTF16(unescapedName));
           pMsgCompFields->SetNewshost(host.get());
         }
         else
         {
           pMsgComposeParams->SetOriginalMsgURI(originalMsgURI);
           pMsgComposeParams->SetOrigMsgHdr(origMsgHdr);
         }
@@ -685,17 +685,17 @@ NS_IMETHODIMP nsMsgComposeService::GetPa
       if (HTMLBodyPart.IsEmpty())
       {
         if (composeHTMLFormat)
         {
           char *escaped = MsgEscapeHTML(bodyPart.get());
           if (!escaped)
             return NS_ERROR_OUT_OF_MEMORY;
 
-          CopyUTF8toUTF16(escaped, sanitizedBody);
+          CopyUTF8toUTF16(nsDependentCString(escaped), sanitizedBody);
           nsMemory::Free(escaped);
         }
         else
           CopyUTF8toUTF16(bodyPart, rawBody);
       }
       else
         CopyUTF8toUTF16(HTMLBodyPart, rawBody);
 
@@ -1187,17 +1187,17 @@ NS_IMETHODIMP nsMsgComposeService::Reply
     // ### probably want to return a specific error and
     // have the calling code disable the filter.
     NS_ASSERTION(PR_FALSE, "failed to get msg hdr");
     return NS_ERROR_FAILURE;
   }
   // we need to convert the template uri, which is of the form
   // <folder uri>?messageId=<messageId>&subject=<subject>
   nsCOMPtr <nsIMsgMessageService> msgService;
-  rv = GetMessageServiceFromURI(nsDependentCString(templateMsgHdrUri), getter_AddRefs(msgService));
+  rv = GetMessageServiceFromURI(templateMsgHdrUri, getter_AddRefs(msgService));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsISupports> listenerSupports;
   helper->QueryInterface(NS_GET_IID(nsISupports), getter_AddRefs(listenerSupports));
 
   rv = msgService->StreamMessage(templateMsgHdrUri.get(), listenerSupports,
                                  aMsgWindow, helper,
                                  PR_FALSE, // convert data
@@ -1597,17 +1597,17 @@ nsMsgComposeService::RunMessageThroughMi
   }
   mimeConverter->SetOverrideComposeFormat(aOverrideComposeFormat);
   mimeConverter->SetIdentity(aIdentity);
   mimeConverter->SetOriginalMsgURI(aOriginalMsgURI);
   mimeConverter->SetOrigMsgHdr(aOrigMsgHdr);
 
   nsCOMPtr<nsIURI> url;
   PRBool fileUrl = StringBeginsWith(aMsgURI, NS_LITERAL_CSTRING("file:"));
-  if (fileUrl || nsDependentCString(aMsgURI).Find("&type=application/x-message-display") >= 0)
+  if (fileUrl || PromiseFlatCString(aMsgURI).Find("&type=application/x-message-display") >= 0)
     rv = NS_NewURI(getter_AddRefs(url), aMsgURI);
   else
     rv = messageService->GetUrlForUri(PromiseFlatCString(aMsgURI).get(), getter_AddRefs(url), aMsgWindow);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // ignore errors here - it's not fatal, and in the case of mailbox messages,
   // we're always passing in an invalid spec...
   (void )url->SetSpec(aMsgURI);
--- a/mailnews/compose/src/nsMsgCopy.cpp
+++ b/mailnews/compose/src/nsMsgCopy.cpp
@@ -56,16 +56,17 @@
 #include "nsIMsgImapMailFolder.h"
 #include "nsThreadUtils.h"
 #include "nsIMsgWindow.h"
 #include "nsIMsgProgress.h"
 #include "nsComposeStrings.h"
 #include "prmem.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
+#include "nsMsgUtils.h"
 
 static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
 
 ////////////////////////////////////////////////////////////////////////////////////
 // This is the listener class for the copy operation. We have to create this class
 // to listen for message copy completion and eventually notify the caller
 ////////////////////////////////////////////////////////////////////////////////////
 NS_IMPL_THREADSAFE_ADDREF(CopyListener)
@@ -297,17 +298,17 @@ nsMsgCopy::DoCopy(nsIFile *aDiskFile, ns
         PRBool shutdownInProgress = PR_FALSE;
         rv = accountManager->GetShutdownInProgress(&shutdownInProgress);
 
         if (NS_SUCCEEDED(rv) && shutdownInProgress && imapFolder)
         {
           // set the following only when we were in the middle of shutdown
           // process
             copyListener->mCopyInProgress = PR_TRUE;
-            NS_GetCurrentThread(getter_AddRefs(thread));
+            thread = do_GetCurrentThread();
         }
     }
     nsCOMPtr<nsIMsgCopyService> copyService = do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = copyService->CopyFileMessage(aDiskFile, dstFolder, aMsgToReplace,
                                       aIsDraft, nsMsgMessageFlags::Read, EmptyCString(),
                                       copyListener, msgWindow);
--- a/mailnews/compose/src/nsMsgPrompts.cpp
+++ b/mailnews/compose/src/nsMsgPrompts.cpp
@@ -37,16 +37,18 @@
 #include "nsMsgPrompts.h"
 
 #include "nsMsgCopy.h"
 #include "nsIPrompt.h"
 #include "nsIWindowWatcher.h"
 #include "nsMsgCompCID.h"
 #include "nsComposeStrings.h"
 #include "nsIStringBundle.h"
+#include "nsServiceManagerUtils.h"
+#include "nsMsgUtils.h"
 
 nsresult
 nsMsgGetMessageByID(PRInt32 aMsgID, nsString& aResult)
 {
   nsresult rv;
   nsCOMPtr<nsIStringBundleService> bundleService(do_GetService("@mozilla.org/intl/stringbundle;1", &rv));
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/mailnews/compose/src/nsMsgSend.cpp
+++ b/mailnews/compose/src/nsMsgSend.cpp
@@ -43,32 +43,30 @@
 #include "nsMsgSendPart.h"
 #include "nsMsgBaseCID.h"
 #include "nsMsgNewsCID.h"
 #include "nsIMsgHeaderParser.h"
 #include "nsISmtpService.h"  // for actually sending the message...
 #include "nsINntpService.h"  // for actually posting the message...
 #include "nsIMsgMailSession.h"
 #include "nsIMsgIdentity.h"
-#include "nsEscape.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsIMsgMailNewsUrl.h"
 #include "nsMsgEncoders.h"
 #include "nsMsgCompUtils.h"
 #include "nsMsgI18N.h"
 #include "nsICharsetConverterManager.h"
 #include "nsIMsgSendListener.h"
 #include "nsIMsgCopyServiceListener.h"
 #include "nsIFile.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 #include "nsIFileURL.h"
 #include "nsMsgCopy.h"
-#include "nsReadableUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsMsgPrompts.h"
 #include "nsIDOMHTMLBodyElement.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIDOMHTMLLinkElement.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsCExternalHandlerService.h"
 #include "nsIMIMEService.h"
@@ -103,17 +101,18 @@
 #include "nsIMsgAccountManager.h"
 #include "nsNativeCharsetUtils.h"
 #include "nsIAbCard.h"
 #include "nsIMsgProgress.h"
 #include "nsIMsgMessageService.h"
 #include "nsIMsgHdr.h"
 #include "nsIMsgFolder.h"
 #include "nsComposeStrings.h"
-#include "nsString.h"
+#include "nsStringGlue.h"
+#include "nsMsgUtils.h"
 
 static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
 
 #define PREF_MAIL_SEND_STRUCT "mail.send_struct"
 #define PREF_MAIL_STRICTLY_MIME "mail.strictly_mime"
 #define PREF_MAIL_MESSAGE_WARNING_SIZE "mailnews.message_warning_size"
 #define PREF_MAIL_COLLECT_EMAIL_ADDRESS_OUTGOING "mail.collect_email_address_outgoing"
 #define PREF_MAIL_DONT_ATTACH_SOURCE "mail.compose.dont_attach_source_of_local_network_links"
@@ -406,17 +405,17 @@ nsresult nsMsgComposeAndSend::GetNotific
   if (msgWindow) {
     nsCOMPtr<nsIDocShell> docShell;
     msgWindow->GetRootDocShell(getter_AddRefs(docShell));
     nsCOMPtr<nsIInterfaceRequestor> ir(do_QueryInterface(docShell));
     nsCOMPtr<nsIInterfaceRequestor> notificationCallbacks;
     msgWindow->GetNotificationCallbacks(getter_AddRefs(notificationCallbacks));
     if (notificationCallbacks) {
       nsCOMPtr<nsIInterfaceRequestor> aggregrateIR;
-      NS_NewInterfaceRequestorAggregation(notificationCallbacks, ir, getter_AddRefs(aggregrateIR));
+      MsgNewInterfaceRequestorAggregation(notificationCallbacks, ir, getter_AddRefs(aggregrateIR));
       ir = aggregrateIR;
     }
     if (ir) {
       NS_ADDREF(*aCallbacks = ir);
       return NS_OK;
     }
   }
   return NS_ERROR_FAILURE;
@@ -1423,38 +1422,38 @@ nsMsgComposeAndSend::GetEmbeddedObjectIn
           return NS_ERROR_OUT_OF_MEMORY;
 
         uri->GetSpec(spec);
 
         // Ok, now get the path to the root doc and tack on the name we
         // got from the GetSrc() call....
         NS_ConvertUTF8toUTF16 workURL(spec);
 
-        PRInt32 loc = workURL.RFind("/");
+        PRInt32 loc = workURL.RFindChar('/');
         if (loc >= 0)
           workURL.SetLength(loc+1);
         workURL.Append(tUrl);
         NS_ConvertUTF16toUTF8 workurlC(workURL);
         if (NS_FAILED(nsMsgNewURL(&attachment->url, workurlC.get())))
         {
           // rhp - just try to continue and send it without this image.
           return NS_OK;
         }
       }
     }
 
     NS_IF_ADDREF(attachment->url);
 
     rv = image->GetName(tName);
     NS_ENSURE_SUCCESS(rv, rv);
-    attachment->real_name = ToNewCString(tName); // XXX i18n
-
-    image->GetLongDesc(tDesc);
+
+    attachment->real_name = ToNewCString(NS_LossyConvertUTF16toASCII(tName)); // XXX i18n
+    rv = image->GetLongDesc(tDesc);
     NS_ENSURE_SUCCESS(rv, rv);
-    attachment->description = ToNewCString(tDesc); // XXX i18n
+    attachment->description = ToNewCString(NS_LossyConvertUTF16toASCII(tDesc)); // XXX i18n
 
   }
   else if (link)        // Is this a link?
   {
     nsString    tUrl;
 
     // Create the URI
     rv = link->GetHref(tUrl);
@@ -1478,17 +1477,17 @@ nsMsgComposeAndSend::GetEmbeddedObjectIn
     CopyUTF16toUTF8(tUrl, turlC);
     rv = nsMsgNewURL(&attachment->url, turlC.get());
     NS_ENSURE_SUCCESS(rv, rv);
 
     NS_IF_ADDREF(attachment->url);
 
     rv = anchor->GetName(tName);
     NS_ENSURE_SUCCESS(rv, rv);
-    attachment->real_name = ToNewCString(tName);
+    attachment->real_name = ToNewCString(NS_LossyConvertUTF16toASCII(tName));
   }
   else
   {
     // If we get here, we got something we didn't expect!
     // Just try to continue and send it without this thing.
     return NS_OK;
   }
 
@@ -1729,17 +1728,17 @@ nsMsgComposeAndSend::GetBodyFromEditor()
           if (prefBranch)
           {
             nsCString prefName("mailnews.disable_fallback_to_utf8.");
             prefName.Append(aCharset);
             prefBranch->GetBoolPref(prefName.get(), &disableFallback);
           }
           if (!disableFallback)
           {
-            CopyUTF16toUTF8(bodyText, outCString);
+            CopyUTF16toUTF8(nsDependentString(bodyText), outCString);
             mCompFields->SetCharacterSet("UTF-8");
           }
         }
       }
       else if (!fallbackCharset.IsEmpty())
       {
         // re-label to the fallback charset
         mCompFields->SetCharacterSet(fallbackCharset.get());
@@ -1759,17 +1758,17 @@ nsMsgComposeAndSend::GetBodyFromEditor()
                                   aCharset, origHTMLBody, &newBody);
       if (NS_SUCCEEDED(rv))
       {
         PR_FREEIF(origHTMLBody);
         origHTMLBody = (PRUnichar *)newBody;
       }
     }
 
-    Recycle(bodyText);    //Don't need it anymore
+    NS_Free(bodyText);    //Don't need it anymore
   }
   else
     return NS_ERROR_FAILURE;
 
   // If our holder for the original body text is STILL null, then just
   // just copy what we have as the original body text.
   //
   if (!origHTMLBody)
@@ -2048,17 +2047,17 @@ nsMsgComposeAndSend::ProcessMultipartRel
       }
       else if (body)
       {
         body->GetBackground(domURL);
         body->SetBackground(newSpec);
       }
 
       if (!domURL.IsEmpty())
-        domSaveArray[j].url = ToNewCString(domURL);
+        domSaveArray[j].url = ToNewCString(NS_LossyConvertUTF16toASCII(domURL));
     }
   }
 
   rv = GetBodyFromEditor();
 
   //
   // Ok, now we need to un-whack the DOM or we have a screwed up document on
   // Send failure.
@@ -2295,17 +2294,18 @@ nsMsgComposeAndSend::AddCompFieldLocalAt
                       mimeFinder->GetTypeFromExtension(fileExt, type);
   #ifndef XP_MACOSX
                     if (!type.Equals("multipart/appledouble"))  // can't do apple double on non-macs
   #endif
                       m_attachments[newLoc].m_type = ToNewCString(type);
                     // rtf and vcs files may look like text to sniffers,
                     // but they're not human readable.
                     if (type.IsEmpty() && !fileExt.IsEmpty() &&
-                         (fileExt.LowerCaseEqualsLiteral("rtf") || fileExt.LowerCaseEqualsLiteral("vcs")))
+                         (MsgLowerCaseEqualsLiteral(fileExt, "rtf") ||
+                          MsgLowerCaseEqualsLiteral(fileExt, "vcs")))
                       m_attachments[newLoc].m_type = PL_strdup(APPLICATION_OCTET_STREAM);
                     }
                   }
                 }
               }
             }
           }
           else
@@ -2934,17 +2934,17 @@ nsMsgComposeAndSend::InitCompositionFiel
           }
         }
       }
 
       if (useDefaultFCC)
       {
         nsCString uri;
         GetFolderURIFromUserPrefs(nsMsgDeliverNow, mUserIdentity, uri);
-        mCompFields->SetFcc(uri.LowerCaseEqualsLiteral("nocopy://") ? "" : uri.get());
+        mCompFields->SetFcc(MsgLowerCaseEqualsLiteral(uri, "nocopy://") ? "" : uri.get());
       }
     }
   }
 
   //
   // Deal with an additional FCC operation for this email.
   //
   const char *fieldsFCC2 = fields->GetFcc2();
@@ -3065,18 +3065,18 @@ nsMsgComposeAndSend::AddDefaultCustomHea
     while (end != -1) {
       end = headersList.FindChar(',', start);
       if (end == -1) {
         len = headersList.Length() - start;
       } else {
         len = end - start;
       }
       // grab the name of the current header pref
-      nsCAutoString headerName(NS_LITERAL_CSTRING("header.") +
-                               Substring(headersList, start, len));
+      nsCAutoString headerName("header.");
+      headerName.Append(Substring(headersList, start, len));
       start = end + 1;
 
       nsCString headerVal;
       rv = mUserIdentity->GetCharAttribute(headerName.get(), headerVal);
       if (NS_SUCCEEDED(rv)) {
         PRInt32 colonIdx = headerVal.FindChar(':') + 1;
         if (colonIdx != 0) { // check that the header is *most likely* valid.
           char * convHeader =
@@ -3106,18 +3106,18 @@ nsMsgComposeAndSend::AddDefaultCustomHea
 nsresult
 nsMsgComposeAndSend::AddMailFollowupToHeader() {
   nsresult rv;
 
   // Get OtherRandomHeaders...
   nsDependentCString customHeaders(mCompFields->GetOtherRandomHeaders());
   // ...and look for MFT-Header.  Stop here if MFT is already set.
   NS_NAMED_LITERAL_CSTRING(mftHeaderLabel, "Mail-Followup-To: ");
-  if ((StringHead(customHeaders, mftHeaderLabel.Length()) == mftHeaderLabel) ||
-      (customHeaders.Find(NS_LITERAL_CSTRING("\r\n") + mftHeaderLabel) != -1))
+  if (StringBeginsWith(customHeaders, mftHeaderLabel) ||
+      customHeaders.Find("\r\nMail-Followup-To: ") != -1)
     return NS_OK;
 
   // Get list of subscribed mailing lists
   nsCAutoString mailing_lists;
   rv = mUserIdentity->GetCharAttribute("subscribed_mailing_lists", mailing_lists);
   // Stop here if this list is missing or empty
   if (NS_FAILED(rv) || mailing_lists.IsEmpty())
     return NS_OK;
@@ -3183,18 +3183,20 @@ nsMsgComposeAndSend::AddMailFollowupToHe
 nsresult
 nsMsgComposeAndSend::AddMailReplyToHeader() {
   nsresult rv;
 
   // Get OtherRandomHeaders...
   nsDependentCString customHeaders(mCompFields->GetOtherRandomHeaders());
   // ...and look for MRT-Header.  Stop here if MRT is already set.
   NS_NAMED_LITERAL_CSTRING(mrtHeaderLabel, "Mail-Reply-To: ");
+  nsCAutoString headers_match = nsCAutoString("\r\n");
+  headers_match.Append(mrtHeaderLabel);
   if ((StringHead(customHeaders, mrtHeaderLabel.Length()) == mrtHeaderLabel) ||
-      (customHeaders.Find(NS_LITERAL_CSTRING("\r\n") + mrtHeaderLabel) != -1))
+      (customHeaders.Find(headers_match) != -1))
     return NS_OK;
 
   // Get list of reply-to mangling mailing lists
   nsCAutoString mailing_lists;
   rv = mUserIdentity->GetCharAttribute("replyto_mangling_mailing_lists", mailing_lists);
   // Stop here if this list is missing or empty
   if (NS_FAILED(rv) || mailing_lists.IsEmpty())
     return NS_OK;
@@ -3692,21 +3694,23 @@ nsMsgComposeAndSend::DeliverFileAsMail()
   {
     // MIME-PartII conversion
     PR_FREEIF(buf);
     buf = convbuf;
   }
 
   strip_nonprintable(buf);
 
-  convbuf = nsEscape(buf, url_Path);
-  if (convbuf)
+  nsCString escaped_buf;
+  MsgEscapeString(nsDependentCString(buf), nsINetUtil::ESCAPE_URL_PATH, escaped_buf);
+
+  if (!escaped_buf.IsEmpty())
   {
     NS_Free(buf);
-    buf = convbuf;
+    buf = ToNewCString(escaped_buf);
   }
 
   nsCOMPtr<nsISmtpService> smtpService(do_GetService(NS_SMTPSERVICE_CONTRACTID, &rv));
   if (NS_SUCCEEDED(rv) && smtpService)
   {
     MsgDeliveryListener *deliveryListener = new MsgDeliveryListener(this, PR_FALSE);
     if (!deliveryListener)
       return NS_ERROR_OUT_OF_MEMORY;
--- a/mailnews/compose/src/nsMsgSend.h
+++ b/mailnews/compose/src/nsMsgSend.h
@@ -133,16 +133,17 @@
    defined, which added a BASE tag to the bodies.  We stopped doing this in
    4.0.  */
 #define GENERATE_CONTENT_BASE
 
 
 //
 // Necessary includes
 //
+#include "nsCOMPtr.h"
 #include "nsIMsgSend.h"
 #include "nsIStringBundle.h"
 #include "msgCore.h"
 #include "prprf.h"
 #include "nsIOutputStream.h"
 #include "nsMsgMessageFlags.h"
 #include "nsIURL.h"
 #include "nsMsgAttachmentHandler.h"
--- a/mailnews/compose/src/nsSmtpProtocol.cpp
+++ b/mailnews/compose/src/nsSmtpProtocol.cpp
@@ -52,29 +52,28 @@
 #include "nsIOutputStream.h"
 #include "nsISocketTransport.h"
 #include "nsIMsgHeaderParser.h"
 #include "nsIMsgMailNewsUrl.h"
 #include "nsMsgBaseCID.h"
 #include "nsMsgCompCID.h"
 #include "nsIPrompt.h"
 #include "nsIAuthPrompt.h"
-#include "nsString.h"
+#include "nsStringGlue.h"
 #include "nsTextFormatter.h"
 #include "nsIMsgIdentity.h"
 #include "nsISmtpServer.h"
 #include "prtime.h"
 #include "prlog.h"
 #include "prerror.h"
 #include "prprf.h"
 #include "prmem.h"
 #include "plbase64.h"
 #include "prnetdb.h"
 #include "prsystem.h"
-#include "nsEscape.h"
 #include "nsMsgUtils.h"
 #include "nsIPipe.h"
 #include "nsNetUtil.h"
 #include "nsIPrefService.h"
 #include "nsISignatureVerifier.h"
 #include "nsISSLSocketControl.h"
 #include "nsComposeStrings.h"
 #include "nsIStringBundle.h"
@@ -388,17 +387,18 @@ void nsSmtpProtocol::AppendHelloArgument
                   NS_ASSERTION(!PR_IsNetAddrType(&iaddr, PR_IpAddrV4Mapped),
                                "unexpected IPv4-mapped IPv6 address");
 
                   if (iaddr.raw.family == PR_AF_INET6)   // IPv6 style address?
                       aResult.AppendLiteral("[IPv6:");
                   else
                       aResult.AppendLiteral("[");
 
-                  aResult.Append(nsDependentCString(ipAddressString) + NS_LITERAL_CSTRING("]"));
+                  aResult.Append(ipAddressString);
+                  aResult.Append(']');
               }
           }
       }
   }
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////////
 // we suppport the nsIStreamListener interface
@@ -741,58 +741,58 @@ PRInt32 nsSmtpProtocol::SendEhloResponse
     PRInt32 startPos = 0;
     PRInt32 endPos;
     do
     {
         endPos = m_responseText.FindChar('\n', startPos + 1);
         nsCAutoString responseLine;
         responseLine.Assign(Substring(m_responseText, startPos,
             (endPos >= 0 ? endPos : responseLength) - startPos));
-        responseLine.CompressWhitespace();
 
-        if (responseLine.Compare("STARTTLS", PR_TRUE) == 0)
+        MsgCompressWhitespace(responseLine);
+        if (responseLine.Equals(NS_LITERAL_CSTRING("STARTTLS"), nsCaseInsensitiveCStringComparator()))
         {
             SetFlag(SMTP_EHLO_STARTTLS_ENABLED);
         }
-        else if (responseLine.Compare("DSN", PR_TRUE) == 0)
+        else if (responseLine.Equals(NS_LITERAL_CSTRING("DSN"), nsCaseInsensitiveCStringComparator()))
         {
             SetFlag(SMTP_EHLO_DSN_ENABLED);
         }
-        else if (responseLine.Compare("AUTH", PR_TRUE, 4) == 0)
+        else if (StringBeginsWith(responseLine, NS_LITERAL_CSTRING("AUTH"), nsCaseInsensitiveCStringComparator()))
         {
             SetFlag(SMTP_AUTH);
 
-            if (responseLine.Find("GSSAPI", PR_TRUE, 5) >= 0)
+            if (responseLine.Find(NS_LITERAL_CSTRING("GSSAPI"), CaseInsensitiveCompare) >= 0)
                 SetFlag(SMTP_AUTH_GSSAPI_ENABLED);
 
             nsresult rv;
             nsCOMPtr<nsISignatureVerifier> verifier = do_GetService(SIGNATURE_VERIFIER_CONTRACTID, &rv);
             // this checks if psm is installed...
             if (NS_SUCCEEDED(rv))
             {
-                if (responseLine.Find("CRAM-MD5", PR_TRUE, 5) >= 0)
+                if (responseLine.Find(NS_LITERAL_CSTRING("CRAM-MD5"), CaseInsensitiveCompare) >= 0)
                     SetFlag(SMTP_AUTH_CRAM_MD5_ENABLED);
 
-                if (responseLine.Find("NTLM", PR_TRUE, 5) >= 0)
+                if (responseLine.Find(NS_LITERAL_CSTRING("NTLM"), CaseInsensitiveCompare) >= 0)
                     SetFlag(SMTP_AUTH_NTLM_ENABLED);
 
-                if (responseLine.Find("MSN", PR_TRUE, 5) >= 0)
+                if (responseLine.Find(NS_LITERAL_CSTRING("MSN"), CaseInsensitiveCompare) >= 0)
                     SetFlag(SMTP_AUTH_MSN_ENABLED);
             }
 
-            if (responseLine.Find("PLAIN", PR_TRUE, 5) >= 0)
+            if (responseLine.Find(NS_LITERAL_CSTRING("PLAIN"), CaseInsensitiveCompare) >= 0)
                 SetFlag(SMTP_AUTH_PLAIN_ENABLED);
 
-            if (responseLine.Find("LOGIN", PR_TRUE, 5) >= 0)
+            if (responseLine.Find(NS_LITERAL_CSTRING("LOGIN"), CaseInsensitiveCompare) >= 0)
                 SetFlag(SMTP_AUTH_LOGIN_ENABLED);
 
-            if (responseLine.Find("EXTERNAL", PR_TRUE, 5) >= 0)
+            if (responseLine.Find(NS_LITERAL_CSTRING("EXTERNAL"), CaseInsensitiveCompare) >= 0)
                 SetFlag(SMTP_AUTH_EXTERNAL_ENABLED);
         }
-        else if (responseLine.Compare("SIZE", PR_TRUE, 4) == 0)
+        else if (StringBeginsWith(responseLine, NS_LITERAL_CSTRING("SIZE"), nsCaseInsensitiveCStringComparator()))
         {
             SetFlag(SMTP_EHLO_SIZE_ENABLED);
 
             m_sizelimit = atol((responseLine.get()) + 4);
         }
 
         startPos = endPos + 1;
     } while (endPos >= 0);
--- a/mailnews/compose/src/nsSmtpServer.cpp
+++ b/mailnews/compose/src/nsSmtpServer.cpp
@@ -33,17 +33,16 @@
  * 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 "nsIPrefService.h"
 #include "nsIPrefBranch.h"
-#include "nsEscape.h"
 #include "nsSmtpServer.h"
 #include "nsNetUtil.h"
 #include "nsIAuthPrompt.h"
 #include "nsMsgUtils.h"
 #include "nsIMsgAccountManager.h"
 #include "nsMsgBaseCID.h"
 #include "nsISmtpService.h"
 #include "nsMsgCompCID.h"
@@ -507,18 +506,17 @@ nsSmtpServer::ForgetPassword()
   // Get the current server URI without the username
   nsCAutoString serverUri(NS_LITERAL_CSTRING("smtp://"));
 
   nsCString hostname;
   rv = GetHostname(hostname);
 
   if (NS_SUCCEEDED(rv) && !hostname.IsEmpty()) {
     nsCString escapedHostname;
-    *((char **)getter_Copies(escapedHostname)) =
-      nsEscape(hostname.get(), url_Path);
+    MsgEscapeString(hostname, nsINetUtil::ESCAPE_URL_PATH, escapedHostname);
     // not all servers have a hostname
     serverUri.Append(escapedHostname);
   }
 
   PRUint32 count;
   nsILoginInfo** logins;
 
   NS_ConvertUTF8toUTF16 currServer(serverUri);
@@ -569,18 +567,17 @@ nsSmtpServer::GetServerURI(nsACString &a
         uri.AppendLiteral("@");
     }
 
     nsCString hostname;
     rv = GetHostname(hostname);
 
     if (NS_SUCCEEDED(rv) && !hostname.IsEmpty()) {
         nsCString escapedHostname;
-        *((char **)getter_Copies(escapedHostname)) =
-            nsEscape(hostname.get(), url_Path);
+        MsgEscapeString(hostname, nsINetUtil::ESCAPE_URL_PATH, escapedHostname);
         // not all servers have a hostname
         uri.Append(escapedHostname);
     }
 
     aResult = uri;
     return NS_OK;
 }
 
--- a/mailnews/compose/src/nsSmtpService.cpp
+++ b/mailnews/compose/src/nsSmtpService.cpp
@@ -33,17 +33,16 @@
  * 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 "msgCore.h"    // precompiled header...
-#include "nsReadableUtils.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsIIOService.h"
 #include "nsIPipe.h"
 #include "nsNetCID.h"
 #include "nsMsgUtils.h"
 #include "nsNetUtil.h"
 #include "nsSmtpService.h"
--- a/mailnews/compose/src/nsSmtpUrl.cpp
+++ b/mailnews/compose/src/nsSmtpUrl.cpp
@@ -36,23 +36,24 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "msgCore.h"
 
 #include "nsIURI.h"
 #include "nsNetCID.h"
 #include "nsSmtpUrl.h"
-#include "nsString.h"
-#include "nsReadableUtils.h"
-#include "nsEscape.h"
+#include "nsStringGlue.h"
 #include "nsMsgUtils.h"
 #include "nsIMimeConverter.h"
 #include "nsMsgMimeCID.h"
 #include "nsISupportsObsolete.h"
+#include "nsComponentManagerUtils.h"
+#include "nsServiceManagerUtils.h"
+#include "nsCRT.h"
 
 /////////////////////////////////////////////////////////////////////////////////////
 // mailto url definition
 /////////////////////////////////////////////////////////////////////////////////////
 nsMailtoUrl::nsMailtoUrl()
 {
   mFormat = nsIMsgCompFormat::Default;
   m_baseURL = do_CreateInstance(NS_SIMPLEURI_CONTRACTID);
@@ -103,17 +104,17 @@ nsresult nsMailtoUrl::ParseMailtoUrl(cha
       char *value = 0;
       char *eq = PL_strchr(token, '=');
       if (eq)
       {
         value = eq+1;
         *eq = 0;
       }
 
-      switch (toupper(*token))
+      switch (NS_ToUpper(*token))
       {
         /* DO NOT support attachment= in mailto urls. This poses a security fire hole!!! 
                           case 'A':
                           if (!PL_strcasecmp (token, "attachment"))
                           m_attachmentPart = value;
                           break;
                      */
       case 'B':
@@ -433,25 +434,23 @@ nsresult nsMailtoUrl::ParseUrl()
   // we can get the path from the simple url.....
   nsCString escapedPath;
   m_baseURL->GetPath(escapedPath);
 
   PRInt32 startOfSearchPart = escapedPath.FindChar('?');
   if (startOfSearchPart >= 0)
   {
     // now parse out the search field...
-    nsCString searchPart;
-    PRUint32 numExtraChars = escapedPath.Right(searchPart,
-                                               escapedPath.Length() -
-                                               startOfSearchPart);
+    nsCAutoString searchPart(Substring(escapedPath, startOfSearchPart));
+
     if (!searchPart.IsEmpty())
     {
       // now we need to strip off the search part from the
       // to part....
-      escapedPath.Cut(startOfSearchPart, numExtraChars);
+      escapedPath.SetLength(startOfSearchPart);
       MsgUnescapeString(escapedPath, 0, m_toPart);
       ParseMailtoUrl(searchPart.BeginWriting());
     }
   }
   else if (!escapedPath.IsEmpty())
   {
     MsgUnescapeString(escapedPath, 0, m_toPart);
   }
@@ -692,19 +691,17 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsSmtpUrl, 
 // Begin nsISmtpUrl specific support
 
 ////////////////////////////////////////////////////////////////////////////////////
 
 NS_IMETHODIMP
 nsSmtpUrl::SetRecipients(const char * aRecipientsList)
 {
   NS_ENSURE_ARG(aRecipientsList);
-  m_toPart = aRecipientsList;
-  if (!m_toPart.IsEmpty())
-    nsUnescape(m_toPart.BeginWriting());
+  MsgUnescapeString(nsDependentCString(aRecipientsList), 0, m_toPart);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSmtpUrl::GetRecipients(char ** aRecipientsList)
 {
   NS_ENSURE_ARG_POINTER(aRecipientsList);
   if (aRecipientsList)
--- a/mailnews/compose/src/nsURLFetcher.cpp
+++ b/mailnews/compose/src/nsURLFetcher.cpp
@@ -43,28 +43,29 @@
 #include <stdio.h>
 #include "nscore.h"
 #include "nsIFactory.h"
 #include "nsISupports.h"
 #include "comi18n.h"
 #include "prmem.h"
 #include "plstr.h"
 #include "nsIComponentManager.h"
-#include "nsString.h"
+#include "nsStringGlue.h"
 #include "nsIIOService.h"
 #include "nsIChannel.h"
 #include "nsNetUtil.h"
 #include "nsMimeTypes.h"
 #include "nsIHttpChannel.h"
 #include "nsIWebProgress.h"
 #include "nsMsgAttachmentHandler.h"
 #include "nsMsgSend.h"
 #include "nsISeekableStream.h"
 #include "nsIStreamConverterService.h"
 #include "nsIMsgProgress.h"
+#include "nsMsgUtils.h"
 
 NS_IMPL_ISUPPORTS7(nsURLFetcher,
                    nsIURLFetcher,
                    nsIStreamListener,
                    nsIRequestObserver,
                    nsIURIContentListener,
                    nsIInterfaceRequestor,
                    nsIWebProgressListener,
@@ -309,18 +310,18 @@ nsURLFetcher::OnStopRequest(nsIRequest *
 
   // time to close the output stream...
   if (mOutStream)
   {
     mOutStream->Close();
     mOutStream = nsnull;
   
     /* In case of multipart/x-mixed-replace, we need to truncate the file to the current part size */
-    if (mConverterContentType.LowerCaseEqualsLiteral(MULTIPART_MIXED_REPLACE))
-  {
+    if (MsgLowerCaseEqualsLiteral(mConverterContentType, MULTIPART_MIXED_REPLACE))
+    {
       PRInt64 fileSize;
       LL_I2L(fileSize, mTotalWritten);
       mLocalFile->SetFileSize(fileSize);
     }
   }
 
   // Now if there is a callback, we need to call it...
   if (mCallback)
@@ -471,17 +472,17 @@ nsURLFetcherStreamConsumer::~nsURLFetche
 
 /* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
 NS_IMETHODIMP nsURLFetcherStreamConsumer::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt)
 {
   if (!mURLFetcher || !mURLFetcher->mOutStream)
     return NS_ERROR_FAILURE;
 
   /* In case of multipart/x-mixed-replace, we need to erase the output file content */
-  if (mURLFetcher->mConverterContentType.LowerCaseEqualsLiteral(MULTIPART_MIXED_REPLACE))
+  if (MsgLowerCaseEqualsLiteral(mURLFetcher->mConverterContentType, MULTIPART_MIXED_REPLACE))
   {
     nsCOMPtr<nsISeekableStream> seekStream = do_QueryInterface(mURLFetcher->mOutStream);
     if (seekStream)
       seekStream->Seek(nsISeekableStream::NS_SEEK_SET, 0);
     mURLFetcher->mTotalWritten = 0;
   }
 
   return NS_OK;