fix bug 664441, separate folder discovery addSubFolder from local folder creation, r=sid0, sr=neil
authorDavid Bienvenu <bienvenu@nventure.com>
Wed, 22 Jun 2011 15:14:15 -0700
changeset 7994 841c8228000453ff7c3525a3aa616f0561655e60
parent 7993 db68cef4037681b9f9bccffd01e9fa7d29274b60
child 7995 c736643477f09d4e0bb2cb2cf15dc1402cc8e138
push id6149
push userbienvenu@nventure.com
push dateWed, 22 Jun 2011 22:13:52 +0000
treeherdercomm-central@841c82280004 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssid0, neil
bugs664441
fix bug 664441, separate folder discovery addSubFolder from local folder creation, r=sid0, sr=neil
mailnews/base/public/nsIMsgFolder.idl
mailnews/base/test/unit/test_bug471682.js
mailnews/base/test/unit/test_copyChaining.js
mailnews/base/test/unit/test_copyThenMoveManual.js
mailnews/base/test/unit/test_folderCompact.js
mailnews/base/test/unit/test_inheritedFolderProperties.js
mailnews/base/test/unit/test_quarantineFilterMove.js
mailnews/base/test/unit/test_searchChaining.js
mailnews/compose/test/unit/test_attachment.js
mailnews/compose/test/unit/test_bug474774.js
mailnews/compose/test/unit/test_detectAttachmentCharset.js
mailnews/compose/test/unit/test_saveDraft.js
mailnews/compose/test/unit/test_sendBackground.js
mailnews/compose/test/unit/test_sendMessageFile.js
mailnews/compose/test/unit/test_sendMessageLater.js
mailnews/compose/test/unit/test_sendMessageLater2.js
mailnews/compose/test/unit/test_sendMessageLater3.js
mailnews/imap/test/unit/test_copyThenMove.js
mailnews/imap/test/unit/test_imapFilterActions.js
mailnews/imap/test/unit/test_imapFolderCopy.js
mailnews/imap/test/unit/test_localToImapFilter.js
mailnews/local/public/nsIMsgLocalMailFolder.idl
mailnews/local/src/nsLocalMailFolder.cpp
mailnews/local/test/unit/test_fileName.js
mailnews/local/test/unit/test_localSubFolders.js
mailnews/local/test/unit/test_pop3Password2.js
mailnews/test/resources/mailTestUtils.js
mailnews/test/resources/messageInjection.js
--- a/mailnews/base/public/nsIMsgFolder.idl
+++ b/mailnews/base/public/nsIMsgFolder.idl
@@ -188,17 +188,29 @@ interface nsIMsgFolder : nsISupports {
   void Delete ();
 
   void deleteSubFolders(in nsIArray folders, in nsIMsgWindow msgWindow);
   void propagateDelete(in nsIMsgFolder folder, in boolean deleteStorage,
                        in nsIMsgWindow msgWindow);
   void recursiveDelete(in boolean deleteStorage, in nsIMsgWindow msgWindow);
 
   void createSubfolder(in AString folderName, in nsIMsgWindow msgWindow);
-  nsIMsgFolder addSubfolder(in AString folderName);
+
+  /**
+   * Adds the subfolder with the passed name to the folder hierarchy.
+   * This is used internally during folder discovery; It shouldn't be
+   * used to create folders since it won't create storage for the folder,
+   * especially for imap. Unless you know exactly what you're doing, you
+   * should be using createSubfolder + getChildNamed or createLocalSubfolder.
+   *
+   * @param aFolderName Name of the folder to add.
+   * @returns The folder added.
+   */
+  nsIMsgFolder addSubfolder(in AString aFolderName);
+
   /* this method ensures the storage for the folder exists.
     For local folders, it creates the berkeley mailbox if missing.
     For imap folders, it subscribes to the folder if it exists,
     or creates it if it doesn't exist
   */
   void createStorageIfMissing(in nsIUrlListener urlListener);
 
   /**
--- a/mailnews/base/test/unit/test_bug471682.js
+++ b/mailnews/base/test/unit/test_bug471682.js
@@ -42,17 +42,17 @@
  */
 const copyService = Cc["@mozilla.org/messenger/messagecopyservice;1"]
                       .getService(Ci.nsIMsgCopyService);
 const bugmail1 = do_get_file("../../../data/bugmail1");
 var gHdr; // header of test message in local folder
 
 loadLocalMailAccount();
 // create a subfolder as a target for copies
-var gSubfolder = gLocalInboxFolder.addSubfolder("subfolder");
+var gSubfolder = gLocalInboxFolder.createLocalSubfolder("subfolder");
 
 function run_test()
 {
   do_test_pending();
   // step 1: copy a message into the local inbox
   copyService.CopyFileMessage(bugmail1, gLocalInboxFolder, null, false, 0,
                               "", step2, null);
   return;
--- a/mailnews/base/test/unit/test_copyChaining.js
+++ b/mailnews/base/test/unit/test_copyChaining.js
@@ -87,22 +87,24 @@ function run_test()
   loadLocalMailAccount();
   let messageGenerator = new MessageGenerator();
   let scenarioFactory = new MessageScenarioFactory(messageGenerator);
 
   // "Master" do_test_pending(), paired with a do_test_finished() at the end of
   // all the operations.
   do_test_pending();
 
-  gCopyDest = gLocalInboxFolder.addSubfolder("copyDest");
+  gCopyDest = gLocalInboxFolder.createLocalSubfolder("copyDest");
   // build up a diverse list of messages
   let messages = [];
   messages = messages.concat(scenarioFactory.directReply(10));
   writeMessagesToMbox(messages, gProfileDir,
                       "Mail", "Local Folders", "copySource");
+  // We use addSubfolder because we created the copySource folder by writing
+  // messages to it.
   gCopySource = gLocalIncomingServer.rootMsgFolder.addSubfolder("copySource");
   updateFolderAndNotify(gCopySource, doTest);
   return true;
 }
 
 function doTest()
 {
   var test = gCurTestNum;
--- a/mailnews/base/test/unit/test_copyThenMoveManual.js
+++ b/mailnews/base/test/unit/test_copyThenMoveManual.js
@@ -102,18 +102,18 @@ function folderCount(folder)
   return count;
 }
 
 function run_test()
 {
   if (!gLocalInboxFolder)
     loadLocalMailAccount();
 
-  gCopyFolder = gLocalIncomingServer.rootFolder.addSubfolder("CopyFolder");
-  gMoveFolder = gLocalIncomingServer.rootFolder.addSubfolder("MoveFolder");
+  gCopyFolder = gLocalIncomingServer.rootFolder.createLocalSubfolder("CopyFolder");
+  gMoveFolder = gLocalIncomingServer.rootFolder.createLocalSubfolder("MoveFolder");
   const mailSession = Cc["@mozilla.org/messenger/services/session;1"]
                         .getService(Ci.nsIMsgMailSession);
 
   mailSession.AddFolderListener(FolderListener, Ci.nsIFolderListener.event |
                                                 Ci.nsIFolderListener.added |
                                                 Ci.nsIFolderListener.removed);
 
   // "Master" do_test_pending(), paired with a do_test_finished() at the end of
--- a/mailnews/base/test/unit/test_folderCompact.js
+++ b/mailnews/base/test/unit/test_folderCompact.js
@@ -182,20 +182,20 @@ function run_test()
   loadLocalMailAccount();
   // Load up some messages so that we can copy them in later.
   gMsgFile1 = do_get_file("../../../data/bugmail10");
   gMsgFile2 = do_get_file("../../../data/bugmail11");
   gMsgFile3 = do_get_file("../../../data/draft1");
 
   // Create another folder to move and copy messages around, and force initialization.
   var rootFolder = gLocalIncomingServer.rootMsgFolder;
-  gLocalFolder2 = rootFolder.addSubfolder("folder2");
+  gLocalFolder2 = rootFolder.createLocalSubfolder("folder2");
   var folderName = gLocalFolder2.prettiestName;
   // Create a third folder for more testing.
-  gLocalFolder3 = rootFolder.addSubfolder("folder3");
+  gLocalFolder3 = rootFolder.createLocalSubfolder("folder3");
   folderName = gLocalFolder3.prettiestName;
 
   // "Master" do_test_pending(), paired with a do_test_finished() at the end of all the operations.
   do_test_pending();
 
 //  do_test_finished();
   // Do the test.
   doTest(1);
--- a/mailnews/base/test/unit/test_inheritedFolderProperties.js
+++ b/mailnews/base/test/unit/test_inheritedFolderProperties.js
@@ -39,20 +39,22 @@
  */
 
 function run_test()
 { 
   loadLocalMailAccount();
   var rootFolder = gLocalIncomingServer.rootMsgFolder;
 
   // add subfolders to the inbox
-  const subFolder11 = gLocalInboxFolder.addSubfolder("subfolder11");
-  const subFolder12 = gLocalInboxFolder.addSubfolder("subfolder12");
-  const subFolder21 = subFolder11.addSubfolder("subfolder21");
-  const subFolder22 = subFolder12.addSubfolder("subfolder22");
+  const subFolder11 = gLocalInboxFolder.createLocalSubfolder("subfolder11")
+                         .QueryInterface(Ci.nsIMsgLocalMailFolder);
+  const subFolder12 = gLocalInboxFolder.createLocalSubfolder("subfolder12")
+                         .QueryInterface(Ci.nsIMsgLocalMailFolder);
+  const subFolder21 = subFolder11.createLocalSubfolder("subfolder21");
+  const subFolder22 = subFolder12.createLocalSubfolder("subfolder22");
 
   // add a global preference
   const propertyName = "iexist";
   const invalidName = "idontexist";
   const globalPref = "mail.server.default." + propertyName;
   const globalValue = "iAmGlobal";
   const folderValue = "iAmFolder";
   const folderValue2 = "iAmFolder2";
--- a/mailnews/base/test/unit/test_quarantineFilterMove.js
+++ b/mailnews/base/test/unit/test_quarantineFilterMove.js
@@ -109,17 +109,17 @@ function run_test()
 
   // quarantine messages
   let prefs = Cc["@mozilla.org/preferences-service;1"]
                 .getService(Ci.nsIPrefBranch);
   prefs.setBoolPref("mailnews.downloadToTempFile", true);
   if (!gLocalInboxFolder)
     loadLocalMailAccount();
 
-  gMoveFolder = gLocalIncomingServer.rootFolder.addSubfolder("MoveFolder");
+  gMoveFolder = gLocalIncomingServer.rootFolder.createLocalSubfolder("MoveFolder");
   const mailSession = Cc["@mozilla.org/messenger/services/session;1"]
                         .getService(Ci.nsIMsgMailSession);
 
   mailSession.AddFolderListener(FolderListener, Ci.nsIFolderListener.event |
                                                 Ci.nsIFolderListener.added |
                                                 Ci.nsIFolderListener.removed);
 
   // "Master" do_test_pending(), paired with a do_test_finished() at the end of
--- a/mailnews/base/test/unit/test_searchChaining.js
+++ b/mailnews/base/test/unit/test_searchChaining.js
@@ -126,17 +126,17 @@ var UrlListener =
     do_check_eq(rc, 0);
     searchTest();
   }
 };
 
 function searchTest()
 {
   // Get the IMAP inbox...
-  emptyLocal1 = gLocalIncomingServer.rootFolder.addSubfolder("empty 1");
+  emptyLocal1 = gLocalIncomingServer.rootFolder.createLocalSubfolder("empty 1");
 
   let searchSession = Cc["@mozilla.org/messenger/searchSession;1"]
                         .createInstance(Ci.nsIMsgSearchSession);
 
   let searchTerm = searchSession.createTerm();
   searchTerm.matchAll = true;
   searchSession.appendTerm(searchTerm);
   searchSession.addScopeTerm(Ci.nsMsgSearchScope.offlineMail, emptyLocal1);
--- a/mailnews/compose/test/unit/test_attachment.js
+++ b/mailnews/compose/test/unit/test_attachment.js
@@ -113,17 +113,17 @@ function createMessage(folding, input) {
   try {
     gDraftFolder = rootFolder.getChildNamed("Drafts");
     // try to delete
     rootFolder.propagateDelete(gDraftFolder, true, null);
   } catch (e) {
     // we don't have to remove the folder because it doen't exist yet
   }
   // Create a new, empty drafts folder
-  gDraftFolder = rootFolder.addSubfolder("Drafts");
+  gDraftFolder = rootFolder.createLocalSubfolder("Drafts");
 
   var attachment = Cc["@mozilla.org/messengercompose/attachment;1"]
                      .createInstance(Ci.nsIMsgAttachment);
   attachment.url = "data:,";
   attachment.name = input;
   fields.addAttachment(attachment);
 
   var progress = Cc["@mozilla.org/messenger/progress;1"]
--- a/mailnews/compose/test/unit/test_bug474774.js
+++ b/mailnews/compose/test/unit/test_bug474774.js
@@ -180,17 +180,17 @@ function run_test() {
 
   var smtpServer = getBasicSmtpServer();
   identity = getSmtpIdentity(kSender, smtpServer);
 
   account.addIdentity(identity);
   account.defaultIdentity = identity;
   account.incomingServer = incomingServer;
 
-  sentFolder = gLocalIncomingServer.rootMsgFolder.addSubfolder("Sent");
+  sentFolder = gLocalIncomingServer.rootMsgFolder.createLocalSubfolder("Sent");
 
   identity.doFcc = false;
 
   // Now prepare to actually "send" the message later, i.e. dump it in the
   // unsent messages folder.
 
   var compFields = Cc["@mozilla.org/messengercompose/composefields;1"]
                      .createInstance(Ci.nsIMsgCompFields);
--- a/mailnews/compose/test/unit/test_detectAttachmentCharset.js
+++ b/mailnews/compose/test/unit/test_detectAttachmentCharset.js
@@ -53,17 +53,17 @@ function createMessage(folding)
   try {
     gDraftFolder = rootFolder.getChildNamed("Drafts");
     // try to delete
     rootFolder.propagateDelete(gDraftFolder, true, null);
   } catch (e) {
     // we don't have to remove the folder because it doen't exist yet
   }
   // Create a new, empty drafts folder
-  gDraftFolder = rootFolder.addSubfolder("Drafts");
+  gDraftFolder = rootFolder.createLocalSubfolder("Drafts");
 
   var attachment = Cc["@mozilla.org/messengercompose/attachment;1"]
                      .createInstance(Ci.nsIMsgAttachment);
   //Set attachment file
   attachment.url = "file://" + gAttachedFilePath;
   attachment.contentType = 'text/plain';
   attachment.name = "test-UTF-8.txt";
   fields.addAttachment(attachment);
--- a/mailnews/compose/test/unit/test_saveDraft.js
+++ b/mailnews/compose/test/unit/test_saveDraft.js
@@ -46,17 +46,17 @@ function createMessage() {
   try {
     gDraftFolder = rootFolder.getChildNamed("Drafts");
     // try to delete
     rootFolder.propagateDelete(gDraftFolder, true, null);
   } catch (e) {
     // we don't have to remove the folder because it doen't exist yet
   }
   // Create a new, empty drafts folder
-  gDraftFolder = rootFolder.addSubfolder("Drafts");
+  gDraftFolder = rootFolder.createLocalSubfolder("Drafts");
 
   var progress = Cc["@mozilla.org/messenger/progress;1"]
                    .createInstance(Ci.nsIMsgProgress);
   progress.registerListener(progressListener);
   msgCompose.SendMsg(Ci.nsIMsgSend.nsMsgSaveAsDraft, identity, "", null,
                      progress);
 }
 
--- a/mailnews/compose/test/unit/test_sendBackground.js
+++ b/mailnews/compose/test/unit/test_sendBackground.js
@@ -108,17 +108,17 @@ function run_test() {
 
   var smtpServer = getBasicSmtpServer();
   identity = getSmtpIdentity(kSender, smtpServer);
 
   account.addIdentity(identity);
   account.defaultIdentity = identity;
   account.incomingServer = incomingServer;
 
-  sentFolder = gLocalIncomingServer.rootMsgFolder.addSubfolder("Sent");
+  sentFolder = gLocalIncomingServer.rootMsgFolder.createLocalSubfolder("Sent");
 
   do_check_eq(identity.doFcc, true);
 
   // Now prepare to actually "send" the message later, i.e. dump it in the
   // unsent messages folder.
 
   var compFields = Cc["@mozilla.org/messengercompose/composefields;1"]
                      .createInstance(Ci.nsIMsgCompFields);
--- a/mailnews/compose/test/unit/test_sendMessageFile.js
+++ b/mailnews/compose/test/unit/test_sendMessageFile.js
@@ -112,17 +112,17 @@ function run_test() {
 
   var acctMgr = Cc["@mozilla.org/messenger/account-manager;1"]
                   .getService(Ci.nsIMsgAccountManager);
   acctMgr.setSpecialFolders();
 
   var smtpServer = getBasicSmtpServer();
   var identity = getSmtpIdentity(kSender, smtpServer);
 
-  sentFolder = gLocalIncomingServer.rootMsgFolder.addSubfolder("Sent");
+  sentFolder = gLocalIncomingServer.rootMsgFolder.createLocalSubfolder("Sent");
 
   do_check_eq(identity.doFcc, true);
 
   var msgSend = Cc["@mozilla.org/messengercompose/send;1"]
                   .createInstance(Ci.nsIMsgSend);
 
   // Handle the server in a try/catch/finally loop so that we always will stop
   // the server if something fails.
--- a/mailnews/compose/test/unit/test_sendMessageLater.js
+++ b/mailnews/compose/test/unit/test_sendMessageLater.js
@@ -188,17 +188,17 @@ function run_test() {
 
   var smtpServer = getBasicSmtpServer();
   identity = getSmtpIdentity(kSender, smtpServer);
 
   account.addIdentity(identity);
   account.defaultIdentity = identity;
   account.incomingServer = incomingServer;
 
-  sentFolder = gLocalIncomingServer.rootMsgFolder.addSubfolder("Sent");
+  sentFolder = gLocalIncomingServer.rootMsgFolder.createLocalSubfolder("Sent");
 
   do_check_eq(identity.doFcc, true);
 
   // Now prepare to actually "send" the message later, i.e. dump it in the
   // unsent messages folder.
 
   var compFields = Cc["@mozilla.org/messengercompose/composefields;1"]
                      .createInstance(Ci.nsIMsgCompFields);
--- a/mailnews/compose/test/unit/test_sendMessageLater2.js
+++ b/mailnews/compose/test/unit/test_sendMessageLater2.js
@@ -232,17 +232,17 @@ function run_test() {
 
   var smtpServer = getBasicSmtpServer();
   identity = getSmtpIdentity(kSender, smtpServer);
 
   account.addIdentity(identity);
   account.defaultIdentity = identity;
   account.incomingServer = incomingServer;
 
-  gLocalIncomingServer.rootMsgFolder.addSubfolder("Sent");
+  gLocalIncomingServer.rootMsgFolder.createLocalSubfolder("Sent");
 
   gSentFolder = msgSendLater.getUnsentMessagesFolder(identity);
 
   // Don't copy messages to sent folder for this test
   identity.doFcc = false;
 
   // Create and add a listener
   var messageListener = new msll();
--- a/mailnews/compose/test/unit/test_sendMessageLater3.js
+++ b/mailnews/compose/test/unit/test_sendMessageLater3.js
@@ -134,17 +134,17 @@ function run_test() {
 
   var smtpServer = getBasicSmtpServer();
   identity = getSmtpIdentity(kSender, smtpServer);
 
   account.addIdentity(identity);
   account.defaultIdentity = identity;
   account.incomingServer = incomingServer;
 
-  sentFolder = gLocalIncomingServer.rootMsgFolder.addSubfolder("Sent");
+  sentFolder = gLocalIncomingServer.rootMsgFolder.createLocalSubfolder("Sent");
 
   identity.doFcc = false;
 
   // Now prepare to actually "send" the message later, i.e. dump it in the
   // unsent messages folder.
 
   var compFields = Cc["@mozilla.org/messengercompose/composefields;1"]
                      .createInstance(Ci.nsIMsgCompFields);
--- a/mailnews/imap/test/unit/test_copyThenMove.js
+++ b/mailnews/imap/test/unit/test_copyThenMove.js
@@ -129,18 +129,18 @@ function run_test()
   // Make sure no biff notifications happen
   prefBranch.setBoolPref("mail.biff.play_sound", false);
   prefBranch.setBoolPref("mail.biff.show_alert", false);
   prefBranch.setBoolPref("mail.biff.show_tray_icon", false);
   prefBranch.setBoolPref("mail.biff.animate_dock_icon", false);
   // We aren't interested in downloading messages automatically
   prefBranch.setBoolPref("mail.server.server1.download_on_biff", false);
 
-  gEmptyLocal1 = gLocalIncomingServer.rootFolder.addSubfolder("empty 1");
-  gEmptyLocal2 = gLocalIncomingServer.rootFolder.addSubfolder("empty 2");
+  gEmptyLocal1 = gLocalIncomingServer.rootFolder.createLocalSubfolder("empty 1");
+  gEmptyLocal2 = gLocalIncomingServer.rootFolder.createLocalSubfolder("empty 2");
   // Get the server list...
   gIMAPIncomingServer.performExpand(null);
 
   gRootFolder = gIMAPIncomingServer.rootFolder;
   gIMAPInbox = gRootFolder.getChildNamed("INBOX");
   dump("gIMAPInbox uri = " + gIMAPInbox.URI + "\n");
   let msgImapFolder = gIMAPInbox.QueryInterface(Ci.nsIMsgImapMailFolder);
   // these hacks are required because we've created the inbox before
--- a/mailnews/imap/test/unit/test_imapFilterActions.js
+++ b/mailnews/imap/test/unit/test_imapFilterActions.js
@@ -343,17 +343,17 @@ function run_test()
   prefBranch.setIntPref("mail.server.default.max_cached_connections", 1);
   // We aren't interested in downloading messages automatically
   prefBranch.setBoolPref("mail.server.default.download_on_biff", false);
   prefBranch.setBoolPref("mail.biff.play_sound", false);
   prefBranch.setBoolPref("mail.biff.show_alert", false);
   prefBranch.setBoolPref("mail.biff.show_tray_icon", false);
   prefBranch.setBoolPref("mail.biff.animate_dock_icon", false);
 
-  gSubfolder = gLocalIncomingServer.rootFolder.addSubfolder("Subfolder");
+  gSubfolder = gLocalIncomingServer.rootFolder.createLocalSubfolder("Subfolder");
   gIMAPIncomingServer.performExpand(null);
 
   gRootFolder = gIMAPIncomingServer.rootFolder;
   gIMAPInbox = gRootFolder.getChildNamed("INBOX");
   gIMAPMailbox = gIMAPDaemon.getMailbox("INBOX");
   dump("gIMAPInbox uri = " + gIMAPInbox.URI + "\n");
   let msgImapFolder = gIMAPInbox.QueryInterface(Ci.nsIMsgImapMailFolder);
   // these hacks are required because we've created the inbox before
--- a/mailnews/imap/test/unit/test_imapFolderCopy.js
+++ b/mailnews/imap/test/unit/test_imapFolderCopy.js
@@ -131,20 +131,20 @@ function run_test()
   // Make sure no biff notifications happen
   prefBranch.setBoolPref("mail.biff.play_sound", false);
   prefBranch.setBoolPref("mail.biff.show_alert", false);
   prefBranch.setBoolPref("mail.biff.show_tray_icon", false);
   prefBranch.setBoolPref("mail.biff.animate_dock_icon", false);
   // We aren't interested in downloading messages automatically
   prefBranch.setBoolPref("mail.server.server1.download_on_biff", false);
 
-  gEmptyLocal1 = gLocalIncomingServer.rootFolder.addSubfolder("empty 1");
-  gEmptyLocal2 = gLocalIncomingServer.rootFolder.addSubfolder("empty 2");
-  gEmptyLocal3 = gLocalIncomingServer.rootFolder.addSubfolder("empty 3");
-  gNotEmptyLocal4 = gLocalIncomingServer.rootFolder.addSubfolder("not empty 4");
+  gEmptyLocal1 = gLocalIncomingServer.rootFolder.createLocalSubfolder("empty 1");
+  gEmptyLocal2 = gLocalIncomingServer.rootFolder.createLocalSubfolder("empty 2");
+  gEmptyLocal3 = gLocalIncomingServer.rootFolder.createLocalSubfolder("empty 3");
+  gNotEmptyLocal4 = gLocalIncomingServer.rootFolder.createLocalSubfolder("not empty 4");
 
   let messageGenerator = new MessageGenerator();
   let message = messageGenerator.makeMessage();
   gNotEmptyLocal4.QueryInterface(Ci.nsIMsgLocalMailFolder);
   gNotEmptyLocal4.addMessage(message.toMboxString());
 
   // Get the server list...
   gIMAPIncomingServer.performExpand(null);
--- a/mailnews/imap/test/unit/test_localToImapFilter.js
+++ b/mailnews/imap/test/unit/test_localToImapFilter.js
@@ -139,18 +139,18 @@ function run_test()
 
   // The server doesn't support more than one connection
   let prefBranch = Cc["@mozilla.org/preferences-service;1"]
                      .getService(Ci.nsIPrefBranch);
   prefBranch.setIntPref("mail.server.default.max_cached_connections", 1);
   // We aren't interested in downloading messages automatically
   prefBranch.setBoolPref("mail.server.default.download_on_biff", false);
 
-  gEmptyLocal1 = gLocalIncomingServer.rootFolder.addSubfolder("empty 1");
-  gEmptyLocal2 = gLocalIncomingServer.rootFolder.addSubfolder("empty 2");
+  gEmptyLocal1 = gLocalIncomingServer.rootFolder.createLocalSubfolder("empty 1");
+  gEmptyLocal2 = gLocalIncomingServer.rootFolder.createLocalSubfolder("empty 2");
   gIMAPIncomingServer.performExpand(null);
 
   gRootFolder = gIMAPIncomingServer.rootFolder;
   gIMAPInbox = gRootFolder.getChildNamed("INBOX");
   dump("gIMAPInbox uri = " + gIMAPInbox.URI + "\n");
   let msgImapFolder = gIMAPInbox.QueryInterface(Ci.nsIMsgImapMailFolder);
   // these hacks are required because we've created the inbox before
   // running initial folder discovery, and adding the folder bails
--- a/mailnews/local/public/nsIMsgLocalMailFolder.idl
+++ b/mailnews/local/public/nsIMsgLocalMailFolder.idl
@@ -51,17 +51,17 @@ interface nsIMsgCopyServiceListener;
 #define POP3_NONE 0
 #define POP3_DELETE 1
 #define POP3_FETCH_BODY 2
 #define POP3_FORCE_DEL 3
 
 struct nsLocalFolderScanState;
 %}
 
-[scriptable, uuid(73d0ae1b-cceb-4a74-a7dd-048b15b20fa7)]
+[scriptable, uuid(d3c496fa-9847-4f1c-94dd-0ce92b598ae3)]
 interface nsIMsgLocalMailFolder : nsISupports {
   /**
    * set the default flags on the subfolders of this folder, such as
    * Drafts, Templates, etc
    * you should bitwise OR all the flags all mailboxes you want to flag,
    * this function will be smart and find the right names.
    * like nsMsgFolderFlags::Inbox | nsMsgFolderFlags::Drafts | etc
    */
@@ -80,16 +80,24 @@ interface nsIMsgLocalMailFolder : nsISup
   void parseFolder(in nsIMsgWindow aMsgWindow, in nsIUrlListener listener);
   void copyFolderLocal(in nsIMsgFolder srcFolder, in boolean isMove, in nsIMsgWindow msgWindow, in nsIMsgCopyServiceListener listener );
   void copyAllSubFolders(in nsIMsgFolder srcFolder, in nsIMsgWindow msgWindow, in nsIMsgCopyServiceListener listener );
   void onCopyCompleted(in nsISupports aSrcSupport, in boolean aMoveCopySucceeded);
   attribute boolean checkForNewMessagesAfterParsing;
   void markMsgsOnPop3Server(in nsIArray aMessages, in PRInt32 aMark);
   void refreshSizeOnDisk(); // file size on disk has possibly changed - update and notify
 
+  /**
+   * Creates a subfolder to the current folder with the passed in folder name.
+   * @param aFolderName name of the folder to create.
+   *
+   * @return newly created folder.
+   */
+  nsIMsgFolder createLocalSubfolder(in AString aFolderName);
+
   // this adds a message to the end of the folder, parsing it as it goes, and
   // applying filters, if applicable.
   void addMessage(in string aMessage);
   /**
    * Add one or more messages to the end of the folder in a single batch.  Each
    * batch requires an fsync() on the mailbox file so it is a good idea to
    * try and minimize the number of calls you make to this method or addMessage.
    *
--- a/mailnews/local/src/nsLocalMailFolder.cpp
+++ b/mailnews/local/src/nsLocalMailFolder.cpp
@@ -288,16 +288,27 @@ nsresult nsMsgLocalMailFolder::CreateChi
   if (!newFolder)
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*folder = newFolder);
   newFolder->Init(uri.get());
   return NS_OK;
 }
 
+NS_IMETHODIMP nsMsgLocalMailFolder::CreateLocalSubfolder(const nsAString &aName,
+                                                         nsIMsgFolder **aChild)
+{
+  nsresult rv = CreateSubfolderInternal(aName, nsnull, aChild);
+  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIMsgFolderNotificationService> notifier(do_GetService(NS_MSGNOTIFICATIONSERVICE_CONTRACTID));
+  if (notifier)
+    notifier->NotifyFolderAdded(*aChild);
+  return rv;
+}
+
 NS_IMETHODIMP nsMsgLocalMailFolder::AddSubfolder(const nsAString &name,
                                                  nsIMsgFolder **child)
 {
   nsresult rv = nsMsgDBFolder::AddSubfolder(name, child);
   NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr <nsILocalFile> path;
   // need to make sure folder exists...
   (*child)->GetFilePath(getter_AddRefs(path));
--- a/mailnews/local/test/unit/test_fileName.js
+++ b/mailnews/local/test/unit/test_fileName.js
@@ -59,17 +59,17 @@ function run_test() {
   let defaultAccount = acctMgr.defaultAccount;
 
   let pop3Server = acctMgr.FindServer("user", "poptest", "pop3");
   var rootFolder = gLocalIncomingServer.rootMsgFolder;
   let pop3Root = pop3Server.rootMsgFolder;
   
   // Note: Inbox is not created automatically when there is no deferred server,
   // so we need to create it.
-  gLocalInboxFolder = rootFolder.addSubfolder("Inbox");
+  gLocalInboxFolder = rootFolder.createLocalSubfolder("Inbox");
   // a local inbox should have a Mail flag!
   gLocalInboxFolder.setFlag(Ci.nsMsgFolderFlags.Mail);
   
   let rootFolder = gLocalIncomingServer.rootMsgFolder;
   let bugmail = rootFolder.getChildNamed("bugmail:1");
   do_check_eq(bugmail.getTotalMessages(false), 1);
   bugmail = pop3Root.getChildNamed("bugmail:1");
   do_check_eq(bugmail.getTotalMessages(false), 1);
--- a/mailnews/local/test/unit/test_localSubFolders.js
+++ b/mailnews/local/test/unit/test_localSubFolders.js
@@ -12,35 +12,35 @@ function run_test() {
   // Create a local mail account (we need this first)
   acctMgr.createLocalMailAccount();
 
   // Get the account
   var account = acctMgr.accounts.GetElementAt(0)
                        .QueryInterface(Components.interfaces.nsIMsgAccount);
 
   // Get the root folder
-  var root = account.incomingServer.rootFolder;
+  var root = account.incomingServer.rootFolder.QueryInterface(Ci.nsIMsgLocalMailFolder);
 
   // Give it a poke so that the directories all exist
   root.subFolders;
 
   // Test - num/hasSubFolders
 
   // Get the current number of folders
   var numSubFolders = root.numSubFolders;
 
-  var folder = root.addSubfolder("folder1", null);
+  var folder = root.createLocalSubfolder("folder1").QueryInterface(Ci.nsIMsgLocalMailFolder);
 
   do_check_true(root.hasSubFolders);
   do_check_eq(root.numSubFolders, numSubFolders + 1);
 
   do_check_false(folder.hasSubFolders);
   do_check_eq(folder.numSubFolders, 0);
 
-  var folder2 = folder.addSubfolder("folder2", null);
+  var folder2 = folder.createLocalSubfolder("folder2");
 
   do_check_true(folder.hasSubFolders);
   do_check_eq(folder.numSubFolders, 1);
 
   // Test - getChildNamed
 
   do_check_eq(root.getChildNamed("folder1"), folder);
 
@@ -89,17 +89,17 @@ function run_test() {
   folder.setFlag(nsMsgFolderFlags.CheckNew);
   folder2.setFlag(nsMsgFolderFlags.Offline);
 
   do_check_eq(root.getFolderWithFlags(nsMsgFolderFlags.CheckNew),
               folder);
 
   // Test - Move folders around
 
-  var folder3 = root.addSubfolder("folder3");
+  var folder3 = root.createLocalSubfolder("folder3");
   var folder3Local = folder3.QueryInterface(Components.interfaces.nsIMsgLocalMailFolder);
   var folder1Local = folder.QueryInterface(Components.interfaces.nsIMsgLocalMailFolder);
 
   // put a single message in folder1.
   let messageGenerator = new MessageGenerator();
   let message = messageGenerator.makeMessage();
   folder1Local.addMessage(message.toMboxString());
 
@@ -115,17 +115,21 @@ function run_test() {
     root.getChildNamed("folder1");
   }
   catch (e) {
     thrown = true;
   }
 
   do_check_true(thrown);
 
+  if (folder.filePath.exists())
+    dump("shouldn't exist - folder file path " + folder.URI + "\n");
   do_check_false(folder.filePath.exists());
+  if (folder2.filePath.exists())
+    dump("shouldn't exist - folder2 file path " + folder2.URI + "\n");
   do_check_false(folder2.filePath.exists());
 
   // make sure getting the db doesn't throw an exception
   let db = folder1Moved.msgDatabase;
   do_check_true(db.summaryValid);
 
   // Move folders back, get them
   var rootLocal = root.QueryInterface(Components.interfaces.nsIMsgLocalMailFolder);
--- a/mailnews/local/test/unit/test_pop3Password2.js
+++ b/mailnews/local/test/unit/test_pop3Password2.js
@@ -166,21 +166,21 @@ function run_test() {
 
   var acctMgr = Cc["@mozilla.org/messenger/account-manager;1"]
                   .getService(Ci.nsIMsgAccountManager);
 
   acctMgr.LoadAccounts();
 
   gLocalIncomingServer = acctMgr.localFoldersServer;
 
-  var rootFolder = gLocalIncomingServer.rootMsgFolder;
+  var rootFolder = gLocalIncomingServer.rootMsgFolder.QueryInterface(Ci.nsIMsgLocalMailFolder);
 
   // Note: Inbox is not created automatically when there is no deferred server,
   // so we need to create it.
-  gLocalInboxFolder = rootFolder.addSubfolder("Inbox");
+  gLocalInboxFolder = rootFolder.createLocalSubfolder("Inbox");
   // a local inbox should have a Mail flag!
   gLocalInboxFolder.setFlag(Ci.nsMsgFolderFlags.Mail);
 
   // Create the incoming server with "original" details.
   incomingServer = acctMgr.getIncomingServer("server2");
 
   // Check that we haven't got any messages in the folder, if we have its a test
   // setup issue.
--- a/mailnews/test/resources/mailTestUtils.js
+++ b/mailnews/test/resources/mailTestUtils.js
@@ -66,21 +66,23 @@ function loadLocalMailAccount()
     return;
   
   MailServices.accounts.createLocalMailAccount();
 
   gLocalIncomingServer = MailServices.accounts.localFoldersServer;
   gLocalMsgAccount = MailServices.accounts.FindAccountForServer(
     gLocalIncomingServer);
 
-  var rootFolder = gLocalIncomingServer.rootMsgFolder;
+  var rootFolder = gLocalIncomingServer.rootMsgFolder
+                     .QueryInterface(Ci.nsIMsgLocalMailFolder);
 
   // Note: Inbox is not created automatically when there is no deferred server,
   // so we need to create it.
-  gLocalInboxFolder = rootFolder.addSubfolder("Inbox");
+  gLocalInboxFolder = rootFolder.createLocalSubfolder("Inbox")
+                       .QueryInterface(Ci.nsIMsgLocalMailFolder);
   // a local inbox should have a Mail flag!
   gLocalInboxFolder.setFlag(Ci.nsMsgFolderFlags.Mail);
 
   // Force an initialization of the Inbox folder database.
   var folderName = gLocalInboxFolder.prettiestName;
 
   _localAccountInitialized = true;
 }
--- a/mailnews/test/resources/messageInjection.js
+++ b/mailnews/test/resources/messageInjection.js
@@ -335,17 +335,18 @@ const SEARCH_TERM_MAP_HELPER = {
 function make_empty_folder(aFolderName, aSpecialFlags) {
   if (aFolderName == null)
     aFolderName = "gabba" + _messageInjectionSetup._nextUniqueFolderId++;
   let testFolder;
 
   let mis = _messageInjectionSetup;
 
   if (mis.injectionConfig.mode == "local") {
-    testFolder = mis.rootFolder.addSubfolder(aFolderName);
+    let localRoot = mis.rootFolder.QueryInterface(Ci.nsIMsgLocalMailFolder);
+    testFolder = localRoot.createLocalSubfolder(aFolderName);
     // it seems dumb that we have to set this.
     testFolder.setFlag(Ci.nsMsgFolderFlags.Mail);
     if (aSpecialFlags) {
       for each (let [, flag] in Iterator(aSpecialFlags)) {
         testFolder.setFlag(flag);
       }
     }
     _messageInjectionSetup.notifyListeners("onRealFolderCreated",