Bug 79709 - import vcards; r=Standard8 sr=bienvenu
authorEvan Stratford <evan.stratford@gmail.com>
Thu, 01 Apr 2010 19:28:46 -0400
changeset 6456 9021466c11d896096a6d83d0cbefcfe9e12c9b00
parent 6455 22f8aae0d6c84027f4a89a9d1b50bed3d8fa1502
child 6457 098388acf16b06ff5fa8d31a95f49365e8b9466f
push idunknown
push userunknown
push dateunknown
reviewersStandard8, bienvenu
bugs79709
Bug 79709 - import vcards; r=Standard8 sr=bienvenu
mail/locales/en-US/chrome/messenger/addressbook/addressBook.properties
mail/locales/en-US/chrome/messenger/importMsgs.properties
mail/locales/en-US/chrome/messenger/vCardImportMsgs.properties
mail/locales/jar.mn
mailnews/import/Makefile.in
mailnews/import/build/Makefile.in
mailnews/import/build/nsImportModule.cpp
mailnews/import/content/importDialog.js
mailnews/import/outlook/src/nsOutlookImport.cpp
mailnews/import/src/nsImportStringBundle.cpp
mailnews/import/src/nsImportStringBundle.h
mailnews/import/vcard/src/Makefile.in
mailnews/import/vcard/src/nsVCardAddress.cpp
mailnews/import/vcard/src/nsVCardAddress.h
mailnews/import/vcard/src/nsVCardImport.cpp
mailnews/import/vcard/src/nsVCardImport.h
mailnews/makefiles.sh
suite/locales/en-US/chrome/mailnews/addressbook/addressBook.properties
suite/locales/en-US/chrome/mailnews/importMsgs.properties
suite/locales/en-US/chrome/mailnews/vCardImportMsgs.properties
--- a/mail/locales/en-US/chrome/messenger/addressbook/addressBook.properties
+++ b/mail/locales/en-US/chrome/messenger/addressbook/addressBook.properties
@@ -150,16 +150,17 @@ invalidResults=Please enter a valid numb
 abReplicationOfflineWarning=You must be online to perform LDAP replication.
 abReplicationSaveSettings=Settings must be saved before a directory may be downloaded.
 
 # For importing / exporting
 ExportAddressBookTitle=Export Address Book
 LDIFFiles=LDIF
 CSVFiles=Comma Separated
 TABFiles=Tab Delimited
+VCFFiles=vCard
 failedToExportTitle=Export Failed
 failedToExportMessageNoDeviceSpace=Failed to export addressbook, no space left on device.
 failedToExportMessageFileAccessDenied=Failed to export addressbook, file access denied.
 
 # For getting authDN for replication using dlg box
 AuthDlgTitle=Address Book LDAP Replication
 AuthDlgDesc=To access the directory server, enter your user name and password.
 
--- a/mail/locales/en-US/chrome/messenger/importMsgs.properties
+++ b/mail/locales/en-US/chrome/messenger/importMsgs.properties
@@ -344,8 +344,11 @@ DefaultFolderName=Imported Mail
 # LOCALIZATION NOTE: Do not translate the word "%S" below.
 ImportModuleFolderName=%S Import
  
 # LOCALIZATION NOTE : "Communicator 4.x" is the used for previous versions of Netscape Communicator
 # Please translate using the brandname in respective languages for Netscape Communicator 4 releases.
 # strings profile dialog that comes up when importing mail from 4.x
 profileTitle=Communicator 4.x profiles
 profileText=Choose the profile that contains the Local Mail you want to import:
+
+# vCard import name
+VCardImportName=vCard file (.vcf)
new file mode 100644
--- /dev/null
+++ b/mail/locales/en-US/chrome/messenger/vCardImportMsgs.properties
@@ -0,0 +1,24 @@
+#
+# The following are used by the vCard import code to display status, error, and
+# informational messages
+#
+
+vCardImportName=vCard file (.vcf)
+
+vCardImportDescription=Import an address book from vCard format
+
+vCardImportAddressName=vCard Address Book
+
+# LOCALIZATION NOTE (vCardImportAddressSuccess): %S is replaced by the
+# name of the address book being imported.
+vCardImportAddressSuccess=Imported address book %S
+
+vCardImportAddressBadParam=Bad parameter passed to import address book.
+
+# LOCALIZATION NOTE (vCardImportAddressSuccess): %S is replaced by the
+# name of the address book being imported.
+vCardImportAddressBadSourceFile=Error accessing file for address book %S.
+
+# LOCALIZATION NOTE (vCardImportAddressSuccess): %S is replaced by the
+# name of the address book being imported.
+vCardImportAddressConvertError=Error importing address book %S, all addresses may not have been imported.
--- a/mail/locales/jar.mn
+++ b/mail/locales/jar.mn
@@ -84,16 +84,17 @@
   locale/@AB_CD@/messenger/msgViewPickerOverlay.dtd                     (%chrome/messenger/msgViewPickerOverlay.dtd)
   locale/@AB_CD@/messenger/mailViewSetup.dtd                            (%chrome/messenger/mailViewSetup.dtd)
   locale/@AB_CD@/messenger/mailViewList.dtd                             (%chrome/messenger/mailViewList.dtd)
   locale/@AB_CD@/messenger/offlineStartup.properties                    (%chrome/messenger/offlineStartup.properties)
   locale/@AB_CD@/messenger/importMsgs.properties                        (%chrome/messenger/importMsgs.properties)
   locale/@AB_CD@/messenger/importDialog.dtd                             (%chrome/messenger/importDialog.dtd)
   locale/@AB_CD@/messenger/fieldMapImport.dtd                           (%chrome/messenger/fieldMapImport.dtd)
   locale/@AB_CD@/messenger/textImportMsgs.properties                    (%chrome/messenger/textImportMsgs.properties)
+  locale/@AB_CD@/messenger/vCardImportMsgs.properties                   (%chrome/messenger/vCardImportMsgs.properties)
   locale/@AB_CD@/messenger/appleMailImportMsgs.properties               (%chrome/messenger/appleMailImportMsgs.properties)
   locale/@AB_CD@/messenger/comm4xMailImportMsgs.properties              (%chrome/messenger/comm4xMailImportMsgs.properties)
   locale/@AB_CD@/messenger/eudoraImportMsgs.properties                  (%chrome/messenger/eudoraImportMsgs.properties)
   locale/@AB_CD@/messenger/oeImportMsgs.properties                      (%chrome/messenger/oeImportMsgs.properties)
   locale/@AB_CD@/messenger/wmImportMsgs.properties                      (%chrome/messenger/wmImportMsgs.properties)
   locale/@AB_CD@/messenger/outlookImportMsgs.properties                 (%chrome/messenger/outlookImportMsgs.properties)
   locale/@AB_CD@/messenger/shutdownWindow.properties                    (%chrome/messenger/shutdownWindow.properties)
   locale/@AB_CD@/messenger/featureConfigurator.dtd                      (%chrome/messenger/featureConfigurator.dtd)
--- a/mailnews/import/Makefile.in
+++ b/mailnews/import/Makefile.in
@@ -39,17 +39,17 @@ DEPTH		= ../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= import
 
-PARALLEL_DIRS	= public src text/src comm4x/public comm4x/src
+PARALLEL_DIRS	= public src text/src vcard/src comm4x/public comm4x/src
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 PARALLEL_DIRS	+= eudora/src applemail/src
 endif
 
 ifeq ($(OS_ARCH),WINNT)
 PARALLEL_DIRS	+= eudora/src
 ifndef GNU_CC
--- a/mailnews/import/build/Makefile.in
+++ b/mailnews/import/build/Makefile.in
@@ -54,16 +54,17 @@ LIBXUL_LIBRARY = 1
 
 MODULE_NAME	= nsImportServiceModule
 
 CPPSRCS		=  nsImportModule.cpp
 
 SHARED_LIBRARY_LIBS = \
 		../src/$(LIB_PREFIX)import_s.$(LIB_SUFFIX) \
 		../text/src/$(LIB_PREFIX)imptext_s.$(LIB_SUFFIX) \
+		../vcard/src/$(LIB_PREFIX)impvcard_s.$(LIB_SUFFIX) \
 		../comm4x/src/$(LIB_PREFIX)imp4mail_s.$(LIB_SUFFIX) \
 		$(NULL)
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 SHARED_LIBRARY_LIBS += ../eudora/src/$(LIB_PREFIX)impEudra_s.$(LIB_SUFFIX)
 SHARED_LIBRARY_LIBS += ../applemail/src/$(LIB_PREFIX)applmail_s.$(LIB_SUFFIX)
 endif
 
@@ -76,16 +77,17 @@ SHARED_LIBRARY_LIBS += ../outlook/src/$(
 SHARED_LIBRARY_LIBS += ../winlivemail/$(LIB_PREFIX)importWM_s.$(LIB_SUFFIX)
 endif
 
 endif
 
 LOCAL_INCLUDES += -I$(srcdir)/../src \
 	-I$(srcdir)/../comm4x/src \
 	-I$(srcdir)/../text/src \
+  -I$(srcdir)/../vcard/src \
 	$(NULL)
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 LOCAL_INCLUDES += -I$(srcdir)/../eudora/src \
 									-I$(srcdir)/../applemail/src \
 									$(NULL)
 endif
 
--- a/mailnews/import/build/nsImportModule.cpp
+++ b/mailnews/import/build/nsImportModule.cpp
@@ -53,16 +53,23 @@ NS_DEFINE_NAMED_CID(NS_IMPORTMIMEENCODE_
 ////////////////////////////////////////////////////////////////////////////////
 // text import Include Files
 ////////////////////////////////////////////////////////////////////////////////
 #include "nsTextImport.h"
 
 NS_DEFINE_NAMED_CID(NS_TEXTIMPORT_CID);
 
 ////////////////////////////////////////////////////////////////////////////////
+// vCard import Include Files
+////////////////////////////////////////////////////////////////////////////////
+#include "nsVCardImport.h"
+
+NS_DEFINE_NAMED_CID(NS_VCARDIMPORT_CID);
+
+////////////////////////////////////////////////////////////////////////////////
 // nsComm4x import Include Files
 ////////////////////////////////////////////////////////////////////////////////
 #include "nsComm4xProfile.h"
 #include "nsComm4xMailStringBundle.h"
 #include "nsComm4xMailImport.h"
 
 NS_DEFINE_NAMED_CID(NS_COMM4XMAILIMPORT_CID);
 NS_DEFINE_NAMED_CID(NS_ICOMM4XPROFILE_CID);
@@ -110,16 +117,21 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsImportS
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsIImportMimeEncodeImpl)
 
 ////////////////////////////////////////////////////////////////////////////////
 // text import factories
 ////////////////////////////////////////////////////////////////////////////////
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTextImport)
 
 ////////////////////////////////////////////////////////////////////////////////
+// vcard import factories
+////////////////////////////////////////////////////////////////////////////////
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsVCardImport)
+
+////////////////////////////////////////////////////////////////////////////////
 // nsComm4x import factories
 ////////////////////////////////////////////////////////////////////////////////
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsComm4xMailImport)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(ImportComm4xMailImpl, Initialize)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsComm4xProfile)
 
 ////////////////////////////////////////////////////////////////////////////////
 // eudora import factories
@@ -143,38 +155,40 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsAp
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsOEImport)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsOutlookImport)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWMImport)
 #endif // XP_WIN
 
 static const mozilla::Module::CategoryEntry kMailNewsImportCategories[] = {
   // XXX These CIDs should match the explicit CIDs defined in the header files,
   // or be changed so that they are contract IDs (with appropraite code updates)
-  { "mailnewsimport", "{A5991D01-ADA7-11d3-A9C2-00A0CC26DA63}", "addressbook"},
+  { "mailnewsimport", "{A5991D01-ADA7-11d3-A9C2-00A0CC26DA63}", NS_IMPORT_ADDRESS_STR },
+  { "mailnewsimport", "{0eb034a3-964a-4e2f-92eb-cc55d9ae9dd2}", NS_IMPORT_ADDRESS_STR },
   { "mailnewsimport", "{647cc990-2bdb-11d6-92a0-0010a4b26cda}", kComm4xMailSupportsString},
 #if defined(XP_WIN) || defined(XP_MACOSX)
-  { "mailnewsimport", "{c8448da0-8f83-11d3-a206-00a0cc26da63}", kEudoraSupportsString},
+  { "mailnewsimport", "{c8448da0-8f83-11d3-a206-00a0cc26da63}", kEudoraSupportsString },
 #endif
 #ifdef XP_WIN
   { "mailnewsimport", "{42bc82bc-8e9f-4597-8b6e-e529daaf3af1}", kWMSupportsString },
   { "mailnewsimport", "{1DB469A0-8B00-11d3-A206-00A0CC26DA63}", kOutlookSupportsString },
-  { "mailnewsimport", "{be0bc880-1742-11d3-a206-00a0cc26da63}", kOESupportsString},
+  { "mailnewsimport", "{be0bc880-1742-11d3-a206-00a0cc26da63}", kOESupportsString },
 #endif
 #if defined(XP_MACOSX)
   { "mailnewsimport", "{6d3f101c-70ec-4e04-b68d-9908d1aeddf3}", kAppleMailSupportsString },
 #endif
   { NULL }
 };
 
-  const mozilla::Module::CIDEntry kMailNewsImportCIDs[] = {
+const mozilla::Module::CIDEntry kMailNewsImportCIDs[] = {
   { &kNS_IMPORTSERVICE_CID, false, NULL, nsImportServiceConstructor },
   { &kNS_IMPORTMIMEENCODE_CID, false, NULL, nsIImportMimeEncodeImplConstructor },
   { &kNS_TEXTIMPORT_CID, false, NULL, nsTextImportConstructor },
+  { &kNS_VCARDIMPORT_CID, false, NULL, nsVCardImportConstructor },
   { &kNS_COMM4XMAILIMPORT_CID, false, NULL, nsComm4xMailImportConstructor },
-  { &kNS_COMM4XMAILIMPL_CID, false, NULL, ImportComm4xMailImplConstructor},
+  { &kNS_COMM4XMAILIMPL_CID, false, NULL, ImportComm4xMailImplConstructor },
   { &kNS_ICOMM4XPROFILE_CID, false, NULL, nsComm4xProfileConstructor },
 #if defined(XP_WIN) || defined(XP_MACOSX)
   { &kNS_EUDORAIMPORT_CID, false, NULL, nsEudoraImportConstructor },
 #endif
 #if defined(XP_MACOSX)
   { &kNS_APPLEMAILIMPORT_CID, false, NULL, nsAppleMailImportModuleConstructor },
   { &kNS_APPLEMAILIMPL_CID, false, NULL, nsAppleMailImportMailConstructor },
 #endif
@@ -182,20 +196,21 @@ static const mozilla::Module::CategoryEn
 #ifdef XP_WIN
   { &kNS_OEIMPORT_CID, false, NULL, nsOEImportConstructor },
   { &kNS_WMIMPORT_CID, false, NULL, nsWMImportConstructor },
   { &kNS_OUTLOOKIMPORT_CID, false, NULL, nsOutlookImportConstructor },
 #endif
   { NULL }
 };
 
-  const mozilla::Module::ContractIDEntry kMailNewsImportContracts[] = {
+const mozilla::Module::ContractIDEntry kMailNewsImportContracts[] = {
   { NS_IMPORTSERVICE_CONTRACTID, &kNS_IMPORTSERVICE_CID },
   { "@mozilla.org/import/import-mimeencode;1", &kNS_IMPORTMIMEENCODE_CID },
   { "@mozilla.org/import/import-text;1", &kNS_TEXTIMPORT_CID },
+  { "@mozilla.org/import/import-vcard;1", &kNS_VCARDIMPORT_CID },
   { "@mozilla.org/import/import-comm4xMail;1", &kNS_COMM4XMAILIMPORT_CID },
   { NS_COMM4XMAILIMPL_CONTRACTID, &kNS_COMM4XMAILIMPL_CID },
   { NS_ICOMM4XPROFILE_CONTRACTID, &kNS_ICOMM4XPROFILE_CID },
 #if defined(XP_WIN) || defined(XP_MACOSX)
   { "@mozilla.org/import/import-eudora;1", &kNS_EUDORAIMPORT_CID },
 #endif
 #if defined(XP_MACOSX)
   { "@mozilla.org/import/import-applemail;1", &kNS_APPLEMAILIMPORT_CID },
--- a/mailnews/import/content/importDialog.js
+++ b/mailnews/import/content/importDialog.js
@@ -829,19 +829,22 @@ function ImportAddress( module, success,
       } catch( ex) {
         file = null;
       }
     }
     else {
       // ask for file
       try {
         filePicker.init( top.window, gImportMsgsBundle.getString('ImportSelectAddrFile'), Components.interfaces.nsIFilePicker.modeOpen);
-	if (selectedModuleName == gImportMsgsBundle.getString('Comm4xImportName'))
-		filePicker.appendFilter(gImportMsgsBundle.getString('Comm4xFiles'),"*.na2");
-        else {
+        if (selectedModuleName == gImportMsgsBundle.getString('Comm4xImportName'))
+          filePicker.appendFilter(gImportMsgsBundle.getString('Comm4xFiles'),"*.na2");
+        else if (selectedModuleName == gImportMsgsBundle.getString('VCardImportName')) {
+          var addressbookBundle = document.getElementById("bundle_addressbook");
+          filePicker.appendFilter(addressbookBundle.getString('VCFFiles'), "*.vcf");
+        } else {
           var addressbookBundle = document.getElementById("bundle_addressbook");
           filePicker.appendFilter(addressbookBundle.getString('LDIFFiles'), "*.ldi; *.ldif");
           filePicker.appendFilter(addressbookBundle.getString('CSVFiles'), "*.csv");
           filePicker.appendFilter(addressbookBundle.getString('TABFiles'), "*.tab; *.txt");
           filePicker.appendFilters(Components.interfaces.nsIFilePicker.filterAll);
         }
 
         if (filePicker.show() == Components.interfaces.nsIFilePicker.returnCancel)
--- a/mailnews/import/outlook/src/nsOutlookImport.cpp
+++ b/mailnews/import/outlook/src/nsOutlookImport.cpp
@@ -275,17 +275,17 @@ NS_IMETHODIMP nsOutlookImport::GetImport
       }
     }
     NS_IF_RELEASE( pMail);
     NS_IF_RELEASE( pGeneric);
     return( rv);
   }
 
   if (!strcmp( pImportType, "addressbook")) {
-    // create the nsIImportMail interface and return it!
+    // create the nsIImportAddressBook interface and return it!
     nsIImportAddressBooks *  pAddress = nsnull;
     nsIImportGeneric *    pGeneric = nsnull;
     rv = ImportOutlookAddressImpl::Create( &pAddress);
     if (NS_SUCCEEDED( rv)) {
       nsCOMPtr<nsIImportService> impSvc(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
       if (NS_SUCCEEDED( rv)) {
         rv = impSvc->CreateNewGenericAddressBooks( &pGeneric);
         if (NS_SUCCEEDED( rv)) {
--- a/mailnews/import/src/nsImportStringBundle.cpp
+++ b/mailnews/import/src/nsImportStringBundle.cpp
@@ -96,8 +96,35 @@ PRUnichar *nsImportStringBundle::GetStri
   }
 
   nsString resultString(NS_LITERAL_STRING("[StringID "));
   resultString.AppendInt(aStringID);
   resultString.AppendLiteral("?]");
 
   return ToNewUnicode(resultString);
 }
+
+void nsImportStringBundle::GetStringByName(const char *aName,
+                                           nsIStringBundle *aBundle,
+                                           nsString &aResult)
+{
+  aResult.Adopt(GetStringByName(aName, aBundle));
+}
+
+PRUnichar *nsImportStringBundle::GetStringByName(const char *aName,
+                                                 nsIStringBundle *aBundle)
+{
+  if (aBundle)
+  {
+    PRUnichar *ptrv = nsnull;
+    nsresult rv = aBundle->GetStringFromName(
+        NS_ConvertUTF8toUTF16(aName).get(), &ptrv);
+
+    if (NS_SUCCEEDED(rv) && ptrv)
+      return(ptrv);
+  }
+
+  nsString resultString(NS_LITERAL_STRING("[StringName "));
+  resultString.Append(NS_ConvertUTF8toUTF16(aName).get());
+  resultString.AppendLiteral("?]");
+
+  return ToNewUnicode(resultString);
+}
--- a/mailnews/import/src/nsImportStringBundle.h
+++ b/mailnews/import/src/nsImportStringBundle.h
@@ -44,16 +44,21 @@ class nsIStringBundle;
 class nsImportStringBundle
 {
 public:
   static PRUnichar* GetStringByID(PRInt32 aStringID,
                                   nsIStringBundle *aBundle = nsnull);
   static void GetStringByID(PRInt32 aStringID,
                             nsIStringBundle *aBundle,
                             nsString &aResult);
+  static PRUnichar* GetStringByName(const char *aName,
+                                    nsIStringBundle *aBundle = nsnull);
+  static void GetStringByName(const char *aName,
+                                nsIStringBundle *aBundle,
+                                nsString &aResult);
   static nsresult GetStringBundle(const char *aPropertyURL,
                                   nsIStringBundle **aBundle);
   static nsresult GetStringBundleProxy(nsIStringBundle *aOriginalBundle,
                                        nsIStringBundle **aProxy);
 };
 
 #define IMPORT_MSGS_URL       "chrome://messenger/locale/importMsgs.properties"
 
new file mode 100644
--- /dev/null
+++ b/mailnews/import/vcard/src/Makefile.in
@@ -0,0 +1,82 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE		= impvcard
+LIBRARY_NAME   = impvcard_s
+META_COMPONENT	= mail
+ifndef MOZ_INCOMPLETE_EXTERNAL_LINKAGE
+MOZILLA_INTERNAL_API = 1
+endif
+
+REQUIRES	= xpcom \
+		  string \
+		  import \
+		  intl \
+		  necko \
+		  addrbook \
+		  mork \
+		  msgcompose \
+		  msgbase \
+		  editor \
+		  dom \
+		  uriloader \
+		  msgbaseutil \
+		  msgdb \
+		  msglocal \
+		  mimetype \
+		  unicharutil \
+		  pref \
+		  $(NULL)
+
+CPPSRCS		= \
+    nsVCardAddress.cpp \
+    nsVCardImport.cpp \
+    $(NULL)
+
+LOCAL_INCLUDES += -I$(srcdir)/../../src
+
+# we don't want the shared lib, but we want to force the creation of a static lib.
+FORCE_STATIC_LIB = 1
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/mailnews/import/vcard/src/nsVCardAddress.cpp
@@ -0,0 +1,164 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mailnews vcard import.
+ *
+ * The Initial Developer of the Original Code is
+ * Evan Stratford <evan.stratford@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsAbBaseCID.h"
+#include "nsNativeCharsetUtils.h"
+#include "nsNetUtil.h"
+#include "nsVCardAddress.h"
+
+#include "nsIAbCard.h"
+#include "nsIAbManager.h"
+#include "nsIAddrDatabase.h"
+#include "nsIFile.h"
+#include "nsIInputStream.h"
+#include "nsILineInputStream.h"
+
+#include "plstr.h"
+#include "msgCore.h"
+
+nsVCardAddress::nsVCardAddress()
+{
+}
+
+nsVCardAddress::~nsVCardAddress()
+{
+}
+
+nsresult nsVCardAddress::ImportAddresses(
+    PRBool *pAbort,
+    const PRUnichar *pName,
+    nsIFile *pSrc,
+    nsIAddrDatabase *pDb,
+    nsString& errors,
+    PRUint32 *pProgress)
+{
+  // Open the source file for reading, read each line and process it!
+  nsCOMPtr<nsIInputStream> inputStream;
+  nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), pSrc);
+  if (NS_FAILED(rv)) {
+    IMPORT_LOG0("*** Error opening address file for reading\n");
+    return rv;
+  }
+
+  // Open the source file for reading, read each line and process it!
+  // Here we use this to work out the size of the file, so we can update
+  // an integer as we go through the file which will update a progress
+  // bar if required by the caller.
+  PRUint32 bytesLeft = 0;
+  rv = inputStream->Available(&bytesLeft);
+  if (NS_FAILED(rv)) {
+    IMPORT_LOG0("*** Error checking address file for size\n");
+    inputStream->Close();
+    return rv;
+  }
+
+  PRUint32 totalBytes = bytesLeft;
+  nsCOMPtr<nsILineInputStream> lineStream(do_QueryInterface(inputStream, &rv));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRBool more = PR_TRUE;
+  nsCString record;
+  while (!(*pAbort) && more && NS_SUCCEEDED(rv)) {
+    rv = ReadRecord(lineStream, record, &more);
+    if (NS_SUCCEEDED(rv)) {
+      // Parse the vCard and build an nsIAbCard from it
+      nsCOMPtr<nsIAbManager> ab =
+        do_GetService(NS_ABMANAGER_CONTRACTID, &rv);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      nsCOMPtr<nsIAbCard> cardFromVCard;
+      rv = ab->EscapedVCardToAbCard(record.get(), getter_AddRefs(cardFromVCard));
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      rv = pDb->CreateNewCardAndAddToDB(cardFromVCard, PR_FALSE, nsnull);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      if (NS_FAILED(rv)) {
+        IMPORT_LOG0("*** Error processing vCard record.\n");
+      }
+    }
+    if (NS_SUCCEEDED(rv) && pProgress) {
+      // This won't be totally accurate, but its the best we can do
+      // considering that lineStream won't give us how many bytes
+      // are actually left.
+      bytesLeft -= record.Length();
+      *pProgress = totalBytes - bytesLeft;
+    }
+  }
+  inputStream->Close();
+
+  if (NS_FAILED(rv)) {
+    IMPORT_LOG0("*** Error reading the address book - probably incorrect ending\n");
+    return NS_ERROR_FAILURE;
+  }
+
+  return pDb->Commit(nsAddrDBCommitType::kLargeCommit);
+}
+
+nsresult nsVCardAddress::ReadRecord(
+    nsILineInputStream *aLineStream, nsCString &aRecord, PRBool *aMore)
+{
+  PRBool more = PR_TRUE;
+  nsresult rv;
+  nsCString line;
+
+  aRecord.Truncate();
+
+  // read BEGIN:VCARD
+  rv = aLineStream->ReadLine(line, &more);
+  if (!line.EqualsIgnoreCase("BEGIN:VCARD")) {
+    IMPORT_LOG0("*** Expected case-insensitive BEGIN:VCARD at start of vCard\n");
+    rv = NS_ERROR_FAILURE;
+    *aMore = more;
+    return rv;
+  }
+  aRecord.Append(line);
+
+  // read until END:VCARD
+  do {
+    if (!more) {
+      IMPORT_LOG0("*** Expected case-insensitive END:VCARD at start of vCard\n");
+      rv = NS_ERROR_FAILURE;
+      break;
+    }
+    rv = aLineStream->ReadLine(line, &more);
+    aRecord.AppendLiteral(MSG_LINEBREAK);
+    aRecord.Append(line);
+  } while (!line.EqualsIgnoreCase("END:VCARD"));
+
+  *aMore = more;
+  return rv;
+}
new file mode 100644
--- /dev/null
+++ b/mailnews/import/vcard/src/nsVCardAddress.h
@@ -0,0 +1,79 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mailnews vcard import.
+ *
+ * The Initial Developer of the Original Code is
+ * Evan Stratford <evan.stratford@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsVCardAddress_h__
+#define nsVCardAddress_h__
+
+#include "nsCOMPtr.h"
+#include "nsStringGlue.h"
+#include "nsIImportFieldMap.h"
+#include "nsIImportService.h"
+#include "prlog.h"
+
+extern PRLogModuleInfo *VCARDLOGMODULE;  // Logging module
+
+#define IMPORT_LOG0(x)          PR_LOG(VCARDLOGMODULE, PR_LOG_DEBUG, (x))
+#define IMPORT_LOG1(x, y)       PR_LOG(VCARDLOGMODULE, PR_LOG_DEBUG, (x, y))
+#define IMPORT_LOG2(x, y, z)    PR_LOG(VCARDLOGMODULE, PR_LOG_DEBUG, (x, y, z))
+#define IMPORT_LOG3(a, b, c, d) PR_LOG(VCARDLOGMODULE, PR_LOG_DEBUG, (a, b, c, d))
+
+class nsIAddrDatabase;
+class nsIFile;
+class nsIInputStream;
+class nsILineInputStream;
+
+class nsVCardAddress {
+public:
+  nsVCardAddress();
+  virtual ~nsVCardAddress();
+
+  nsresult ImportAddresses(
+      PRBool *pAbort,
+      const PRUnichar *pName,
+      nsIFile *pSrc,
+      nsIAddrDatabase *pDb,
+      nsString& errors,
+      PRUint32 *pProgress);
+
+private:
+  static nsresult ReadRecord(
+      nsILineInputStream *aLineStream, nsCString &aRecord, PRBool *aMore);
+
+  nsCOMPtr<nsIImportService> m_pService;
+};
+
+#endif /* nsVCardAddress_h__ */
+
new file mode 100644
--- /dev/null
+++ b/mailnews/import/vcard/src/nsVCardImport.cpp
@@ -0,0 +1,445 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mailnews vcard import.
+ *
+ * The Initial Developer of the Original Code is
+ * Evan Stratford <evan.stratford@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+  VCard import addressbook interfaces
+*/
+#ifdef MOZ_LOGGING
+// sorry, this has to be before the pre-compiled header
+#define FORCE_PR_LOG /* Allow logging in the release build */
+#endif
+
+#include "nscore.h"
+#include "nsIAddrDatabase.h"
+#include "nsIFile.h"
+#include "nsIImportABDescriptor.h"
+#include "nsIImportAddressBooks.h"
+#include "nsIImportFieldMap.h"
+#include "nsIImportGeneric.h"
+#include "nsIImportService.h"
+#include "nsILocalFile.h"
+#include "nsImportStringBundle.h"
+#include "nsISupportsArray.h"
+#include "nsServiceManagerUtils.h"
+#include "nsTextFormatter.h"
+#include "nsVCardAddress.h"
+#include "nsVCardImport.h"
+
+PRLogModuleInfo *VCARDLOGMODULE = nsnull;
+static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
+
+class ImportVCardAddressImpl : public nsIImportAddressBooks
+{
+public:
+  ImportVCardAddressImpl(nsIStringBundle* aStringBundle); 
+  virtual ~ImportVCardAddressImpl();
+
+  static nsresult Create(
+      nsIImportAddressBooks** aImport, nsIStringBundle* aStringBundle);
+
+  // nsISupports interface
+  NS_DECL_ISUPPORTS
+
+  // nsIImportAddressBooks interface
+
+  // TODO: support multiple vCard files in future - shouldn't be too hard,
+  // since you just import each file in turn.
+  NS_IMETHOD GetSupportsMultiple(PRBool *_retval)
+  { *_retval = PR_FALSE; return NS_OK;}
+
+  NS_IMETHOD GetAutoFind(PRUnichar **description, PRBool *_retval);
+
+  NS_IMETHOD GetNeedsFieldMap(nsIFile *location, PRBool *_retval)
+  { *_retval = PR_FALSE; return NS_OK;}
+
+  NS_IMETHOD GetDefaultLocation(
+      nsIFile **location, PRBool *found, PRBool *userVerify);
+
+  NS_IMETHOD FindAddressBooks(nsIFile *location, nsISupportsArray **_retval);
+
+  NS_IMETHOD InitFieldMap(nsIImportFieldMap *fieldMap)
+  { return NS_ERROR_FAILURE;}
+
+  NS_IMETHOD ImportAddressBook(nsIImportABDescriptor *source,
+                               nsIAddrDatabase *destination,
+                               nsIImportFieldMap *fieldMap,
+                               nsISupports *aSupportService,
+                               PRBool isAddrLocHome,
+                               PRUnichar **errorLog,
+                               PRUnichar **successLog,
+                               PRBool *fatalError);
+
+  NS_IMETHOD GetImportProgress(PRUint32 *_retval);
+
+  NS_IMETHOD GetSampleData(PRInt32 index, PRBool *pFound, PRUnichar **pStr)
+  { return NS_ERROR_FAILURE;}
+
+  NS_IMETHOD SetSampleLocation(nsIFile *)
+  { return NS_ERROR_FAILURE; } 
+
+private:
+  static void ReportSuccess(
+      nsString& name, nsString *pStream, nsIStringBundle* pBundle);
+  static void SetLogs(
+      nsString& success, nsString& error,
+      PRUnichar **pError, PRUnichar **pSuccess);
+  static void ReportError(
+      const char *errorName, nsString& name, nsString *pStream,
+      nsIStringBundle* pBundle);
+
+private:
+  nsVCardAddress m_vCard;
+  nsCOMPtr<nsILocalFile> m_fileLoc;
+  PRUint32 m_bytesImported;
+  nsCOMPtr<nsIStringBundle> m_notProxyBundle;
+};
+
+nsVCardImport::nsVCardImport()
+{
+  if (!VCARDLOGMODULE)
+    VCARDLOGMODULE = PR_NewLogModule("IMPORT");
+
+  nsImportStringBundle::GetStringBundle(
+      VCARDIMPORT_MSGS_URL, getter_AddRefs(m_stringBundle));
+
+  IMPORT_LOG0("nsVCardImport Module Created\n");
+}
+
+nsVCardImport::~nsVCardImport()
+{
+  IMPORT_LOG0("nsVCardImport Module Deleted\n");
+}
+
+NS_IMPL_ISUPPORTS1(nsVCardImport, nsIImportModule)
+
+NS_IMETHODIMP nsVCardImport::GetName(PRUnichar **name)
+{
+  NS_ENSURE_ARG_POINTER(name);
+  *name = nsImportStringBundle::GetStringByName(
+      "vCardImportName", m_stringBundle);
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsVCardImport::GetDescription(PRUnichar **name)
+{
+  NS_ENSURE_ARG_POINTER(name);
+  *name = nsImportStringBundle::GetStringByName(
+      "vCardImportDescription", m_stringBundle);
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsVCardImport::GetSupports(char **supports)
+{
+  NS_ENSURE_ARG_POINTER(supports);
+  *supports = strdup(NS_IMPORT_ADDRESS_STR);
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsVCardImport::GetSupportsUpgrade(PRBool *pUpgrade)
+{
+  NS_ENSURE_ARG_POINTER(pUpgrade);
+  *pUpgrade = PR_TRUE;
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsVCardImport::GetImportInterface(
+    const char *pImportType, nsISupports **ppInterface)
+{
+  NS_ENSURE_ARG_POINTER(pImportType);
+  NS_ENSURE_ARG_POINTER(ppInterface);
+  *ppInterface = nsnull;
+  if (!strcmp(pImportType, "addressbook")) {
+    nsresult rv;
+    // create the nsIImportMail interface and return it!
+    nsIImportAddressBooks *pAddress = nsnull;
+    nsIImportGeneric *pGeneric = nsnull;
+    rv = ImportVCardAddressImpl::Create(&pAddress, m_stringBundle);
+    if (NS_SUCCEEDED(rv)) {
+      nsCOMPtr<nsIImportService> impSvc(
+          do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
+      if (NS_SUCCEEDED(rv)) {
+        rv = impSvc->CreateNewGenericAddressBooks(&pGeneric);
+        if (NS_SUCCEEDED(rv)) {
+          pGeneric->SetData("addressInterface", pAddress);
+          rv = pGeneric->QueryInterface( kISupportsIID, (void **)ppInterface);
+        }
+      }
+    }
+    NS_IF_RELEASE(pAddress);
+    NS_IF_RELEASE(pGeneric);
+    return rv;
+  }
+  return NS_ERROR_NOT_AVAILABLE;
+}
+
+nsresult ImportVCardAddressImpl::Create(
+    nsIImportAddressBooks** aImport, nsIStringBundle* aStringBundle)
+{
+  NS_ENSURE_ARG_POINTER(aImport);
+  *aImport = new ImportVCardAddressImpl(aStringBundle);
+  if (!*aImport)
+    return NS_ERROR_OUT_OF_MEMORY;
+  NS_ADDREF(*aImport);
+  return NS_OK;
+}
+
+ImportVCardAddressImpl::ImportVCardAddressImpl(
+    nsIStringBundle* aStringBundle) : m_notProxyBundle(aStringBundle)
+{
+}
+
+ImportVCardAddressImpl::~ImportVCardAddressImpl()
+{
+}
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(ImportVCardAddressImpl, nsIImportAddressBooks)
+
+NS_IMETHODIMP ImportVCardAddressImpl::GetAutoFind(
+    PRUnichar **addrDescription, PRBool *_retval)
+{
+  NS_ENSURE_ARG_POINTER(addrDescription);
+  NS_ENSURE_ARG_POINTER(_retval);
+
+  nsString str;
+  *_retval = PR_FALSE;
+
+  if (!m_notProxyBundle)
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIStringBundle> proxy;
+  nsresult rv = nsImportStringBundle::GetStringBundleProxy(
+      m_notProxyBundle, getter_AddRefs(proxy));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsImportStringBundle::GetStringByName("vCardImportAddressName", proxy, str);
+  *addrDescription = ToNewUnicode(str);
+  return NS_OK;
+}
+
+NS_IMETHODIMP ImportVCardAddressImpl::GetDefaultLocation(
+    nsIFile **ppLoc, PRBool *found, PRBool *userVerify)
+{
+  NS_ENSURE_ARG_POINTER(found);
+  NS_ENSURE_ARG_POINTER(ppLoc);
+  NS_ENSURE_ARG_POINTER(userVerify);
+
+  *ppLoc = nsnull;
+  *found = PR_FALSE;
+  *userVerify = PR_TRUE;
+  return NS_OK;
+}
+
+NS_IMETHODIMP ImportVCardAddressImpl::FindAddressBooks(
+    nsIFile *pLoc, nsISupportsArray **ppArray)
+{
+  NS_ENSURE_ARG_POINTER(pLoc);
+  NS_ENSURE_ARG_POINTER(ppArray);
+
+  *ppArray = nsnull;
+  PRBool exists = PR_FALSE;
+  nsresult rv = pLoc->Exists(&exists);
+  if (NS_FAILED(rv) || !exists)
+    return NS_ERROR_FAILURE;
+
+  PRBool isFile = PR_FALSE;
+  rv = pLoc->IsFile(&isFile);
+  if (NS_FAILED(rv) || !isFile)
+    return NS_ERROR_FAILURE;
+
+  m_fileLoc = do_QueryInterface(pLoc);
+  
+  /* Build an address book descriptor based on the file passed in! */
+  nsCOMPtr<nsISupportsArray> array;
+  rv = NS_NewISupportsArray(getter_AddRefs(array));
+  if (NS_FAILED(rv)) {
+    IMPORT_LOG0("FAILED to allocate the nsISupportsArray\n");
+    return rv;
+  }
+
+  nsString name;
+  m_fileLoc->GetLeafName(name);
+  if (NS_FAILED(rv)) {
+    IMPORT_LOG0("*** Failed getting leaf name of file\n");
+    return rv;
+  }
+
+  PRInt32 idx = name.RFindChar('.');
+  if ((idx != -1) && (idx > 0) && ((name.Length() - idx - 1) < 5)) {
+    name.SetLength(idx);
+  }
+
+  nsCOMPtr<nsIImportABDescriptor>  desc;
+  nsCOMPtr<nsIImportService> impSvc(
+      do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
+  if (NS_FAILED(rv)) {
+    IMPORT_LOG0("*** Failed to obtain the import service\n");
+    return rv;
+  }
+
+  rv = impSvc->CreateNewABDescriptor(getter_AddRefs(desc));
+  if (NS_SUCCEEDED(rv)) {
+    PRInt64 sz = 0;
+    pLoc->GetFileSize(&sz);
+    desc->SetPreferredName(name);
+    desc->SetSize((PRUint32) sz);
+    desc->SetAbFile(m_fileLoc);
+    nsCOMPtr<nsISupports> pInterface(do_QueryInterface(desc, &rv));
+    array->AppendElement(pInterface);
+  }
+  if (NS_FAILED(rv)) {
+    IMPORT_LOG0(
+        "*** Error creating address book descriptor for vCard import\n");
+  } else {
+    array.swap(*ppArray);
+  }
+
+  return rv;
+}
+
+void ImportVCardAddressImpl::ReportSuccess(
+    nsString& name, nsString *pStream, nsIStringBundle* pBundle)
+{
+  if (!pStream)
+    return;
+
+  // load the success string
+  PRUnichar *pFmt = nsImportStringBundle::GetStringByName(
+      "vCardImportAddressSuccess", pBundle);
+
+  PRUnichar *pText = nsTextFormatter::smprintf(pFmt, name.get());
+  pStream->Append(pText);
+  nsTextFormatter::smprintf_free(pText);
+  NS_Free(pFmt);
+  pStream->Append(PRUnichar('\n'));
+}
+
+void ImportVCardAddressImpl::ReportError(
+    const char *errorName, nsString& name, nsString *pStream,
+    nsIStringBundle* pBundle)
+{
+  if (!pStream)
+    return;
+
+  // load the error string
+  PRUnichar *pFmt = nsImportStringBundle::GetStringByName(errorName, pBundle);
+  PRUnichar *pText = nsTextFormatter::smprintf(pFmt, name.get());
+  pStream->Append(pText);
+  nsTextFormatter::smprintf_free(pText);
+  NS_Free(pFmt);
+  pStream->Append(PRUnichar('\n'));
+}
+
+void ImportVCardAddressImpl::SetLogs(
+    nsString& success, nsString& error,
+    PRUnichar **pError, PRUnichar **pSuccess)
+{ 
+  if (pError) 
+    *pError = ToNewUnicode(error);
+  if (pSuccess) 
+    *pSuccess = ToNewUnicode(success);
+}
+
+NS_IMETHODIMP ImportVCardAddressImpl::ImportAddressBook(
+    nsIImportABDescriptor *pSource,
+    nsIAddrDatabase *pDestination,
+    nsIImportFieldMap *fieldMap,
+    nsISupports *aSupportService,
+    PRBool isAddrLocHome,
+    PRUnichar ** pErrorLog,
+    PRUnichar ** pSuccessLog,
+    PRBool * fatalError)
+{
+  NS_ENSURE_ARG_POINTER(pSource);
+  NS_ENSURE_ARG_POINTER(pDestination);
+  NS_ENSURE_ARG_POINTER(fatalError);
+
+  if (!m_notProxyBundle)
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIStringBundle> proxy;
+  nsresult rv = nsImportStringBundle::GetStringBundleProxy(
+      m_notProxyBundle, getter_AddRefs(proxy));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  m_bytesImported = 0;
+  nsString success, error;
+  PRBool addrAbort = PR_FALSE;
+  nsString name;
+  pSource->GetPreferredName(name);
+
+  PRUint32 addressSize = 0;
+  pSource->GetSize(&addressSize);
+  if (addressSize == 0) {
+    IMPORT_LOG0("Address book size is 0, skipping import.\n");
+    ReportSuccess(name, &success, proxy);
+    SetLogs(success, error, pErrorLog, pSuccessLog);
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsIFile> inFile;
+  if (NS_FAILED(pSource->GetAbFile(getter_AddRefs(inFile)))) {
+    ReportError("vCardImportAddressBadSourceFile", name, &error, proxy);
+    SetLogs(success, error, pErrorLog, pSuccessLog);
+    return NS_ERROR_FAILURE;
+  }
+
+  if (!aSupportService) {
+    IMPORT_LOG0("Missing support service to import call\n");
+    return NS_ERROR_FAILURE;
+  }
+
+  rv = m_vCard.ImportAddresses(
+      &addrAbort, name.get(), inFile, pDestination, error, &m_bytesImported);
+
+  if (NS_SUCCEEDED(rv) && error.IsEmpty()) {
+    ReportSuccess(name, &success, proxy);
+    SetLogs(success, error, pErrorLog, pSuccessLog);
+  }
+  else {
+    ReportError("vCardImportAddressConvertError", name, &error, proxy);
+    SetLogs(success, error, pErrorLog, pSuccessLog);
+  }
+
+  IMPORT_LOG0("*** VCard address import done\n");
+  return rv;
+}
+
+NS_IMETHODIMP ImportVCardAddressImpl::GetImportProgress(PRUint32 *_retval)
+{
+  NS_ENSURE_ARG_POINTER(_retval);
+  *_retval = m_bytesImported;
+  return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/mailnews/import/vcard/src/nsVCardImport.h
@@ -0,0 +1,70 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mailnews vcard import.
+ *
+ * The Initial Developer of the Original Code is
+ * Evan Stratford <evan.stratford@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsVCardImport_h___
+#define nsVCardImport_h___
+
+#include "nsIImportModule.h"
+#include "nsIStringBundle.h"
+#include "nsCOMPtr.h"
+
+#define NS_VCARDIMPORT_CID \
+{ /* 0EB034A3-964A-4E2F-92EBCC55D9AE9DD2 */ \
+  0x0eb034a3, 0x964a, 0x4e2f, \
+  {0x92, 0xeb, 0xcc, 0x55, 0xd9, 0xae, 0x9d, 0xd2}}
+
+#define VCARDIMPORT_MSGS_URL "chrome://messenger/locale/vCardImportMsgs.properties"
+
+class nsVCardImport : public nsIImportModule
+{
+public:
+
+  nsVCardImport();
+  virtual ~nsVCardImport();
+
+  NS_DECL_ISUPPORTS
+
+  ////////////////////////////////////////////////////////////////////////////////////////
+  // we suppport the nsIImportModule interface
+  ////////////////////////////////////////////////////////////////////////////////////////
+
+  NS_DECL_NSIIMPORTMODULE
+
+protected:
+  nsCOMPtr<nsIStringBundle> m_stringBundle;
+};
+
+#endif /* nsVCardImport_h___ */
--- a/mailnews/makefiles.sh
+++ b/mailnews/makefiles.sh
@@ -103,16 +103,17 @@ mailnews/import/comm4x/public/Makefile
 mailnews/import/comm4x/src/Makefile
 mailnews/import/eudora/src/Makefile
 mailnews/import/oexpress/Makefile
 mailnews/import/outlook/src/Makefile
 mailnews/import/public/Makefile
 mailnews/import/src/Makefile
 mailnews/import/test/Makefile
 mailnews/import/text/src/Makefile
+mailnews/import/vcard/src/Makefile
 mailnews/import/winlivemail/Makefile
 mailnews/local/Makefile
 mailnews/local/build/Makefile
 mailnews/local/public/Makefile
 mailnews/local/src/Makefile
 mailnews/local/test/Makefile
 mailnews/mapi/mapiDll/Makefile
 mailnews/mapi/mapihook/Makefile
--- a/suite/locales/en-US/chrome/mailnews/addressbook/addressBook.properties
+++ b/suite/locales/en-US/chrome/mailnews/addressbook/addressBook.properties
@@ -154,16 +154,17 @@ invalidResults=Please enter a valid numb
 abReplicationOfflineWarning=You must be online to perform LDAP replication.
 abReplicationSaveSettings=Settings must be saved before a directory may be downloaded.
 
 # For importing / exporting
 ExportAddressBookTitle=Export Address Book
 LDIFFiles=LDIF
 CSVFiles=Comma Separated
 TABFiles=Tab Delimited
+VCFFiles=vCard
 failedToExportTitle=Export Failed
 failedToExportMessageNoDeviceSpace=Failed to export addressbook, no space left on device.
 failedToExportMessageFileAccessDenied=Failed to export addressbook, file access denied.
 
 # For getting authDN for replication using dlg box
 AuthDlgTitle=Address Book LDAP Replication
 AuthDlgDesc=To access the directory server, enter your user name and password.
 
--- a/suite/locales/en-US/chrome/mailnews/importMsgs.properties
+++ b/suite/locales/en-US/chrome/mailnews/importMsgs.properties
@@ -347,8 +347,10 @@ DefaultFolderName=Imported Mail
 ImportModuleFolderName=%S Import
  
 # LOCALIZATION NOTE : "Communicator 4.x" is the used for previous versions of Netscape Communicator
 # Please translate using the brandname in respective languages for Netscape Communicator 4 releases.
 # strings profile dialog that comes up when importing mail from 4.x
 profileTitle=Communicator 4.x profiles
 profileText=Choose the profile that contains the Local Mail you want to import:
 
+# vCard import name
+VCardImportName=vCard file (.vcf)
new file mode 100644
--- /dev/null
+++ b/suite/locales/en-US/chrome/mailnews/vCardImportMsgs.properties
@@ -0,0 +1,24 @@
+#
+# The following are used by the vCard import code to display status, error, and
+# informational messages
+#
+
+vCardImportName=vCard file (.vcf)
+
+vCardImportDescription=Import an address book from vCard format
+
+vCardImportAddressName=vCard Address Book
+
+# LOCALIZATION NOTE (vCardImportAddressSuccess): %S is replaced by the
+# name of the address book being imported.
+vCardImportAddressSuccess=Imported address book %S
+
+vCardImportAddressBadParam=Bad parameter passed to import address book.
+
+# LOCALIZATION NOTE (vCardImportAddressSuccess): %S is replaced by the
+# name of the address book being imported.
+vCardImportAddressBadSourceFile=Error accessing file for address book %S.
+
+# LOCALIZATION NOTE (vCardImportAddressSuccess): %S is replaced by the
+# name of the address book being imported.
+vCardImportAddressConvertError=Error importing address book %S, all addresses may not have been imported.