Bug 1639430 - Use ICAL.js to parse and encode vCard; remove old vCard components. r=mkmelin DONTBUILD
authorGeoff Lankow <geoff@darktrojan.net>
Fri, 15 May 2020 14:51:12 +1200
changeset 39195 299e88e21913bdcf79169bd0d84197ce32b1df07
parent 39194 450c5f1fed903d2a49004cf0eaa8c492fa8da362
child 39196 f577795ca28c305465e95ceb4e0eb04d9bb54568
push id402
push userclokep@gmail.com
push dateMon, 29 Jun 2020 20:48:04 +0000
reviewersmkmelin
bugs1639430
Bug 1639430 - Use ICAL.js to parse and encode vCard; remove old vCard components. r=mkmelin DONTBUILD
mailnews/addrbook/jsaddrbook/AddrBookCard.jsm
mailnews/addrbook/jsaddrbook/VCardUtils.jsm
mailnews/addrbook/jsaddrbook/components.conf
mailnews/addrbook/public/nsIMsgVCardService.idl
mailnews/addrbook/src/moz.build
mailnews/addrbook/src/nsAbCardProperty.cpp
mailnews/addrbook/src/nsAbContentHandler.cpp
mailnews/addrbook/src/nsMsgVCardService.cpp
mailnews/addrbook/src/nsMsgVCardService.h
mailnews/addrbook/src/nsVCard.cpp
mailnews/addrbook/src/nsVCard.h
mailnews/addrbook/src/nsVCardObj.cpp
mailnews/addrbook/src/nsVCardObj.h
mailnews/addrbook/test/unit/data/export.vcf
mailnews/addrbook/test/unit/test_bug387403.js
mailnews/addrbook/test/unit/test_export.js
mailnews/addrbook/test/unit/test_nsIAbCard.js
mailnews/build/nsMailModule.cpp
mailnews/mime/cthandlers/moz.build
mailnews/mime/cthandlers/vcard/mimevcrd.cpp
mailnews/mime/cthandlers/vcard/mimevcrd.h
mailnews/mime/cthandlers/vcard/moz.build
--- a/mailnews/addrbook/jsaddrbook/AddrBookCard.jsm
+++ b/mailnews/addrbook/jsaddrbook/AddrBookCard.jsm
@@ -222,16 +222,17 @@ AddrBookCard.prototype = {
     }
     return false;
   },
   translateTo(type) {
     // Get nsAbCardProperty to do the work, the code is in C++ anyway.
     let cardCopy = Cc["@mozilla.org/addressbook/cardproperty;1"].createInstance(
       Ci.nsIAbCard
     );
+    cardCopy.UID = this.UID;
     cardCopy.copy(this);
     return cardCopy.translateTo(type);
   },
   generatePhoneticName(lastNameFirst) {
     if (lastNameFirst) {
       return `${this.lastName}, ${this.firstName}`;
     }
     return `${this.firstName} ${this.lastName}`;
--- a/mailnews/addrbook/jsaddrbook/VCardUtils.jsm
+++ b/mailnews/addrbook/jsaddrbook/VCardUtils.jsm
@@ -1,13 +1,13 @@
 /* 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/. */
 
-const EXPORTED_SYMBOLS = ["VCardUtils"];
+const EXPORTED_SYMBOLS = ["VCardService", "VCardMimeConverter", "VCardUtils"];
 
 const { ICAL } = ChromeUtils.import("resource:///modules/calendar/Ical.jsm");
 
 /**
  * Utilities for working with vCard data. This file uses ICAL.js as parser and
  * formatter to avoid reinventing the wheel.
  * @see RFC 6350.
  */
@@ -131,16 +131,83 @@ var VCardUtils = {
       delete telProps[0][1].type;
     }
 
     vProps.push(["uid", {}, "text", abCard.UID]);
     return ICAL.stringify(["vcard", vProps]);
   },
 };
 
+function VCardService() {}
+VCardService.prototype = {
+  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgVCardService]),
+  classID: Components.ID("{e2e0f615-bc5a-4441-a16b-a26e75949376}"),
+
+  escapedVCardToAbCard(vCard) {
+    return VCardUtils.vCardToAbCard(decodeURIComponent(vCard));
+  },
+  abCardToEscapedVCard(abCard) {
+    return encodeURIComponent(VCardUtils.abCardToVCard(abCard));
+  },
+};
+
+function VCardMimeConverter() {}
+VCardMimeConverter.prototype = {
+  QueryInterface: ChromeUtils.generateQI([Ci.nsISimpleMimeConverter]),
+  classID: Components.ID("{dafab386-bd4c-4238-bb48-228fbc98ba29}"),
+
+  uri: null,
+  convertToHTML(contentType, data) {
+    function escapeHTML(template, ...parts) {
+      let arr = [];
+      for (let i = 0; i < parts.length; i++) {
+        arr.push(template[i]);
+        arr.push(
+          parts[i]
+            .replace(/&/g, "&amp;")
+            .replace(/"/g, "&quot;")
+            .replace(/</g, "&lt;")
+            .replace(/>/g, "&gt;")
+        );
+      }
+      arr.push(template[template.length - 1]);
+      return arr.join("");
+    }
+
+    let abCard = VCardUtils.vCardToAbCard(data);
+    let escapedVCard = encodeURIComponent(data);
+
+    let propertiesTable = `<table class="moz-vcard-properties-table">`;
+    propertiesTable += escapeHTML`<tr><td class="moz-vcard-title-property">${abCard.displayName}`;
+    if (abCard.primaryEmail) {
+      propertiesTable += escapeHTML`&nbsp;&lt;<a href="mailto:${abCard.primaryEmail}" private>${abCard.primaryEmail}</a>&gt;`;
+    }
+    propertiesTable += `</td></tr>`;
+    for (let propName of ["JobTitle", "Department", "Company"]) {
+      let propValue = abCard.getProperty(propName, "");
+      if (propValue) {
+        propertiesTable += escapeHTML`<tr><td class="moz-vcard-property">${propValue}</td></tr>`;
+      }
+    }
+    propertiesTable += `</table>`;
+
+    return `<html>
+      <body>
+        <table class="moz-vcard-table">
+          <tr>
+            <td valign="top"><a class="moz-vcard-badge" href="addbook:add?action=add?vcard=${escapedVCard}"></a></td>
+            <td>
+              ${propertiesTable}
+            </td>
+          </tr>
+        </table>
+      </body>
+    </html>`;
+  },
+};
 
 /** Helper functions for propertyMap. */
 
 function singleTextProperty(
   abPropName,
   vPropName,
   vPropParams = {},
   vPropType = "text"
--- a/mailnews/addrbook/jsaddrbook/components.conf
+++ b/mailnews/addrbook/jsaddrbook/components.conf
@@ -9,10 +9,21 @@ Classes = [
         'contract_ids': ['@mozilla.org/addressbook/jsaddrbookcard;1'],
         'jsm': 'resource:///modules/AddrBookCard.jsm',
         'constructor': 'AddrBookCard',
     }, {
         'cid': '{224d3ef9-d81c-4d94-8826-a79a5835af93}',
         'contract_ids': ['@mozilla.org/abmanager;1'],
         'jsm': 'resource:///modules/AddrBookManager.jsm',
         'constructor': 'AddrBookManager',
+    }, {
+        'cid': '{e2e0f615-bc5a-4441-a16b-a26e75949376}',
+        'contract_ids': ['@mozilla.org/addressbook/msgvcardservice;1'],
+        'jsm': 'resource:///modules/VCardUtils.jsm',
+        'constructor': 'VCardService',
+    }, {
+        'cid': '{dafab386-bd4c-4238-bb48-228fbc98ba29}',
+        'contract_ids': ['@mozilla.org/mimecth;1?type=text/x-vcard'],
+        'jsm': 'resource:///modules/VCardUtils.jsm',
+        'constructor': 'VCardMimeConverter',
+        'categories': {'simple-mime-converters': 'text/x-vcard'},
     },
 ]
--- a/mailnews/addrbook/public/nsIMsgVCardService.idl
+++ b/mailnews/addrbook/public/nsIMsgVCardService.idl
@@ -2,39 +2,27 @@
 /* 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"
 
 interface nsIAbCard;
 
-%{C++
-#include "nsVCardObj.h"
-%}
-
-[ptr] native VObject_ptr(VObject);
-[ptr] native VObjectIterator_ptr(VObjectIterator);
-[ptr] native const_char_ptr(const char);
-
-[scriptable, builtinclass, uuid(8b6ae917-676d-4f1f-bbad-2ecc9be0d9b1)]
+[scriptable, uuid(8b6ae917-676d-4f1f-bbad-2ecc9be0d9b1)]
 interface nsIMsgVCardService : nsISupports {
-  [noscript, notxpcom] void cleanVObject(in VObject_ptr o);
-  [noscript, notxpcom] VObject_ptr nextVObjectInList(in VObject_ptr o);
-  [noscript, notxpcom] VObject_ptr parse_MIME(in string input, in unsigned long len);
-  [noscript, notxpcom] charPtr fakeCString(in VObject_ptr o);
-  [noscript, notxpcom] VObject_ptr isAPropertyOf(in VObject_ptr o, in string id);
-  [noscript, notxpcom] charPtr writeMemoryVObjects(in string s, out long len, in VObject_ptr list, in boolean expandSpaces);
-  [noscript, notxpcom] VObject_ptr nextVObject(in VObjectIterator_ptr i);
-  [noscript, notxpcom] void initPropIterator(in VObjectIterator_ptr i, in VObject_ptr o);
-  [noscript, notxpcom] long moreIteration(in VObjectIterator_ptr i);
-  [noscript, notxpcom] const_char_ptr vObjectName(in VObject_ptr o);
-  [noscript, notxpcom] charPtr vObjectAnyValue(in VObject_ptr o);
 
   /**
-   * Translates an escaped vcard string into a nsIAbCard.
+   * Translates an URL-encoded vCard string into a nsIAbCard.
    *
-   * @param  escapedVCardStr  The string containing the vcard.
-   *
-   * @return A card containing the translated vcard data.
+   * @param escapedVCardStr - The string containing the vCard data.
+   * @return - A card containing the translated vCard data.
    */
   nsIAbCard escapedVCardToAbCard(in string escapedVCardStr);
+
+  /**
+   * Translates a nsIAbCard into an URL-encoded vCard.
+   *
+   * @param abCard - A card to be translated.
+   * @return - The string containing the vCard data.
+   */
+  ACString abCardToEscapedVCard(in nsIAbCard abCard);
 };
--- a/mailnews/addrbook/src/moz.build
+++ b/mailnews/addrbook/src/moz.build
@@ -1,17 +1,16 @@
 # vim: set filetype=python:
 # 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/.
 
 EXPORTS += [
     'nsAbDirProperty.h',
     'nsDirPrefs.h',
-    'nsVCardObj.h',
 ]
 
 SOURCES += [
     'nsAbAddressCollector.cpp',
     'nsAbBooleanExpression.cpp',
     'nsAbBoolExprToLDAPFilter.cpp',
     'nsAbCardProperty.cpp',
     'nsAbContentHandler.cpp',
@@ -24,19 +23,16 @@ SOURCES += [
     'nsAbLDAPReplicationData.cpp',
     'nsAbLDAPReplicationQuery.cpp',
     'nsAbLDAPReplicationService.cpp',
     'nsAbLDIFService.cpp',
     'nsAbQueryStringToExpression.cpp',
     'nsAddbookProtocolHandler.cpp',
     'nsAddbookUrl.cpp',
     'nsAddrDatabase.cpp',
-    'nsMsgVCardService.cpp',
-    'nsVCard.cpp',
-    'nsVCardObj.cpp',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT' and CONFIG['MOZ_MAPI_SUPPORT']:
     SOURCES += [
         'nsAbOutlookDirectory.cpp',
         'nsAbOutlookInterface.cpp',
         'nsAbWinHelper.cpp',
         'nsMapiAddressBook.cpp',
--- a/mailnews/addrbook/src/nsAbCardProperty.cpp
+++ b/mailnews/addrbook/src/nsAbCardProperty.cpp
@@ -10,23 +10,22 @@
 #include "plbase64.h"
 #include "nsIStringBundle.h"
 #include "plstr.h"
 #include "nsMsgUtils.h"
 #include "nsINetUtil.h"
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsMemory.h"
-#include "nsVCardObj.h"
 #include "nsIMutableArray.h"
 #include "nsArrayUtils.h"
 #include "mozITXTToHTMLConv.h"
 #include "nsIAbManager.h"
 #include "nsIUUIDGenerator.h"
-
+#include "nsIMsgVCardService.h"
 #include "nsVariant.h"
 #include "nsIProperty.h"
 #include "nsCOMArray.h"
 #include "nsArrayEnumerator.h"
 #include "prmem.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Services.h"
 using namespace mozilla;
@@ -502,215 +501,39 @@ NS_IMETHODIMP nsAbCardProperty::Equals(n
 
 ////////////////////////////////////////////////////////////////////////////////
 // The following methods are other views of a card
 ////////////////////////////////////////////////////////////////////////////////
 
 // XXX: Use the category manager instead of this file to implement these
 NS_IMETHODIMP nsAbCardProperty::TranslateTo(const nsACString &type,
                                             nsACString &result) {
-  if (type.EqualsLiteral("base64xml"))
+  if (type.EqualsLiteral("base64xml")) {
     return ConvertToBase64EncodedXML(result);
-  else if (type.EqualsLiteral("xml")) {
+  } else if (type.EqualsLiteral("xml")) {
     nsString utf16String;
     nsresult rv = ConvertToXMLPrintData(utf16String);
     NS_ENSURE_SUCCESS(rv, rv);
     result = NS_ConvertUTF16toUTF8(utf16String);
     return NS_OK;
-  } else if (type.EqualsLiteral("vcard"))
+  } else if (type.EqualsLiteral("vcard")) {
     return ConvertToEscapedVCard(result);
+  }
 
   return NS_ERROR_ILLEGAL_VALUE;
 }
-//
-static VObject *myAddPropValue(VObject *o, const char *propName,
-                               const char16_t *propValue, bool *aCardHasData) {
-  if (aCardHasData) *aCardHasData = true;
-  return addPropValue(o, propName, NS_ConvertUTF16toUTF8(propValue).get());
-}
 
 nsresult nsAbCardProperty::ConvertToEscapedVCard(nsACString &aResult) {
-  nsString str;
   nsresult rv;
-  bool vCardHasData = false;
-  VObject *vObj = newVObject(VCCardProp);
-  VObject *t;
-
-  // [comment from 4.x]
-  // Big flame coming....so Vobject is not designed at all to work with  an
-  // array of attribute values. It wants you to have all of the attributes
-  // easily available. You cannot add one attribute at a time as you find them
-  // to the vobject. Why? Because it creates a property for a particular type
-  // like phone number and then that property has multiple values. This
-  // implementation is not pretty. I can hear my algos prof yelling from
-  // here.....I have to do a linear search through my attributes array for EACH
-  // vcard property we want to set. *sigh* One day I will have time to come back
-  // to this function and remedy this O(m*n) function where n = # attribute
-  // values and m = # of vcard properties....
-
-  (void)GetDisplayName(str);
-  if (!str.IsEmpty()) {
-    // Full name is a field with the same name.
-    t = isAPropertyOf(vObj, VCFullNameProp);
-    if (!t) t = addProp(vObj, VCFullNameProp);
-    myAddPropValue(t, VCFullNameProp, str.get(), &vCardHasData);
-  }
-
-  (void)GetLastName(str);
-  if (!str.IsEmpty()) {
-    t = isAPropertyOf(vObj, VCNameProp);
-    if (!t) t = addProp(vObj, VCNameProp);
-    myAddPropValue(t, VCFamilyNameProp, str.get(), &vCardHasData);
-  }
-
-  (void)GetFirstName(str);
-  if (!str.IsEmpty()) {
-    t = isAPropertyOf(vObj, VCNameProp);
-    if (!t) t = addProp(vObj, VCNameProp);
-    myAddPropValue(t, VCGivenNameProp, str.get(), &vCardHasData);
-  }
-
-  rv = GetPropertyAsAString(kCompanyProperty, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    t = isAPropertyOf(vObj, VCOrgProp);
-    if (!t) t = addProp(vObj, VCOrgProp);
-    myAddPropValue(t, VCOrgNameProp, str.get(), &vCardHasData);
-  }
-
-  rv = GetPropertyAsAString(kDepartmentProperty, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    t = isAPropertyOf(vObj, VCOrgProp);
-    if (!t) t = addProp(vObj, VCOrgProp);
-    myAddPropValue(t, VCOrgUnitProp, str.get(), &vCardHasData);
-  }
-
-  rv = GetPropertyAsAString(kWorkAddress2Property, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    t = isAPropertyOf(vObj, VCAdrProp);
-    if (!t) t = addProp(vObj, VCAdrProp);
-    myAddPropValue(t, VCPostalBoxProp, str.get(), &vCardHasData);
-  }
-
-  rv = GetPropertyAsAString(kWorkAddressProperty, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    t = isAPropertyOf(vObj, VCAdrProp);
-    if (!t) t = addProp(vObj, VCAdrProp);
-    myAddPropValue(t, VCStreetAddressProp, str.get(), &vCardHasData);
-  }
-
-  rv = GetPropertyAsAString(kWorkCityProperty, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    t = isAPropertyOf(vObj, VCAdrProp);
-    if (!t) t = addProp(vObj, VCAdrProp);
-    myAddPropValue(t, VCCityProp, str.get(), &vCardHasData);
-  }
-
-  rv = GetPropertyAsAString(kWorkStateProperty, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    t = isAPropertyOf(vObj, VCAdrProp);
-    if (!t) t = addProp(vObj, VCAdrProp);
-    myAddPropValue(t, VCRegionProp, str.get(), &vCardHasData);
-  }
-
-  rv = GetPropertyAsAString(kWorkZipCodeProperty, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    t = isAPropertyOf(vObj, VCAdrProp);
-    if (!t) t = addProp(vObj, VCAdrProp);
-    myAddPropValue(t, VCPostalCodeProp, str.get(), &vCardHasData);
-  }
+  nsCOMPtr<nsIMsgVCardService> vCardService =
+      do_GetService(NS_MSGVCARDSERVICE_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = GetPropertyAsAString(kWorkCountryProperty, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    t = isAPropertyOf(vObj, VCAdrProp);
-    if (!t) t = addProp(vObj, VCAdrProp);
-    myAddPropValue(t, VCCountryNameProp, str.get(), &vCardHasData);
-  } else {
-    // only add this if VCAdrProp already exists
-    t = isAPropertyOf(vObj, VCAdrProp);
-    if (t) {
-      addProp(t, VCDomesticProp);
-    }
-  }
-
-  (void)GetPrimaryEmail(str);
-  if (!str.IsEmpty()) {
-    t = myAddPropValue(vObj, VCEmailAddressProp, str.get(), &vCardHasData);
-    addProp(t, VCInternetProp);
-  }
-
-  rv = GetPropertyAsAString(kJobTitleProperty, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    myAddPropValue(vObj, VCTitleProp, str.get(), &vCardHasData);
-  }
-
-  rv = GetPropertyAsAString(kWorkPhoneProperty, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    t = myAddPropValue(vObj, VCTelephoneProp, str.get(), &vCardHasData);
-    addProp(t, VCWorkProp);
-  }
-
-  rv = GetPropertyAsAString(kFaxProperty, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    t = myAddPropValue(vObj, VCTelephoneProp, str.get(), &vCardHasData);
-    addProp(t, VCFaxProp);
-  }
-
-  rv = GetPropertyAsAString(kPagerProperty, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    t = myAddPropValue(vObj, VCTelephoneProp, str.get(), &vCardHasData);
-    addProp(t, VCPagerProp);
-  }
-
-  rv = GetPropertyAsAString(kHomePhoneProperty, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    t = myAddPropValue(vObj, VCTelephoneProp, str.get(), &vCardHasData);
-    addProp(t, VCHomeProp);
-  }
-
-  rv = GetPropertyAsAString(kCellularProperty, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    t = myAddPropValue(vObj, VCTelephoneProp, str.get(), &vCardHasData);
-    addProp(t, VCCellularProp);
-  }
-
-  rv = GetPropertyAsAString(kNotesProperty, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    myAddPropValue(vObj, VCNoteProp, str.get(), &vCardHasData);
-  }
-
-  uint32_t format;
-  rv = GetPropertyAsUint32(kPreferMailFormatProperty, &format);
-  if (NS_SUCCEEDED(rv) && format == nsIAbPreferMailFormat::html) {
-    myAddPropValue(vObj, VCUseHTML, u"TRUE", &vCardHasData);
-  } else if (NS_SUCCEEDED(rv) && format == nsIAbPreferMailFormat::plaintext) {
-    myAddPropValue(vObj, VCUseHTML, u"FALSE", &vCardHasData);
-  }
-
-  rv = GetPropertyAsAString(kWorkWebPageProperty, str);
-  if (NS_SUCCEEDED(rv) && !str.IsEmpty()) {
-    myAddPropValue(vObj, VCURLProp, str.get(), &vCardHasData);
-  }
-
-  myAddPropValue(vObj, VCVersionProp, u"2.1", nullptr);
-
-  if (!vCardHasData) {
-    aResult.Truncate();
-    cleanVObject(vObj);
-    return NS_OK;
-  }
-
-  int len = 0;
-  char *vCard = writeMemVObject(0, &len, vObj);
-  if (vObj) cleanVObject(vObj);
-
-  nsCString escResult;
-  MsgEscapeString(nsDependentCString(vCard), nsINetUtil::ESCAPE_URL_PATH,
-                  escResult);
-  aResult = escResult;
-  return NS_OK;
+  nsCOMPtr<nsIAbCard> cardFromVCard;
+  return vCardService->AbCardToEscapedVCard(this, aResult);
 }
 
 nsresult nsAbCardProperty::ConvertToBase64EncodedXML(nsACString &result) {
   nsresult rv;
   nsString xmlStr;
 
   xmlStr.AppendLiteral(
       "<?xml version=\"1.0\"?>\n"
--- a/mailnews/addrbook/src/nsAbContentHandler.cpp
+++ b/mailnews/addrbook/src/nsAbContentHandler.cpp
@@ -14,19 +14,17 @@
 #include "plstr.h"
 #include "nsPIDOMWindow.h"
 #include "mozIDOMWindow.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsMsgUtils.h"
 #include "nsIMsgVCardService.h"
 #include "nsIAbCard.h"
-#include "nsVCard.h"
 #include "nsIChannel.h"
-#include "nsIMsgVCardService.h"
 //
 // nsAbContentHandler
 //
 nsAbContentHandler::nsAbContentHandler() {}
 
 nsAbContentHandler::~nsAbContentHandler() {}
 
 NS_IMPL_ISUPPORTS(nsAbContentHandler, nsIContentHandler,
@@ -142,44 +140,29 @@ nsAbContentHandler::OnStreamComplete(nsI
                                      uint32_t datalen, const uint8_t *data) {
   NS_ENSURE_ARG_POINTER(aContext);
   NS_ENSURE_SUCCESS(
       aStatus, aStatus);  // don't process the vcard if we got a status error
   nsresult rv = NS_OK;
 
   // take our vCard string and open up an address book window based on it
   nsCOMPtr<nsIMsgVCardService> vCardService =
-      do_GetService(NS_MSGVCARDSERVICE_CONTRACTID);
-  if (vCardService) {
-    mozilla::UniquePtr<VObject> vObj(
-        vCardService->Parse_MIME((const char *)data, datalen));
-    if (vObj) {
-      int32_t len = 0;
-      nsCString vCard;
-      vCard.Adopt(
-          vCardService->WriteMemoryVObjects(0, &len, vObj.get(), false));
+      do_GetService(NS_MSGVCARDSERVICE_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
 
-      nsCOMPtr<nsIMsgVCardService> vCardService =
-          do_GetService(NS_MSGVCARDSERVICE_CONTRACTID, &rv);
-      NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIAbCard> cardFromVCard;
+  rv = vCardService->EscapedVCardToAbCard((const char *)data,
+                                          getter_AddRefs(cardFromVCard));
+  NS_ENSURE_SUCCESS(rv, rv);
 
-      nsCOMPtr<nsIAbCard> cardFromVCard;
-      rv = vCardService->EscapedVCardToAbCard(vCard.get(),
-                                              getter_AddRefs(cardFromVCard));
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      nsCOMPtr<mozIDOMWindowProxy> domWindow = do_GetInterface(aContext);
-      NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
-      nsCOMPtr<nsPIDOMWindowOuter> parentWindow =
-          nsPIDOMWindowOuter::From(domWindow);
+  nsCOMPtr<mozIDOMWindowProxy> domWindow = do_GetInterface(aContext);
+  NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
+  nsCOMPtr<nsPIDOMWindowOuter> parentWindow =
+      nsPIDOMWindowOuter::From(domWindow);
 
-      RefPtr<mozilla::dom::BrowsingContext> dialogWindow;
-      rv = parentWindow->OpenDialog(
-          NS_LITERAL_STRING(
-              "chrome://messenger/content/addressbook/abNewCardDialog.xhtml"),
-          EmptyString(),
-          NS_LITERAL_STRING("chrome,resizable=no,titlebar,modal,centerscreen"),
-          cardFromVCard, getter_AddRefs(dialogWindow));
-    }
-  }
-
-  return rv;
+  RefPtr<mozilla::dom::BrowsingContext> dialogWindow;
+  return parentWindow->OpenDialog(
+      NS_LITERAL_STRING(
+          "chrome://messenger/content/addressbook/abNewCardDialog.xhtml"),
+      EmptyString(),
+      NS_LITERAL_STRING("chrome,resizable=no,titlebar,modal,centerscreen"),
+      cardFromVCard, getter_AddRefs(dialogWindow));
 }
deleted file mode 100644
--- a/mailnews/addrbook/src/nsMsgVCardService.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/* -*- 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/. */
-
-#include "nsIAbCard.h"
-#include "nsAbBaseCID.h"
-#include "nsString.h"
-#include "nsMsgUtils.h"
-#include "nsMsgVCardService.h"
-#include "nsVCard.h"
-#include "prmem.h"
-#include "plstr.h"
-
-NS_IMPL_ISUPPORTS(nsMsgVCardService, nsIMsgVCardService)
-
-nsMsgVCardService::nsMsgVCardService() {}
-
-nsMsgVCardService::~nsMsgVCardService() {}
-
-NS_IMETHODIMP_(void) nsMsgVCardService::CleanVObject(VObject *o) {
-  cleanVObject(o);
-}
-
-NS_IMETHODIMP_(VObject *) nsMsgVCardService::NextVObjectInList(VObject *o) {
-  return nextVObjectInList(o);
-}
-
-NS_IMETHODIMP_(VObject *)
-nsMsgVCardService::Parse_MIME(const char *input, uint32_t len) {
-  return parse_MIME(input, (unsigned long)len);
-}
-
-NS_IMETHODIMP_(char *) nsMsgVCardService::FakeCString(VObject *o) {
-  return fakeCString(vObjectUStringZValue(o));
-}
-
-NS_IMETHODIMP_(VObject *)
-nsMsgVCardService::IsAPropertyOf(VObject *o, const char *id) {
-  return isAPropertyOf(o, id);
-}
-
-NS_IMETHODIMP_(char *)
-nsMsgVCardService::WriteMemoryVObjects(const char *s, int32_t *len,
-                                       VObject *list, bool expandSpaces) {
-  return writeMemoryVObjects((char *)s, len, list, expandSpaces);
-}
-
-NS_IMETHODIMP_(VObject *) nsMsgVCardService::NextVObject(VObjectIterator *i) {
-  return nextVObject(i);
-}
-
-NS_IMETHODIMP_(void)
-nsMsgVCardService::InitPropIterator(VObjectIterator *i, VObject *o) {
-  initPropIterator(i, o);
-}
-
-NS_IMETHODIMP_(int32_t) nsMsgVCardService::MoreIteration(VObjectIterator *i) {
-  return ((int32_t)moreIteration(i));
-}
-
-NS_IMETHODIMP_(const char *) nsMsgVCardService::VObjectName(VObject *o) {
-  return vObjectName(o);
-}
-
-NS_IMETHODIMP_(char *) nsMsgVCardService::VObjectAnyValue(VObject *o) {
-  char *retval = (char *)PR_MALLOC(strlen((char *)vObjectAnyValue(o)) + 1);
-  if (retval) PL_strcpy(retval, (char *)vObjectAnyValue(o));
-  return retval;
-}
-
-char *getCString(VObject *vObj) {
-  if (VALUE_TYPE(vObj) == VCVT_USTRINGZ)
-    return fakeCString(vObjectUStringZValue(vObj));
-  if (VALUE_TYPE(vObj) == VCVT_STRINGZ)
-    return PL_strdup(vObjectStringZValue(vObj));
-  return NULL;
-}
-
-static void convertNameValue(VObject *vObj, nsIAbCard *aCard) {
-  const char *cardPropName = NULL;
-
-  // if the vCard property is not a root property then we need to determine its
-  // exact property. a good example of this is VCTelephoneProp, this prop has
-  // four objects underneath it: fax, work and home and cellular.
-  if (PL_strcasecmp(VCCityProp, vObjectName(vObj)) == 0)
-    cardPropName = kWorkCityProperty;
-  else if (PL_strcasecmp(VCTelephoneProp, vObjectName(vObj)) == 0) {
-    if (isAPropertyOf(vObj, VCFaxProp))
-      cardPropName = kFaxProperty;
-    else if (isAPropertyOf(vObj, VCWorkProp))
-      cardPropName = kWorkPhoneProperty;
-    else if (isAPropertyOf(vObj, VCHomeProp))
-      cardPropName = kHomePhoneProperty;
-    else if (isAPropertyOf(vObj, VCCellularProp))
-      cardPropName = kCellularProperty;
-    else if (isAPropertyOf(vObj, VCPagerProp))
-      cardPropName = kPagerProperty;
-    else
-      return;
-  } else if (PL_strcasecmp(VCEmailAddressProp, vObjectName(vObj)) == 0)
-    cardPropName = kPriEmailProperty;
-  else if (PL_strcasecmp(VCFamilyNameProp, vObjectName(vObj)) == 0)
-    cardPropName = kLastNameProperty;
-  else if (PL_strcasecmp(VCFullNameProp, vObjectName(vObj)) == 0)
-    cardPropName = kDisplayNameProperty;
-  else if (PL_strcasecmp(VCGivenNameProp, vObjectName(vObj)) == 0)
-    cardPropName = kFirstNameProperty;
-  else if (PL_strcasecmp(VCOrgNameProp, vObjectName(vObj)) == 0)
-    cardPropName = kCompanyProperty;
-  else if (PL_strcasecmp(VCOrgUnitProp, vObjectName(vObj)) == 0)
-    cardPropName = kDepartmentProperty;
-  else if (PL_strcasecmp(VCPostalCodeProp, vObjectName(vObj)) == 0)
-    cardPropName = kWorkZipCodeProperty;
-  else if (PL_strcasecmp(VCRegionProp, vObjectName(vObj)) == 0)
-    cardPropName = kWorkStateProperty;
-  else if (PL_strcasecmp(VCStreetAddressProp, vObjectName(vObj)) == 0)
-    cardPropName = kWorkAddressProperty;
-  else if (PL_strcasecmp(VCPostalBoxProp, vObjectName(vObj)) == 0)
-    cardPropName = kWorkAddress2Property;
-  else if (PL_strcasecmp(VCCountryNameProp, vObjectName(vObj)) == 0)
-    cardPropName = kWorkCountryProperty;
-  else if (PL_strcasecmp(VCTitleProp, vObjectName(vObj)) == 0)
-    cardPropName = kJobTitleProperty;
-  else if (PL_strcasecmp(VCUseHTML, vObjectName(vObj)) == 0)
-    cardPropName = kPreferMailFormatProperty;
-  else if (PL_strcasecmp(VCNoteProp, vObjectName(vObj)) == 0)
-    cardPropName = kNotesProperty;
-  else if (PL_strcasecmp(VCURLProp, vObjectName(vObj)) == 0)
-    cardPropName = kWorkWebPageProperty;
-  else
-    return;
-
-  if (!VALUE_TYPE(vObj)) return;
-
-  char *cardPropValue = getCString(vObj);
-  if (PL_strcmp(cardPropName, kPreferMailFormatProperty)) {
-    aCard->SetPropertyAsAUTF8String(cardPropName,
-                                    nsDependentCString(cardPropValue));
-  } else {
-    if (!PL_strcmp(cardPropValue, "TRUE"))
-      aCard->SetPropertyAsUint32(cardPropName, nsIAbPreferMailFormat::html);
-    else if (!PL_strcmp(cardPropValue, "FALSE"))
-      aCard->SetPropertyAsUint32(cardPropName,
-                                 nsIAbPreferMailFormat::plaintext);
-    else
-      aCard->SetPropertyAsUint32(cardPropName, nsIAbPreferMailFormat::unknown);
-  }
-  PR_FREEIF(cardPropValue);
-  return;
-}
-
-static void convertFromVObject(VObject *vObj, nsIAbCard *aCard) {
-  if (vObj) {
-    VObjectIterator t;
-
-    convertNameValue(vObj, aCard);
-
-    initPropIterator(&t, vObj);
-    while (moreIteration(&t)) {
-      VObject *nextObject = nextVObject(&t);
-      convertFromVObject(nextObject, aCard);
-    }
-  }
-  return;
-}
-
-NS_IMETHODIMP nsMsgVCardService::EscapedVCardToAbCard(
-    const char *aEscapedVCardStr, nsIAbCard **aCard) {
-  NS_ENSURE_ARG_POINTER(aEscapedVCardStr);
-  NS_ENSURE_ARG_POINTER(aCard);
-
-  nsCOMPtr<nsIAbCard> cardFromVCard =
-      do_CreateInstance(NS_ABCARDPROPERTY_CONTRACTID);
-  if (!cardFromVCard) return NS_ERROR_FAILURE;
-
-  // aEscapedVCardStr will be "" the first time, before you have a vCard
-  if (*aEscapedVCardStr != '\0') {
-    nsCString unescapedData;
-    MsgUnescapeString(nsDependentCString(aEscapedVCardStr), 0, unescapedData);
-
-    VObject *vObj = parse_MIME(unescapedData.get(), unescapedData.Length());
-    if (vObj) {
-      convertFromVObject(vObj, cardFromVCard);
-
-      cleanVObject(vObj);
-    } else
-      NS_WARNING("Parse of vCard failed");
-  }
-
-  cardFromVCard.forget(aCard);
-  return NS_OK;
-}
deleted file mode 100644
--- a/mailnews/addrbook/src/nsMsgVCardService.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* 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 nsMsgVCardService_h___
-#define nsMsgVCardService_h___
-
-#include "nsIMsgVCardService.h"
-#include "nsISupports.h"
-
-class nsMsgVCardService : public nsIMsgVCardService {
- public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIMSGVCARDSERVICE
-
-  nsMsgVCardService();
-
- private:
-  virtual ~nsMsgVCardService();
-};
-
-#endif /* nsMsgVCardService_h___ */
deleted file mode 100644
--- a/mailnews/addrbook/src/nsVCard.cpp
+++ /dev/null
@@ -1,1483 +0,0 @@
-/* -*- 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/. */
-
-/***************************************************************************
-(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
-Business Machines Corporation and Siemens Rolm Communications Inc.
-
-For purposes of this license notice, the term Licensors shall mean,
-collectively, Apple Computer, Inc., AT&T Corp., International
-Business Machines Corporation and Siemens Rolm Communications Inc.
-The term Licensor shall mean any of the Licensors.
-
-Subject to acceptance of the following conditions, permission is hereby
-granted by Licensors without the need for written agreement and without
-license or royalty fees, to use, copy, modify and distribute this
-software for any purpose.
-
-The above copyright notice and the following four paragraphs must be
-reproduced in all copies of this software and any software including
-this software.
-
-THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
-ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
-MODIFICATIONS.
-
-IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
-INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
-OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGE.
-
-EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.
-
-The software is provided with RESTRICTED RIGHTS.  Use, duplication, or
-disclosure by the government are subject to restrictions set forth in
-DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
-
-***************************************************************************/
-
-/*
- * src: vcc.c
- * doc: Parser for vCard and vCalendar. Note that this code is
- * generated by a yacc parser generator. Generally it should not
- * be edited by hand. The real source is vcc.y. The #line directives
- * can be commented out here to make it easier to trace through
- * in a debugger. However, if a bug is found it should
- *
- * the vcc.y that _this_ vcc.c comes from is lost.
- * I couldn't find it in the 4.x tree
- * I bet we took it from IMC's original SDK, but the SDK has been taken down.
- * see http://www.imc.org/imc-vcard/mail-archive/msg00460.html
- *
- * for what it's worth, see
- * http://softwarestudio.org/libical/
- * http://lxr.mozilla.org/mozilla/source/other-licenses/libical/src/libicalvcal/vcc.y
- * http://lxr.mozilla.org/mozilla/source/other-licenses/libical/src/libicalvcal/vcc.c
- */
-#include "nsVCard.h"
-#include "nsVCardObj.h"
-#include "prprf.h"
-#include "nscore.h"
-#include <string.h>
-#include <ctype.h>
-
-#ifndef lint
-char yysccsid[] = "@(#)yaccpar  1.4 (Berkeley) 02/25/90";
-#endif
-/*#line 2 "vcc.y" */
-
-/* debugging utilities */
-#define DBG_(x)
-
-#ifndef _NO_LINE_FOLDING
-#  define _SUPPORT_LINE_FOLDING
-#endif
-
-/****  External Functions  ****/
-
-/* assign local name to parser variables and functions so that
- * we can use more than one yacc based parser.
- */
-
-#define yyparse mime_parse
-#define yylex mime_lex
-#define yyerror mime_error
-#define yychar mime_char
-/* #define p_yyval p_mime_val */
-#undef yyval
-#define yyval mime_yyval
-/* #define p_yylval p_mime_lval */
-#undef yylval
-#define yylval mime_yylval
-#define yydebug mime_debug
-#define yynerrs mime_nerrs
-#define yyerrflag mime_errflag
-#define yyss mime_ss
-#define yyssp mime_ssp
-#define yyvs mime_vs
-#define yyvsp mime_vsp
-#define yylhs mime_lhs
-#define yylen mime_len
-#define yydefred mime_defred
-#define yydgoto mime_dgoto
-#define yysindex mime_sindex
-#define yyrindex mime_rindex
-#define yygindex mime_gindex
-#define yytable mime_table
-#define yycheck mime_check
-#define yyname mime_name
-#define yyrule mime_rule
-#define YYPREFIX "mime_"
-
-#include "prmem.h"
-#include "plstr.h"
-
-#ifndef FALSE
-#  define FALSE 0
-#endif
-#ifndef TRUE
-#  define TRUE 1
-#endif
-
-/****  Types, Constants  ****/
-
-#define YYDEBUG 0       /* 1 to compile in some debugging code */
-#define PR_MAXTOKEN 256 /* maximum token (line) length */
-#define YYSTACKSIZE 50  /* ~unref ?*/
-#define PR_MAXLEVEL 10  /* max # of nested objects parseable */
-                        /* (includes outermost) */
-
-/****  Global Variables  ****/
-int mime_lineNum, mime_numErrors; /* yyerror() can use these */
-static VObject *vObjList;
-static VObject *curProp;
-static VObject *curObj;
-static VObject *ObjStack[PR_MAXLEVEL];
-static int ObjStackTop;
-
-/* A helpful utility for the rest of the app. */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern void yyerror(const char *s);
-extern char **fieldedProp;
-
-#ifdef __cplusplus
-}
-#endif
-
-int yyparse();
-
-enum LexMode {
-  L_NORMAL,
-  L_VCARD,
-  L_VCAL,
-  L_VEVENT,
-  L_VTODO,
-  L_VALUES,
-  L_BASE64,
-  L_QUOTED_PRINTABLE
-};
-
-/****  Private Forward Declarations  ****/
-static int pushVObject(const char *prop);
-static VObject *popVObject();
-static int lexGeta();
-static int lexGetc_();
-static int lexGetc();
-static void lexSkipLookahead();
-static int lexLookahead();
-static void lexSkipWhite();
-static void lexClearToken();
-static char *lexStr();
-static char *lexGetDataFromBase64();
-static char *lexGetQuotedPrintable();
-static char *lexGet1Value();
-static char *lexGetWord();
-static void finiLex();
-
-static VObject *parse_MIMEHelper();
-
-/*static char* lexDataFromBase64();*/
-static void lexPopMode(int top);
-static int lexWithinMode(enum LexMode mode);
-static void lexPushMode(enum LexMode mode);
-static void enterProps(const char *s);
-static void enterAttr(const char *s1, const char *s2);
-static void enterValues(const char *value);
-
-/*#line 250 "vcc.y" */
-typedef union {
-  char *str;
-  VObject *vobj;
-} YYSTYPE;
-/*#line 253 "y_tab.c"*/
-#define EQ 257
-#define COLON 258
-#define DOT 259
-#define SEMICOLON 260
-#define SPACE 261
-#define HTAB 262
-#define LINESEP 263
-#define NEWLINE 264
-#define BEGIN_VCARD 265
-#define END_VCARD 266
-#define BEGIN_VCAL 267
-#define END_VCAL 268
-#define BEGIN_VEVENT 269
-#define END_VEVENT 270
-#define BEGIN_VTODO 271
-#define END_VTODO 272
-#define ID 273
-#define STRING 274
-#define YYERRCODE 256
-
-// clang-format off
-short yylhs[] = {                                        -1,
-    0,    7,    6,    6,    5,    5,    9,    3,   10,    3,
-    8,    8,   14,   11,   11,   16,   12,   12,   15,   15,
-   17,   18,   18,    1,   19,   13,   13,    2,    2,   21,
-    4,   22,    4,   20,   20,   23,   23,   23,   26,   24,
-   27,   24,   28,   25,   29,   25,
-};
-short yylen[] = {                                         2,
-    1,    0,    3,    1,    1,    1,    0,    4,    0,    3,
-    2,    1,    0,    5,    1,    0,    3,    1,    2,    1,
-    2,    1,    3,    1,    0,    4,    1,    1,    0,    0,
-    4,    0,    3,    2,    1,    1,    1,    1,    0,    4,
-    0,    3,    0,    4,    0,    3,
-};
-short yydefred[] = {                                      0,
-    0,    0,    0,    5,    6,    0,    1,    0,    0,    0,
-    0,    0,   15,   24,    0,    0,    0,    0,   10,    0,
-    0,   38,    0,    0,   36,   37,   33,    3,    0,    8,
-   11,   13,    0,    0,    0,    0,   31,   34,    0,   17,
-    0,    0,    0,   42,    0,   46,    0,   21,   19,   28,
-    0,    0,   40,   44,    0,   25,   14,   23,    0,   26,
-};
-short yydgoto[] = {                                       3,
-   15,   51,    4,    5,    6,    7,   12,   22,    8,    9,
-   17,   18,   52,   42,   40,   29,   41,   48,   59,   23,
-   10,   11,   24,   25,   26,   33,   34,   35,   36,
-};
-short yysindex[] = {                                   -227,
-    0,    0,    0,    0,    0,    0,    0, -249, -262, -253,
- -258, -227,    0,    0,    0, -234, -249, -215,    0,    0,
-    0,    0, -223, -253,    0,    0,    0,    0, -247,    0,
-    0,    0, -249, -222, -249, -225,    0,    0, -224,    0,
- -247, -221, -220,    0, -218,    0, -206,    0,    0,    0,
- -208, -207,    0,    0, -224,    0,    0,    0, -221,    0,
-};
-short yyrindex[] = {                                      0,
- -245, -254,    0,    0,    0,    1,    0,    0,    0,    0,
-    0,    0,    0,    0, -219,    0, -235,    0,    0, -244,
- -250,    0,    0, -213,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
- -201, -255,    0,    0,    0,    0, -216,    0,    0,    0,
- -205,    0,    0,    0,    0,    0,    0,    0, -255,    0,
-};
-short yygindex[] = {                                      0,
-   -9,    0,    0,    0,    0,   47,    0,   -8,    0,    0,
-    0,    0,    2,    0,   19,    0,    0,    0,    0,   38,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,
-};
-#define YYTABLESIZE 268
-short yytable[] = {                                      16,
-    4,   30,   13,   19,   29,   43,   13,   29,   31,   27,
-    7,   39,   39,   32,   30,   20,   30,   21,   30,   14,
-    9,   45,   43,   14,   43,   41,   45,    7,   39,   47,
-   12,   30,   12,   12,   12,   12,   12,    1,   18,    2,
-   16,   22,   32,   22,   37,   58,   46,   44,   14,   53,
-   55,   56,   50,   54,   35,   57,   20,   27,   28,   49,
-   60,   38,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    2,    0,    2,
-};
-short yycheck[] = {                                       8,
-    0,  256,  256,  266,  260,  256,  256,  263,   17,  268,
-  256,  256,  260,  268,  269,  269,  271,  271,  273,  273,
-  266,  272,  273,  273,   33,  270,   35,  273,  273,   39,
-  266,  266,  268,  269,  270,  271,  272,  265,  258,  267,
-  260,  258,  258,  260,  268,   55,  272,  270,  273,  270,
-  257,  260,  274,  272,  268,  263,  258,  263,   12,   41,
-   59,   24,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,  265,   -1,  267,
-};
-#define YYFINAL 3
-#ifndef YYDEBUG
-#define YYDEBUG 0
-#endif
-#define YYPR_MAXTOKEN 274
-#if YYDEBUG
-char *yyname[] = {
-"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"EQ","COLON","DOT","SEMICOLON",
-"SPACE","HTAB","LINESEP","NEWLINE","BEGIN_VCARD","END_VCARD","BEGIN_VCAL",
-"END_VCAL","BEGIN_VEVENT","END_VEVENT","BEGIN_VTODO","END_VTODO","ID","STRING",
-};
-char *yyrule[] = {
-  "$accept : mime",
-  "mime : vobjects",
-  "$$1 :",
-  "vobjects : vobject $$1 vobjects",
-  "vobjects : vobject",
-  "vobject : vcard",
-  "vobject : vcal",
-  "$$2 :",
-  "vcard : BEGIN_VCARD $$2 items END_VCARD",
-  "$$3 :",
-  "vcard : BEGIN_VCARD $$3 END_VCARD",
-  "items : item items",
-  "items : item",
-  "$$4 :",
-  "item : prop COLON $$4 values LINESEP",
-  "item : error",
-  "$$5 :",
-  "prop : name $$5 attr_params",
-  "prop : name",
-  "attr_params : attr_param attr_params",
-  "attr_params : attr_param",
-  "attr_param : SEMICOLON attr",
-  "attr : name",
-  "attr : name EQ name",
-  "name : ID",
-  "$$6 :",
-  "values : value SEMICOLON $$6 values",
-  "values : value",
-  "value : STRING",
-  "value :",
-  "$$7 :",
-  "vcal : BEGIN_VCAL $$7 calitems END_VCAL",
-  "$$8 :",
-  "vcal : BEGIN_VCAL $$8 END_VCAL",
-  "calitems : calitem calitems",
-  "calitems : calitem",
-  "calitem : eventitem",
-  "calitem : todoitem",
-  "calitem : items",
-  "$$9 :",
-  "eventitem : BEGIN_VEVENT $$9 items END_VEVENT",
-  "$$10 :",
-  "eventitem : BEGIN_VEVENT $$10 END_VEVENT",
-  "$$11 :",
-  "todoitem : BEGIN_VTODO $$11 items END_VTODO",
-  "$$12 :",
-  "todoitem : BEGIN_VTODO $$12 END_VTODO",
-};
-#endif
-// clang-format on
-
-#define yyclearin (yychar = (-1))
-#define yyerrok (yyerrflag = 0)
-#ifndef YYSTACKSIZE
-#  ifdef YYPR_MAXDEPTH
-#    define YYSTACKSIZE YYPR_MAXDEPTH
-#  else
-#    define YYSTACKSIZE 300
-#  endif
-#endif
-int yydebug;
-int yynerrs;
-int yyerrflag;
-int yychar;
-short *yyssp;
-YYSTYPE *yyvsp;
-YYSTYPE yyval;
-YYSTYPE yylval;
-#define yystacksize YYSTACKSIZE
-short yyss[YYSTACKSIZE];
-YYSTYPE yyvs[YYSTACKSIZE];
-/*#line 444 "vcc.y"*/
-/******************************************************************************/
-static int pushVObject(const char *prop) {
-  VObject *newObj;
-  if (ObjStackTop == PR_MAXLEVEL) return FALSE;
-
-  ObjStack[++ObjStackTop] = curObj;
-
-  if (curObj) {
-    newObj = addProp(curObj, prop);
-    curObj = newObj;
-  } else
-    curObj = newVObject(prop);
-
-  return TRUE;
-}
-
-/******************************************************************************/
-/* This pops the recently built vCard off the stack and returns it. */
-static VObject *popVObject() {
-  VObject *oldObj;
-  if (ObjStackTop < 0) {
-    yyerror("pop on empty Object Stack\n");
-    return 0;
-  }
-  oldObj = curObj;
-  curObj = ObjStack[ObjStackTop--];
-
-  return oldObj;
-}
-
-extern "C" void deleteString(char *p);
-
-static void enterValues(const char *value) {
-  if (fieldedProp && *fieldedProp) {
-    if (value) {
-      addPropValue(curProp, *fieldedProp, value);
-    }
-    /* else this field is empty, advance to next field */
-    fieldedProp++;
-  } else {
-    if (value) {
-      setVObjectUStringZValue_(curProp, fakeUnicode(value, 0));
-    }
-  }
-  deleteString((char *)value);
-}
-
-static void enterProps(const char *s) {
-  curProp = addGroup(curObj, s);
-  deleteString((char *)s);
-}
-
-static void enterAttr(const char *s1, const char *s2) {
-  const char *p1, *p2 = nullptr;
-  p1 = lookupProp_(s1);
-  if (s2) {
-    VObject *a;
-    p2 = lookupProp_(s2);
-    a = addProp(curProp, p1);
-    setVObjectStringZValue(a, p2);
-  } else
-    addProp(curProp, p1);
-  if (PL_strcasecmp(p1, VCBase64Prop) == 0 ||
-      (s2 && PL_strcasecmp(p2, VCBase64Prop) == 0))
-    lexPushMode(L_BASE64);
-  else if (PL_strcasecmp(p1, VCQuotedPrintableProp) == 0 ||
-           (s2 && PL_strcasecmp(p2, VCQuotedPrintableProp) == 0))
-    lexPushMode(L_QUOTED_PRINTABLE);
-  deleteString((char *)s1);
-  deleteString((char *)s2);
-}
-
-#define PR_MAX_LEX_LOOKAHEAD_0 32
-#define PR_MAX_LEX_LOOKAHEAD 64
-#define PR_MAX_LEX_MODE_STACK_SIZE 10
-#define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop])
-
-struct LexBuf {
-  /* input */
-  char *inputString;
-  unsigned long curPos;
-  unsigned long inputLen;
-  /* lookahead buffer:
-   * lookahead buffer is short instead of char so that EOF
-   * can be represented correctly.
-   */
-  unsigned long len;
-  short buf[PR_MAX_LEX_LOOKAHEAD];
-  unsigned long getPtr;
-  /* context stack */
-  unsigned long lexModeStackTop;
-  enum LexMode lexModeStack[PR_MAX_LEX_MODE_STACK_SIZE];
-  /* token buffer */
-  unsigned long maxToken;
-  char *strs;
-  unsigned long strsLen;
-} lexBuf;
-
-static void lexPushMode(enum LexMode mode) {
-  if (lexBuf.lexModeStackTop == (PR_MAX_LEX_MODE_STACK_SIZE - 1))
-    yyerror("lexical context stack overflow");
-  else {
-    lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode;
-  }
-}
-
-static void lexPopMode(int top) {
-  /* special case of pop for ease of error recovery -- this
-  version will never underflow */
-  if (top)
-    lexBuf.lexModeStackTop = 0;
-  else if (lexBuf.lexModeStackTop > 0)
-    lexBuf.lexModeStackTop--;
-}
-
-static int lexWithinMode(enum LexMode mode) {
-  unsigned long i;
-  for (i = 0; i < lexBuf.lexModeStackTop; i++)
-    if (mode == lexBuf.lexModeStack[i]) return 1;
-  return 0;
-}
-
-static int lexGetc_() {
-  /* get next char from input, no buffering. */
-  if (lexBuf.curPos == lexBuf.inputLen) return EOF;
-  if (lexBuf.inputString) return *(lexBuf.inputString + lexBuf.curPos++);
-
-  return -1;
-}
-
-static int lexGeta() {
-  ++lexBuf.len;
-  return (lexBuf.buf[lexBuf.getPtr] = lexGetc_());
-}
-
-static int lexGeta_(int i) {
-  ++lexBuf.len;
-  return (lexBuf.buf[(lexBuf.getPtr + i) % PR_MAX_LEX_LOOKAHEAD] = lexGetc_());
-}
-
-static void lexSkipLookahead() {
-  if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr] != EOF) {
-    /* don't skip EOF. */
-    lexBuf.getPtr = (lexBuf.getPtr + 1) % PR_MAX_LEX_LOOKAHEAD;
-    lexBuf.len--;
-  }
-}
-
-static int lexLookahead() {
-  int c = (lexBuf.len) ? lexBuf.buf[lexBuf.getPtr] : lexGeta();
-  /* do the \r\n -> \n or \r -> \n translation here */
-  if (c == '\r') {
-    int a = (lexBuf.len > 1)
-                ? lexBuf.buf[(lexBuf.getPtr + 1) % PR_MAX_LEX_LOOKAHEAD]
-                : lexGeta_(1);
-    if (a == '\n') {
-      lexSkipLookahead();
-    }
-    lexBuf.buf[lexBuf.getPtr] = c = '\n';
-  } else if (c == '\n') {
-    int a = (lexBuf.len > 1) ? lexBuf.buf[lexBuf.getPtr + 1] : lexGeta_(1);
-    if (a == '\r') {
-      lexSkipLookahead();
-    }
-    lexBuf.buf[lexBuf.getPtr] = '\n';
-  }
-  return c;
-}
-
-static int lexGetc() {
-  int c = lexLookahead();
-  if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr] != EOF) {
-    /* EOF will remain in lookahead buffer */
-    lexBuf.getPtr = (lexBuf.getPtr + 1) % PR_MAX_LEX_LOOKAHEAD;
-    lexBuf.len--;
-  }
-  return c;
-}
-
-static void lexSkipLookaheadWord() {
-  if (lexBuf.strsLen <= lexBuf.len) {
-    lexBuf.len -= lexBuf.strsLen;
-    lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % PR_MAX_LEX_LOOKAHEAD;
-  }
-}
-
-static void lexClearToken() { lexBuf.strsLen = 0; }
-
-static void lexAppendc(int c) {
-  lexBuf.strs[lexBuf.strsLen] = c;
-  /* append up to zero termination */
-  if (c == 0) return;
-  lexBuf.strsLen++;
-  if (lexBuf.strsLen >= lexBuf.maxToken) {
-    /* double the token string size */
-    lexBuf.maxToken <<= 1;
-    lexBuf.strs = (char *)PR_Realloc(lexBuf.strs, lexBuf.maxToken);
-  }
-}
-
-static char *lexStr() { return dupStr(lexBuf.strs, lexBuf.strsLen + 1); }
-
-static void lexSkipWhite() {
-  int c = lexLookahead();
-  while (c == ' ' || c == '\t') {
-    lexSkipLookahead();
-    c = lexLookahead();
-  }
-}
-
-static char *lexGetWord() {
-  int c;
-  lexSkipWhite();
-  lexClearToken();
-  c = lexLookahead();
-  while (c != EOF && !PL_strchr("\t\n ;:=", (char)c)) {
-    lexAppendc(c);
-    lexSkipLookahead();
-    c = lexLookahead();
-  }
-  lexAppendc(0);
-  return lexStr();
-}
-
-#if 0
-static void lexPushLookahead(char *s, int len) {
-  int putptr;
-  if (len == 0) len = PL_strlen(s);
-  putptr = lexBuf.getPtr - len;
-  /* this function assumes that length of word to push back
-   * is not greater than PR_MAX_LEX_LOOKAHEAD.
-   */
-  if (putptr < 0) putptr += PR_MAX_LEX_LOOKAHEAD;
-  lexBuf.getPtr = putptr;
-  while (*s) {
-    lexBuf.buf[putptr] = *s++;
-    putptr = (putptr + 1) % PR_MAX_LEX_LOOKAHEAD;
-  }
-  lexBuf.len += len;
-}
-#endif
-
-static void lexPushLookaheadc(int c) {
-  int putptr;
-  /* can't putback EOF, because it never leaves lookahead buffer */
-  if (c == EOF) return;
-  putptr = (int)lexBuf.getPtr - 1;
-  if (putptr < 0) putptr += PR_MAX_LEX_LOOKAHEAD;
-  lexBuf.getPtr = putptr;
-  lexBuf.buf[putptr] = c;
-  lexBuf.len += 1;
-}
-
-static char *lexLookaheadWord() {
-  /* this function can lookahead word with max size of PR_MAX_LEX_LOOKAHEAD_0
-   /  and thing bigger than that will stop the lookahead and return 0;
-   / leading white spaces are not recoverable.
-   */
-  int c;
-  int len = 0;
-  int curgetptr = 0;
-  lexSkipWhite();
-  lexClearToken();
-  curgetptr = (int)lexBuf.getPtr; /* remember! */
-  while (len < (PR_MAX_LEX_LOOKAHEAD_0)) {
-    c = lexGetc();
-    len++;
-    if (c == EOF || PL_strchr("\t\n ;:=", (char)c)) {
-      lexAppendc(0);
-      /* restore lookahead buf. */
-      lexBuf.len += len;
-      lexBuf.getPtr = curgetptr;
-      return lexStr();
-    } else
-      lexAppendc(c);
-  }
-  lexBuf.len += len; /* char that has been moved to lookahead buffer */
-  lexBuf.getPtr = curgetptr;
-  return 0;
-}
-
-#ifdef _SUPPORT_LINE_FOLDING
-static void handleMoreRFC822LineBreak(int c) {
-  /* support RFC 822 line break in cases like
-   *  ADR: foo;
-   *  morefoo;
-   *  more foo;
-   */
-  if (c == ';') {
-    int a;
-    lexSkipLookahead();
-    /* skip white spaces */
-    a = lexLookahead();
-    while (a == ' ' || a == '\t') {
-      lexSkipLookahead();
-      a = lexLookahead();
-    }
-    if (a == '\n') {
-      lexSkipLookahead();
-      a = lexLookahead();
-      if (a == ' ' || a == '\t') {
-        /* continuation, throw away all the \n and spaces read so
-         * far
-         */
-        lexSkipWhite();
-        lexPushLookaheadc(';');
-      } else {
-        lexPushLookaheadc('\n');
-        lexPushLookaheadc(';');
-      }
-    } else {
-      lexPushLookaheadc(';');
-    }
-  }
-}
-
-static char *lexGet1Value() {
-  /*  int size = 0; */
-  int c;
-  lexSkipWhite();
-  c = lexLookahead();
-  lexClearToken();
-  while (c != EOF && c != ';') {
-    if (c == '\n') {
-      int a;
-      lexSkipLookahead();
-      a = lexLookahead();
-      if (a == ' ' || a == '\t') {
-        lexAppendc(' ');
-        lexSkipLookahead();
-      } else {
-        lexPushLookaheadc('\n');
-        break;
-      }
-    } else if (c == '\\') {
-      int a;
-      lexSkipLookahead();
-      a = lexLookahead();
-      if (a == '\\' || a == ',' || a == ';' || a == ':') {
-        lexAppendc(a);
-      } else if (a == 'n' || a == 'N') {
-        lexAppendc('\n');
-      } else {
-        lexAppendc(c);
-        lexAppendc(a);
-      }
-      lexSkipLookahead();
-    } else {
-      lexAppendc(c);
-      lexSkipLookahead();
-    }
-    c = lexLookahead();
-  }
-  lexAppendc(0);
-  handleMoreRFC822LineBreak(c);
-  return c == EOF ? 0 : lexStr();
-}
-#endif
-
-#ifndef _SUPPORT_LINE_FOLDING
-static char *lexGetStrUntil(char *termset) {
-  int c = lexLookahead();
-  lexClearToken();
-  while (c != EOF && !PL_strchr(termset, c)) {
-    lexAppendc(c);
-    lexSkipLookahead();
-    c = lexLookahead();
-  }
-  lexAppendc(0);
-  return c == EOF ? 0 : lexStr();
-}
-#endif /* ! _SUPPORT_LINE_FOLDING */
-
-static int match_begin_name(int end) {
-  char *n = lexLookaheadWord();
-  int token = ID;
-  if (n) {
-    if (!PL_strcasecmp(n, "vcard"))
-      token = end ? END_VCARD : BEGIN_VCARD;
-    else if (!PL_strcasecmp(n, "vcalendar"))
-      token = end ? END_VCAL : BEGIN_VCAL;
-    else if (!PL_strcasecmp(n, "vevent"))
-      token = end ? END_VEVENT : BEGIN_VEVENT;
-    else if (!PL_strcasecmp(n, "vtodo"))
-      token = end ? END_VTODO : BEGIN_VTODO;
-    deleteString(n);
-    return token;
-  }
-  return 0;
-}
-
-void initLex(const char *inputstring, unsigned long inputlen) {
-  /* initialize lex mode stack */
-  lexBuf.lexModeStack[lexBuf.lexModeStackTop = 0] = L_NORMAL;
-
-  /* iniatialize lex buffer. */
-  lexBuf.inputString = (char *)inputstring;
-  lexBuf.inputLen = inputlen;
-  lexBuf.curPos = 0;
-
-  lexBuf.len = 0;
-  lexBuf.getPtr = 0;
-
-  lexBuf.maxToken = PR_MAXTOKEN;
-  lexBuf.strs = (char *)PR_CALLOC(PR_MAXTOKEN);
-  lexBuf.strsLen = 0;
-}
-
-static void finiLex() { PR_FREEIF(lexBuf.strs); }
-
-/******************************************************************************/
-/* This parses and converts the base64 format for binary encoding into
- * a decoded buffer (allocated with new).  See RFC 1521.
- */
-static char *lexGetDataFromBase64() {
-  unsigned long bytesLen = 0, bytesMax = 0;
-  int quadIx = 0, pad = 0;
-  unsigned long trip = 0;
-  unsigned char b;
-  int c;
-  unsigned char *bytes = nullptr;
-  unsigned char *oldBytes = nullptr;
-
-  DBG_(("db: lexGetDataFromBase64\n"));
-  while (1) {
-    c = lexGetc();
-    if (c == '\n') {
-      ++mime_lineNum;
-      if (lexLookahead() == '\n') {
-        /* a '\n' character by itself means end of data */
-        break;
-      } else
-        continue; /* ignore '\n' */
-    } else {
-      if ((c >= 'A') && (c <= 'Z'))
-        b = (unsigned char)(c - 'A');
-      else if ((c >= 'a') && (c <= 'z'))
-        b = (unsigned char)(c - 'a') + 26;
-      else if ((c >= '0') && (c <= '9'))
-        b = (unsigned char)(c - '0') + 52;
-      else if (c == '+')
-        b = 62;
-      else if (c == '/')
-        b = 63;
-      else if (c == '=' && (quadIx == 2 || quadIx == 3)) {
-        b = 0;
-        pad++;
-      } else if ((c == ' ') || (c == '\t')) {
-        continue;
-      } else { /* error condition */
-        if (bytes)
-          PR_Free(bytes);
-        else if (oldBytes)
-          PR_Free(oldBytes);
-        /* error recovery: skip until 2 adjacent newlines. */
-        DBG_(("db: invalid character 0x%x '%c'\n", c, c));
-        if (c != EOF) {
-          c = lexGetc();
-          while (c != EOF) {
-            if (c == '\n' && lexLookahead() == '\n') {
-              ++mime_lineNum;
-              break;
-            }
-            c = lexGetc();
-          }
-        }
-        return NULL;
-      }
-      trip = (trip << 6) | b;
-      if (++quadIx == 4) {
-        unsigned char outBytes[3];
-        int numOut;
-        int i;
-        for (i = 0; i < 3; i++) {
-          outBytes[2 - i] = (unsigned char)(trip & 0xFF);
-          trip >>= 8;
-        }
-        numOut = 3 - pad;
-        if (bytesLen + numOut > bytesMax) {
-          if (!bytes) {
-            bytesMax = 1024;
-          } else {
-            bytesMax <<= 2;
-            oldBytes = bytes;
-          }
-          bytes = (unsigned char *)PR_Realloc(oldBytes, bytesMax);
-          if (!bytes) {
-            mime_error("out of memory while processing BASE64 data\n");
-            break;
-          }
-        }
-        if (bytes) {
-          memcpy(bytes + bytesLen, outBytes, numOut);
-          bytesLen += numOut;
-        }
-        trip = 0;
-        quadIx = 0;
-        pad = 0;
-      }
-    }
-  } /* while */
-  DBG_(("db: bytesLen = %d\n", bytesLen));
-  /* kludge: all this won't be necessary if we have tree form
-  representation */
-  if (bytes) {
-    setValueWithSize(curProp, bytes, (unsigned int)bytesLen);
-    PR_FREEIF(bytes);
-  } else if (oldBytes) {
-    setValueWithSize(curProp, oldBytes, (unsigned int)bytesLen);
-    PR_FREEIF(oldBytes);
-  }
-  return 0;
-}
-
-static int match_begin_end_name(int end) {
-  int token;
-  lexSkipWhite();
-  if (lexLookahead() != ':') return ID;
-  lexSkipLookahead();
-  lexSkipWhite();
-  token = match_begin_name(end);
-  if (token == ID) {
-    lexPushLookaheadc(':');
-    DBG_(("db: ID '%s'\n", yylval.str));
-    return ID;
-  } else if (token != 0) {
-    lexSkipLookaheadWord();
-    deleteString(yylval.str);
-    DBG_(("db: begin/end %d\n", token));
-    return token;
-  }
-  return 0;
-}
-
-static char *lexGetQuotedPrintable() {
-  char cur;
-  /* unsigned long len = 0; */
-
-  lexClearToken();
-  do {
-    cur = lexGetc();
-    switch (cur) {
-      case '=': {
-        int c = 0;
-        int next[2];
-        int tab[1];
-        int i;
-        for (i = 0; i < 2; i++) {
-          next[i] = lexGetc();
-          if (next[i] >= '0' && next[i] <= '9')
-            c = c * 16 + next[i] - '0';
-          else if (next[i] >= 'A' && next[i] <= 'F')
-            c = c * 16 + next[i] - 'A' + 10;
-          else
-            break;
-        }
-        if (i == 0) {
-          /* single '=' follow by LINESEP is continuation sign? */
-          if (next[0] == '\n') {
-            tab[0] = lexGetc();
-            if (tab[0] == '\t') lexSkipWhite();
-            ++mime_lineNum;
-          } else {
-            lexAppendc(cur);
-            /* lexPushLookaheadc('=');
-            goto EndString; */
-          }
-        } else if (i == 1) {
-          lexPushLookaheadc(next[1]);
-          lexPushLookaheadc(next[0]);
-          lexAppendc('=');
-        } else {
-          lexAppendc(c);
-        }
-        break;
-      } /* '=' */
-      case '\n': {
-        lexPushLookaheadc('\n');
-        goto EndString;
-      }
-      case ';': {
-        lexPushLookaheadc(';');
-        goto EndString;
-      }
-      case (char)EOF:
-        break;
-      default:
-        lexAppendc(cur);
-        break;
-    } /* switch */
-  } while (cur != (char)EOF);
-
-EndString:
-  lexAppendc(0);
-  return lexStr();
-} /* LexQuotedPrintable */
-
-static int yylex() {
-  /* int token = 0; */
-  int lexmode = LEXMODE();
-  if (lexmode == L_VALUES) {
-    int c = lexGetc();
-    if (c == ';') {
-      DBG_(("db: SEMICOLON\n"));
-#ifdef _SUPPORT_LINE_FOLDING
-      lexPushLookaheadc(c);
-      handleMoreRFC822LineBreak(c);
-      lexSkipLookahead();
-#endif
-      return SEMICOLON;
-    } else if (PL_strchr("\n", (char)c)) {
-      ++mime_lineNum;
-      /* consume all line separator(s) adjacent to each other */
-      c = lexLookahead();
-      while (PL_strchr("\n", (char)c)) {
-        lexSkipLookahead();
-        c = lexLookahead();
-        ++mime_lineNum;
-      }
-      DBG_(("db: LINESEP\n"));
-      return LINESEP;
-    } else {
-      char *p = 0;
-      lexPushLookaheadc(c);
-      if (lexWithinMode(L_BASE64)) {
-        /* get each char and convert to bin on the fly... */
-        p = lexGetDataFromBase64();
-        yylval.str = p;
-        return !p && lexLookahead() == EOF ? 0 : STRING;
-      } else if (lexWithinMode(L_QUOTED_PRINTABLE)) {
-        p = lexGetQuotedPrintable();
-      } else {
-#ifdef _SUPPORT_LINE_FOLDING
-        p = lexGet1Value();
-#else
-        p = lexGetStrUntil(";\n");
-#endif
-      }
-      if (p && (*p || lexLookahead() != EOF)) {
-        DBG_(("db: STRING: '%s'\n", p));
-        yylval.str = p;
-        return STRING;
-      } else
-        return 0;
-    }
-  } else {
-    /* normal mode */
-    while (1) {
-      int c = lexGetc();
-      switch (c) {
-        case ':': {
-          /* consume all line separator(s) adjacent to each other */
-          /* ignoring linesep immediately after colon. */
-          c = lexLookahead();
-          while (PL_strchr("\n", (char)c)) {
-            lexSkipLookahead();
-            c = lexLookahead();
-            ++mime_lineNum;
-          }
-          DBG_(("db: COLON\n"));
-          return COLON;
-        }
-        case ';':
-          DBG_(("db: SEMICOLON\n"));
-          return SEMICOLON;
-        case '=':
-          DBG_(("db: EQ\n"));
-          return EQ;
-        /* ignore whitespace in this mode */
-        case '\t':
-        case ' ':
-          continue;
-        case '\n': {
-          ++mime_lineNum;
-          continue;
-        }
-        case EOF:
-          return 0;
-        default: {
-          lexPushLookaheadc(c);
-          if (isalpha(c)) {
-            char *t = lexGetWord();
-            yylval.str = t;
-            if (!PL_strcasecmp(t, "BEGIN")) {
-              return match_begin_end_name(0);
-            } else if (!PL_strcasecmp(t, "END")) {
-              return match_begin_end_name(1);
-            } else {
-              DBG_(("db: ID '%s'\n", t));
-              return ID;
-            }
-          } else {
-            /* unknown token */
-            return 0;
-          }
-        }
-      }
-    }
-  }
-}
-
-/***************************************************************************/
-/***              Public Functions            ****/
-/***************************************************************************/
-
-static VObject *parse_MIMEHelper() {
-  ObjStackTop = -1;
-  mime_numErrors = 0;
-  mime_lineNum = 1;
-  vObjList = 0;
-  curObj = 0;
-
-  if (yyparse() != 0) return 0;
-
-  finiLex();
-  return vObjList;
-}
-
-/******************************************************************************/
-VObject *parse_MIME(const char *input, unsigned long len) {
-  initLex(input, len);
-  return parse_MIMEHelper();
-}
-
-static MimeErrorHandler mimeErrorHandler;
-
-void registerMimeErrorHandler(MimeErrorHandler me) { mimeErrorHandler = me; }
-
-void mime_error(const char *s) {
-  char msg[256];
-  if (mimeErrorHandler) {
-    PR_snprintf(msg, sizeof(msg), "%s at line %d", s, mime_lineNum);
-    mimeErrorHandler(msg);
-  }
-}
-
-/*#line 1221 "y_tab.c"*/
-#define YYABORT goto yyabort
-#define YYACCEPT goto yyaccept
-#define YYERROR goto yyerrlab
-int yyparse() {
-  int yym, yyn, yystate;
-#if YYDEBUG
-  char *yys;
-  extern char *getenv();
-
-  if (yys = getenv("YYDEBUG")) {
-    yyn = *yys;
-    if (yyn >= '0' && yyn <= '9') yydebug = yyn - '0';
-  }
-#endif
-
-  yynerrs = 0;
-  yyerrflag = 0;
-  yychar = (-1);
-
-  yyssp = yyss;
-  yyvsp = yyvs;
-  *yyssp = yystate = 0;
-
-yyloop:
-  if ((yyn = yydefred[yystate])) goto yyreduce;
-  if (yychar < 0) {
-    if ((yychar = yylex()) < 0) yychar = 0;
-#if YYDEBUG
-    if (yydebug) {
-      yys = 0;
-      if (yychar <= YYPR_MAXTOKEN) yys = yyname[yychar];
-      if (!yys) yys = "illegal-symbol";
-      printf("yydebug: state %d, reading %d (%s)\n", yystate, yychar, yys);
-    }
-#endif
-  }
-  if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE &&
-      yycheck[yyn] == yychar) {
-#if YYDEBUG
-    if (yydebug)
-      printf("yydebug: state %d, shifting to state %d\n", yystate,
-             yytable[yyn]);
-#endif
-    if (yyssp >= yyss + yystacksize - 1) {
-      goto yyoverflow;
-    }
-    *++yyssp = yystate = yytable[yyn];
-    *++yyvsp = yylval;
-    yychar = (-1);
-    if (yyerrflag > 0) --yyerrflag;
-    goto yyloop;
-  }
-  if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE &&
-      yycheck[yyn] == yychar) {
-    yyn = yytable[yyn];
-    goto yyreduce;
-  }
-  if (yyerrflag) goto yyinrecovery;
-#ifdef lint
-  goto yynewerror;
-#endif
-  /*yynewerror: */
-  yyerror("syntax error");
-#ifdef lint
-  goto yyerrlab;
-#endif
-yyerrlab:
-  ++yynerrs;
-yyinrecovery:
-  if (yyerrflag < 3) {
-    yyerrflag = 3;
-    for (;;) {
-      if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
-          yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) {
-#if YYDEBUG
-        if (yydebug)
-          printf("yydebug: state %d, error recovery shifting to state %d\n",
-                 *yyssp, yytable[yyn]);
-#endif
-        if (yyssp >= yyss + yystacksize - 1) {
-          goto yyoverflow;
-        }
-        *++yyssp = yystate = yytable[yyn];
-        *++yyvsp = yylval;
-        goto yyloop;
-      } else {
-#if YYDEBUG
-        if (yydebug)
-          printf("yydebug: error recovery discarding state %d\n", *yyssp);
-#endif
-        if (yyssp <= yyss) goto yyabort;
-        --yyssp;
-        --yyvsp;
-      }
-    }
-  } else {
-    if (yychar == 0) goto yyabort;
-#if YYDEBUG
-    if (yydebug) {
-      yys = 0;
-      if (yychar <= YYPR_MAXTOKEN) yys = yyname[yychar];
-      if (!yys) yys = "illegal-symbol";
-      printf("yydebug: state %d, error recovery discards token %d (%s)\n",
-             yystate, yychar, yys);
-    }
-#endif
-    yychar = (-1);
-    goto yyloop;
-  }
-yyreduce:
-#if YYDEBUG
-  if (yydebug)
-    printf("yydebug: state %d, reducing by rule %d (%s)\n", yystate, yyn,
-           yyrule[yyn]);
-#endif
-  yym = yylen[yyn];
-  yyval = yyvsp[1 - yym];
-  switch (yyn) {
-    case 2:
-      /*#line 282 "vcc.y"*/
-      {
-        addList(&vObjList, yyvsp[0].vobj);
-        curObj = 0;
-      }
-      break;
-    case 4:
-      /*#line 285 "vcc.y"*/
-      {
-        addList(&vObjList, yyvsp[0].vobj);
-        curObj = 0;
-      }
-      break;
-    case 7:
-      /*#line 294 "vcc.y"*/
-      {
-        lexPushMode(L_VCARD);
-        if (!pushVObject(VCCardProp)) YYERROR;
-      }
-      break;
-    case 8:
-      /*#line 299 "vcc.y"*/
-      {
-        lexPopMode(0);
-        yyval.vobj = popVObject();
-      }
-      break;
-    case 9:
-      /*#line 304 "vcc.y"*/
-      {
-        lexPushMode(L_VCARD);
-        if (!pushVObject(VCCardProp)) YYERROR;
-      }
-      break;
-    case 10:
-      /*#line 309 "vcc.y"*/
-      {
-        lexPopMode(0);
-        yyval.vobj = popVObject();
-      }
-      break;
-    case 13:
-      /*#line 320 "vcc.y"*/
-      { lexPushMode(L_VALUES); }
-      break;
-    case 14:
-      /*#line 324 "vcc.y"*/
-      {
-        if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE))
-          lexPopMode(0);
-        lexPopMode(0);
-      }
-      break;
-    case 16:
-      /*#line 332 "vcc.y"*/
-      { enterProps(yyvsp[0].str); }
-      break;
-    case 18:
-      /*#line 337 "vcc.y"*/
-      { enterProps(yyvsp[0].str); }
-      break;
-    case 22:
-      /*#line 350 "vcc.y"*/
-      { enterAttr(yyvsp[0].str, 0); }
-      break;
-    case 23:
-      /*#line 354 "vcc.y"*/
-      { enterAttr(yyvsp[-2].str, yyvsp[0].str); }
-      break;
-    case 25:
-      /*#line 363 "vcc.y"*/
-      { enterValues(yyvsp[-1].str); }
-      break;
-    case 27:
-      /*#line 365 "vcc.y"*/
-      { enterValues(yyvsp[0].str); }
-      break;
-    case 29:
-      /*#line 370 "vcc.y"*/
-      { yyval.str = 0; }
-      break;
-    case 30:
-      /*#line 375 "vcc.y"*/
-      {
-        if (!pushVObject(VCCalProp)) YYERROR;
-      }
-      break;
-    case 31:
-      /*#line 378 "vcc.y"*/
-      { yyval.vobj = popVObject(); }
-      break;
-    case 32:
-      /*#line 380 "vcc.y"*/
-      {
-        if (!pushVObject(VCCalProp)) YYERROR;
-      }
-      break;
-    case 33:
-      /*#line 382 "vcc.y"*/
-      { yyval.vobj = popVObject(); }
-      break;
-    case 39:
-      /*#line 397 "vcc.y"*/
-      {
-        lexPushMode(L_VEVENT);
-        if (!pushVObject(VCEventProp)) YYERROR;
-      }
-      break;
-    case 40:
-      /*#line 403 "vcc.y"*/
-      {
-        lexPopMode(0);
-        popVObject();
-      }
-      break;
-    case 41:
-      /*#line 408 "vcc.y"*/
-      {
-        lexPushMode(L_VEVENT);
-        if (!pushVObject(VCEventProp)) YYERROR;
-      }
-      break;
-    case 42:
-      /*#line 413 "vcc.y"*/
-      {
-        lexPopMode(0);
-        popVObject();
-      }
-      break;
-    case 43:
-      /*#line 421 "vcc.y"*/
-      {
-        lexPushMode(L_VTODO);
-        if (!pushVObject(VCTodoProp)) YYERROR;
-      }
-      break;
-    case 44:
-      /*#line 427 "vcc.y"*/
-      {
-        lexPopMode(0);
-        popVObject();
-      }
-      break;
-    case 45:
-      /*#line 432 "vcc.y"*/
-      {
-        lexPushMode(L_VTODO);
-        if (!pushVObject(VCTodoProp)) YYERROR;
-      }
-      break;
-    case 46:
-      /*#line 437 "vcc.y"*/
-      {
-        lexPopMode(0);
-        popVObject();
-      }
-      break;
-      /*#line 1520 "y_tab.c"*/
-  }
-  yyssp -= yym;
-  yystate = *yyssp;
-  yyvsp -= yym;
-  yym = yylhs[yyn];
-  if (yystate == 0 && yym == 0) {
-#if YYDEBUG
-    if (yydebug)
-      printf("yydebug: after reduction, shifting from state 0 to state %d\n",
-             YYFINAL);
-#endif
-    yystate = YYFINAL;
-    *++yyssp = YYFINAL;
-    *++yyvsp = yyval;
-    if (yychar < 0) {
-      if ((yychar = yylex()) < 0) yychar = 0;
-#if YYDEBUG
-      if (yydebug) {
-        yys = 0;
-        if (yychar <= YYPR_MAXTOKEN) yys = yyname[yychar];
-        if (!yys) yys = "illegal-symbol";
-        printf("yydebug: state %d, reading %d (%s)\n", YYFINAL, yychar, yys);
-      }
-#endif
-    }
-    if (yychar == 0) goto yyaccept;
-    goto yyloop;
-  }
-  if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && yyn <= YYTABLESIZE &&
-      yycheck[yyn] == yystate)
-    yystate = yytable[yyn];
-  else
-    yystate = yydgoto[yym];
-#if YYDEBUG
-  if (yydebug)
-    printf("yydebug: after reduction, shifting from state %d to state %d\n",
-           *yyssp, yystate);
-#endif
-  if (yyssp >= yyss + yystacksize - 1) {
-    goto yyoverflow;
-  }
-  *++yyssp = yystate;
-  *++yyvsp = yyval;
-  goto yyloop;
-yyoverflow:
-  yyerror("yacc stack overflow");
-yyabort:
-  return (1);
-yyaccept:
-  return (0);
-}
deleted file mode 100644
--- a/mailnews/addrbook/src/nsVCard.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- 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/. */
-
-/***************************************************************************
-(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
-Business Machines Corporation and Siemens Rolm Communications Inc.
-
-For purposes of this license notice, the term Licensors shall mean,
-collectively, Apple Computer, Inc., AT&T Corp., International
-Business Machines Corporation and Siemens Rolm Communications Inc.
-The term Licensor shall mean any of the Licensors.
-
-Subject to acceptance of the following conditions, permission is hereby
-granted by Licensors without the need for written agreement and without
-license or royalty fees, to use, copy, modify and distribute this
-software for any purpose.
-
-The above copyright notice and the following four paragraphs must be
-reproduced in all copies of this software and any software including
-this software.
-
-THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
-ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
-MODIFICATIONS.
-
-IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
-INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
-OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGE.
-
-EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.
-
-The software is provided with RESTRICTED RIGHTS.  Use, duplication, or
-disclosure by the government are subject to restrictions set forth in
-DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
-
-***************************************************************************/
-
-#ifndef __VCC_H__
-#define __VCC_H__ 1
-
-#include "nsVCardObj.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-VObject *parse_MIME(const char *input, unsigned long len);
-
-typedef void (*MimeErrorHandler)(char *);
-
-void registerMimeErrorHandler(MimeErrorHandler);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __VCC_H__ */
deleted file mode 100644
--- a/mailnews/addrbook/src/nsVCardObj.cpp
+++ /dev/null
@@ -1,1179 +0,0 @@
-/* -*- 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/. */
-
-/***************************************************************************
-(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
-Business Machines Corporation and Siemens Rolm Communications Inc.
-
-For purposes of this license notice, the term Licensors shall mean,
-collectively, Apple Computer, Inc., AT&T Corp., International
-Business Machines Corporation and Siemens Rolm Communications Inc.
-The term Licensor shall mean any of the Licensors.
-
-Subject to acceptance of the following conditions, permission is hereby
-granted by Licensors without the need for written agreement and without
-license or royalty fees, to use, copy, modify and distribute this
-software for any purpose.
-
-The above copyright notice and the following four paragraphs must be
-reproduced in all copies of this software and any software including
-this software.
-
-THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
-ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
-MODIFICATIONS.
-
-IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
-INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
-OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGE.
-
-EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.
-
-The software is provided with RESTRICTED RIGHTS.  Use, duplication, or
-disclosure by the government are subject to restrictions set forth in
-DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
-
-***************************************************************************/
-
-/*
- * doc: vobject and APIs to construct vobject, APIs pretty print
- * vobject, and convert a vobject into its textual representation.
- */
-
-#include "prlog.h"
-#include "nsVCard.h"
-#include "nsVCardObj.h"
-#include "prmem.h"
-#include "plstr.h"
-#include "prprf.h"
-#include "nsString.h"
-
-/* debugging utilities */
-#define DBG_(x)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-char **fieldedProp;
-
-#ifdef __cplusplus
-}
-#endif
-
-static VObject *newVObject_(const char *id);
-#if 0
-static int vObjectValueType(VObject *o);
-static void initVObjectIterator(VObjectIterator *i, VObject *o);
-#endif
-
-/*----------------------------------------------------------------------
-  The following functions involve with memory allocation:
-  newVObject
-  deleteVObject
-  dupStr
-  deleteString
-  newStrItem
-  deleteStrItem
-  ----------------------------------------------------------------------*/
-
-static bool needsQuotedPrintable(const char *s) {
-  const unsigned char *p = (const unsigned char *)s;
-
-  while (*p) {
-    if (*p & 0x80 || *p == '\015' || *p == '\012') return true;
-    p++;
-  }
-
-  return false;
-}
-
-VObject *newVObject_(const char *id) {
-  VObject *p = (VObject *)new (VObject);
-  p->next = 0;
-  p->id = id;
-  p->prop = 0;
-  VALUE_TYPE(p) = 0;
-  ANY_VALUE_OF(p) = 0;
-  return p;
-}
-
-VObject *newVObject(const char *id) { return newVObject_(lookupStr(id)); }
-
-void deleteVObject(VObject *p) {
-  unUseStr(p->id);
-  delete (p);
-}
-
-char *dupStr(const char *s, unsigned int size) {
-  char *t;
-  if (size == 0) {
-    size = PL_strlen(s);
-  }
-  t = (char *)PR_CALLOC(size + 1);
-  if (t) {
-    memcpy(t, s, size);
-    t[size] = 0;
-    return t;
-  } else {
-    return (char *)0;
-  }
-}
-
-static StrItem *newStrItem(const char *s, StrItem *next) {
-  StrItem *p = (StrItem *)PR_CALLOC(sizeof(StrItem));
-  p->next = next;
-  p->s = s;
-  p->refCnt = 1;
-  return p;
-}
-
-extern "C" void deleteString(char *p) {
-  if (p) PR_Free((void *)p);
-}
-
-extern "C" void deleteStrItem(StrItem *p) {
-  if (p) PR_FREEIF(p);
-}
-
-/*----------------------------------------------------------------------
-  The following function provide accesses to VObject's value.
-  ----------------------------------------------------------------------*/
-
-const char *vObjectName(VObject *o) { return NAME_OF(o); }
-
-void setVObjectName(VObject *o, const char *id) { NAME_OF(o) = id; }
-
-const char *vObjectStringZValue(VObject *o) { return STRINGZ_VALUE_OF(o); }
-
-void setVObjectStringZValue(VObject *o, const char *s) {
-  STRINGZ_VALUE_OF(o) = dupStr(s, 0);
-  VALUE_TYPE(o) = VCVT_STRINGZ;
-}
-
-void setVObjectStringZValue_(VObject *o, const char *s) {
-  STRINGZ_VALUE_OF(o) = s;
-  VALUE_TYPE(o) = VCVT_STRINGZ;
-}
-
-const vwchar_t *vObjectUStringZValue(VObject *o) {
-  return USTRINGZ_VALUE_OF(o);
-}
-
-void setVObjectUStringZValue(VObject *o, const vwchar_t *s) {
-  USTRINGZ_VALUE_OF(o) = (vwchar_t *)dupStr((char *)s, (uStrLen(s) + 1) * 2);
-  VALUE_TYPE(o) = VCVT_USTRINGZ;
-}
-
-void setVObjectUStringZValue_(VObject *o, const vwchar_t *s) {
-  USTRINGZ_VALUE_OF(o) = s;
-  VALUE_TYPE(o) = VCVT_USTRINGZ;
-}
-
-unsigned int vObjectIntegerValue(VObject *o) { return INTEGER_VALUE_OF(o); }
-
-void setVObjectIntegerValue(VObject *o, unsigned int i) {
-  INTEGER_VALUE_OF(o) = i;
-  VALUE_TYPE(o) = VCVT_UINT;
-}
-
-unsigned long vObjectLongValue(VObject *o) { return LONG_VALUE_OF(o); }
-
-void setVObjectLongValue(VObject *o, unsigned long l) {
-  LONG_VALUE_OF(o) = l;
-  VALUE_TYPE(o) = VCVT_ULONG;
-}
-
-void *vObjectAnyValue(VObject *o) { return ANY_VALUE_OF(o); }
-
-void setVObjectAnyValue(VObject *o, void *t) {
-  ANY_VALUE_OF(o) = t;
-  VALUE_TYPE(o) = VCVT_RAW;
-}
-
-VObject *vObjectVObjectValue(VObject *o) { return VOBJECT_VALUE_OF(o); }
-
-void setVObjectVObjectValue(VObject *o, VObject *p) {
-  VOBJECT_VALUE_OF(o) = p;
-  VALUE_TYPE(o) = VCVT_VOBJECT;
-}
-
-#if 0
-int vObjectValueType(VObject *o)
-{
-  return VALUE_TYPE(o);
-}
-#endif
-
-/*----------------------------------------------------------------------
-  The following functions can be used to build VObject.
-  ----------------------------------------------------------------------*/
-
-VObject *addVObjectProp(VObject *o, VObject *p) {
-  /* circular link list pointed to tail */
-  /*
-  o {next,id,prop,val}
-             V
-  pn {next,id,prop,val}
-             V
-  ...
-  p1 {next,id,prop,val}
-             V
-  pn
-  -->
-  o {next,id,prop,val}
-             V
-  pn {next,id,prop,val}
-             V
-  p {next,id,prop,val}
-  ...
-  p1 {next,id,prop,val}
-             V
-  pn
-  */
-
-  VObject *tail = o->prop;
-  if (tail) {
-    p->next = tail->next;
-    o->prop = tail->next = p;
-  } else {
-    o->prop = p->next = p;
-  }
-  return p;
-}
-
-VObject *addProp(VObject *o, const char *id) {
-  return addVObjectProp(o, newVObject(id));
-}
-
-VObject *addProp_(VObject *o, const char *id) {
-  return addVObjectProp(o, newVObject_(id));
-}
-
-void addList(VObject **o, VObject *p) {
-  p->next = 0;
-  if (*o == 0) {
-    *o = p;
-  } else {
-    VObject *t = *o;
-    while (t->next) {
-      t = t->next;
-    }
-    t->next = p;
-  }
-}
-
-VObject *nextVObjectInList(VObject *o) { return o->next; }
-
-VObject *setValueWithSize_(VObject *prop, void *val, unsigned int size) {
-  VObject *sizeProp;
-  setVObjectAnyValue(prop, val);
-  sizeProp = addProp(prop, VCDataSizeProp);
-  setVObjectLongValue(sizeProp, size);
-  return prop;
-}
-
-VObject *setValueWithSize(VObject *prop, void *val, unsigned int size) {
-  void *p = dupStr((const char *)val, size);
-  return setValueWithSize_(prop, p, p ? size : 0);
-}
-
-void initPropIterator(VObjectIterator *i, VObject *o) {
-  i->start = o->prop;
-  i->next = 0;
-}
-
-#if 0
-void initVObjectIterator(VObjectIterator *i, VObject *o)
-{
-  i->start = o->next;
-  i->next = 0;
-}
-#endif
-
-int moreIteration(VObjectIterator *i) {
-  return (i->start && (i->next == 0 || i->next != i->start));
-}
-
-VObject *nextVObject(VObjectIterator *i) {
-  if (i->start && i->next != i->start) {
-    if (i->next == 0) {
-      i->next = i->start->next;
-      return i->next;
-    } else {
-      i->next = i->next->next;
-      return i->next;
-    }
-  } else
-    return (VObject *)0;
-}
-
-VObject *isAPropertyOf(VObject *o, const char *id) {
-  VObjectIterator i;
-  initPropIterator(&i, o);
-  while (moreIteration(&i)) {
-    VObject *each = nextVObject(&i);
-    if (!PL_strcasecmp(id, each->id)) return each;
-  }
-  return (VObject *)0;
-}
-
-VObject *addGroup(VObject *o, const char *g) {
-  /*
-  a.b.c
-  -->
-  prop(c)
-  prop(VCGrouping=b)
-  prop(VCGrouping=a)
-  */
-  char *dot = PL_strrchr(g, '.');
-  if (dot) {
-    VObject *p, *t;
-    char *gs, *n = dot + 1;
-    gs = dupStr(g, 0); /* so we can write to it. */
-    t = p = addProp_(o, lookupProp(n));
-    dot = PL_strrchr(gs, '.');
-    *dot = 0;
-    do {
-      dot = PL_strrchr(gs, '.');
-      if (dot) {
-        n = dot + 1;
-        *dot = 0;
-      } else
-        n = gs;
-      /* property(VCGroupingProp=n);
-       *  and the value may have VCGrouping property
-       */
-      t = addProp(t, VCGroupingProp);
-      setVObjectStringZValue(t, lookupProp_(n));
-    } while (n != gs);
-    deleteString(gs);
-    return p;
-  } else
-    return addProp_(o, lookupProp(g));
-}
-
-VObject *addPropValue(VObject *o, const char *p, const char *v) {
-  VObject *prop;
-  prop = addProp(o, p);
-  if (v) {
-    setVObjectUStringZValue_(prop, fakeUnicode(v, 0));
-    if (needsQuotedPrintable(v)) {
-      if (PL_strcasecmp(VCCardProp, vObjectName(o)) == 0)
-        addProp(prop, VCQuotedPrintableProp);
-      else
-        addProp(o, VCQuotedPrintableProp);
-    }
-  } else
-    setVObjectUStringZValue_(prop, fakeUnicode("", 0));
-
-  return prop;
-}
-
-VObject *addPropSizedValue_(VObject *o, const char *p, const char *v,
-                            unsigned int size) {
-  VObject *prop;
-  prop = addProp(o, p);
-  setValueWithSize_(prop, (void *)v, size);
-  return prop;
-}
-
-VObject *addPropSizedValue(VObject *o, const char *p, const char *v,
-                           unsigned int size) {
-  return addPropSizedValue_(o, p, dupStr(v, size), size);
-}
-
-void cleanVObject(VObject *o) {
-  if (o == 0) return;
-  if (o->prop) {
-    /* destroy time: cannot use the iterator here.
-       Have to break the cycle in the circular link
-       list and turns it into regular NULL-terminated
-       list -- since at some point of destruction,
-       the reference entry for the iterator to work
-       will not longer be valid.
-     */
-    VObject *p;
-    p = o->prop->next;
-    o->prop->next = 0;
-    do {
-      VObject *t = p->next;
-      cleanVObject(p);
-      p = t;
-    } while (p);
-  }
-  switch (VALUE_TYPE(o)) {
-    case VCVT_USTRINGZ:
-    case VCVT_STRINGZ:
-    case VCVT_RAW:
-      /* assume they are all allocated by malloc. */
-      if ((char *)STRINGZ_VALUE_OF(o)) PR_Free((char *)STRINGZ_VALUE_OF(o));
-      break;
-    case VCVT_VOBJECT:
-      cleanVObject(VOBJECT_VALUE_OF(o));
-      break;
-  }
-  deleteVObject(o);
-}
-
-void cleanVObjects(VObject *list) {
-  while (list) {
-    VObject *t = list;
-    list = nextVObjectInList(list);
-    cleanVObject(t);
-  }
-}
-
-/*----------------------------------------------------------------------
-  The following is a String Table Facilities.
-  ----------------------------------------------------------------------*/
-
-#define STRTBLSIZE 255
-
-static StrItem *strTbl[STRTBLSIZE];
-
-static unsigned int hashStr(const char *s) {
-  unsigned int h = 0;
-  int i;
-  for (i = 0; s[i]; i++) {
-    h += s[i] * i;
-  }
-  return h % STRTBLSIZE;
-}
-
-void unUseStr(const char *s) {
-  StrItem *t, *p;
-  unsigned int h = hashStr(s);
-  if ((t = strTbl[h]) != 0) {
-    p = t;
-    do {
-      if (PL_strcasecmp(t->s, s) == 0) {
-        t->refCnt--;
-        if (t->refCnt == 0) {
-          if (t == strTbl[h]) {
-            strTbl[h] = t->next;
-          } else {
-            p->next = t->next;
-          }
-          deleteString((char *)t->s);
-          deleteStrItem(t);
-          return;
-        }
-      }
-      p = t;
-      t = t->next;
-    } while (t);
-  }
-}
-
-struct PreDefProp {
-  const char *name;
-  const char *alias;
-  const char **fields;
-  unsigned int flags;
-};
-
-/* flags in PreDefProp */
-#define PD_BEGIN 0x1
-#define PD_INTERNAL 0x2
-
-static const char *adrFields[] = {
-    VCPostalBoxProp, VCExtAddressProp, VCStreetAddressProp, VCCityProp,
-    VCRegionProp,    VCPostalCodeProp, VCCountryNameProp,   0};
-
-static const char *nameFields[] = {VCFamilyNameProp,      VCGivenNameProp,
-                                   VCAdditionalNamesProp, VCNamePrefixesProp,
-                                   VCNameSuffixesProp,    NULL};
-
-// VCFullNameProp needs to be a field so VCQuotedPrintableProp can be stored
-// with it.
-static const char *fnFields[] = {VCFullNameProp, NULL};
-
-static const char *orgFields[] = {VCOrgNameProp,  VCOrgUnitProp,
-                                  VCOrgUnit2Prop, VCOrgUnit3Prop,
-                                  VCOrgUnit4Prop, NULL};
-
-static const char *AAlarmFields[] = {VCRunTimeProp, VCSnoozeTimeProp,
-                                     VCRepeatCountProp, VCAudioContentProp, 0};
-
-static const char *coolTalkFields[] = {VCCooltalkAddress, VCUseServer, 0};
-
-/* ExDate -- has unnamed fields */
-/* RDate -- has unnamed fields */
-
-static const char *DAlarmFields[] = {VCRunTimeProp, VCSnoozeTimeProp,
-                                     VCRepeatCountProp, VCDisplayStringProp, 0};
-
-static const char *MAlarmFields[] = {VCRunTimeProp,     VCSnoozeTimeProp,
-                                     VCRepeatCountProp, VCEmailAddressProp,
-                                     VCNoteProp,        0};
-
-static const char *PAlarmFields[] = {VCRunTimeProp, VCSnoozeTimeProp,
-                                     VCRepeatCountProp, VCProcedureNameProp, 0};
-
-// clang-format off
-static struct PreDefProp propNames[] = {
-  {VC7bitProp, 0, 0, 0},
-  {VC8bitProp, 0, 0, 0},
-  {VCAAlarmProp, 0, AAlarmFields, 0},
-  {VCAdditionalNamesProp, 0, 0, 0},
-  {VCAdrProp, 0, adrFields, 0},
-  {VCAgentProp, 0, 0, 0},
-  {VCAIFFProp, 0, 0, 0},
-  {VCAOLProp, 0, 0, 0},
-  {VCAppleLinkProp, 0, 0, 0},
-  {VCAttachProp, 0, 0, 0},
-  {VCAttendeeProp, 0, 0, 0},
-  {VCATTMailProp, 0, 0, 0},
-  {VCAudioContentProp, 0, 0, 0},
-  {VCAVIProp, 0, 0, 0},
-  {VCBase64Prop, 0, 0, 0},
-  {VCBBSProp, 0, 0, 0},
-  {VCBirthDateProp, 0, 0, 0},
-  {VCBMPProp, 0, 0, 0},
-  {VCBodyProp, 0, 0, 0},
-  {VCBusinessRoleProp, 0, 0, 0},
-  {VCCalProp, 0, 0, PD_BEGIN},
-  {VCCaptionProp, 0, 0, 0},
-  {VCCardProp, 0, 0, PD_BEGIN},
-  {VCCarProp, 0, 0, 0},
-  {VCCategoriesProp, 0, 0, 0},
-  {VCCellularProp, 0, 0, 0},
-  {VCCGMProp, 0, 0, 0},
-  {VCCharSetProp, 0, 0, 0},
-  {VCCIDProp, VCContentIDProp, 0, 0},
-  {VCCISProp, 0, 0, 0},
-  {VCCityProp, 0, 0, 0},
-  {VCClassProp, 0, 0, 0},
-  {VCCommentProp, 0, 0, 0},
-  {VCCompletedProp, 0, 0, 0},
-  {VCContentIDProp, 0, 0, 0},
-  {VCCountryNameProp, 0, 0, 0},
-  {VCDAlarmProp, 0, DAlarmFields, 0},
-  {VCDataSizeProp, 0, 0, PD_INTERNAL},
-  {VCDayLightProp, 0, 0, 0},
-  {VCDCreatedProp, 0, 0, 0},
-  {VCDeliveryLabelProp, 0, 0, 0},
-  {VCDescriptionProp, 0, 0, 0},
-  {VCDIBProp, 0, 0, 0},
-  {VCDisplayStringProp, 0, 0, 0},
-  {VCDomesticProp, 0, 0, 0},
-  {VCDTendProp, 0, 0, 0},
-  {VCDTstartProp, 0, 0, 0},
-  {VCDueProp, 0, 0, 0},
-  {VCEmailAddressProp, 0, 0, 0},
-  {VCEncodingProp, 0, 0, 0},
-  {VCEndProp, 0, 0, 0},
-  {VCEventProp, 0, 0, PD_BEGIN},
-  {VCEWorldProp, 0, 0, 0},
-  {VCExNumProp, 0, 0, 0},
-  {VCExpDateProp, 0, 0, 0},
-  {VCExpectProp, 0, 0, 0},
-  {VCExtAddressProp, 0, 0, 0},
-  {VCFamilyNameProp, 0, 0, 0},
-  {VCFaxProp, 0, 0, 0},
-  {VCFullNameProp, 0, fnFields, 0},
-  {VCGeoLocationProp, 0, 0, 0},
-  {VCGeoProp, 0, 0, 0},
-  {VCGIFProp, 0, 0, 0},
-  {VCGivenNameProp, 0, 0, 0},
-  {VCGroupingProp, 0, 0, 0},
-  {VCHomeProp, 0, 0, 0},
-  {VCIBMMailProp, 0, 0, 0},
-  {VCInlineProp, 0, 0, 0},
-  {VCInternationalProp, 0, 0, 0},
-  {VCInternetProp, 0, 0, 0},
-  {VCISDNProp, 0, 0, 0},
-  {VCJPEGProp, 0, 0, 0},
-  {VCLanguageProp, 0, 0, 0},
-  {VCLastModifiedProp, 0, 0, 0},
-  {VCLastRevisedProp, 0, 0, 0},
-  {VCLocationProp, 0, 0, 0},
-  {VCLogoProp, 0, 0, 0},
-  {VCMailerProp, 0, 0, 0},
-  {VCMAlarmProp, 0, MAlarmFields, 0},
-  {VCMCIMailProp, 0, 0, 0},
-  {VCMessageProp, 0, 0, 0},
-  {VCMETProp, 0, 0, 0},
-  {VCModemProp, 0, 0, 0},
-  {VCMPEG2Prop, 0, 0, 0},
-  {VCMPEGProp, 0, 0, 0},
-  {VCMSNProp, 0, 0, 0},
-  {VCNamePrefixesProp, 0, 0, 0},
-  {VCNameProp, 0, nameFields, 0},
-  {VCNameSuffixesProp, 0, 0, 0},
-  {VCNoteProp, 0, 0, 0},
-  {VCOrgNameProp, 0, 0, 0},
-  {VCOrgProp, 0, orgFields, 0},
-  {VCOrgUnit2Prop, 0, 0, 0},
-  {VCOrgUnit3Prop, 0, 0, 0},
-  {VCOrgUnit4Prop, 0, 0, 0},
-  {VCOrgUnitProp, 0, 0, 0},
-  {VCPagerProp, 0, 0, 0},
-  {VCPAlarmProp, 0, PAlarmFields, 0},
-  {VCParcelProp, 0, 0, 0},
-  {VCPartProp, 0, 0, 0},
-  {VCPCMProp, 0, 0, 0},
-  {VCPDFProp, 0, 0, 0},
-  {VCPGPProp, 0, 0, 0},
-  {VCPhotoProp, 0, 0, 0},
-  {VCPICTProp, 0, 0, 0},
-  {VCPMBProp, 0, 0, 0},
-  {VCPostalBoxProp, 0, 0, 0},
-  {VCPostalCodeProp, 0, 0, 0},
-  {VCPostalProp, 0, 0, 0},
-  {VCPowerShareProp, 0, 0, 0},
-  {VCPreferredProp, 0, 0, 0},
-  {VCPriorityProp, 0, 0, 0},
-  {VCProcedureNameProp, 0, 0, 0},
-  {VCProdIdProp, 0, 0, 0},
-  {VCProdigyProp, 0, 0, 0},
-  {VCPronunciationProp, 0, 0, 0},
-  {VCPSProp, 0, 0, 0},
-  {VCPublicKeyProp, 0, 0, 0},
-  {VCQPProp, VCQuotedPrintableProp, 0, 0},
-  {VCQuickTimeProp, 0, 0, 0},
-  {VCQuotedPrintableProp, 0, 0, 0},
-  {VCRDateProp, 0, 0, 0},
-  {VCRegionProp, 0, 0, 0},
-  {VCRelatedToProp, 0, 0, 0},
-  {VCRepeatCountProp, 0, 0, 0},
-  {VCResourcesProp, 0, 0, 0},
-  {VCRNumProp, 0, 0, 0},
-  {VCRoleProp, 0, 0, 0},
-  {VCRRuleProp, 0, 0, 0},
-  {VCRSVPProp, 0, 0, 0},
-  {VCRunTimeProp, 0, 0, 0},
-  {VCSequenceProp, 0, 0, 0},
-  {VCSnoozeTimeProp, 0, 0, 0},
-  {VCStartProp, 0, 0, 0},
-  {VCStatusProp, 0, 0, 0},
-  {VCStreetAddressProp, 0, 0, 0},
-  {VCSubTypeProp, 0, 0, 0},
-  {VCSummaryProp, 0, 0, 0},
-  {VCTelephoneProp, 0, 0, 0},
-  {VCTIFFProp, 0, 0, 0},
-  {VCTimeZoneProp, 0, 0, 0},
-  {VCTitleProp, 0, 0, 0},
-  {VCTLXProp, 0, 0, 0},
-  {VCTodoProp, 0, 0, PD_BEGIN},
-  {VCTranspProp, 0, 0, 0},
-  {VCUniqueStringProp, 0, 0, 0},
-  {VCURLProp, 0, 0, 0},
-  {VCURLValueProp, 0, 0, 0},
-  {VCValueProp, 0, 0, 0},
-  {VCVersionProp, 0, 0, 0},
-  {VCVideoProp, 0, 0, 0},
-  {VCVoiceProp, 0, 0, 0},
-  {VCWAVEProp, 0, 0, 0},
-  {VCWMFProp, 0, 0, 0},
-  {VCWorkProp, 0, 0, 0},
-  {VCX400Prop, 0, 0, 0},
-  {VCX509Prop, 0, 0, 0},
-  {VCXRuleProp, 0, 0, 0},
-  {VCCooltalk, 0, coolTalkFields, 0},
-  {VCCooltalkAddress, 0, 0, 0},
-  {VCUseServer, 0, 0, 0},
-  {VCUseHTML, 0, 0, 0},
-  {0, 0, 0, 0}
-};
-// clang-format on
-
-static struct PreDefProp *lookupPropInfo(const char *str) {
-  /* brute force for now, could use a hash table here. */
-  int i;
-
-  for (i = 0; propNames[i].name; i++)
-    if (PL_strcasecmp(str, propNames[i].name) == 0) {
-      return &propNames[i];
-    }
-
-  return 0;
-}
-
-const char *lookupProp_(const char *str) {
-  int i;
-
-  for (i = 0; propNames[i].name; i++)
-    if (PL_strcasecmp(str, propNames[i].name) == 0) {
-      const char *s;
-      s = propNames[i].alias ? propNames[i].alias : propNames[i].name;
-      return lookupStr(s);
-    }
-  return lookupStr(str);
-}
-
-const char *lookupProp(const char *str) {
-  int i;
-
-  for (i = 0; propNames[i].name; i++)
-    if (PL_strcasecmp(str, propNames[i].name) == 0) {
-      const char *s;
-      fieldedProp = (char **)propNames[i].fields;
-      s = propNames[i].alias ? propNames[i].alias : propNames[i].name;
-      return lookupStr(s);
-    }
-  fieldedProp = 0;
-  return lookupStr(str);
-}
-
-/*----------------------------------------------------------------------
-  APIs to Output text form.
-  ----------------------------------------------------------------------*/
-#define OFILE_REALLOC_SIZE 256
-
-static void appendcOFile_(OFile *fp, char c) {
-  if (fp->fail) return;
-stuff:
-  if (fp->len + 1 < fp->limit) {
-    fp->s[fp->len] = c;
-    fp->len++;
-    return;
-  } else if (fp->alloc) {
-    fp->limit = fp->limit + OFILE_REALLOC_SIZE;
-    char *newBuf = (char *)PR_Realloc(fp->s, fp->limit);
-    if (newBuf) {
-      fp->s = newBuf;
-      goto stuff;
-    }
-  }
-  if (fp->alloc) PR_FREEIF(fp->s);
-  fp->s = 0;
-  fp->fail = 1;
-}
-
-static void appendcOFile(OFile *fp, char c) {
-  /* int i = 0; */
-  if (c == '\n') {
-    /* write out as <CR><LF> */
-    /* for (i = 0; i < LINEBREAK_LEN; i++)
-      appendcOFile_(fp,LINEBREAK [ i ]); */
-    appendcOFile_(fp, 0xd);
-    appendcOFile_(fp, 0xa);
-  } else
-    appendcOFile_(fp, c);
-}
-
-static void appendsOFile(OFile *fp, const char *s) {
-  int i, slen;
-  slen = PL_strlen(s);
-  for (i = 0; i < slen; i++) {
-    appendcOFile(fp, s[i]);
-  }
-}
-
-static void initMemOFile(OFile *fp, char *s, int len) {
-  fp->s = s;
-  fp->len = 0;
-  fp->limit = s ? len : 0;
-  fp->alloc = s ? 0 : 1;
-  fp->fail = 0;
-}
-
-static int writeBase64(OFile *fp, unsigned char *s, long len) {
-  long cur = 0;
-  int i, numQuads = 0;
-  unsigned long trip;
-  unsigned char b;
-  char quad[5];
-#define PR_MAXQUADS 16
-
-  quad[4] = 0;
-
-  while (cur < len) {
-    /* collect the triplet of bytes into 'trip' */
-    trip = 0;
-    for (i = 0; i < 3; i++) {
-      b = (cur < len) ? *(s + cur) : 0;
-      cur++;
-      trip = trip << 8 | b;
-    }
-    /* fill in 'quad' with the appropriate four characters */
-    for (i = 3; i >= 0; i--) {
-      b = (unsigned char)(trip & 0x3F);
-      trip = trip >> 6;
-      if ((3 - i) < (cur - len))
-        quad[i] = '='; /* pad char */
-      else if (b < 26)
-        quad[i] = (char)b + 'A';
-      else if (b < 52)
-        quad[i] = (char)(b - 26) + 'a';
-      else if (b < 62)
-        quad[i] = (char)(b - 52) + '0';
-      else if (b == 62)
-        quad[i] = '+';
-      else
-        quad[i] = '/';
-    }
-    /* now output 'quad' with appropriate whitespace and line ending */
-    appendsOFile(fp, (numQuads == 0 ? "    " : ""));
-    appendsOFile(fp, quad);
-    appendsOFile(
-        fp, ((cur >= len) ? "\n" : (numQuads == PR_MAXQUADS - 1 ? "\n" : "")));
-    numQuads = (numQuads + 1) % PR_MAXQUADS;
-  }
-  appendcOFile(fp, '\n');
-
-  return 1;
-}
-
-static void writeQPString(OFile *fp, const char *s) {
-  const unsigned char *p = (const unsigned char *)s;
-  int current_column = 0;
-  static const char hexdigits[] = "0123456789ABCDEF";
-  bool white = false;
-  bool contWhite = false;
-  bool mb_p = false;
-
-  if (needsQuotedPrintable(s)) {
-    while (*p) {
-      if (*p == '\r' || *p == '\n') {
-        /* Whitespace cannot be allowed to occur at the end of the line.
-           So we encode " \n" as " =\n\n", that is, the whitespace, a
-           soft line break, and then a hard line break.
-         */
-
-        if (white) {
-          appendcOFile(fp, '=');
-          appendcOFile(fp, '\n');
-          appendcOFile(fp, '\t');
-          appendsOFile(fp, "=0D");
-          appendsOFile(fp, "=0A");
-          appendcOFile(fp, '=');
-          appendcOFile(fp, '\n');
-          appendcOFile(fp, '\t');
-        } else {
-          appendsOFile(fp, "=0D");
-          appendsOFile(fp, "=0A");
-          appendcOFile(fp, '=');
-          appendcOFile(fp, '\n');
-          appendcOFile(fp, '\t');
-          contWhite = false;
-        }
-
-        /* If its CRLF, swallow two chars instead of one. */
-        if (*p == '\r' && *(p + 1) == '\n') p++;
-        white = false;
-        current_column = 0;
-      } else {
-        if ((*p >= 33 && *p <= 60) || /* safe printing chars */
-            (*p >= 62 && *p <= 126) ||
-            (mb_p && (*p == 61 || *p == 127 || *p == 0x1B))) {
-          appendcOFile(fp, *p);
-          current_column++;
-          white = false;
-          contWhite = false;
-        } else if (*p == ' ' || *p == '\t') /* whitespace */
-        {
-          if (contWhite) {
-            appendcOFile(fp, '=');
-            appendcOFile(fp, hexdigits[*p >> 4]);
-            appendcOFile(fp, hexdigits[*p & 0xF]);
-            current_column += 3;
-            contWhite = false;
-          } else {
-            appendcOFile(fp, *p);
-            current_column++;
-          }
-          white = true;
-        } else /* print as =FF */
-        {
-          appendcOFile(fp, '=');
-          appendcOFile(fp, hexdigits[*p >> 4]);
-          appendcOFile(fp, hexdigits[*p & 0xF]);
-          current_column += 3;
-          white = false;
-          contWhite = false;
-        }
-
-        NS_ASSERTION(
-            current_column <= 76,
-            "1.10 <rhp@netscape.com> 06 Jan 2000 08:01"); /* Hard limit required
-                                                             by spec */
-
-        if (current_column >= 73 ||
-            ((*(p + 1) == ' ') &&
-             (current_column + 3 >= 73))) /* soft line break: "=\r\n" */
-        {
-          appendcOFile(fp, '=');
-          appendcOFile(fp, '\n');
-          appendcOFile(fp, '\t');
-          current_column = 0;
-          if (white)
-            contWhite = true;
-          else
-            contWhite = false;
-          white = false;
-        }
-      }
-      p++;
-    } /* while */
-  }   /* if */
-  else {
-    while (*p) {
-      appendcOFile(fp, *p);
-      p++;
-    }
-  }
-}
-
-static void writeValue(OFile *fp, VObject *o, unsigned long size) {
-  if (o == 0) return;
-  switch (VALUE_TYPE(o)) {
-    case VCVT_USTRINGZ: {
-      char *s = fakeCString(USTRINGZ_VALUE_OF(o));
-      writeQPString(fp, s);
-      deleteString(s);
-      break;
-    }
-    case VCVT_STRINGZ: {
-      writeQPString(fp, STRINGZ_VALUE_OF(o));
-      break;
-    }
-    case VCVT_UINT: {
-      char buf[11];
-      sprintf(buf, "%u", INTEGER_VALUE_OF(o));
-      appendsOFile(fp, buf);
-      break;
-    }
-    case VCVT_ULONG: {
-      char buf[21];
-      sprintf(buf, "%lu", LONG_VALUE_OF(o));
-      appendsOFile(fp, buf);
-      break;
-    }
-    case VCVT_RAW: {
-      appendcOFile(fp, '\n');
-      writeBase64(fp, (unsigned char *)(ANY_VALUE_OF(o)), size);
-      break;
-    }
-    case VCVT_VOBJECT:
-      appendcOFile(fp, '\n');
-      writeVObject_(fp, VOBJECT_VALUE_OF(o));
-      break;
-  }
-}
-
-static void writeAttrValue(OFile *fp, VObject *o, int *length) {
-  int ilen = 0;
-  if (NAME_OF(o)) {
-    struct PreDefProp *pi;
-    pi = lookupPropInfo(NAME_OF(o));
-    if (pi && ((pi->flags & PD_INTERNAL) != 0)) return;
-    appendcOFile(fp, ';');
-    if (*length != -1) (*length)++;
-    appendsOFile(fp, NAME_OF(o));
-    if (*length != -1) (*length) += PL_strlen(NAME_OF(o));
-  } else {
-    appendcOFile(fp, ';');
-    (*length)++;
-  }
-  if (VALUE_TYPE(o)) {
-    appendcOFile(fp, '=');
-    if (*length != -1) {
-      (*length)++;
-      for (ilen = 0; ilen < MAXMOZPROPNAMESIZE - (*length); ilen++)
-        appendcOFile(fp, ' ');
-    }
-    writeValue(fp, o, 0);
-  }
-}
-
-static void writeGroup(OFile *fp, VObject *o) {
-  nsAutoCString buf(NAME_OF(o));
-
-  while ((o = isAPropertyOf(o, VCGroupingProp)) != 0) {
-    buf.InsertLiteral(".", 0);
-    buf.Insert(STRINGZ_VALUE_OF(o), 0);
-  }
-  appendsOFile(fp, buf.get());
-}
-
-static int inList(const char **list, const char *s) {
-  if (list == 0) return 0;
-  while (*list) {
-    if (PL_strcasecmp(*list, s) == 0) return 1;
-    list++;
-  }
-  return 0;
-}
-
-static void writeProp(OFile *fp, VObject *o) {
-  int length = -1;
-  // int ilen = 0;
-
-  if (NAME_OF(o)) {
-    struct PreDefProp *pi;
-    VObjectIterator t;
-    const char **fields_ = 0;
-    pi = lookupPropInfo(NAME_OF(o));
-    if (pi && ((pi->flags & PD_BEGIN) != 0)) {
-      writeVObject_(fp, o);
-      return;
-    }
-    if (isAPropertyOf(o, VCGroupingProp))
-      writeGroup(fp, o);
-    else
-      appendsOFile(fp, NAME_OF(o));
-    if (pi) fields_ = pi->fields;
-    initPropIterator(&t, o);
-    while (moreIteration(&t)) {
-      const char *s;
-      VObject *eachProp = nextVObject(&t);
-      s = NAME_OF(eachProp);
-      if (PL_strcasecmp(VCGroupingProp, s) && !inList(fields_, s))
-        writeAttrValue(fp, eachProp, &length);
-    }
-    if (fields_) {
-      int i = 0, n = 0;
-      const char **fields = fields_;
-      /* output prop as fields */
-      appendcOFile(fp, ':');
-      while (*fields) {
-        VObject *tt = isAPropertyOf(o, *fields);
-        i++;
-        if (tt) n = i;
-        fields++;
-      }
-      fields = fields_;
-      for (i = 0; i < n; i++) {
-        writeValue(fp, isAPropertyOf(o, *fields), 0);
-        fields++;
-        if (i < (n - 1)) appendcOFile(fp, ';');
-      }
-    }
-  }
-
-  if (VALUE_TYPE(o)) {
-    unsigned long size = 0;
-    VObject *p = isAPropertyOf(o, VCDataSizeProp);
-    if (p) size = LONG_VALUE_OF(p);
-    appendcOFile(fp, ':');
-    writeValue(fp, o, size);
-  }
-  appendcOFile(fp, '\n');
-}
-
-void writeVObject_(OFile *fp, VObject *o) {
-  // int ilen = 0;
-  if (NAME_OF(o)) {
-    struct PreDefProp *pi;
-    pi = lookupPropInfo(NAME_OF(o));
-
-    if (pi && ((pi->flags & PD_BEGIN) != 0)) {
-      VObjectIterator t;
-      const char *begin = NAME_OF(o);
-      appendsOFile(fp, "begin:");
-      appendsOFile(fp, begin);
-      appendcOFile(fp, '\n');
-      initPropIterator(&t, o);
-      while (moreIteration(&t)) {
-        VObject *eachProp = nextVObject(&t);
-        writeProp(fp, eachProp);
-      }
-      appendsOFile(fp, "end:");
-      appendsOFile(fp, begin);
-      appendsOFile(fp, "\n\n");
-    }
-  }
-}
-
-char *writeMemVObject(char *s, int *len, VObject *o) {
-  OFile ofp;
-  initMemOFile(&ofp, s, len ? *len : 0);
-  writeVObject_(&ofp, o);
-  if (len) *len = ofp.len;
-  appendcOFile(&ofp, 0);
-  return ofp.s;
-}
-
-extern "C" char *writeMemoryVObjects(char *s, int *len, VObject *list,
-                                     bool expandSpaces) {
-  OFile ofp;
-  initMemOFile(&ofp, s, len ? *len : 0);
-  while (list) {
-    writeVObject_(&ofp, list);
-    list = nextVObjectInList(list);
-  }
-  if (len) *len = ofp.len;
-  appendcOFile(&ofp, 0);
-  return ofp.s;
-}
-
-/*----------------------------------------------------------------------
-  APIs to do fake Unicode stuff.
-  ----------------------------------------------------------------------*/
-vwchar_t *fakeUnicode(const char *ps, int *bytes) {
-  vwchar_t *r, *pw;
-  int len = strlen(ps) + 1;
-
-  pw = r = (vwchar_t *)PR_CALLOC(sizeof(vwchar_t) * len);
-  if (bytes) *bytes = len * sizeof(vwchar_t);
-
-  while (*ps) {
-    if (*ps == '\n')
-      *pw = (vwchar_t)0x2028;
-    else if (*ps == '\r')
-      *pw = (vwchar_t)0x2029;
-    else
-      *pw = (vwchar_t)(unsigned char)*ps;
-    ps++;
-    pw++;
-  }
-  *pw = (vwchar_t)0;
-
-  return r;
-}
-
-int uStrLen(const vwchar_t *u) {
-  if (!u) return 0;
-  int i = 0;
-  while (*u != (vwchar_t)0) {
-    u++;
-    i++;
-  }
-  return i;
-}
-
-char *fakeCString(const vwchar_t *u) {
-  char *s, *t;
-  int len = uStrLen(u) + 1;
-  t = s = (char *)PR_CALLOC(len);
-  if (u) {
-    while (*u) {
-      if (*u == (vwchar_t)0x2028)
-        *t = '\n';
-      else if (*u == (vwchar_t)0x2029)
-        *t = '\r';
-      else
-        *t = (char)*u;
-      u++;
-      t++;
-    }
-  }
-  *t = 0;
-  return s;
-}
-
-const char *lookupStr(const char *s) {
-  StrItem *t;
-  unsigned int h = hashStr(s);
-  if ((t = strTbl[h]) != 0) {
-    do {
-      if (PL_strcasecmp(t->s, s) == 0) {
-        t->refCnt++;
-        return t->s;
-      }
-      t = t->next;
-    } while (t);
-  }
-  s = dupStr(s, 0);
-  strTbl[h] = newStrItem(s, strTbl[h]);
-  return s;
-}
deleted file mode 100644
--- a/mailnews/addrbook/src/nsVCardObj.h
+++ /dev/null
@@ -1,397 +0,0 @@
-/* -*- 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/. */
-/***************************************************************************
-(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
-Business Machines Corporation and Siemens Rolm Communications Inc.
-
-For purposes of this license notice, the term Licensors shall mean,
-collectively, Apple Computer, Inc., AT&T Corp., International
-Business Machines Corporation and Siemens Rolm Communications Inc.
-The term Licensor shall mean any of the Licensors.
-
-Subject to acceptance of the following conditions, permission is hereby
-granted by Licensors without the need for written agreement and without
-license or royalty fees, to use, copy, modify and distribute this
-software for any purpose.
-
-The above copyright notice and the following four paragraphs must be
-reproduced in all copies of this software and any software including
-this software.
-
-THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
-ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
-MODIFICATIONS.
-
-IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
-INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
-OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGE.
-
-EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.
-
-The software is provided with RESTRICTED RIGHTS.  Use, duplication, or
-disclosure by the government are subject to restrictions set forth in
-DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
-
-***************************************************************************/
-
-/*
-
-The vCard/vCalendar C interface is implemented in the set
-of files as follows:
-
-vcc.y, yacc source, and vcc.c, the yacc output you will use
-implements the core parser
-
-vobject.c implements an API that insulates the caller from
-the parser and changes in the vCard/vCalendar BNF
-
-port.h defines compilation environment dependent stuff
-
-vcc.h and vobject.h are header files for their .c counterparts
-
-vcaltmp.h and vcaltmp.c implement vCalendar "macro" functions
-which you may find useful.
-
-test.c is a standalone test driver that exercises some of
-the features of the APIs provided. Invoke test.exe on a
-VCARD/VCALENDAR input text file and you will see the pretty
-print output of the internal representation (this pretty print
-output should give you a good idea of how the internal
-representation looks like -- there is one such output in the
-following too). Also, a file with the .out suffix is generated
-to show that the internal representation can be written back
-in the original text format.
-
-For more information on this API see the readme.txt file
-which accompanied this distribution.
-
-  Also visit:
-
-    http://www.versit.com
-    http://www.ralden.com
-
-*/
-
-#ifndef __VOBJECT_H__
-#define __VOBJECT_H__ 1
-
-/*
-Unfortunately, on the Mac (and possibly other platforms) with our current,
-out-dated libraries (Plauger), |wchar_t| is defined incorrectly, which breaks
-vcards.
-
-We can't fix Plauger because it doesn't come with source. Later, when we
-upgrade to MSL, we can make this evil hack go away.  In the mean time,
-vcards are not allowed to use the (incorrectly defined) |wchar_t| type. Instead,
-they will use an appropriately defined local type |vwchar_t|.
-*/
-
-typedef wchar_t vwchar_t;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define VC7bitProp "7bit"
-#define VC8bitProp "8bit"
-#define VCAAlarmProp "aalarm"
-#define VCAdditionalNamesProp "addn"
-#define VCAdrProp "adr"
-#define VCAgentProp "agent"
-#define VCAIFFProp "aiff"
-#define VCAOLProp "aol"
-#define VCAppleLinkProp "applelink"
-#define VCAttachProp "attach"
-#define VCAttendeeProp "attendee"
-#define VCATTMailProp "attmail"
-#define VCAudioContentProp "audiocontent"
-#define VCAVIProp "avi"
-#define VCBase64Prop "base64"
-#define VCBBSProp "bbs"
-#define VCBirthDateProp "bday"
-#define VCBMPProp "bmp"
-#define VCBodyProp "body"
-#define VCBusinessRoleProp "role"
-#define VCCalProp "vcalendar"
-#define VCCaptionProp "cap"
-#define VCCardProp "vcard"
-#define VCCarProp "car"
-#define VCCategoriesProp "categories"
-#define VCCellularProp "cell"
-#define VCCGMProp "cgm"
-#define VCCharSetProp "cs"
-#define VCCIDProp "cid"
-#define VCCISProp "cis"
-#define VCCityProp "l"
-#define VCClassProp "class"
-#define VCCommentProp "note"
-#define VCCompletedProp "completed"
-#define VCContentIDProp "content-id"
-#define VCCountryNameProp "c"
-#define VCDAlarmProp "dalarm"
-#define VCDataSizeProp "datasize"
-#define VCDayLightProp "daylight"
-#define VCDCreatedProp "dcreated"
-#define VCDeliveryLabelProp "label"
-#define VCDescriptionProp "description"
-#define VCDIBProp "dib"
-#define VCDisplayStringProp "displaystring"
-#define VCDomesticProp "dom"
-#define VCDTendProp "dtend"
-#define VCDTstartProp "dtstart"
-#define VCDueProp "due"
-#define VCEmailAddressProp "email"
-#define VCEncodingProp "encoding"
-#define VCEndProp "end"
-#define VCEventProp "vevent"
-#define VCEWorldProp "eworld"
-#define VCExNumProp "exnum"
-#define VCExpDateProp "exdate"
-#define VCExpectProp "expect"
-#define VCExtAddressProp "ext add"
-#define VCFamilyNameProp "f"
-#define VCFaxProp "fax"
-#define VCFullNameProp "fn"
-#define VCGeoProp "geo"
-#define VCGeoLocationProp "geo"
-#define VCGIFProp "gif"
-#define VCGivenNameProp "g"
-#define VCGroupingProp "grouping"
-#define VCHomeProp "home"
-#define VCIBMMailProp "ibmmail"
-#define VCInlineProp "inline"
-#define VCInternationalProp "intl"
-#define VCInternetProp "internet"
-#define VCISDNProp "isdn"
-#define VCJPEGProp "jpeg"
-#define VCLanguageProp "lang"
-#define VCLastModifiedProp "last-modified"
-#define VCLastRevisedProp "rev"
-#define VCLocationProp "location"
-#define VCLogoProp "logo"
-#define VCMailerProp "mailer"
-#define VCMAlarmProp "malarm"
-#define VCMCIMailProp "mcimail"
-#define VCMessageProp "msg"
-#define VCMETProp "met"
-#define VCModemProp "modem"
-#define VCMPEG2Prop "mpeg2"
-#define VCMPEGProp "mpeg"
-#define VCMSNProp "msn"
-#define VCNamePrefixesProp "npre"
-#define VCNameProp "n"
-#define VCNameSuffixesProp "nsuf"
-#define VCNoteProp "note"
-#define VCOrgNameProp "orgname"
-#define VCOrgProp "org"
-#define VCOrgUnit2Prop "oun2"
-#define VCOrgUnit3Prop "oun3"
-#define VCOrgUnit4Prop "oun4"
-#define VCOrgUnitProp "oun"
-#define VCPagerProp "pager"
-#define VCPAlarmProp "palarm"
-#define VCParcelProp "parcel"
-#define VCPartProp "part"
-#define VCPCMProp "pcm"
-#define VCPDFProp "pdf"
-#define VCPGPProp "pgp"
-#define VCPhotoProp "photo"
-#define VCPICTProp "pict"
-#define VCPMBProp "pmb"
-#define VCPostalBoxProp "box"
-#define VCPostalCodeProp "pc"
-#define VCPostalProp "postal"
-#define VCPowerShareProp "powershare"
-#define VCPreferredProp "pref"
-#define VCPriorityProp "priority"
-#define VCProcedureNameProp "procedurename"
-#define VCProdIdProp "prodid"
-#define VCProdigyProp "prodigy"
-#define VCPronunciationProp "sound"
-#define VCPSProp "ps"
-#define VCPublicKeyProp "key"
-#define VCQPProp "qp"
-#define VCQuickTimeProp "qtime"
-#define VCQuotedPrintableProp "quoted-printable"
-#define VCRDateProp "rdate"
-#define VCRegionProp "r"
-#define VCRelatedToProp "related-to"
-#define VCRepeatCountProp "repeatcount"
-#define VCResourcesProp "resources"
-#define VCRNumProp "rnum"
-#define VCRoleProp "role"
-#define VCRRuleProp "rrule"
-#define VCRSVPProp "rsvp"
-#define VCRunTimeProp "runtime"
-#define VCSequenceProp "sequence"
-#define VCSnoozeTimeProp "snoozetime"
-#define VCStartProp "start"
-#define VCStatusProp "status"
-#define VCStreetAddressProp "street"
-#define VCSubTypeProp "subtype"
-#define VCSummaryProp "summary"
-#define VCTelephoneProp "tel"
-#define VCTIFFProp "tiff"
-#define VCTimeZoneProp "tz"
-#define VCTitleProp "title"
-#define VCTLXProp "tlx"
-#define VCTodoProp "vtodo"
-#define VCTranspProp "transp"
-#define VCUniqueStringProp "uid"
-#define VCURLProp "url"
-#define VCURLValueProp "urlval"
-#define VCValueProp "value"
-#define VCVersionProp "version"
-#define VCVideoProp "video"
-#define VCVoiceProp "voice"
-#define VCWAVEProp "wave"
-#define VCWMFProp "wmf"
-#define VCWorkProp "work"
-#define VCX400Prop "x400"
-#define VCX509Prop "x509"
-#define VCXRuleProp "xrule"
-#define VCCooltalk "x-mozilla-cpt"
-#define VCCooltalkAddress "x-moxilla-cpadr"
-#define VCUseServer "x-mozilla-cpsrv"
-#define VCUseHTML "x-mozilla-html"
-
-/* return type of vObjectValueType: */
-#define VCVT_NOVALUE 0
-/* if the VObject has no value associated with it. */
-#define VCVT_STRINGZ 1
-/* if the VObject has value set by setVObjectStringZValue. */
-#define VCVT_USTRINGZ 2
-/* if the VObject has value set by setVObjectUStringZValue. */
-#define VCVT_UINT 3
-/* if the VObject has value set by setVObjectIntegerValue. */
-#define VCVT_ULONG 4
-/* if the VObject has value set by setVObjectLongValue. */
-#define VCVT_RAW 5
-/* if the VObject has value set by setVObjectAnyValue. */
-#define VCVT_VOBJECT 6
-/* if the VObject has value set by setVObjectVObjectValue. */
-
-#define NAME_OF(o) o->id
-#define VALUE_TYPE(o) o->valType
-#define STRINGZ_VALUE_OF(o) o->val.strs
-#define USTRINGZ_VALUE_OF(o) o->val.ustrs
-#define INTEGER_VALUE_OF(o) o->val.i
-#define LONG_VALUE_OF(o) o->val.l
-#define ANY_VALUE_OF(o) o->val.any
-#define VOBJECT_VALUE_OF(o) o->val.vobj
-
-typedef struct VObject VObject;
-
-typedef union ValueItem {
-  const char *strs;
-  const vwchar_t *ustrs;
-  unsigned int i;
-  unsigned long l;
-  void *any;
-  VObject *vobj;
-} ValueItem;
-
-struct VObject {
-  VObject *next;
-  const char *id;
-  VObject *prop;
-  unsigned short valType;
-  ValueItem val;
-};
-
-typedef struct StrItem StrItem;
-
-struct StrItem {
-  StrItem *next;
-  const char *s;
-  unsigned int refCnt;
-};
-
-typedef struct OFile {
-  char *s;
-  int len;
-  int limit;
-  int alloc : 1;
-  int fail : 1;
-} OFile;
-
-typedef struct VObjectIterator {
-  VObject *start;
-  VObject *next;
-} VObjectIterator;
-
-VObject *newVObject(const char *id);
-void deleteVObject(VObject *p);
-char *dupStr(const char *s, unsigned int size);
-extern "C" void deleteString(char *p);
-void unUseStr(const char *s);
-
-void setVObjectName(VObject *o, const char *id);
-void setVObjectStringZValue(VObject *o, const char *s);
-void setVObjectStringZValue_(VObject *o, const char *s);
-void setVObjectUStringZValue(VObject *o, const vwchar_t *s);
-void setVObjectUStringZValue_(VObject *o, const vwchar_t *s);
-void setVObjectIntegerValue(VObject *o, unsigned int i);
-void setVObjectLongValue(VObject *o, unsigned long l);
-void setVObjectAnyValue(VObject *o, void *t);
-VObject *setValueWithSize(VObject *prop, void *val, unsigned int size);
-VObject *setValueWithSize_(VObject *prop, void *val, unsigned int size);
-
-const char *vObjectName(VObject *o);
-const char *vObjectStringZValue(VObject *o);
-const vwchar_t *vObjectUStringZValue(VObject *o);
-unsigned int vObjectIntegerValue(VObject *o);
-unsigned long vObjectLongValue(VObject *o);
-void *vObjectAnyValue(VObject *o);
-VObject *vObjectVObjectValue(VObject *o);
-void setVObjectVObjectValue(VObject *o, VObject *p);
-
-VObject *addVObjectProp(VObject *o, VObject *p);
-VObject *addProp(VObject *o, const char *id);
-VObject *addProp_(VObject *o, const char *id);
-VObject *addPropValue(VObject *o, const char *p, const char *v);
-VObject *addPropSizedValue_(VObject *o, const char *p, const char *v,
-                            unsigned int size);
-VObject *addPropSizedValue(VObject *o, const char *p, const char *v,
-                           unsigned int size);
-VObject *addGroup(VObject *o, const char *g);
-void addList(VObject **o, VObject *p);
-
-VObject *isAPropertyOf(VObject *o, const char *id);
-
-VObject *nextVObjectInList(VObject *o);
-void initPropIterator(VObjectIterator *i, VObject *o);
-int moreIteration(VObjectIterator *i);
-VObject *nextVObject(VObjectIterator *i);
-
-void writeVObject_(OFile *fp, VObject *o);
-char *writeMemVObject(char *s, int *len, VObject *o);
-extern "C" char *writeMemoryVObjects(char *s, int *len, VObject *list,
-                                     bool expandSpaces);
-
-const char *lookupStr(const char *s);
-
-void cleanVObject(VObject *o);
-void cleanVObjects(VObject *list);
-
-const char *lookupProp(const char *str);
-const char *lookupProp_(const char *str);
-
-vwchar_t *fakeUnicode(const char *ps, int *bytes);
-int uStrLen(const vwchar_t *u);
-char *fakeCString(const vwchar_t *u);
-
-#define MAXPROPNAMESIZE 256
-#define MAXMOZPROPNAMESIZE 16
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __VOBJECT_H__ */
--- a/mailnews/addrbook/test/unit/data/export.vcf
+++ b/mailnews/addrbook/test/unit/data/export.vcf
@@ -1,16 +1,16 @@
-begin:vcard
-fn:contact number one
-n:one;contact
-email;internet:contact1@invalid
-version:2.1
-end:vcard
-
-begin:vcard
-fn:contact number two
-n:two;contact
-email;internet:contact2@invalid
-title:"worker"
-note;quoted-printable:here's some unicode text=E2=80=A6
-version:2.1
-end:vcard
-
+BEGIN:VCARD
+VERSION:4.0
+EMAIL:contact1@invalid
+FN:contact number one
+N:one;contact;;;
+UID:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+END:VCARD
+BEGIN:VCARD
+VERSION:4.0
+EMAIL:contact2@invalid
+FN:contact number two
+NOTE:here's some unicode text…
+TITLE:"worker"
+N:two;contact;;;
+UID:yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy
+END:VCARD
--- a/mailnews/addrbook/test/unit/test_bug387403.js
+++ b/mailnews/addrbook/test/unit/test_bug387403.js
@@ -1,14 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /**
  * Test for bug 387403 crash when opening e-mail with broken vcard.
  */
 
 function run_test() {
   // Before bug 387403 this would hang, eating up all the memory until it
   // crashed.
-  Cc["@mozilla.org/addressbook/msgvcardservice;1"]
-    .getService(Ci.nsIMsgVCardService)
-    .escapedVCardToAbCard(
-      "begin:vcard\nfn;quoted-printable:Xxxx=C5=82xx  Xxx\nn;quoted-printable:Xxx;Xxxx=C5=82xx \nadr;quoted-printable;quoted-printable;dom:;;xx. Xxxxxxxxxxxx X;Xxxxxx=C3=3"
-    );
+  try {
+    Cc["@mozilla.org/addressbook/msgvcardservice;1"]
+      .getService(Ci.nsIMsgVCardService)
+      .escapedVCardToAbCard(
+        "begin:vcard\nfn;quoted-printable:Xxxx=C5=82xx  Xxx\nn;quoted-printable:Xxx;Xxxx=C5=82xx \nadr;quoted-printable;quoted-printable;dom:;;xx. Xxxxxxxxxxxx X;Xxxxxx=C3=3"
+      );
+  } catch (ex) {}
 }
--- a/mailnews/addrbook/test/unit/test_export.js
+++ b/mailnews/addrbook/test/unit/test_export.js
@@ -20,25 +20,27 @@ var { Services } = ChromeUtils.import("r
 
 add_task(async () => {
   let dirPrefId = MailServices.ab.newAddressBook("new book", "", 101);
   let book = MailServices.ab.getDirectoryFromId(dirPrefId);
 
   let contact1 = Cc["@mozilla.org/addressbook/cardproperty;1"].createInstance(
     Ci.nsIAbCard
   );
+  contact1.UID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
   contact1.displayName = "contact number one";
   contact1.firstName = "contact";
   contact1.lastName = "one";
   contact1.primaryEmail = "contact1@invalid";
   contact1 = book.addCard(contact1);
 
   let contact2 = Cc["@mozilla.org/addressbook/cardproperty;1"].createInstance(
     Ci.nsIAbCard
   );
+  contact2.UID = "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy";
   contact2.displayName = "contact number two";
   contact2.firstName = "contact";
   contact2.lastName = "two";
   contact2.primaryEmail = "contact2@invalid";
   contact2.setProperty("JobTitle", `"worker"`);
   contact2.setProperty("Custom1", "custom, 1");
   contact2.setProperty("Custom2", "custom\t2");
   contact2.setProperty("Custom3", "custom\r3");
--- a/mailnews/addrbook/test/unit/test_nsIAbCard.js
+++ b/mailnews/addrbook/test/unit/test_nsIAbCard.js
@@ -23,20 +23,65 @@ function run_test() {
       fullCard = tempCard;
     }
   }
 
   Assert.ok(fullCard != null);
 
   // Test - VCard.
 
-  Assert.equal(
-    fullCard.translateTo("vcard"),
-    "begin%3Avcard%0D%0Afn%3ADisplayName1%0D%0An%3ALastName1%3BFirstName1%0D%0Aorg%3AOrganization1%3BDepartment1%0D%0Aadr%3AWorkAddress21%3B%3BWorkAddress1%3BWorkCity1%3BWorkState1%3BWorkZipCode1%3BWorkCountry1%0D%0Aemail%3Binternet%3APrimaryEmail1%40test.invalid%0D%0Atitle%3AJobTitle1%0D%0Atel%3Bwork%3AWorkPhone1%0D%0Atel%3Bfax%3AFaxNumber1%0D%0Atel%3Bpager%3APagerNumber1%0D%0Atel%3Bhome%3AHomePhone1%0D%0Atel%3Bcell%3ACellularNumber1%0D%0Anote%3ANotes1%0D%0Aurl%3Ahttp%3A//WebPage21%0D%0Aversion%3A2.1%0D%0Aend%3Avcard%0D%0A%0D%0A"
+  let actual = fullCard.translateTo("vcard");
+  Assert.ok(actual.startsWith("BEGIN%3AVCARD%0D%0A"));
+  Assert.ok(actual.endsWith("%0D%0AEND%3AVCARD%0D%0A"));
+
+  let lines = decodeURIComponent(actual).split("\r\n");
+  // The theory, the lines of the vCard are valid in any order, so just check
+  // that they exist. In practice they are in this order.
+  Assert.ok(lines.includes("EMAIL:PrimaryEmail1@test.invalid"), "EMAIL");
+  Assert.ok(lines.includes("FN:DisplayName1"), "FN");
+  Assert.ok(lines.includes("NICKNAME:NickName1"), "NICKNAME");
+  Assert.ok(lines.includes("NOTE:Notes1"), "NOTE");
+  Assert.ok(lines.includes("ORG:Organization1;Department1"), "ORG");
+  Assert.ok(lines.includes("TITLE:JobTitle1"), "TITLE");
+  Assert.ok(lines.includes("N:LastName1;FirstName1;;;"), "N");
+  // These two lines wrap. If the wrapping width changes, this test will break.
+  Assert.ok(
+    lines.includes(
+      "ADR;TYPE=home:;HomeAddress21;HomeAddress11;HomeCity1;HomeState1;HomeZipCode"
+    ),
+    "ADR;TYPE=home"
   );
+  Assert.ok(
+    lines.includes(
+      "ADR;TYPE=work:;WorkAddress21;WorkAddress1;WorkCity1;WorkState1;WorkZipCode1"
+    ),
+    "ADR;TYPE=work"
+  );
+  Assert.ok(
+    lines.includes("TEL;TYPE=home;VALUE=TEXT:HomePhone1"),
+    "TEL;TYPE=home"
+  );
+  Assert.ok(
+    lines.includes("TEL;TYPE=work;VALUE=TEXT:WorkPhone1"),
+    "TEL;TYPE=work"
+  );
+  Assert.ok(
+    lines.includes("TEL;TYPE=fax;VALUE=TEXT:FaxNumber1"),
+    "TEL;TYPE=fax"
+  );
+  Assert.ok(
+    lines.includes("TEL;TYPE=pager;VALUE=TEXT:PagerNumber1"),
+    "TEL;TYPE=pager"
+  );
+  Assert.ok(
+    lines.includes("TEL;TYPE=cell;VALUE=TEXT:CellularNumber1"),
+    "TEL;TYPE=cell"
+  );
+  Assert.ok(lines.includes("URL;VALUE=URL:http://WebPage21"), "URL");
+  Assert.ok(lines.includes("UID:fdcb9131-38ec-4daf-a4a7-2ef115f562a7"), "UID");
 
   // Test - XML
 
   // Bug 761304: Starting in TB 15, Thunderbird and SeaMonkey differ in how
   // they handle Chat / IM usernames. Unfortunately, it's not easy to multiplex
   // by appname here in XPCShell tests, so for now, we're going to make sure
   // the XML output matches what we expect from Thunderbird OR SeaMonkey. This
   // is obviously less than ideal, and we should fix this in a follow-up patch
--- a/mailnews/build/nsMailModule.cpp
+++ b/mailnews/build/nsMailModule.cpp
@@ -117,17 +117,16 @@
 #include "nsAbDirProperty.h"
 #include "nsAbAddressCollector.h"
 #include "nsAddbookProtocolHandler.h"
 #include "nsAddbookUrl.h"
 
 #include "nsAbDirectoryQuery.h"
 #include "nsAbBooleanExpression.h"
 #include "nsAbDirectoryQueryProxy.h"
-#include "nsMsgVCardService.h"
 #include "nsAbLDIFService.h"
 
 #include "nsAbLDAPDirectory.h"
 #include "nsAbLDAPDirectoryQuery.h"
 #include "nsAbLDAPReplicationService.h"
 #include "nsAbLDAPReplicationQuery.h"
 #include "nsAbLDAPReplicationData.h"
 
@@ -276,29 +275,25 @@
 #include "nsCMSSecureMessage.h"
 #include "nsCertPicker.h"
 #include "nsMsgSMIMECID.h"
 #include "nsMsgComposeSecure.h"
 #include "nsSMimeJSHelper.h"
 #include "nsEncryptedSMIMEURIsService.h"
 
 ///////////////////////////////////////////////////////////////////////////////
-// vcard includes
-///////////////////////////////////////////////////////////////////////////////
-#include "nsMimeContentTypeHandler.h"
-
-///////////////////////////////////////////////////////////////////////////////
 // FTS3 Tokenizer
 ///////////////////////////////////////////////////////////////////////////////
 #include "nsFts3TokenizerCID.h"
 #include "nsFts3Tokenizer.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // PGP/MIME includes
 ////////////////////////////////////////////////////////////////////////////////
+#include "nsMimeContentTypeHandler.h"
 #include "nsPgpMimeProxy.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // i18n includes
 ////////////////////////////////////////////////////////////////////////////////
 #include "nsCommUConvCID.h"
 
 #include "nsCharsetConverterManager.h"
@@ -441,17 +436,16 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbBoole
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbLDAPDirectory)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbLDAPDirectoryQuery)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbLDAPReplicationService)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbLDAPReplicationQuery)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbLDAPProcessReplicationData)
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbDirectoryQueryProxy)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgVCardService)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbLDIFService)
 
 #ifdef XP_MACOSX
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbOSXDirectory)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbOSXCard)
 #endif
 
 NS_DEFINE_NAMED_CID(NS_ADDRDATABASE_CID);
@@ -474,17 +468,16 @@ NS_DEFINE_NAMED_CID(NS_ABLDAPDIRECTORYQU
 NS_DEFINE_NAMED_CID(NS_ABLDAP_REPLICATIONSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_ABLDAP_REPLICATIONQUERY_CID);
 NS_DEFINE_NAMED_CID(NS_ABLDAP_PROCESSREPLICATIONDATA_CID);
 NS_DEFINE_NAMED_CID(NS_ABDIRECTORYQUERYPROXY_CID);
 #ifdef XP_MACOSX
 NS_DEFINE_NAMED_CID(NS_ABOSXDIRECTORY_CID);
 NS_DEFINE_NAMED_CID(NS_ABOSXCARD_CID);
 #endif
-NS_DEFINE_NAMED_CID(NS_MSGVCARDSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_ABLDIFSERVICE_CID);
 
 ////////////////////////////////////////////////////////////////////////////////
 // bayesian spam filter factories
 ////////////////////////////////////////////////////////////////////////////////
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsBayesianFilter, Init)
 
 NS_DEFINE_NAMED_CID(NS_BAYESIANFILTER_CID);
@@ -716,50 +709,16 @@ NS_DEFINE_NAMED_CID(NS_SMIMEJSJELPER_CID
 NS_DEFINE_NAMED_CID(NS_SMIMEENCRYPTURISERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_CMSDECODER_CID);
 NS_DEFINE_NAMED_CID(NS_CMSENCODER_CID);
 NS_DEFINE_NAMED_CID(NS_CMSMESSAGE_CID);
 NS_DEFINE_NAMED_CID(NS_CMSSECUREMESSAGE_CID);
 NS_DEFINE_NAMED_CID(NS_CERT_PICKER_CID);
 
 ////////////////////////////////////////////////////////////////////////////////
-// vcard factories
-////////////////////////////////////////////////////////////////////////////////
-
-NS_DEFINE_NAMED_CID(NS_VCARD_CONTENT_TYPE_HANDLER_CID);
-
-// XXX this vcard stuff needs cleaned up to use a generic factory constructor
-extern "C" MimeObjectClass *MIME_VCardCreateContentTypeHandlerClass(
-    const char *content_type, contentTypeHandlerInitStruct *initStruct);
-
-static nsresult nsVCardMimeContentTypeHandlerConstructor(nsISupports *aOuter,
-                                                         REFNSIID aIID,
-                                                         void **aResult) {
-  nsresult rv;
-  nsMimeContentTypeHandler *inst = nullptr;
-
-  if (NULL == aResult) {
-    rv = NS_ERROR_NULL_POINTER;
-    return rv;
-  }
-  *aResult = NULL;
-  if (NULL != aOuter) {
-    rv = NS_ERROR_NO_AGGREGATION;
-    return rv;
-  }
-
-  NS_ADDREF(inst = new nsMimeContentTypeHandler(
-                "text/x-vcard", &MIME_VCardCreateContentTypeHandlerClass));
-  rv = inst->QueryInterface(aIID, aResult);
-  NS_RELEASE(inst);
-
-  return rv;
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // PGP/MIME factories
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPgpMimeProxy, Init)
 
 NS_DEFINE_NAMED_CID(NS_PGPMIMEPROXY_CID);
 
 NS_DEFINE_NAMED_CID(NS_PGPMIME_CONTENT_TYPE_HANDLER_CID);
@@ -891,17 +850,16 @@ const mozilla::Module::CIDEntry kMailNew
     {&kNS_ABLDAP_PROCESSREPLICATIONDATA_CID, false, NULL,
      nsAbLDAPProcessReplicationDataConstructor},
     {&kNS_ABDIRECTORYQUERYPROXY_CID, false, NULL,
      nsAbDirectoryQueryProxyConstructor},
 #ifdef XP_MACOSX
     {&kNS_ABOSXDIRECTORY_CID, false, NULL, nsAbOSXDirectoryConstructor},
     {&kNS_ABOSXCARD_CID, false, NULL, nsAbOSXCardConstructor},
 #endif
-    {&kNS_MSGVCARDSERVICE_CID, false, NULL, nsMsgVCardServiceConstructor},
     {&kNS_ABLDIFSERVICE_CID, false, NULL, nsAbLDIFServiceConstructor},
     // Bayesian Filter Entries
     {&kNS_BAYESIANFILTER_CID, false, NULL, nsBayesianFilterConstructor},
     // Compose Entries
     {&kNS_MSGCOMPOSE_CID, false, NULL, nsMsgComposeConstructor},
     {&kNS_MSGCOMPOSESERVICE_CID, false, NULL, nsMsgComposeServiceConstructor},
     {&kNS_MSGCOMPOSECONTENTHANDLER_CID, false, NULL,
      nsMsgComposeContentHandlerConstructor},
@@ -1013,19 +971,16 @@ const mozilla::Module::CIDEntry kMailNew
     {&kNS_SMIMEJSJELPER_CID, false, NULL, nsSMimeJSHelperConstructor},
     {&kNS_SMIMEENCRYPTURISERVICE_CID, false, NULL,
      nsEncryptedSMIMEURIsServiceConstructor},
     {&kNS_CMSDECODER_CID, false, NULL, nsCMSDecoderConstructor},
     {&kNS_CMSENCODER_CID, false, NULL, nsCMSEncoderConstructor},
     {&kNS_CMSMESSAGE_CID, false, NULL, nsCMSMessageConstructor},
     {&kNS_CMSSECUREMESSAGE_CID, false, NULL, nsCMSSecureMessageConstructor},
     {&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},
     // Tokenizer Entries
@@ -1119,17 +1074,16 @@ const mozilla::Module::ContractIDEntry k
     {NS_ABLDAP_REPLICATIONQUERY_CONTRACTID, &kNS_ABLDAP_REPLICATIONQUERY_CID},
     {NS_ABLDAP_PROCESSREPLICATIONDATA_CONTRACTID,
      &kNS_ABLDAP_PROCESSREPLICATIONDATA_CID},
     {NS_ABDIRECTORYQUERYPROXY_CONTRACTID, &kNS_ABDIRECTORYQUERYPROXY_CID},
 #ifdef XP_MACOSX
     {NS_ABOSXDIRECTORY_CONTRACTID, &kNS_ABOSXDIRECTORY_CID},
     {NS_ABOSXCARD_CONTRACTID, &kNS_ABOSXCARD_CID},
 #endif
-    {NS_MSGVCARDSERVICE_CONTRACTID, &kNS_MSGVCARDSERVICE_CID},
     {NS_ABLDIFSERVICE_CONTRACTID, &kNS_ABLDIFSERVICE_CID},
     // Bayesian Filter Entries
     {NS_BAYESIANFILTER_CONTRACTID, &kNS_BAYESIANFILTER_CID},
     // Compose Entries
     {NS_MSGCOMPOSE_CONTRACTID, &kNS_MSGCOMPOSE_CID},
     {NS_MSGCOMPOSESERVICE_CONTRACTID, &kNS_MSGCOMPOSESERVICE_CID},
     {NS_MSGCOMPOSESTARTUPHANDLER_CONTRACTID, &kNS_MSGCOMPOSESERVICE_CID},
     {NS_MSGCOMPOSECONTENTHANDLER_CONTRACTID, &kNS_MSGCOMPOSECONTENTHANDLER_CID},
@@ -1256,19 +1210,16 @@ const mozilla::Module::ContractIDEntry k
     {NS_SMIMEJSHELPER_CONTRACTID, &kNS_SMIMEJSJELPER_CID},
     {NS_SMIMEENCRYPTURISERVICE_CONTRACTID, &kNS_SMIMEENCRYPTURISERVICE_CID},
     {NS_CMSSECUREMESSAGE_CONTRACTID, &kNS_CMSSECUREMESSAGE_CID},
     {NS_CMSDECODER_CONTRACTID, &kNS_CMSDECODER_CID},
     {NS_CMSENCODER_CONTRACTID, &kNS_CMSENCODER_CID},
     {NS_CMSMESSAGE_CONTRACTID, &kNS_CMSMESSAGE_CID},
     {NS_CERTPICKDIALOGS_CONTRACTID, &kNS_CERT_PICKER_CID},
     {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},
     // Tokenizer Entries
     {NULL}};
--- a/mailnews/mime/cthandlers/moz.build
+++ b/mailnews/mime/cthandlers/moz.build
@@ -1,12 +1,11 @@
 # vim: set filetype=python:
 # 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/.
 
 # pgpmime depends on glue.
 DIRS += [
     'glue',
-    'vcard',
     'pgpmime',
 ]
 
deleted file mode 100644
--- a/mailnews/mime/cthandlers/vcard/mimevcrd.cpp
+++ /dev/null
@@ -1,367 +0,0 @@
-/* -*- 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/. */
-
-#include "mimevcrd.h"
-
-#include "mimecth.h"
-#include "mimexpcom.h"
-#include "nsIMsgVCardService.h"
-#include "nsINetUtil.h"
-#include "nsMsgUtils.h"
-#include "prmem.h"
-#include "prprf.h"
-#include "nsServiceManagerUtils.h"
-
-static int MimeInlineTextVCard_parse_line(const char *, int32_t, MimeObject *);
-static int MimeInlineTextVCard_parse_eof(MimeObject *, bool);
-static int MimeInlineTextVCard_parse_begin(MimeObject *obj);
-
-static int s_unique = 0;
-
-static int BeginVCard(MimeObject *obj);
-static int EndVCard(MimeObject *obj);
-static int WriteOutVCard(MimeObject *obj, VObject *v);
-
-static int GenerateVCardData(MimeObject *aMimeObj, VObject *aVcard);
-static int OutputVcardAttribute(MimeObject *aMimeObj, VObject *aVcard,
-                                const char *id, nsACString &vCardOutput);
-static int OutputBasicVcard(MimeObject *aMimeObj, VObject *aVcard,
-                            nsACString &vCardOutput);
-
-typedef struct {
-  const char *attributeName;
-  int resourceId;
-} AttributeName;
-
-#define kNumAttributes 12
-
-#define MSGVCARDSERVICE_CONTRACT_ID "@mozilla.org/addressbook/msgvcardservice;1"
-
-/* This is the object definition. Note: we will set the superclass
-   to NULL and manually set this on the class creation */
-MimeDefClass(MimeInlineTextVCard, MimeInlineTextVCardClass,
-             mimeInlineTextVCardClass, NULL);
-
-extern "C" MimeObjectClass *MIME_VCardCreateContentTypeHandlerClass(
-    const char *content_type, contentTypeHandlerInitStruct *initStruct) {
-  MimeObjectClass *clazz = (MimeObjectClass *)&mimeInlineTextVCardClass;
-  /*
-   * Must set the superclass by hand.
-   */
-  if (!COM_GetmimeInlineTextClass()) return NULL;
-
-  clazz->superclass = (MimeObjectClass *)COM_GetmimeInlineTextClass();
-  initStruct->force_inline_display = true;
-  return clazz;
-}
-
-/*
- * Implementation of VCard clazz
- */
-static int MimeInlineTextVCardClassInitialize(MimeInlineTextVCardClass *clazz) {
-  MimeObjectClass *oclass = (MimeObjectClass *)clazz;
-  NS_ASSERTION(!oclass->class_initialized,
-               "1.1 <rhp@netscape.com> 19 Mar 1999 12:11");
-  oclass->parse_begin = MimeInlineTextVCard_parse_begin;
-  oclass->parse_line = MimeInlineTextVCard_parse_line;
-  oclass->parse_eof = MimeInlineTextVCard_parse_eof;
-  return 0;
-}
-
-static int MimeInlineTextVCard_parse_begin(MimeObject *obj) {
-  int status = ((MimeObjectClass *)COM_GetmimeLeafClass())->parse_begin(obj);
-  MimeInlineTextVCardClass *clazz;
-  if (status < 0) return status;
-
-  if (!obj->output_p) return 0;
-  if (!obj->options || !obj->options->write_html_p) return 0;
-
-  /* This is a fine place to write out any HTML before the real meat begins.
-  In this sample code, we tell it to start a table. */
-
-  clazz = ((MimeInlineTextVCardClass *)obj->clazz);
-  /* initialize vcard string to empty; */
-  NS_MsgSACopy(&(clazz->vCardString), "");
-
-  obj->options->state->separator_suppressed_p = true;
-  return 0;
-}
-
-char *strcpySafe(char *dest, const char *src, size_t destLength) {
-  char *result = strncpy(dest, src, --destLength);
-  dest[destLength] = '\0';
-  return result;
-}
-
-static int MimeInlineTextVCard_parse_line(const char *line, int32_t length,
-                                          MimeObject *obj) {
-  // This routine gets fed each line of data, one at a time.
-  char *linestring;
-  MimeInlineTextVCardClass *clazz = ((MimeInlineTextVCardClass *)obj->clazz);
-
-  if (!obj->output_p) return 0;
-  if (!obj->options || !obj->options->output_fn) return 0;
-  if (!obj->options->write_html_p) {
-    return COM_MimeObject_write(obj, line, length, true);
-  }
-
-  linestring = (char *)PR_MALLOC(length + 1);
-  memset(linestring, 0, (length + 1));
-
-  if (linestring) {
-    strcpySafe((char *)linestring, line, length + 1);
-    NS_MsgSACat(&clazz->vCardString, linestring);
-    PR_Free(linestring);
-  }
-
-  return 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-static int MimeInlineTextVCard_parse_eof(MimeObject *obj, bool abort_p) {
-  nsCOMPtr<nsIMsgVCardService> vCardService =
-      do_GetService(MSGVCARDSERVICE_CONTRACT_ID);
-  if (!vCardService) return -1;
-
-  int status = 0;
-  MimeInlineTextVCardClass *clazz = ((MimeInlineTextVCardClass *)obj->clazz);
-
-  VObject *t, *v;
-
-  if (obj->closed_p) return 0;
-
-  /* Run parent method first, to flush out any buffered data. */
-  //    status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(obj, abort_p);
-  status = ((MimeObjectClass *)COM_GetmimeInlineTextClass())
-               ->parse_eof(obj, abort_p);
-  if (status < 0) return status;
-
-  // Don't quote vCards...
-  if ((obj->options) &&
-      ((obj->options->format_out == nsMimeOutput::nsMimeMessageQuoting) ||
-       (obj->options->format_out == nsMimeOutput::nsMimeMessageBodyQuoting)))
-    return 0;
-
-  if (!clazz->vCardString) return 0;
-
-  v = vCardService->Parse_MIME(clazz->vCardString, strlen(clazz->vCardString));
-  NS_ASSERTION(v, "parse of vCard failed");
-
-  if (clazz->vCardString) {
-    PR_Free((char *)clazz->vCardString);
-    clazz->vCardString = NULL;
-  }
-
-  if (obj->output_p && obj->options && obj->options->write_html_p &&
-      obj->options->headers != MimeHeadersCitation) {
-    /* This is a fine place to write any closing HTML.  In fact, you may
-    want all the writing to be here, and all of the above would just
-    collect data into datastructures, though that isn't very
-    "streaming". */
-    t = v;
-    while (v && status >= 0) {
-      /* write out html */
-      status = WriteOutVCard(obj, v);
-      /* parse next vcard in case they're embedded */
-      v = vCardService->NextVObjectInList(v);
-    }
-
-    (void)vCardService->CleanVObject(t);
-  }
-
-  if (status < 0) return status;
-
-  return 0;
-}
-
-static int EndVCard(MimeObject *obj) {
-  int status = 0;
-
-  /* Scribble HTML-ending stuff into the stream */
-  char htmlFooters[32];
-  PR_snprintf(htmlFooters, sizeof(htmlFooters), "</BODY>%s</HTML>%s",
-              MSG_LINEBREAK, MSG_LINEBREAK);
-  status = COM_MimeObject_write(obj, htmlFooters, strlen(htmlFooters), false);
-
-  if (status < 0) return status;
-
-  return 0;
-}
-
-static int BeginVCard(MimeObject *obj) {
-  int status = 0;
-
-  /* Scribble HTML-starting stuff into the stream */
-  char htmlHeaders[32];
-
-  s_unique++;
-  PR_snprintf(htmlHeaders, sizeof(htmlHeaders), "<HTML>%s<BODY>%s",
-              MSG_LINEBREAK, MSG_LINEBREAK);
-  status = COM_MimeObject_write(obj, htmlHeaders, strlen(htmlHeaders), true);
-
-  if (status < 0) return status;
-
-  return 0;
-}
-
-static int WriteOutVCard(MimeObject *aMimeObj, VObject *aVcard) {
-  BeginVCard(aMimeObj);
-
-  GenerateVCardData(aMimeObj, aVcard);
-
-  return EndVCard(aMimeObj);
-}
-
-static int GenerateVCardData(MimeObject *aMimeObj, VObject *aVcard) {
-  // style is driven from CSS not here. Just layout the minimal vCard data
-  nsCString vCardOutput;
-
-  vCardOutput =
-      "<table class=\"moz-vcard-table\"> <tr> ";  // outer table plus the first
-                                                  // (and only row) we use for
-                                                  // this table
-
-  // we need to get an escaped vCard url to bind to our add to address book
-  // button
-  nsCOMPtr<nsIMsgVCardService> vCardService =
-      do_GetService(MSGVCARDSERVICE_CONTRACT_ID);
-  if (!vCardService) return -1;
-
-  nsAutoCString vCard;
-  nsAutoCString vEscCard;
-  int len = 0;
-
-  vCard.Adopt(vCardService->WriteMemoryVObjects(0, &len, aVcard, false));
-  MsgEscapeString(vCard, nsINetUtil::ESCAPE_XALPHAS, vEscCard);
-
-  // first cell in the outer table row is a clickable image which brings up the
-  // rich address book UI for the vcard
-  vCardOutput +=
-      "<td valign=\"top\"> <a class=\"moz-vcard-badge\" "
-      "href=\"addbook:add?action=add?vcard=";
-  vCardOutput += vEscCard;  // the href is the vCard
-  vCardOutput += "\"></a></td>";
-
-  // the 2nd cell in the outer table row is a nested table containing the actual
-  // vCard properties
-  vCardOutput += "<td> <table id=\"moz-vcard-properties-table\"> <tr> ";
-
-  OutputBasicVcard(aMimeObj, aVcard, vCardOutput);
-
-  // close the properties table
-  vCardOutput += "</table> </td> ";
-
-  // 2nd  cell in the outer table is our vCard image
-
-  vCardOutput += "</tr> </table>";
-
-  // now write out the vCard
-  return COM_MimeObject_write(aMimeObj, (char *)vCardOutput.get(),
-                              vCardOutput.Length(), true);
-}
-
-static int OutputBasicVcard(MimeObject *aMimeObj, VObject *aVcard,
-                            nsACString &vCardOutput) {
-  VObject *prop = NULL;
-  nsAutoCString urlstring;
-  nsAutoCString namestring;
-  nsAutoCString emailstring;
-
-  nsCOMPtr<nsIMsgVCardService> vCardService =
-      do_GetService(MSGVCARDSERVICE_CONTRACT_ID);
-  if (!vCardService) return -1;
-
-  // Get the name and email, the full name is stored as a field.
-  prop = vCardService->IsAPropertyOf(aVcard, VCFullNameProp);
-  if (prop) prop = vCardService->IsAPropertyOf(prop, VCFullNameProp);
-  if (prop) {
-    if (VALUE_TYPE(prop)) {
-      if (VALUE_TYPE(prop) != VCVT_RAW)
-        namestring.Adopt(vCardService->FakeCString(prop));
-      else
-        namestring.Adopt(vCardService->VObjectAnyValue(prop));
-
-      if (!namestring.IsEmpty()) {
-        vCardOutput += "<td class=\"moz-vcard-title-property\"> ";
-
-        prop = vCardService->IsAPropertyOf(aVcard, VCURLProp);
-        if (prop) {
-          urlstring.Adopt(vCardService->FakeCString(prop));
-          if (urlstring.IsEmpty())
-            vCardOutput += namestring;
-          else {
-            char buf[512];
-            PR_snprintf(buf, 512,
-                        "<a href="
-                        "%s"
-                        " private>%s</a>",
-                        urlstring.get(), namestring.get());
-            vCardOutput.Append(buf);
-          }
-        } else
-          vCardOutput += namestring;
-
-        /* get the email address */
-        prop = vCardService->IsAPropertyOf(aVcard, VCEmailAddressProp);
-        if (prop) {
-          emailstring.Adopt(vCardService->FakeCString(prop));
-          if (!emailstring.IsEmpty()) {
-            char buf[512];
-            PR_snprintf(buf, 512,
-                        "&nbsp;&lt;<a href="
-                        "mailto:%s"
-                        " private>%s</a>&gt;",
-                        emailstring.get(), emailstring.get());
-            vCardOutput.Append(buf);
-          }
-        }  // if email address property
-
-        vCardOutput +=
-            "</td> </tr> ";  // end the cell for the name/email address
-      }                      // if we have a name property
-    }
-  }  // if full name property
-
-  // now each basic property goes on its own line
-
-  // title
-  (void)OutputVcardAttribute(aMimeObj, aVcard, VCTitleProp, vCardOutput);
-
-  // org name and company name
-  prop = vCardService->IsAPropertyOf(aVcard, VCOrgProp);
-  if (prop) {
-    OutputVcardAttribute(aMimeObj, prop, VCOrgUnitProp, vCardOutput);
-    OutputVcardAttribute(aMimeObj, prop, VCOrgNameProp, vCardOutput);
-  }
-
-  return 0;
-}
-
-static int OutputVcardAttribute(MimeObject *aMimeObj, VObject *aVcard,
-                                const char *id, nsACString &vCardOutput) {
-  VObject *prop = NULL;
-  nsAutoCString string;
-
-  nsCOMPtr<nsIMsgVCardService> vCardService =
-      do_GetService(MSGVCARDSERVICE_CONTRACT_ID);
-  if (!vCardService) return -1;
-
-  prop = vCardService->IsAPropertyOf(aVcard, id);
-  if (prop)
-    if (VALUE_TYPE(prop)) {
-      if (VALUE_TYPE(prop) != VCVT_RAW)
-        string.Adopt(vCardService->FakeCString(prop));
-      else
-        string.Adopt(vCardService->VObjectAnyValue(prop));
-
-      if (!string.IsEmpty()) {
-        vCardOutput += "<tr> <td class=\"moz-vcard-property\">";
-        vCardOutput += string;
-        vCardOutput += "</td> </tr> ";
-      }
-    }
-
-  return 0;
-}
deleted file mode 100644
--- a/mailnews/mime/cthandlers/vcard/mimevcrd.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- 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 _MIMEVCRD_H_
-#define _MIMEVCRD_H_
-
-#include "mimetext.h"
-#include "nsCOMPtr.h"
-
-/* The MimeInlineTextHTML class implements the text/x-vcard and (maybe?
-   someday?) the application/directory MIME content types.
- */
-
-typedef struct MimeInlineTextVCardClass MimeInlineTextVCardClass;
-typedef struct MimeInlineTextVCard MimeInlineTextVCard;
-
-struct MimeInlineTextVCardClass {
-  MimeInlineTextClass text;
-  char *vCardString;
-};
-
-extern MimeInlineTextVCardClass mimeInlineTextVCardClass;
-
-struct MimeInlineTextVCard {
-  MimeInlineText text;
-};
-
-#define MimeInlineTextVCardClassInitializer(ITYPE, CSUPER) \
-  { MimeInlineTextClassInitializer(ITYPE, CSUPER) }
-
-#endif /* _MIMEVCRD_H_ */
deleted file mode 100644
--- a/mailnews/mime/cthandlers/vcard/moz.build
+++ /dev/null
@@ -1,14 +0,0 @@
-# vim: set filetype=python:
-# 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/.
-
-SOURCES += [
-    'mimevcrd.cpp',
-]
-
-FINAL_LIBRARY = 'mail'
-
-LOCAL_INCLUDES += [
-    '../glue',
-]