Bug 1363281 - Port bug 1261841 |Replace uconv with encoding_rs| to mailnews. rs=mkmelin, f=hsivonen
authorJorg K <jorgk@jorgk.com>
Wed, 14 Jun 2017 08:01:14 +0200
changeset 28337 f558febc1ead57c76ba5eb5af4443a67680f7fa4
parent 28336 36e37076b1b36bb009b6f64a36e77a74e2ee1387
child 28338 ac30eed3d7e54d44f6824d9da864d3a89579e76c
push id1986
push userclokep@gmail.com
push dateWed, 02 Aug 2017 14:43:31 +0000
treeherdercomm-beta@b51c9adf2c9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin
bugs1363281, 1261841
Bug 1363281 - Port bug 1261841 |Replace uconv with encoding_rs| to mailnews. rs=mkmelin, f=hsivonen
mailnews/addrbook/src/nsAbQueryStringToExpression.cpp
mailnews/base/src/nsMessenger.cpp
mailnews/base/util/nsMsgI18N.cpp
mailnews/base/util/nsMsgI18N.h
mailnews/build/nsMailModule.cpp
mailnews/compose/src/nsMsgCompose.cpp
mailnews/compose/src/nsMsgCompose.h
mailnews/compose/src/nsMsgSend.cpp
mailnews/import/outlook/src/MapiMessage.cpp
mailnews/import/src/nsImportService.cpp
mailnews/import/src/nsImportService.h
mailnews/intl/nsCharsetConverterManager.cpp
mailnews/intl/nsICharsetConverterManager.idl
mailnews/intl/nsUTF7ToUnicode.h
mailnews/intl/nsUnicodeToUTF7.h
mailnews/mime/src/comi18n.cpp
mailnews/mime/src/comi18n.h
mailnews/mime/src/mimemoz2.cpp
mailnews/mime/src/mimetext.cpp
mailnews/mime/src/mimetext.h
mailnews/mime/src/modlmime.h
mailnews/news/src/nsNNTPProtocol.cpp
--- a/mailnews/addrbook/src/nsAbQueryStringToExpression.cpp
+++ b/mailnews/addrbook/src/nsAbQueryStringToExpression.cpp
@@ -299,22 +299,22 @@ nsresult nsAbQueryStringToExpression::Cr
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsITextToSubURI> textToSubURI = do_GetService(NS_ITEXTTOSUBURI_CONTRACTID,&rv); 
     if (NS_SUCCEEDED(rv))
     {
         nsString attributeUCS2;
         nsString valueUCS2;
 
-        rv = textToSubURI->UnEscapeAndConvert("UTF-8",
-            attribute, getter_Copies(attributeUCS2));
+        rv = textToSubURI->UnEscapeAndConvert(nsDependentCString("UTF-8"),
+            nsDependentCString(attribute), attributeUCS2);
         NS_ENSURE_SUCCESS(rv, rv);
 
-        rv = textToSubURI->UnEscapeAndConvert("UTF-8",
-            value, getter_Copies(valueUCS2));
+        rv = textToSubURI->UnEscapeAndConvert(nsDependentCString("UTF-8"),
+            nsDependentCString(value), valueUCS2);
         NS_ENSURE_SUCCESS(rv, rv);
 
         NS_ConvertUTF16toUTF8 attributeUTF8(attributeUCS2);
 
         rv = cs->SetName (attributeUTF8.get ());
         NS_ENSURE_SUCCESS(rv, rv);
         rv = cs->SetValue(valueUCS2.get());
         NS_ENSURE_SUCCESS(rv, rv);
--- a/mailnews/base/src/nsMessenger.cpp
+++ b/mailnews/base/src/nsMessenger.cpp
@@ -1863,17 +1863,17 @@ nsSaveMsgListener::OnStopRequest(nsIRequ
     // For HTML, code is emitted immediately in OnDataAvailable.
     MOZ_ASSERT(m_outputFormat == ePlainText,
       "For HTML, m_doCharsetConversion shouldn't be set");
     NS_ConvertUTF8toUTF16 utf16Buffer(m_msgBuffer);
     ConvertBufToPlainText(utf16Buffer, false, false, false, false);
 
     nsCString outCString;
     rv = nsMsgI18NConvertFromUnicode(nsMsgI18NFileSystemCharset(),
-      utf16Buffer, outCString, false, true);
+      utf16Buffer, outCString, true);
     if (rv == NS_ERROR_UENC_NOMAPPING) {
       // If we can't encode with the preferred charset, use UTF-8.
       CopyUTF16toUTF8(utf16Buffer, outCString);
       rv = NS_OK;
     }
     if (NS_SUCCEEDED(rv))
     {
       uint32_t writeCount;
--- a/mailnews/base/util/nsMsgI18N.cpp
+++ b/mailnews/base/util/nsMsgI18N.cpp
@@ -28,162 +28,60 @@
 #include "nsIFileStreams.h"
 //
 // International functions necessary for composition
 //
 
 nsresult nsMsgI18NConvertFromUnicode(const char* aCharset,
                                      const nsString& inString,
                                      nsACString& outString,
-                                     bool aIsCharsetCanonical,
                                      bool aReportUencNoMapping)
 {
   if (inString.IsEmpty()) {
     outString.Truncate();
     return NS_OK;
   }
-  // Note: This will hide a possible error if the Unicode contains more than one
-  // charset, e.g. Latin1 + Japanese.
-  else if (!aReportUencNoMapping && (!*aCharset ||
-             !PL_strcasecmp(aCharset, "us-ascii") ||
-             !PL_strcasecmp(aCharset, "ISO-8859-1"))) {
-    LossyCopyUTF16toASCII(inString, outString);
-    return NS_OK;
-  }
-  else if (!PL_strcasecmp(aCharset, "UTF-8")) {
-    CopyUTF16toUTF8(inString, outString);
-    return NS_OK;
+
+  auto encoding = mozilla::Encoding::ForLabelNoReplacement(nsDependentCString(aCharset));
+  if (!encoding) {
+    return NS_ERROR_UCONV_NOCONV;
+  } else if (encoding == UTF_16LE_ENCODING || UTF_16BE_ENCODING) {
+    // We shouldn't ever ship anything in these encodings.
+    return NS_ERROR_UCONV_NOCONV;
   }
 
+  const mozilla::Encoding* actualEncoding;
   nsresult rv;
-  nsCOMPtr <nsICharsetConverterManager> ccm = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-  nsCOMPtr <nsIUnicodeEncoder> encoder;
-
-  // get an unicode converter
-  if (aIsCharsetCanonical)  // optimize for modified UTF-7 used by IMAP
-    rv = ccm->GetUnicodeEncoderRaw(aCharset, getter_AddRefs(encoder));
-  else
-    rv = ccm->GetUnicodeEncoder(aCharset, getter_AddRefs(encoder));
-  NS_ENSURE_SUCCESS(rv, rv);
-  // Must set behavior to kOnError_Signal if we want to receive the
-  // NS_ERROR_UENC_NOMAPPING signal, should it occur.
-  int32_t behavior = aReportUencNoMapping ? nsIUnicodeEncoder::kOnError_Signal:
-    nsIUnicodeEncoder::kOnError_Replace;
-  rv = encoder->SetOutputErrorBehavior(behavior, nullptr, '?');
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  const char16_t *originalSrcPtr = inString.get();
-  const char16_t *currentSrcPtr = originalSrcPtr;
-  int32_t originalUnicharLength = inString.Length();
-  int32_t srcLength;
-  int32_t dstLength;
-  char localbuf[512+10]; // We have seen cases were the buffer was overrun
-                         // by two (!!) bytes (Bug 1255863).
-                         // So give it ten bytes more for now to avoid a crash.
-  int32_t consumedLen = 0;
+  mozilla::Tie(rv, actualEncoding) = encoding->Encode(inString, outString);
+  mozilla::Unused << actualEncoding;
 
-  bool mappingFailure = false;
-  outString.Truncate();
-  // convert
-  while (consumedLen < originalUnicharLength) {
-    srcLength = originalUnicharLength - consumedLen;  
-    dstLength = 512;
-    rv = encoder->Convert(currentSrcPtr, &srcLength, localbuf, &dstLength);
-#ifdef DEBUG
-    if (dstLength > 512) {
-      char warning[100];
-      sprintf(warning, "encoder->Convert() returned %d bytes. Limit = 512", dstLength);
-      NS_WARNING(warning);
-    }
-#endif
-    if (rv == NS_ERROR_UENC_NOMAPPING) {
-      mappingFailure = true;
-    }
-    if (NS_FAILED(rv) || dstLength == 0)
-      break;
-    outString.Append(localbuf, dstLength);
+  if (rv == NS_OK_HAD_REPLACEMENTS) {
+    rv = aReportUencNoMapping ? NS_ERROR_UENC_NOMAPPING : NS_OK;
+  }
 
-    currentSrcPtr += srcLength;
-    consumedLen = currentSrcPtr - originalSrcPtr; // src length used so far
-  }
-  dstLength = 512; // Reset available buffer size.
-  rv = encoder->Finish(localbuf, &dstLength);
-  if (NS_SUCCEEDED(rv)) {
-    if (dstLength)
-      outString.Append(localbuf, dstLength);
-    return !mappingFailure ? rv: NS_ERROR_UENC_NOMAPPING;
-  }
   return rv;
 }
 
 nsresult nsMsgI18NConvertToUnicode(const char* aCharset,
                                    const nsCString& inString, 
-                                   nsAString& outString,
-                                   bool aIsCharsetCanonical)
+                                   nsAString& outString)
 {
   if (inString.IsEmpty()) {
     outString.Truncate();
     return NS_OK;
   }
-  else if (!*aCharset || !PL_strcasecmp(aCharset, "us-ascii") ||
-           !PL_strcasecmp(aCharset, "ISO-8859-1")) {
-    // Despite its name, it also works for Latin-1.
-    CopyASCIItoUTF16(inString, outString);
-    return NS_OK;
-  }
   else if (!PL_strcasecmp(aCharset, "UTF-8")) {
-    if (MsgIsUTF8(inString)) {
-      nsAutoString tmp;
-      CopyUTF8toUTF16(inString, tmp);
-      if (!tmp.IsEmpty() && tmp.First() == char16_t(0xFEFF))
-        tmp.Cut(0, 1);
-      outString.Assign(tmp);
-      return NS_OK;
-    }
-    NS_WARNING("Invalid UTF-8 string");
-    return NS_ERROR_UNEXPECTED;
+    return UTF_8_ENCODING->DecodeWithBOMRemoval(inString, outString);
   }
 
-  nsresult rv;
-  nsCOMPtr <nsICharsetConverterManager> ccm = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr <nsIUnicodeDecoder> decoder;
-
-  // get an unicode converter
-  if (aIsCharsetCanonical)  // optimize for modified UTF-7 used by IMAP
-    rv = ccm->GetUnicodeDecoderRaw(aCharset, getter_AddRefs(decoder));
-  else
-    rv = ccm->GetUnicodeDecoderInternal(aCharset, getter_AddRefs(decoder));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  const char *originalSrcPtr = inString.get();
-  const char *currentSrcPtr = originalSrcPtr;
-  int32_t originalLength = inString.Length();
-  int32_t srcLength;
-  int32_t dstLength;
-  char16_t localbuf[512];
-  int32_t consumedLen = 0;
-
-  outString.Truncate();
-
-  // convert
-  while (consumedLen < originalLength) {
-    srcLength = originalLength - consumedLen;  
-    dstLength = 512;
-    rv = decoder->Convert(currentSrcPtr, &srcLength, localbuf, &dstLength);
-    if (NS_FAILED(rv) || dstLength == 0)
-      break;
-    outString.Append(localbuf, dstLength);
-
-    currentSrcPtr += srcLength;
-    consumedLen = currentSrcPtr - originalSrcPtr; // src length used so far
-  }
-  return rv;
+  auto encoding = mozilla::Encoding::ForLabelNoReplacement(nsDependentCString(aCharset));
+  if (!encoding)
+    return NS_ERROR_UCONV_NOCONV;
+  return encoding->DecodeWithoutBOMHandlingAndWithoutReplacement(inString,
+                                                                 outString);
 }
 
 // Charset used by the file system.
 const char * nsMsgI18NFileSystemCharset()
 {
   /* Get a charset used for the file. */
   static nsAutoCString fileSystemCharset;
 
@@ -261,67 +159,51 @@ bool nsMsgI18Nmultibyte_charset(const ch
     if (NS_SUCCEEDED(res)) {
       result = charsetData.LowerCaseEqualsLiteral("true");
     }
   }
 
   return result;
 }
 
-bool nsMsgI18Ncheck_data_in_charset_range(const char *charset, const char16_t* inString, char **fallbackCharset)
+bool nsMsgI18Ncheck_data_in_charset_range(const char *charset, const char16_t* inString)
 {
   if (!charset || !*charset || !inString || !*inString)
     return true;
 
-  nsresult res;
-  bool result = true;
-  
-  nsCOMPtr <nsICharsetConverterManager> ccm = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &res);
-
-  if (NS_SUCCEEDED(res)) {
-    nsCOMPtr <nsIUnicodeEncoder> encoder;
+  bool res = true;
 
-    // get an unicode converter
-    res = ccm->GetUnicodeEncoderRaw(charset, getter_AddRefs(encoder));
-    if(NS_SUCCEEDED(res)) {
-      const char16_t *originalPtr = inString;
-      int32_t originalLen = NS_strlen(inString);
-      const char16_t *currentSrcPtr = originalPtr;
-      char localBuff[512];
-      int32_t consumedLen = 0;
-      int32_t srcLen;
-      int32_t dstLength;
+  auto encoding = mozilla::Encoding::ForLabelNoReplacement(nsDependentCString(charset));
+  if (!encoding)
+    return false;
+  auto encoder = encoding->NewEncoder();
 
-      // convert from unicode
-      while (consumedLen < originalLen) {
-        srcLen = originalLen - consumedLen;
-        dstLength = 512;
-        res = encoder->Convert(currentSrcPtr, &srcLen, localBuff, &dstLength);
-        if (NS_ERROR_UENC_NOMAPPING == res) {
-          result = false;
-          break;
-        }
-        else if (NS_FAILED(res) || (0 == dstLength))
-          break;
-
-        currentSrcPtr += srcLen;
-        consumedLen = currentSrcPtr - originalPtr; // src length used so far
-      }
-    }    
+  uint8_t buffer[512];
+  auto src = mozilla::MakeStringSpan(inString);
+  auto dst = mozilla::MakeSpan(buffer);
+  while (true) {
+    uint32_t result;
+    size_t read;
+    size_t written;
+    mozilla::Tie(result, read, written) =
+      encoder->EncodeFromUTF16WithoutReplacement(src, dst, false);
+    if (result == mozilla::kInputEmpty) {
+      // All converted successfully.
+      break;
+    } else if (result != mozilla::kOutputFull) {
+      // Didn't use all the input but the outout isn't full, hence
+      // there was an unencodable character.
+      res = false;
+      break;
+    }
+    src = src.From(read);
+    // dst = dst.From(written); // Just overwrite output since we don't need it.
   }
-
-  // if the conversion was not successful then try fallback to other charsets
-  if (!result && fallbackCharset) {
-    nsCString convertedString;
-    res = nsMsgI18NConvertFromUnicode(*fallbackCharset,
-      nsDependentString(inString), convertedString, false, true);
-    result = (NS_SUCCEEDED(res) && NS_ERROR_UENC_NOMAPPING != res);
-  }
-
-  return result;
+  
+  return res;
 }
 
 // Simple parser to parse META charset. 
 // It only supports the case when the description is within one line. 
 const char * 
 nsMsgI18NParseMetaCharset(nsIFile* file) 
 { 
   static char charset[nsIMimeConverter::MAX_CHARSET_NAME_LENGTH+1];
--- a/mailnews/base/util/nsMsgI18N.h
+++ b/mailnews/base/util/nsMsgI18N.h
@@ -47,18 +47,17 @@ NS_MSG_BASE bool nsMsgI18Nmultibyte_char
  * @param inString    [IN] Input unicode string to be examined.
  * @param fallbackCharset [OUT]
  *                         null if fallback charset is not needed.
  *                         Otherwise, a fallback charset name may be set if that was used for the conversion. 
  *                         Caller is responsible for freeing the memory.
  * @return            True if the string can be converted within the charset range.
  *                    False if one or more characters cannot be converted to the target charset.
  */
-NS_MSG_BASE bool      nsMsgI18Ncheck_data_in_charset_range(const char *charset, const char16_t* inString,
-                                                           char **fallbackCharset=nullptr);
+NS_MSG_BASE bool      nsMsgI18Ncheck_data_in_charset_range(const char *charset, const char16_t* inString);
 
 /**
  * Return charset name of file system (OS dependent).
  *
  * @return            File system charset name.
  */
 NS_MSG_BASE const char * nsMsgI18NFileSystemCharset(void);
 
@@ -70,44 +69,39 @@ NS_MSG_BASE const char * nsMsgI18NFileSy
 NS_MSG_BASE void nsMsgI18NTextFileCharset(nsACString& aCharset);
 
 /**
  * Convert from unicode to target charset.
  *
  * @param charset     [IN] Charset name.
  * @param inString    [IN] Unicode string to convert.
  * @param outString   [OUT] Converted output string.
- * @param aIsCharsetCanonical  [IN] Whether the charset is canonical or not.
  * @param aReportUencNoMapping [IN] Set encoder to report (instead of using
  *                                  replacement char on errors). Set to true
  *                                  to receive NS_ERROR_UENC_NOMAPPING when
  *                                  that happens. Note that
  *                                  NS_ERROR_UENC_NOMAPPING is a success code!
  * @return            nsresult.
  */
 NS_MSG_BASE nsresult nsMsgI18NConvertFromUnicode(const char* aCharset,
                                                  const nsString& inString,
                                                  nsACString& outString,
-                                                 bool aIsCharsetCanonical =
-                                                        false,
                                                  bool reportUencNoMapping =
                                                         false);
 /**
  * Convert from charset to unicode.
  *
  * @param charset     [IN] Charset name.
  * @param inString    [IN] Input string to convert.
  * @param outString   [OUT] Output unicode string.
  * @return            nsresult.
  */
 NS_MSG_BASE nsresult nsMsgI18NConvertToUnicode(const char* aCharset,
                                                const nsCString& inString,
-                                               nsAString& outString,
-                                               bool aIsCharsetCanonical =
-                                                      false);
+                                               nsAString& outString);
 /**
  * Parse for META charset.
  *
  * @param file    [IN] A nsIFile.
  * @return            A charset name or empty string if not found.
  */
 NS_MSG_BASE const char *nsMsgI18NParseMetaCharset(nsIFile* file);
 
@@ -142,24 +136,22 @@ NS_MSG_BASE void nsMsgI18NConvertRawByte
  */
 NS_MSG_BASE void nsMsgI18NConvertRawBytesToUTF8(const nsCString& inString, 
                                                 const char* charset,
                                                 nsACString& outString);
 
 // inline forwarders to avoid littering with 'x-imap4-.....'
 inline nsresult CopyUTF16toMUTF7(const nsString &aSrc, nsACString& aDest)
 {
-    return nsMsgI18NConvertFromUnicode("x-imap4-modified-utf7", aSrc,
-                                       aDest, true);
+    return nsMsgI18NConvertFromUnicode("x-imap4-modified-utf7", aSrc, aDest);
 }
 
 inline nsresult CopyMUTF7toUTF16(const nsCString& aSrc, nsAString& aDest)
 {
-    return nsMsgI18NConvertToUnicode("x-imap4-modified-utf7", aSrc,
-                                     aDest, true);
+    return nsMsgI18NConvertToUnicode("x-imap4-modified-utf7", aSrc, aDest);
 }
 
 inline nsresult ConvertToUnicode(const char* charset,
                                  const nsCString &aSrc, nsAString& aDest)
 {
     return nsMsgI18NConvertToUnicode(charset, aSrc, aDest);
 }
 
--- a/mailnews/build/nsMailModule.cpp
+++ b/mailnews/build/nsMailModule.cpp
@@ -309,25 +309,24 @@
 ////////////////////////////////////////////////////////////////////////////////
 // PGP/MIME includes
 ////////////////////////////////////////////////////////////////////////////////
 #include "nsPgpMimeProxy.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // i18n includes
 ////////////////////////////////////////////////////////////////////////////////
-#include "nsEncoderDecoderUtils.h"
 #include "nsCommUConvCID.h"
 
 #include "nsCharsetConverterManager.h"
 
-#include "nsUTF7ToUnicode.h"
-#include "nsMUTF7ToUnicode.h"
-#include "nsUnicodeToUTF7.h"
-#include "nsUnicodeToMUTF7.h"
+// #include "nsUTF7ToUnicode.h"
+// #include "nsMUTF7ToUnicode.h"
+// #include "nsUnicodeToUTF7.h"
+// #include "nsUnicodeToMUTF7.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // mailnews base factories
 ////////////////////////////////////////////////////////////////////////////////
 using namespace mozilla::mailnews;
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMessengerBootstrap)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsMsgMailSession, Init)
@@ -854,21 +853,16 @@ nsPgpMimeMimeContentTypeHandlerConstruct
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // i18n factories
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsCharsetConverterManager)
 
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsUTF7ToUnicode)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsMUTF7ToUnicode)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsUnicodeToUTF7)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsUnicodeToMUTF7)
-
 NS_DEFINE_NAMED_CID(NS_ICHARSETCONVERTERMANAGER_CID);
 
 NS_DEFINE_NAMED_CID(NS_UTF7TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_MUTF7TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOUTF7_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOMUTF7_CID);
 
 const mozilla::Module::CIDEntry kMailNewsCIDs[] = {
@@ -1077,20 +1071,16 @@ const mozilla::Module::CIDEntry kMailNew
   { &kNS_CERT_PICKER_CID, false, nullptr, nsCertPickerConstructor },
   // Vcard Entries
   { &kNS_VCARD_CONTENT_TYPE_HANDLER_CID, false, NULL, nsVCardMimeContentTypeHandlerConstructor},
   // PGP/MIME Entries
   { &kNS_PGPMIME_CONTENT_TYPE_HANDLER_CID, false, NULL, nsPgpMimeMimeContentTypeHandlerConstructor },
   { &kNS_PGPMIMEPROXY_CID, false, NULL, nsPgpMimeProxyConstructor },
   // i18n Entries
   { &kNS_ICHARSETCONVERTERMANAGER_CID, false, nullptr, nsCharsetConverterManagerConstructor },
-  { &kNS_UTF7TOUNICODE_CID, false, nullptr, nsUTF7ToUnicodeConstructor },
-  { &kNS_MUTF7TOUNICODE_CID, false, nullptr, nsMUTF7ToUnicodeConstructor },
-  { &kNS_UNICODETOUTF7_CID, false, nullptr, nsUnicodeToUTF7Constructor },
-  { &kNS_UNICODETOMUTF7_CID, false, nullptr, nsUnicodeToMUTF7Constructor },
   // Tokenizer Entries
   { NULL }
 };
 
 const mozilla::Module::ContractIDEntry kMailNewsContracts[] = {
   // MailNews Base Entries
   { NS_MESSENGERBOOTSTRAP_CONTRACTID, &kNS_MESSENGERBOOTSTRAP_CID },
   { NS_MESSENGERWINDOWSERVICE_CONTRACTID, &kNS_MESSENGERWINDOWSERVICE_CID },
@@ -1325,20 +1315,16 @@ const mozilla::Module::ContractIDEntry k
   { NS_CERT_PICKER_CONTRACTID, &kNS_CERT_PICKER_CID },
   // Vcard Entries
   { "@mozilla.org/mimecth;1?type=text/x-vcard", &kNS_VCARD_CONTENT_TYPE_HANDLER_CID },
   // PGP/MIME Entries
   { "@mozilla.org/mimecth;1?type=multipart/encrypted", &kNS_PGPMIME_CONTENT_TYPE_HANDLER_CID },
   { NS_PGPMIMEPROXY_CONTRACTID, &kNS_PGPMIMEPROXY_CID },
   // i18n Entries
   { NS_CHARSETCONVERTERMANAGER_CONTRACTID, &kNS_ICHARSETCONVERTERMANAGER_CID },
-  { NS_UNICODEDECODER_CONTRACTID_BASE "UTF-7", &kNS_UTF7TOUNICODE_CID },
-  { NS_UNICODEDECODER_CONTRACTID_BASE "x-imap4-modified-utf7", &kNS_MUTF7TOUNICODE_CID },
-  { NS_UNICODEENCODER_CONTRACTID_BASE "UTF-7", &kNS_UNICODETOUTF7_CID },
-  { NS_UNICODEENCODER_CONTRACTID_BASE "x-imap4-modified-utf7", &kNS_UNICODETOMUTF7_CID },
   // Tokenizer Entries
   { NULL }
 };
 
 static const mozilla::Module::CategoryEntry kMailNewsCategories[] = {
   // MailNews Base Entries
   { XPCOM_DIRECTORY_PROVIDER_CATEGORY, "mail-directory-provider", NS_MAILDIRPROVIDER_CONTRACTID },
   { "content-policy", NS_MSGCONTENTPOLICY_CONTRACTID, NS_MSGCONTENTPOLICY_CONTRACTID },
@@ -1363,18 +1349,16 @@ static const mozilla::Module::CategoryEn
   { "mime-emitter", NS_RAW_MIME_EMITTER_CONTRACTID, NS_RAW_MIME_EMITTER_CONTRACTID },
   // News Entries
   { "command-line-handler", "m-news", NS_NEWSSTARTUPHANDLER_CONTRACTID },
   // Mail View Entries
   // mdn Entries
   // i18n Entries
   { NS_TITLE_BUNDLE_CATEGORY, "chrome://messenger/locale/charsetTitles.properties", "" },
   { NS_DATA_BUNDLE_CATEGORY, "resource://gre-resources/charsetData.properties", "" },
-  NS_UCONV_REG_UNREG("UTF-7", NS_UTF7TOUNICODE_CID, NS_UNICODETOUTF7_CID)
-  NS_UCONV_REG_UNREG("x-imap4-modified-utf7", NS_MUTF7TOUNICODE_CID, NS_UNICODETOMUTF7_CID)
   // Tokenizer Entries
   { NULL }
 };
 
 static void
 msgMailNewsModuleDtor()
 {
   nsAddrDatabase::CleanupCache();
--- a/mailnews/compose/src/nsMsgCompose.cpp
+++ b/mailnews/compose/src/nsMsgCompose.cpp
@@ -1327,17 +1327,17 @@ NS_IMETHODIMP nsMsgCompose::SendMsg(MSG_
   {
     m_compFields->GetBody(msgBody);
   }
   if (!msgBody.IsEmpty())
   {
     // Convert body to mail charset
     nsCString outCString;
     rv = nsMsgI18NConvertFromUnicode(m_compFields->GetCharacterSet(),
-      msgBody, outCString, false, true);
+      msgBody, outCString, true);
     bool isAsciiOnly = NS_IsAscii(outCString.get()) &&
       !nsMsgI18Nstateful_charset(m_compFields->GetCharacterSet());
     if (m_compFields->GetForceMsgEncoding())
       isAsciiOnly = false;
     if (NS_SUCCEEDED(rv) && !outCString.IsEmpty())
     {
       // If the body contains characters outside the repertoire of the current
       // charset, just convert to UTF-8 and be done with it
@@ -2291,18 +2291,16 @@ NS_IMETHODIMP nsMsgCompose::GetOriginalM
 }
 
 ////////////////////////////////////////////////////////////////////////////////////
 // THIS IS THE CLASS THAT IS THE STREAM CONSUMER OF THE HTML OUPUT
 // FROM LIBMIME. THIS IS FOR QUOTING
 ////////////////////////////////////////////////////////////////////////////////////
 QuotingOutputStreamListener::~QuotingOutputStreamListener()
 {
-  if (mUnicodeConversionBuffer)
-    free(mUnicodeConversionBuffer);
 }
 
 QuotingOutputStreamListener::QuotingOutputStreamListener(const char * originalMsgURI,
                                                          nsIMsgDBHdr *originalMsgHdr,
                                                          bool quoteHeaders,
                                                          bool headersOnly,
                                                          nsIMsgIdentity *identity,
                                                          nsIMsgQuote* msgQuote,
@@ -2311,17 +2309,16 @@ QuotingOutputStreamListener::QuotingOutp
                                                          const nsACString& htmlToQuote)
 {
   nsresult rv;
   mQuoteHeaders = quoteHeaders;
   mHeadersOnly = headersOnly;
   mIdentity = identity;
   mOrigMsgHdr = originalMsgHdr;
   mUnicodeBufferCharacterLength = 0;
-  mUnicodeConversionBuffer = nullptr;
   mQuoteOriginal = quoteOriginal;
   mHtmlToQuote = htmlToQuote;
   mQuote = msgQuote;
   mCharsetFixed = charsetFixed;
 
   if (!mHeadersOnly || !mHtmlToQuote.IsEmpty())
   {
     // Get header type, locale and strings from pref.
@@ -3047,102 +3044,22 @@ NS_IMETHODIMP QuotingOutputStreamListene
 
   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 (!inStr.IsEmpty()) {
+    nsAutoString tmp;
+    rv = UTF_8_ENCODING->DecodeWithoutBOMHandling(inStr, tmp);
     if (NS_SUCCEEDED(rv))
-    {
-      int32_t unicharLength;
-      int32_t inputLength = inStr.Length();
-      rv = mUnicodeDecoder->GetMaxLength(inStr.get(), inStr.Length(), &unicharLength);
-      if (NS_SUCCEEDED(rv))
-      {
-        // Use this local buffer if possible.
-        const int32_t kLocalBufSize = 4096;
-        char16_t localBuf[kLocalBufSize];
-        char16_t *unichars = localBuf;
-
-        if (unicharLength > kLocalBufSize)
-        {
-          // Otherwise, use the buffer of the class.
-          if (!mUnicodeConversionBuffer ||
-              unicharLength > mUnicodeBufferCharacterLength)
-          {
-            if (mUnicodeConversionBuffer)
-              free(mUnicodeConversionBuffer);
-            mUnicodeConversionBuffer = (char16_t *) moz_xmalloc(unicharLength * sizeof(char16_t));
-            if (!mUnicodeConversionBuffer)
-            {
-              mUnicodeBufferCharacterLength = 0;
-              return NS_ERROR_OUT_OF_MEMORY;
-            }
-            mUnicodeBufferCharacterLength = unicharLength;
-          }
-          unichars = mUnicodeConversionBuffer;
-        }
-
-        int32_t consumedInputLength = 0;
-        int32_t originalInputLength = inputLength;
-        const char *inputBuffer = inStr.get();
-        int32_t convertedOutputLength = 0;
-        int32_t outputBufferLength = unicharLength;
-        char16_t *originalOutputBuffer = unichars;
-        do
-        {
-          rv = mUnicodeDecoder->Convert(inputBuffer, &inputLength, unichars, &unicharLength);
-          if (NS_SUCCEEDED(rv))
-          {
-            convertedOutputLength += unicharLength;
-            break;
-          }
-
-          // if we failed, we consume one byte, replace it with a question mark
-          // and try the conversion again.
-          unichars += unicharLength;
-          *unichars = (char16_t)'?';
-          unichars++;
-          unicharLength++;
-
-          mUnicodeDecoder->Reset();
-
-          inputBuffer += ++inputLength;
-          consumedInputLength += inputLength;
-          inputLength = originalInputLength - consumedInputLength;  // update input length to convert
-          convertedOutputLength += unicharLength;
-          unicharLength = outputBufferLength - unicharLength;       // update output length
-
-        } while (NS_FAILED(rv) &&
-                 (originalInputLength > consumedInputLength) &&
-                 (outputBufferLength > convertedOutputLength));
-
-        if (convertedOutputLength > 0)
-          mMsgBody.Append(originalOutputBuffer, convertedOutputLength);
-      }
-    }
+      mMsgBody.Append(tmp);
   }
-
   return rv;
 }
 
 nsresult
 QuotingOutputStreamListener::SetComposeObj(nsIMsgCompose *obj)
 {
   mWeakComposeObj = do_GetWeakReference(obj);
   return NS_OK;
--- a/mailnews/compose/src/nsMsgCompose.h
+++ b/mailnews/compose/src/nsMsgCompose.h
@@ -13,17 +13,16 @@
 #include "nsMsgCompFields.h"
 #include "nsIOutputStream.h"
 #include "nsIMsgQuote.h"
 #include "nsIMsgCopyServiceListener.h"
 #include "nsIBaseWindow.h"
 #include "nsIAbDirectory.h"
 #include "nsIWebProgressListener.h"
 #include "nsIMimeConverter.h"
-#include "nsIUnicodeDecoder.h"
 #include "nsIMsgFolder.h"
 #include "nsIDOMNode.h"
 #include "mozIDOMWindow.h"
 
 // Forward declares
 class QuotingOutputStreamListener;
 class nsMsgComposeSendListener;
 class nsIEditorMailSupport;
@@ -186,19 +185,17 @@ private:
     bool                        mHeadersOnly;
     bool                        mCharsetFixed;
     nsCOMPtr<nsIMsgQuote>       mQuote;
     nsCOMPtr<nsIMimeHeaders>    mHeaders;
     nsCOMPtr<nsIMsgIdentity>    mIdentity;
     nsCOMPtr<nsIMsgDBHdr>       mOrigMsgHdr;
     nsString                    mCiteReference;
     nsCOMPtr<nsIMimeConverter>  mMimeConverter;
-    nsCOMPtr<nsIUnicodeDecoder> mUnicodeDecoder;
     int32_t                     mUnicodeBufferCharacterLength;
-    char16_t*                   mUnicodeConversionBuffer;
     bool                        mQuoteOriginal;
     nsCString                   mHtmlToQuote;
 };
 
 ////////////////////////////////////////////////////////////////////////////////////
 // This is the listener class for the send operation. We have to create this class 
 // to listen for message send completion and eventually notify the caller
 ////////////////////////////////////////////////////////////////////////////////////
--- a/mailnews/compose/src/nsMsgSend.cpp
+++ b/mailnews/compose/src/nsMsgSend.cpp
@@ -1596,17 +1596,17 @@ nsMsgComposeAndSend::GetBodyFromEditor()
   nsCString attachment1_body;
 
   // Convert body to mail charset
   nsCString    outCString;
   const char  *aCharset = mCompFields->GetCharacterSet();
 
   if (aCharset && *aCharset)
   {
-    rv = nsMsgI18NConvertFromUnicode(aCharset, nsDependentString(bodyText), outCString, false, true);
+    rv = nsMsgI18NConvertFromUnicode(aCharset, nsDependentString(bodyText), outCString, true);
     bool isAsciiOnly = NS_IsAscii(outCString.get()) &&
       !nsMsgI18Nstateful_charset(mCompFields->GetCharacterSet());
     if (mCompFields->GetForceMsgEncoding())
       isAsciiOnly = false;
     mCompFields->SetBodyIsAsciiOnly(isAsciiOnly);
 
     // If the body contains characters outside the current mail charset,
     // convert to UTF-8.
@@ -1639,17 +1639,17 @@ nsMsgComposeAndSend::GetBodyFromEditor()
 
     // If we have an origHTMLBody that is not null, this means that it is
     // different than the bodyText because of formatting conversions. Because of
     // this we need to do the charset conversion on this part separately
     if (origHTMLBody)
     {
       nsCString newBody;
       rv = nsMsgI18NConvertFromUnicode(aCharset,
-        nsDependentString(origHTMLBody), newBody, false, true);
+        nsDependentString(origHTMLBody), newBody, true);
       if (NS_SUCCEEDED(rv))
       {
         mOriginalHTMLBody = ToNewCString(newBody);
       }
     }
     else {
       mOriginalHTMLBody = ToNewCString(attachment1_body);
     }
--- a/mailnews/import/outlook/src/MapiMessage.cpp
+++ b/mailnews/import/outlook/src/MapiMessage.cpp
@@ -555,65 +555,51 @@ const char* CpToCharset(unsigned int cp)
     if (cp < mid_cp)
       end = mid - 1;
     else // cp > cptocharset[mid].cp
       begin = mid + 1;
   }
   return 0; // not found
 }
 
-// We don't use nsMsgI18Ncheck_data_in_charset_range because it returns true
-// even if there's no such charset:
-// 1. result initialized by true and returned if, eg, GetUnicodeEncoderRaw fail
-// 2. it uses GetUnicodeEncoderRaw(), not GetUnicodeEncoder() (to normalize the
-//    charset string) (see nsMsgI18N.cpp)
 // This function returns true only if the unicode (utf-16) text can be
 // losslessly represented in specified charset
 bool CMapiMessage::CheckBodyInCharsetRange(const char* charset)
 {
   if (m_body.IsEmpty())
     return true;
   if (!_stricmp(charset, "utf-8"))
     return true;
-  if (!_stricmp(charset, "utf-7"))
-    return true;
 
-  nsresult rv;
-  static nsCOMPtr<nsICharsetConverterManager> ccm =
-    do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, false);
-  nsCOMPtr<nsIUnicodeEncoder> encoder;
-
-  // get an unicode converter
-  rv = ccm->GetUnicodeEncoder(charset, getter_AddRefs(encoder));
-  NS_ENSURE_SUCCESS(rv, false);
-  rv = encoder->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Signal, nullptr, 0);
-  NS_ENSURE_SUCCESS(rv, false);
+  auto encoding = mozilla::Encoding::ForLabelNoReplacement(nsDependentCString(charset));
+  if (!encoding)
+    return false;
+  auto encoder = encoding->NewEncoder();
 
-  const char16_t *txt = m_body.get();
-  int32_t txtLen = m_body.Length();
-  const char16_t *currentSrcPtr = txt;
-  int srcLength;
-  int dstLength;
-  char localbuf[512];
-  int consumedLen = 0;
+  uint8_t buffer[512];
+  auto src = mozilla::MakeSpan(m_body);
+  auto dst = mozilla::MakeSpan(buffer);
+  while (true) {
+    uint32_t result;
+    size_t read;
+    size_t written;
+    mozilla::Tie(result, read, written) =
+      encoder->EncodeFromUTF16WithoutReplacement(src, dst, false);
+    if (result == mozilla::kInputEmpty) {
+      // All converted successfully.
+      break;
+    } else if (result != mozilla::kOutputFull) {
+      // Didn't use all the input but the outout isn't full, hence
+      // there was an unencodable character.
+      return false;
+    }
+    src = src.From(read);
+    // dst = dst.From(written); // Just overwrite output since we don't need it.
+  }
 
-  // convert
-  while (consumedLen < txtLen) {
-    srcLength = txtLen - consumedLen;
-    dstLength = sizeof(localbuf)/sizeof(localbuf[0]);
-    rv = encoder->Convert(currentSrcPtr, &srcLength, localbuf, &dstLength);
-    if (rv == NS_ERROR_UENC_NOMAPPING)
-      return false;
-    if (NS_FAILED(rv) || dstLength == 0)
-      break;
-
-    currentSrcPtr += srcLength;
-    consumedLen = currentSrcPtr - txt; // src length used so far
-  }
   return true;
 }
 
 bool CaseInsensitiveComp (wchar_t elem1, wchar_t elem2)
 {
   return _wcsnicmp(&elem1, &elem2, 1) == 0;
 }
 
--- a/mailnews/import/src/nsImportService.cpp
+++ b/mailnews/import/src/nsImportService.cpp
@@ -43,30 +43,25 @@ static const char *  kWhitespace = "\b\t
 ////////////////////////////////////////////////////////////////////////
 
 
 nsImportService::nsImportService() : m_pModules(nullptr)
 {
   IMPORT_LOG0("* nsImport Service Created\n");
 
   m_didDiscovery = false;
-  m_pDecoder = nullptr;
-  m_pEncoder = nullptr;
 
   nsresult rv = nsImportStringBundle::GetStringBundle(IMPORT_MSGS_URL, getter_AddRefs(m_stringBundle));
   if (NS_FAILED(rv))
     IMPORT_LOG0("Failed to get string bundle for Importing Mail");
 }
 
 
 nsImportService::~nsImportService()
 {
-  NS_IF_RELEASE(m_pDecoder);
-  NS_IF_RELEASE(m_pEncoder);
-
   gImportService = nullptr;
 
     if (m_pModules != nullptr)
         delete m_pModules;
 
   IMPORT_LOG0("* nsImport Service Deleted\n");
 }
 
--- a/mailnews/import/src/nsImportService.h
+++ b/mailnews/import/src/nsImportService.h
@@ -33,18 +33,16 @@ private:
   virtual ~nsImportService();
     nsresult LoadModuleInfo(const char*pClsId, const char *pSupports);
   nsresult DoDiscover(void);
 
 private:
     nsImportModuleList * m_pModules;
   bool m_didDiscovery;
   nsCString m_sysCharset;
-  nsIUnicodeDecoder * m_pDecoder;
-  nsIUnicodeEncoder * m_pEncoder;
   nsCOMPtr<nsIStringBundle> m_stringBundle;
 };
 
 class ImportModuleDesc {
 public:
   ImportModuleDesc() { m_pModule = nullptr;}
   ~ImportModuleDesc() { ReleaseModule();  }
 
--- a/mailnews/intl/nsCharsetConverterManager.cpp
+++ b/mailnews/intl/nsCharsetConverterManager.cpp
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsUnicharUtils.h"
 #include "nsCharsetAlias.h"
 #include "nsICategoryManager.h"
 #include "nsICharsetConverterManager.h"
-#include "nsEncoderDecoderUtils.h"
 #include "nsIStringBundle.h"
 #include "nsTArray.h"
 #include "nsStringEnumerator.h"
 #include "mozilla/Services.h"
 
 #include "nsComponentManagerUtils.h"
 #include "nsISupportsPrimitives.h"
 #include "nsServiceManagerUtils.h"
@@ -112,176 +111,19 @@ bool nsCharsetConverterManager::IsIntern
   // fully qualify to possibly avoid vtable call
   nsresult rv = GetCharsetDataImpl(PromiseFlatCString(aCharset).get(),
                                    u".isInternal",
                                    str);
 
   return NS_SUCCEEDED(rv);
 }
 
-
 //----------------------------------------------------------------------------//----------------------------------------------------------------------------
 // Interface nsICharsetConverterManager [implementation]
 
-NS_IMETHODIMP
-nsCharsetConverterManager::GetUnicodeEncoder(const char * aDest, 
-                                             nsIUnicodeEncoder ** aResult)
-{
-  // resolve the charset first
-  nsAutoCString charset;
-  
-  // fully qualify to possibly avoid vtable call
-  nsCharsetConverterManager::GetCharsetAlias(aDest, charset);
-
-  return nsCharsetConverterManager::GetUnicodeEncoderRaw(charset.get(),
-                                                         aResult);
-}
-
-
-NS_IMETHODIMP
-nsCharsetConverterManager::GetUnicodeEncoderRaw(const char * aDest, 
-                                                nsIUnicodeEncoder ** aResult)
-{
-  *aResult= nullptr;
-  nsCOMPtr<nsIUnicodeEncoder> encoder;
-
-  nsresult rv = NS_OK;
-
-  nsAutoCString
-    contractid(NS_LITERAL_CSTRING(NS_UNICODEENCODER_CONTRACTID_BASE) +
-               nsDependentCString(aDest));
-
-  // Always create an instance since encoders hold state.
-  encoder = do_CreateInstance(contractid.get(), &rv);
-
-  if (NS_FAILED(rv))
-    rv = NS_ERROR_UCONV_NOCONV;
-  else
-  {
-    *aResult = encoder.get();
-    NS_ADDREF(*aResult);
-  }
-  return rv;
-}
-
-NS_IMETHODIMP
-nsCharsetConverterManager::GetUnicodeDecoder(const char * aSrc, 
-                                             nsIUnicodeDecoder ** aResult)
-{
-  // resolve the charset first
-  nsAutoCString charset;
-
-  // fully qualify to possibly avoid vtable call
-  if (NS_FAILED(nsCharsetConverterManager::GetCharsetAlias(aSrc, charset)))
-    return NS_ERROR_UCONV_NOCONV;
-
-  return nsCharsetConverterManager::GetUnicodeDecoderRaw(charset.get(),
-                                                         aResult);
-}
-
-NS_IMETHODIMP
-nsCharsetConverterManager::GetUnicodeDecoderInternal(const char * aSrc, 
-                                                     nsIUnicodeDecoder ** aResult)
-{
-  // resolve the charset first
-  nsAutoCString charset;
-
-  nsresult rv = nsCharsetAlias::GetPreferredInternal(nsDependentCString(aSrc),
-                                                     charset);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return nsCharsetConverterManager::GetUnicodeDecoderRaw(charset.get(),
-                                                         aResult);
-}
-
-NS_IMETHODIMP
-nsCharsetConverterManager::GetUnicodeDecoderRaw(const char * aSrc, 
-                                                nsIUnicodeDecoder ** aResult)
-{
-  *aResult= nullptr;
-  nsCOMPtr<nsIUnicodeDecoder> decoder;
-
-  nsresult rv = NS_OK;
-
-  NS_NAMED_LITERAL_CSTRING(contractbase, NS_UNICODEDECODER_CONTRACTID_BASE);
-  nsDependentCString src(aSrc);
-
-  decoder = do_CreateInstance(PromiseFlatCString(contractbase + src).get(),
-                              &rv);
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_UCONV_NOCONV);
-
-  decoder.forget(aResult);
-  return rv;
-}
-
-static
-nsresult GetList(const nsACString& aCategory,
-                 const nsACString& aPrefix,
-                 nsIUTF8StringEnumerator** aResult)
-{
-  NS_ENSURE_ARG_POINTER(aResult);
-  *aResult = nullptr;
-
-  nsresult rv;
-
-  nsCOMPtr<nsICategoryManager> catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
-  if (NS_FAILED(rv))
-    return rv;
-
-  nsTArray<nsCString>* array = new nsTArray<nsCString>;
-  if (!array)
-    return NS_ERROR_OUT_OF_MEMORY;
-  
-  nsCOMPtr<nsISimpleEnumerator> enumerator;
-  catman->EnumerateCategory(PromiseFlatCString(aCategory).get(), 
-                            getter_AddRefs(enumerator));
-
-  bool hasMore;
-  while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) {
-    nsCOMPtr<nsISupports> supports;
-    if (NS_FAILED(enumerator->GetNext(getter_AddRefs(supports))))
-      continue;
-    
-    nsCOMPtr<nsISupportsCString> supStr = do_QueryInterface(supports);
-    if (!supStr)
-      continue;
-
-    nsAutoCString name;
-    if (NS_FAILED(supStr->GetData(name)))
-      continue;
-
-    nsAutoCString fullName(aPrefix);
-    fullName.Append(name);
-    NS_ENSURE_TRUE(array->AppendElement(fullName), NS_ERROR_OUT_OF_MEMORY);
-  }
-    
-  return NS_NewAdoptingUTF8StringEnumerator(aResult, array);
-}
-
-// we should change the interface so that we can just pass back a enumerator!
-NS_IMETHODIMP
-nsCharsetConverterManager::GetDecoderList(nsIUTF8StringEnumerator ** aResult)
-{
-  return GetList(NS_LITERAL_CSTRING(NS_UNICODEDECODER_NAME),
-                 EmptyCString(), aResult);
-}
-
-NS_IMETHODIMP
-nsCharsetConverterManager::GetEncoderList(nsIUTF8StringEnumerator ** aResult)
-{
-  return GetList(NS_LITERAL_CSTRING(NS_UNICODEENCODER_NAME),
-                 EmptyCString(), aResult);
-}
-
-NS_IMETHODIMP
-nsCharsetConverterManager::GetCharsetDetectorList(nsIUTF8StringEnumerator** aResult)
-{
-  return GetList(NS_LITERAL_CSTRING("charset-detectors"),
-                 NS_LITERAL_CSTRING("chardet."), aResult);
-}
 
 // XXX Improve the implementation of this method. Right now, it is build on 
 // top of the nsCharsetAlias service. We can make the nsCharsetAlias
 // better, with its own hash table (not the StringBundle anymore) and
 // a nicer file format.
 NS_IMETHODIMP
 nsCharsetConverterManager::GetCharsetAlias(const char * aCharset, 
                                            nsACString& aResult)
--- a/mailnews/intl/nsICharsetConverterManager.idl
+++ b/mailnews/intl/nsICharsetConverterManager.idl
@@ -2,82 +2,37 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 #include "nsIAtom.idl"
 
 %{ C++
-#include "nsIUnicodeDecoder.h"
-#include "nsIUnicodeEncoder.h"
+#include "mozilla/Encoding.h"
 
 // XXX change to NS_CHARSETCONVERTERMANAGER_CID
 #define NS_ICHARSETCONVERTERMANAGER_CID \
   {0x3c1c0163, 0x9bd0, 0x11d3, { 0x9d, 0x9, 0x0, 0x50, 0x4, 0x0, 0x7, 0xb2}}
 
 #define NS_CHARSETCONVERTERMANAGER_CONTRACTID "@mozilla.org/charset-converter-manager;1"
 %}
 
-interface nsIUnicodeDecoder;
-interface nsIUnicodeEncoder;
 interface nsIUTF8StringEnumerator;
 
-/**
- * DON'T ADD NEW USES OF THIS INTERFACE TO MOZILLA-CENTRAL. Use 
- * mozilla::dom::EncodingUtils instead.
- *
- * Here Charsets are identified by ASCII strings. Charset alias
- * resolution is provided by default in most methods. "Raw"
- * versions that do not need this resolution are also provided.
- *
- * @deprecated Use mozilla::dom::EncodingUtils in mozilla-central instead.
- * @created         21/Feb/2000
- * @author  Catalin Rotaru [CATA]
- */
 [scriptable, uuid(a0550d46-8d9c-47dd-acc7-c083620dff12)]
 interface nsICharsetConverterManager : nsISupports
 {
     /**
-     * Get the Unicode decoder for the given charset.
-     * The "Raw" version skips charset alias resolution
-     */
-    [noscript] nsIUnicodeDecoder getUnicodeDecoder(in string charset);
-    [noscript] nsIUnicodeDecoder getUnicodeDecoderRaw(in string charset);
-    [noscript] nsIUnicodeDecoder getUnicodeDecoderInternal(in string charset);
-
-    /**
-     * Get the Unicode encoder for the given charset.
-     * The "Raw" version skips charset alias resolution
-     */
-    [noscript] nsIUnicodeEncoder getUnicodeEncoder(in string charset);
-    [noscript] nsIUnicodeEncoder getUnicodeEncoderRaw(in string charset);
-
-    /**
      * A shortcut to calling nsICharsetAlias to do alias resolution
      * @throws if aCharset is an unknown charset.
      */
     ACString getCharsetAlias(in string aCharset);
     
     /**
-     * Get the complete list of available decoders.
-     */
-    nsIUTF8StringEnumerator getDecoderList();
-
-    /**
-     * Get the complete list of available encoders.
-     */
-    nsIUTF8StringEnumerator getEncoderList();
-
-    /**
-     * Get the complete list of available charset detectors.
-     */
-    nsIUTF8StringEnumerator GetCharsetDetectorList();
-
-    /**
      * Get the human-readable name for the given charset.
      * @throws if aCharset is an unknown charset.
      */
     AString getCharsetTitle(in string aCharset);
 
     /**
      * Get some data about the given charset. This includes whether the 
      * character encoding may be used for certain purposes, if it is 
--- a/mailnews/intl/nsUTF7ToUnicode.h
+++ b/mailnews/intl/nsUTF7ToUnicode.h
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsUTF7ToUnicode_h___
 #define nsUTF7ToUnicode_h___
 
-#include "nsUCSupport.h"
 
 //----------------------------------------------------------------------
 // Class nsBasicUTF7Decoder [declaration]
 
 /**
  * Basic class for a character set converter from UTF-7 to Unicode.
  *
  * @created         03/Jun/1999
--- a/mailnews/intl/nsUnicodeToUTF7.h
+++ b/mailnews/intl/nsUnicodeToUTF7.h
@@ -1,18 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsUnicodeToUTF7_h___
 #define nsUnicodeToUTF7_h___
 
-#include "nsUCSupport.h"
-
 //----------------------------------------------------------------------
 // Class nsBasicUTF7Encoder [declaration]
 
 /**
  * Basic class for a character set converter from Unicode to UTF-7.
  *
  * @created         03/Jun/1999
  * @author  Catalin Rotaru [CATA]
--- a/mailnews/mime/src/comi18n.cpp
+++ b/mailnews/mime/src/comi18n.cpp
@@ -57,52 +57,11 @@ MIME_detect_charset(const char *aBuf, in
       if (NS_SUCCEEDED(res) && (eBestAnswer == oConfident || eSureAnswer == oConfident)) {
         return NS_OK;
       }
     }
   }
   return res;
 }
 
-//Get unicode decoder(from inputcharset to unicode) for aInputCharset
-nsresult
-MIME_get_unicode_decoder(const char* aInputCharset, nsIUnicodeDecoder **aDecoder)
-{
-  nsresult res;
-
-  // get charset converters.
-  nsCOMPtr<nsICharsetConverterManager> ccm =
-           do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &res);
-  if (NS_SUCCEEDED(res)) {
-
-    // create a decoder (conv to unicode), ok if failed if we do auto detection
-    if (!*aInputCharset || !PL_strcasecmp("us-ascii", aInputCharset))
-      res = ccm->GetUnicodeDecoderRaw("ISO-8859-1", aDecoder);
-    else
-      // GetUnicodeDecoderInternal in order to support UTF-7 messages
-      //
-      // XXX this means that even HTML messages in UTF-7 will be decoded
-      res = ccm->GetUnicodeDecoderInternal(aInputCharset, aDecoder);
-  }
-
-  return res;
-}
-
-//Get unicode encoder(from unicode to inputcharset) for aOutputCharset
-nsresult
-MIME_get_unicode_encoder(const char* aOutputCharset, nsIUnicodeEncoder **aEncoder)
-{
-  nsresult res;
-
-  // get charset converters.
-  nsCOMPtr<nsICharsetConverterManager> ccm =
-           do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &res);
-  if (NS_SUCCEEDED(res) && *aOutputCharset) {
-      // create a encoder (conv from unicode)
-      res = ccm->GetUnicodeEncoder(aOutputCharset, aEncoder);
-  }
-
-  return res;
-}
-
 } /* end of extern "C" */
 // END PUBLIC INTERFACE
 
--- a/mailnews/mime/src/comi18n.h
+++ b/mailnews/mime/src/comi18n.h
@@ -1,20 +1,17 @@
 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef _COMI18N_LOADED_H_
 #define _COMI18N_LOADED_H_
 
 #include "msgCore.h"
-
-class nsIUnicodeDecoder;
-class nsIUnicodeEncoder;
-
+#include "mozilla/Encoding.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
 /**
  * Decode MIME header to UTF-8.
  * Uses MIME_ConvertCharset if the decoded string needs a conversion.
@@ -26,17 +23,15 @@ extern "C" {
  * @param eatContinuations    [IN] If true, unfold headers
  * @param result      [OUT] Decoded buffer
  */
 void MIME_DecodeMimeHeader(const char *header, const char *default_charset,
                            bool override_charset, bool eatContinuations,
                            nsACString &result);
 
 nsresult MIME_detect_charset(const char *aBuf, int32_t aLength, const char** aCharset);
-nsresult MIME_get_unicode_decoder(const char* aInputCharset, nsIUnicodeDecoder **aDecoder);
-nsresult MIME_get_unicode_encoder(const char* aOutputCharset, nsIUnicodeEncoder **aEncoder);
 
 #ifdef __cplusplus
 } /* extern "C" */
 #endif /* __cplusplus */
 
 #endif // _COMI18N_LOADED_H_
 
--- a/mailnews/mime/src/mimemoz2.cpp
+++ b/mailnews/mime/src/mimemoz2.cpp
@@ -803,145 +803,39 @@ mime_file_type (const char *filename, vo
       mimeFinder->GetTypeFromExtension(nsDependentCString(ext), type);
       retType = ToNewCString(type);
     }
   }
 
   return retType;
 }
 
-int ConvertUsingEncoderAndDecoder(const char *stringToUse, int32_t inLength,
-                                  nsIUnicodeEncoder *encoder, nsIUnicodeDecoder *decoder,
-                                  char **pConvertedString, int32_t *outLength)
+int ConvertToUTF8(const char *stringToUse, int32_t inLength,
+                  const char *input_charset,
+                  nsACString& outString)
 {
-  // buffer size 144 =
-  // 72 (default line len for compose)
-  // times 2 (converted byte len might be larger)
-  const int klocalbufsize = 144;
-  // do the conversion
-  char16_t *unichars;
-  int32_t unicharLength;
-  int32_t srcLen = inLength;
-  int32_t dstLength = 0;
-  char *dstPtr;
-  nsresult rv;
-
-  // use this local buffer if possible
-  char16_t localbuf[klocalbufsize+1];
-  if (inLength > klocalbufsize) {
-    rv = decoder->GetMaxLength(stringToUse, srcLen, &unicharLength);
-    // allocate temporary buffer to hold unicode string
-    unichars = new char16_t[unicharLength];
-  }
-  else {
-    unichars = localbuf;
-    unicharLength = klocalbufsize+1;
-  }
-  if (unichars == nullptr) {
-    rv = NS_ERROR_OUT_OF_MEMORY;
-  }
-  else {
-    // convert to unicode, replacing failed chars with 0xFFFD as in
-    // the methode used in nsXMLHttpRequest::ConvertBodyToText and nsScanner::Append
-    //
-    // We will need several pass to convert the whole string if it has invalid characters
-    // 'totalChars' is where the sum of the number of converted characters will be done
-    // 'dataLen' is the number of character left to convert
-    // 'outLen' is the number of characters still available in the output buffer as input of decoder->Convert
-    // and the number of characters written in it as output.
-    int32_t totalChars = 0,
-            inBufferIndex = 0,
-            outBufferIndex = 0;
-    int32_t dataLen = srcLen,
-            outLen = unicharLength;
+  nsresult rv = NS_OK;
 
-    do {
-      int32_t inBufferLength = dataLen;
-      rv = decoder->Convert(&stringToUse[inBufferIndex],
-                           &inBufferLength,
-                           &unichars[outBufferIndex],
-                           &outLen);
-      totalChars += outLen;
-      // Done if conversion successful
-      if (NS_SUCCEEDED(rv))
-          break;
-
-      // We consume one byte, replace it with U+FFFD
-      // and try the conversion again.
-      outBufferIndex += outLen;
-      unichars[outBufferIndex++] = char16_t(0xFFFD);
-      // totalChars is updated here
-      outLen = unicharLength - (++totalChars);
-
-      inBufferIndex += inBufferLength + 1;
-      dataLen -= inBufferLength + 1;
-
-      decoder->Reset();
-
-      // If there is not at least one byte available after the one we
-      // consumed, we're done
-    } while ( dataLen > 0 );
-
-    rv = encoder->GetMaxLength(unichars, totalChars, &dstLength);
-    // allocale an output buffer
-    dstPtr = (char *) PR_Malloc(dstLength + 1);
-    if (dstPtr == nullptr) {
-      rv = NS_ERROR_OUT_OF_MEMORY;
-    }
-    else {
-      int32_t buffLength = dstLength;
-      // convert from unicode
-      rv = encoder->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace, nullptr, '?');
-      if (NS_SUCCEEDED(rv)) {
-        rv = encoder->Convert(unichars, &totalChars, dstPtr, &dstLength);
-        if (NS_SUCCEEDED(rv)) {
-          int32_t finLen = buffLength - dstLength;
-          rv = encoder->Finish((char *)(dstPtr+dstLength), &finLen);
-          if (NS_SUCCEEDED(rv)) {
-            dstLength += finLen;
-          }
-          dstPtr[dstLength] = '\0';
-          *pConvertedString = dstPtr;       // set the result string
-          *outLength = dstLength;
-        }
-      }
-    }
-    if (inLength > klocalbufsize)
-      delete [] unichars;
+  auto encoding = mozilla::Encoding::ForLabel(nsDependentCString(input_charset));
+  if (!encoding) {
+    // Assume input is UTF-8.
+    encoding = UTF_8_ENCODING;
   }
 
+  rv = encoding->DecodeWithoutBOMHandling(nsDependentCString(stringToUse, inLength), outString);
   return NS_SUCCEEDED(rv) ? 0 : -1;
 }
 
-
 static int
 mime_convert_charset (const char *input_line, int32_t input_length,
-                      const char *input_charset, const char *output_charset,
-                      char **output_ret, int32_t *output_size_ret,
-                      void *stream_closure, nsIUnicodeDecoder *decoder, nsIUnicodeEncoder *encoder)
+                      const char *input_charset,
+                      nsACString& convertedString,
+                      void *stream_closure)
 {
-  int32_t res = -1;
-  char  *convertedString = NULL;
-  int32_t convertedStringLen = 0;
-  if (encoder && decoder)
-  {
-    res = ConvertUsingEncoderAndDecoder(input_line, input_length, encoder, decoder, &convertedString, &convertedStringLen);
-  }
-  if (res != 0)
-  {
-      *output_ret = 0;
-      *output_size_ret = 0;
-  }
-  else
-  {
-    *output_ret = (char *) convertedString;
-    *output_size_ret = convertedStringLen;
-  }
-
-  return 0;
+  return ConvertToUTF8(input_line, input_length, input_charset, convertedString);
 }
 
 static int
 mime_output_fn(const char *buf, int32_t size, void *stream_closure)
 {
   uint32_t  written = 0;
   mime_stream_data *msd = (mime_stream_data *) stream_closure;
   if ( (!msd->pluginObj2) && (!msd->output_emitter) )
--- a/mailnews/mime/src/mimetext.cpp
+++ b/mailnews/mime/src/mimetext.cpp
@@ -172,18 +172,16 @@ static int MimeInlineText_initializeChar
 static void
 MimeInlineText_finalize (MimeObject *obj)
 {
   MimeInlineText *text = (MimeInlineText *) obj;
 
   obj->clazz->parse_eof (obj, false);
   obj->clazz->parse_end (obj, false);
 
-  text->inputDecoder = nullptr;
-  text->utf8Encoder = nullptr;
   PR_FREEIF(text->charset);
 
   /* Should have been freed by parse_eof, but just in case... */
   PR_ASSERT(!text->cbuffer);
   PR_FREEIF (text->cbuffer);
 
   if (text->inputAutodetect) {
     PR_FREEIF(text->lineDamBuffer);
@@ -332,88 +330,55 @@ MimeInlineText_parse_decoded_buffer (con
    mime_GrowBuffer ((desired_size), sizeof(char), 100, \
            &(text)->cbuffer, &(text)->cbuffer_size) \
    : 0)
 
 static int 
 MimeInlineText_convert_and_parse_line(char *line, int32_t length, MimeObject *obj)
 {
   int status;
-  char *converted = 0;
-  int32_t converted_len = 0;
+  nsAutoCString converted;
   
   MimeInlineText *text = (MimeInlineText *) obj;
 
   //in case of charset autodetection, charset can be override by meta charset
   if (text->charsetOverridable) {
     if (mime_typep(obj, (MimeObjectClass *) &mimeInlineTextHTMLClass))
     {
       MimeInlineTextHTML  *textHTML = (MimeInlineTextHTML *) obj;
       if (textHTML->charset && 
           *textHTML->charset &&
           strcmp(textHTML->charset, text->charset))
       {
         //if meta tag specified charset is different from our detected result, use meta charset.
         //but we don't want to redo previous lines
-        MIME_get_unicode_decoder(textHTML->charset, getter_AddRefs(text->inputDecoder));
         PR_FREEIF(text->charset);
         text->charset = strdup(textHTML->charset);
 
         //update MsgWindow charset if we are instructed to do so
         if (text->needUpdateMsgWinCharset && *text->charset)
           SetMailCharacterSetToMsgWindow(obj, text->charset);
       }
     }
   }
 
-  //initiate decoder if not yet
-  if (text->inputDecoder == nullptr)
-    MIME_get_unicode_decoder(text->charset, getter_AddRefs(text->inputDecoder));
-  // If no decoder found, use ""UTF-8"", that will map most non-US-ASCII chars as invalid
-  // A pure-ASCII only decoder would be better, but there is none
-  if (text->inputDecoder == nullptr)
-    MIME_get_unicode_decoder("UTF-8", getter_AddRefs(text->inputDecoder));
-  if (text->utf8Encoder == nullptr)
-    MIME_get_unicode_encoder("UTF-8", getter_AddRefs(text->utf8Encoder));
-
-  bool useInputCharsetConverter = obj->options->m_inputCharsetToUnicodeDecoder && !PL_strcasecmp(text->charset, obj->options->charsetForCachedInputDecoder.get());
+  status = obj->options->charset_conversion_fn(line, length,
+                       text->charset,
+                       converted,
+                       obj->options->stream_closure);
 
-  if (useInputCharsetConverter)
-    status = obj->options->charset_conversion_fn(line, length,
-                         text->charset,
-                         "UTF-8",
-                         &converted,
-                         &converted_len,
-                         obj->options->stream_closure, obj->options->m_inputCharsetToUnicodeDecoder,
-                       obj->options->m_unicodeToUTF8Encoder);
-  else
-    status = obj->options->charset_conversion_fn(line, length,
-                         text->charset,
-                       "UTF-8",
-                         &converted,
-                         &converted_len,
-                         obj->options->stream_closure, (nsIUnicodeDecoder*)text->inputDecoder,
-                         (nsIUnicodeEncoder*)text->utf8Encoder);
-
-  if (status < 0)
+  if (status == 0)
   {
-    PR_FREEIF(converted);
-    return status;
-  }
-
-  if (converted)
-  {
-    line = converted;
-    length = converted_len;
+    line = (char *) converted.get();
+    length = converted.Length();
   }
 
   /* Now that the line has been converted, call the subclass's parse_line
    method with the decoded data. */
   status = obj->clazz->parse_line(line, length, obj);
-  PR_FREEIF(converted);
 
   return status;
 }
 
 //In this function call, all buffered lines in lineDam will be sent to charset detector 
 // and a charset will be used to parse all those line and following lines in this mime obj.
 static int 
 MimeInlineText_open_dam(char *line, int32_t length, MimeObject *obj)
--- a/mailnews/mime/src/mimetext.h
+++ b/mailnews/mime/src/mimetext.h
@@ -60,19 +60,16 @@ struct MimeInlineText {
   char *charset;      /* The charset from the content-type of this
                          object, or the caller-specified overrides
                          or defaults. */
   bool charsetOverridable;
   bool needUpdateMsgWinCharset;
   char *cbuffer;      /* Buffer used for charset conversion. */
   int32_t cbuffer_size;
 
-  nsCOMPtr<nsIUnicodeDecoder> inputDecoder;
-  nsCOMPtr<nsIUnicodeEncoder> utf8Encoder;
-
   bool    inputAutodetect;
   bool    initializeCharset;
   int32_t lastLineInDam;
   int32_t curDamOffset;
   char *lineDamBuffer;
   char **lineDamPtrs;
 };
 
--- a/mailnews/mime/src/modlmime.h
+++ b/mailnews/mime/src/modlmime.h
@@ -8,18 +8,17 @@
 
 #ifdef XP_UNIX
 #undef Bool
 #endif
 
 #include "nsString.h"
 #include "nsMailHeaders.h"
 #include "nsIMimeStreamConverter.h"
-#include "nsIUnicodeDecoder.h"
-#include "nsIUnicodeEncoder.h"
+#include "mozilla/Encoding.h"
 #include "nsIPrefBranch.h"
 #include "mozITXTToHTMLConv.h"
 #include "nsCOMPtr.h"
 #include "modmimee.h" // for MimeConverterOutputCallback
 
 #define MIME_DRAFTS
 
 /* Opaque object describing a block of message headers, and a couple of
@@ -132,19 +131,16 @@ typedef char *(*MimeHTMLGeneratorFunctio
 class MimeDisplayOptions
 {
 public:
   MimeDisplayOptions();
   virtual ~MimeDisplayOptions();
   mozITXTToHTMLConv   *conv;        // For text conversion...
   nsCOMPtr<nsIPrefBranch> m_prefBranch; /* prefBranch-service */
   nsMimeOutputType    format_out;   // The format out type
-  nsCString           charsetForCachedInputDecoder;
-  nsCOMPtr<nsIUnicodeDecoder>   m_inputCharsetToUnicodeDecoder;
-  nsCOMPtr<nsIUnicodeEncoder>   m_unicodeToUTF8Encoder;
 
   const char *url;      /* Base URL for the document.  This string should
                  be freed by the caller, after the parser
                  completes (possibly at the same time as the
                  MimeDisplayOptions itself.) */
 
   MimeHeadersState headers;  /* How headers should be displayed. */
   bool fancy_headers_p;  /* Whether to do clever formatting of headers
@@ -226,27 +222,26 @@ public:
    into HTML.  (This should return bytes which may appear in an HTML file,
    ie, we must be able to scan through the string to search for "<" and
    turn it in to "&lt;", and so on.)
 
    `input' is a non-NULL-terminated string of a single line from the message.
    `input_length' is how long it is.
    `input_charset' is a string representing the charset of this string (as
      specified by MIME headers.)
-   `output_charset' is the charset to which conversion is desired.
+   The conversion is always to UTF-8.
    `output_ret' is where a newly-malloced string is returned.  It may be
      NULL if no translation is needed.
    `output_size_ret' is how long the returned string is (it need not be
      NULL-terminated.).
    */
   int (*charset_conversion_fn) (const char *input_line,
                 int32_t input_length, const char *input_charset,
-                const char *output_charset,
-                char **output_ret, int32_t *output_size_ret,
-                void *stream_closure, nsIUnicodeDecoder *decoder, nsIUnicodeEncoder *encoder);
+                nsACString& output_ret,
+                void *stream_closure);
 
   /* If true, perform both charset-conversion and decoding of
    MIME-2 header fields (using RFC-1522 encoding.)
    */
   bool rfc1522_conversion_p;
 
   /* A hook for the caller to turn a file name into a content-type. */
   char *(*file_type_fn) (const char *filename, void *stream_closure);
--- a/mailnews/news/src/nsNNTPProtocol.cpp
+++ b/mailnews/news/src/nsNNTPProtocol.cpp
@@ -1552,17 +1552,17 @@ nsresult nsNNTPProtocol::SendListSearche
 
   if ('.' != line[0])
   {
         nsAutoCString charset;
         nsAutoString lineUtf16;
         if (NS_FAILED(m_nntpServer->GetCharset(charset)) ||
             NS_FAILED(nsMsgI18NConvertToUnicode(charset.get(),
                                                 nsDependentCString(line),
-                                                lineUtf16, true)))
+                                                lineUtf16)))
             CopyUTF8toUTF16(nsDependentCString(line), lineUtf16);
 
     m_nntpServer->AddSearchableGroup(lineUtf16);
   }
   else
   {
     /* all searchable groups received */
     /* LIST SRCHFIELDS is legal if the server supports the SEARCH extension, which */
@@ -2679,17 +2679,17 @@ nsresult nsNNTPProtocol::ProcessNewsgrou
   rv = m_nntpServer->QueryExtension("XACTIVE",&xactive);
   if (NS_SUCCEEDED(rv) && xactive)
   {
     nsAutoCString charset;
     nsAutoString lineUtf16;
     if (NS_SUCCEEDED(m_nntpServer->GetCharset(charset)) &&
         NS_SUCCEEDED(nsMsgI18NConvertToUnicode(charset.get(),
                                                nsDependentCString(line),
-                                               lineUtf16, true)))
+                                               lineUtf16)))
       m_nntpServer->SetGroupNeedsExtraInfo(NS_ConvertUTF16toUTF8(lineUtf16),
                                            true);
     else
       m_nntpServer->SetGroupNeedsExtraInfo(nsDependentCString(line), true);
   }
 
   PR_Free(lineToFree);
   return rv;