Bug 467116 -- Merge default client dialog and search integration dialog into an "OS Integration" dialog. r=bienvenu+humph, ui-r=clarkbw, r=Standard8 for additional changes
authorSiddharth Agarwal <sid.bugzilla@gmail.com>
Fri, 15 May 2009 16:10:34 +0530
changeset 2648 16fea4d289f6310dcb7db3cd8b5cadb85a8627b9
parent 2647 a285d6d942be691a2662143adefd8441171ba983
child 2649 2dfdbe90425f960cc36f78038ff841eb519c047d
push idunknown
push userunknown
push dateunknown
reviewersbienvenu, clarkbw, Standard8
bugs467116
Bug 467116 -- Merge default client dialog and search integration dialog into an "OS Integration" dialog. r=bienvenu+humph, ui-r=clarkbw, r=Standard8 for additional changes
mail/app/profile/all-thunderbird.js
mail/base/content/defaultClientDialog.js
mail/base/content/defaultClientDialog.xul
mail/base/content/msgMail3PaneWindow.js
mail/base/content/systemIntegrationDialog.js
mail/base/content/systemIntegrationDialog.xul
mail/base/jar.mn
mail/components/Makefile.in
mail/components/preferences/advanced.js
mail/components/preferences/advanced.xul
mail/components/search/Makefile.in
mail/components/search/SearchIntegration.js
mail/components/search/SpotlightIntegration.js
mail/components/search/WinSearchIntegration.js
mail/components/search/content/searchCommon.js
mail/components/search/content/searchIntegrationDialog.xul
mail/components/search/content/searchOverlay.js
mail/components/search/jar.mn
mail/components/search/wsenable/WSEnable.cpp
mail/locales/en-US/chrome/messenger/defaultClientDialog.dtd
mail/locales/en-US/chrome/messenger/preferences/advanced.dtd
mail/locales/en-US/chrome/messenger/search/searchIntegrationDialogWin.dtd
mail/locales/en-US/chrome/messenger/searchIntegrationDefault.dtd
mail/locales/en-US/chrome/messenger/searchIntegrationMac.dtd
mail/locales/en-US/chrome/messenger/searchIntegrationWin.dtd
mail/locales/en-US/chrome/messenger/systemIntegrationDialog.dtd
mail/locales/jar.mn
mailnews/test/performance/common/mailnewsTestPrefs.js
--- a/mail/app/profile/all-thunderbird.js
+++ b/mail/app/profile/all-thunderbird.js
@@ -425,18 +425,24 @@ pref("mail.tabs.closeWindowWithLastTab",
 // 2 - no close buttons
 // 3 - at the end of the tabstrip
 pref("mail.tabs.closeButtons", 1);
 
 // The breakpad report server to link to in about:crashes
 pref("breakpad.reportURL", "http://crash-stats.mozilla.com/report/index/");
 
 // OS Integrated Search and Indexing
+#ifdef XP_WIN
+pref("mail.winsearch.enable", false);
+pref("mail.winsearch.firstRunDone", false);
+#else
 #ifdef XP_MACOSX
 pref("mail.spotlight.enable", false);
+pref("mail.spotlight.firstRunDone", false);
+#endif
 #endif
 
 // -- Windows Search/Spotlight logging options
 #ifdef XP_WIN
 // Should we output warnings and errors to the "error console"?
 pref("mail.winsearch.logging.console", false);
 // Should we output all output levels to stdout via dump?
 pref("mail.winsearch.logging.dump", false);
--- a/mail/base/content/msgMail3PaneWindow.js
+++ b/mail/base/content/msgMail3PaneWindow.js
@@ -720,44 +720,54 @@ function LoadPostAccountWizard()
       gStartFolderUri = null;
     }
     else
       gStartFolderUri = (window.arguments.length > 0) ? window.arguments[0] : null;
     gStartMsgKey = (window.arguments.length > 1) ? window.arguments[1]: nsMsgKey_None;
     gSearchEmailAddress = (window.arguments.length > 2) ? window.arguments[2] : null;
   }
 
-  function showDefaultClientDialog() {
+  function completeStartup() {
 #ifdef HAVE_SHELL_SERVICE
+    // Check whether we need to show the default client dialog
+    // First, check the shell service
     var nsIShellService = Components.interfaces.nsIShellService;
     var shellService;
     var defaultAccount;
     try {
       shellService = Components.classes["@mozilla.org/mail/shell-service;1"].getService(nsIShellService);
       defaultAccount = accountManager.defaultAccount;
     } catch (ex) {}
 
-    // Show the default client dialog only if we have at least one account,
-    // we should check for the default client, and we aren't already the default
-    // for mail.
+    // Next, try loading the search integration module
+    // We'll get a null SearchIntegration if we don't have one
+    Components.utils.import("resource://app/modules/SearchIntegration.js");
+
+    // Show the default client dialog only if
+    // EITHER: we have at least one account, and we aren't already the default
+    // for mail,
+    // OR: we have the search integration module, the OS version is suitable,
+    // and the first run hasn't already been completed.
     // Needs to be shown outside the he normal load sequence so it doesn't appear
     // before any other displays, in the wrong place of the screen.
-    if (shellService && defaultAccount && shellService.shouldCheckDefaultClient
-        && !shellService.isDefaultClient(true, nsIShellService.MAIL))
-      window.openDialog("chrome://messenger/content/defaultClientDialog.xul",
-                        "DefaultClient", "modal,centerscreen,chrome,resizable=no");
+    if ((shellService && defaultAccount && shellService.shouldCheckDefaultClient
+         && !shellService.isDefaultClient(true, nsIShellService.MAIL)) ||
+        (SearchIntegration && !SearchIntegration.osVersionTooLow &&
+         !SearchIntegration.osComponentsNotRunning && !SearchIntegration.firstRunDone))
+      window.openDialog("chrome://messenger/content/systemIntegrationDialog.xul",
+                        "SystemIntegration", "modal,centerscreen,chrome,resizable=no");
 #endif
 
     // All core modal dialogs are done, the user can now interact with the 3-pane window
     var obs = Components.classes["@mozilla.org/observer-service;1"]
                         .getService(Components.interfaces.nsIObserverService);
     obs.notifyObservers(window, "mail-startup-done", null);
   }
 
-  setTimeout(showDefaultClientDialog, 0);
+  setTimeout(completeStartup, 0);
 
   // FIX ME - later we will be able to use onload from the overlay
   OnLoadMsgHeaderPane();
 
   gHaveLoadedMessage = false;
 
   //Set focus to the Thread Pane the first time the window is opened.
   SetFocusThreadPane();
rename from mail/base/content/defaultClientDialog.js
rename to mail/base/content/systemIntegrationDialog.js
--- a/mail/base/content/defaultClientDialog.js
+++ b/mail/base/content/systemIntegrationDialog.js
@@ -32,17 +32,20 @@
 # 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 *****
 
 // this dialog can only be opened if we have a shell service
 
-var gDefaultClientDialog = {
+var gSystemIntegrationDialog = {
+  /// Whether the search integration checkbox is disabled or hidden
+  _searchCheckboxInactive: false,
+  
   onLoad: function () 
   {
     var nsIShellService = Components.interfaces.nsIShellService;
     var shellSvc = Components.classes["@mozilla.org/mail/shell-service;1"]
                              .getService(nsIShellService);
                                
     // initialize the check boxes based on the default app states.
     var mailCheckbox = document.getElementById('checkMail');
@@ -54,17 +57,51 @@ var gDefaultClientDialog = {
     // for the user. We'll leave news and RSS alone.
     mailCheckbox.checked = true;
     newsCheckbox.checked = newsCheckbox.disabled = shellSvc.isDefaultClient(false, nsIShellService.NEWS);
     rssCheckbox.checked  = rssCheckbox.disabled  = shellSvc.isDefaultClient(false, nsIShellService.RSS);       
     
     // read the raw pref value and not shellSvc.shouldCheckDefaultMail
     var prefs = Components.classes["@mozilla.org/preferences-service;1"]
                 .getService(Components.interfaces.nsIPrefBranch);
-    document.getElementById('checkOnStartup').checked = prefs.getBoolPref("mail.shell.checkDefaultClient");    
+    document.getElementById('checkOnStartup').checked = prefs.getBoolPref("mail.shell.checkDefaultClient");
+
+    // Search integration -- check whether we should hide or disable integration
+    let hideSearchUI = false;
+    let disableSearchUI = false;
+    Components.utils.import("resource://app/modules/SearchIntegration.js");
+    if (SearchIntegration)
+    {
+      if (SearchIntegration.osVersionTooLow)
+        hideSearchUI = true;
+      else if (SearchIntegration.osComponentsNotRunning)
+        disableSearchUI = true;
+    }
+    else
+    {
+      hideSearchUI = true;
+    }
+
+    let searchCheckbox = document.getElementById("searchIntegration");
+
+    if (hideSearchUI)
+    {
+      this._searchCheckboxInactive = true;
+      document.getElementById("searchIntegrationContainer").hidden = true;
+    }
+    else if (disableSearchUI)
+    {
+      this._searchCheckboxInactive = true;
+      searchCheckbox.checked = false;
+      searchCheckbox.disabled = true;
+    }
+    else
+    {
+      searchCheckbox.checked = SearchIntegration.prefEnabled;
+    }
   },
   
   onAccept: function()
   {
     // for each checked item, if we aren't already the default, make us the default.
     var nsIShellService = Components.interfaces.nsIShellService;    
     var shellSvc = Components.classes["@mozilla.org/mail/shell-service;1"]
                              .getService(nsIShellService);
@@ -75,10 +112,18 @@ var gDefaultClientDialog = {
       appTypes |= nsIShellService.NEWS;
     if (document.getElementById('checkRSS').checked &&  !shellSvc.isDefaultClient(false, nsIShellService.RSS))
       appTypes |= nsIShellService.RSS;
     
     if (appTypes)
       shellSvc.setDefaultClient(false, appTypes);
 
     shellSvc.shouldCheckDefaultClient = document.getElementById('checkOnStartup').checked;
+    
+    // Set the search integration pref if it's changed
+    // The integration will handle the rest
+    if (!this._searchCheckboxInactive)
+    {
+      SearchIntegration.prefEnabled = document.getElementById("searchIntegration").checked;
+      SearchIntegration.firstRunDone = true;
+    }
   }
 };
rename from mail/base/content/defaultClientDialog.xul
rename to mail/base/content/systemIntegrationDialog.xul
--- a/mail/base/content/defaultClientDialog.xul
+++ b/mail/base/content/systemIntegrationDialog.xul
@@ -37,33 +37,50 @@
 #
 # ***** END LICENSE BLOCK *****
 
 <?xml-stylesheet href="chrome://global/skin/"?>
 
 <!DOCTYPE window [
   <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
   %brandDTD;
-  <!ENTITY % defaultClientDTD SYSTEM "chrome://messenger/locale/defaultClientDialog.dtd" >
-  %defaultClientDTD;
+  <!ENTITY % systemIntegrationDTD SYSTEM "chrome://messenger/locale/systemIntegrationDialog.dtd" >
+  %systemIntegrationDTD;
+#ifdef XP_WIN
+  <!ENTITY % searchIntegrationWinDTD SYSTEM "chrome://messenger/locale/searchIntegrationWin.dtd" >
+  %searchIntegrationWinDTD;
+#else
+#ifdef XP_MACOSX
+  <!ENTITY % searchIntegrationMacDTD SYSTEM "chrome://messenger/locale/searchIntegrationMac.dtd" >
+  %searchIntegrationMacDTD;
+#else
+  <!ENTITY % searchIntegrationDefaultDTD SYSTEM "chrome://messenger/locale/searchIntegrationDefault.dtd" >
+  %searchIntegrationDefaultDTD;
+#endif
+#endif
 ]>
 
 <dialog xmlns:html="http://www.w3.org/1999/xhtml"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        id="defaultClientDialog"
+        id="systemIntegrationDialog"
         buttons="accept,cancel"
-        onload="gDefaultClientDialog.onLoad();"
-        ondialogaccept="return gDefaultClientDialog.onAccept();"
-        title="&defaultClient.title;">
+        onload="gSystemIntegrationDialog.onLoad();"
+        ondialogaccept="return gSystemIntegrationDialog.onAccept();"
+        title="&systemIntegration.title;">
   
-  <script type="application/x-javascript" src="chrome://messenger/content/defaultClientDialog.js"/>
+  <script type="application/x-javascript" src="chrome://messenger/content/systemIntegrationDialog.js"/>
   
   <label control="defaultClientList">&defaultClient.intro;</label>
   <listbox rows="3" seltype="single" id="defaultClientList">   
     <listitem id="checkMail" type="checkbox" label="&email.label;"/>
     <listitem id="checkNews" type="checkbox" label="&newsgroups.label;"/>
     <listitem id="checkRSS"  type="checkbox" label="&feeds.label;"/>
   </listbox>
 
+  <!-- Wrap this in a vbox to hide if there's no search integration available -->
+  <vbox id="searchIntegrationContainer">
+    <checkbox id="searchIntegration" label="&searchIntegration.label;" accesskey="&searchIntegration.accesskey;"/>
+  </vbox>
+
   <separator class="thin"/>
   <checkbox id="checkOnStartup" label="&checkOnStartup.label;" accesskey="&checkOnStartup.accesskey;"/>
 
 </dialog>
--- a/mail/base/jar.mn
+++ b/mail/base/jar.mn
@@ -43,18 +43,18 @@ messenger.jar:
 *   content/messenger/FilterListDialog.xul          (content/FilterListDialog.xul)
 *   content/messenger/FilterListDialog.js           (content/FilterListDialog.js)
     content/messenger/specialTabs.js                (content/specialTabs.js)
 *   content/messenger/subscribe.xul                 (content/subscribe.xul)
     content/messenger/subscribe.js                  (content/subscribe.js)
 *   content/messenger/aboutDialog.xul               (content/aboutDialog.xul)
 *   content/messenger/aboutDialog.js                (content/aboutDialog.js)
 *   content/messenger/aboutRights.xhtml             (content/aboutRights.xhtml)
-*   content/messenger/defaultClientDialog.xul       (content/defaultClientDialog.xul)
-*   content/messenger/defaultClientDialog.js        (content/defaultClientDialog.js)
+*   content/messenger/systemIntegrationDialog.xul   (content/systemIntegrationDialog.xul)
+*   content/messenger/systemIntegrationDialog.js    (content/systemIntegrationDialog.js)
     content/messenger/folderPane.js                 (content/folderPane.js)
 *   content/messenger/msgSelectOffline.xul          (content/msgSelectOffline.xul)
 *   content/messenger/msgPrintEngine.xul            (content/msgPrintEngine.xul)
 *   content/messenger/searchBar.js                  (content/searchBar.js)
 *   content/messenger/phishingDetector.js           (content/phishingDetector.js)
 *   content/messenger/mail-offline.js               (content/mail-offline.js)
     content/messenger/about-footer.png              (content/about-footer.png)
     content/messenger/aboutDialog.css               (content/aboutDialog.css)
--- a/mail/components/Makefile.in
+++ b/mail/components/Makefile.in
@@ -37,36 +37,28 @@
 
 DEPTH   = ../..
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH   = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-DIRS    = compose preferences addrbook migration activity
+# Only Mac and Windows have search integration components, but we include at
+# least one module from search/ on all platforms
+DIRS    = compose preferences addrbook migration activity search
 
 ifneq (,$(filter windows gtk2 mac cocoa, $(MOZ_WIDGET_TOOLKIT)))
 DIRS += shell
 endif
 
 ifdef MOZ_SAFE_BROWSING
 DIRS += phishing 
 endif
 
-# Mac and Windows have search integration components
-ifneq (,$(filter cocoa mac, $(MOZ_WIDGET_TOOLKIT)))
-DIRS += search
-endif
-ifneq (,$(filter windows, $(MOZ_WIDGET_TOOLKIT)))
-ifndef MOZ_DISABLE_VISTA_SDK_REQUIREMENTS
-DIRS += search
-endif
-endif
-
 DIRS += build
 
 EXTRA_COMPONENTS = \
 	nsMailDefaultHandler.js \
 	aboutRights.js \
 	$(NULL)
 
 EXTRA_JS_MODULES = \
--- a/mail/components/preferences/advanced.js
+++ b/mail/components/preferences/advanced.js
@@ -53,16 +53,44 @@ var gAdvancedPane = {
       if (preference.value)
         document.getElementById("advancedPrefs").selectedIndex = preference.value;
     }
 #ifdef MOZ_UPDATER
     this.updateAppUpdateItems();
     this.updateAutoItems();
     this.updateModeItems();
 #endif
+
+    // Search integration -- check whether we should hide or disable integration
+    let hideSearchUI = false;
+    let disableSearchUI = false;
+    Components.utils.import("resource://app/modules/SearchIntegration.js");
+    if (SearchIntegration)
+    {
+      if (SearchIntegration.osVersionTooLow)
+        hideSearchUI = true;
+      else if (SearchIntegration.osComponentsNotRunning)
+        disableSearchUI = true;
+    }
+    else
+    {
+      hideSearchUI = true;
+    }
+
+    if (hideSearchUI)
+    {
+      document.getElementById("searchIntegrationContainer").hidden = true;
+    }
+    else if (disableSearchUI)
+    {
+      let searchCheckbox = document.getElementById("searchIntegration");
+      searchCheckbox.checked = false;
+      document.getElementById("search-enable").disabled = true;
+    }
+
     this.mInitialized = true;
   },
 
   tabSelectionChanged: function ()
   {
     if (this.mInitialized)
     {
       document.getElementById("mail.preferences.advanced.selectedTabIndex")
@@ -101,18 +129,18 @@ var gAdvancedPane = {
 
       var promptMessage = preferencesBundle.getFormattedString("alreadyDefault",
                                                                [brandShortName]);
       psvc.alert(window, promptTitle, promptMessage);
     }
     else
     {
       // otherwise, bring up the default client dialog
-      window.openDialog("chrome://messenger/content/defaultClientDialog.xul",
-                        "Default Client",
+      window.openDialog("chrome://messenger/content/systemIntegrationDialog.xul",
+                        "SystemIntegration",
                         "modal,centerscreen,chrome,resizable=no");
     }
   },
 #endif
 
   showConfigEdit: function()
   {
     document.documentElement.openWindow("Preferences:ConfigManager",
--- a/mail/components/preferences/advanced.xul
+++ b/mail/components/preferences/advanced.xul
@@ -37,16 +37,28 @@
 #
 # ***** END LICENSE BLOCK *****
 
 <!DOCTYPE overlay [
 <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
 <!ENTITY % advancedDTD SYSTEM "chrome://messenger/locale/preferences/advanced.dtd">
 %brandDTD;
 %advancedDTD;
+#ifdef XP_WIN
+<!ENTITY % searchIntegrationWinDTD SYSTEM "chrome://messenger/locale/searchIntegrationWin.dtd" >
+%searchIntegrationWinDTD;
+#else
+#ifdef XP_MACOSX
+<!ENTITY % searchIntegrationMacDTD SYSTEM "chrome://messenger/locale/searchIntegrationMac.dtd" >
+%searchIntegrationMacDTD;
+#else
+<!ENTITY % searchIntegrationDefaultDTD SYSTEM "chrome://messenger/locale/searchIntegrationDefault.dtd" >
+%searchIntegrationDefaultDTD;
+#endif
+#endif
 ]>
 
 <overlay id="AdvancedPaneOverlay"
          xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <prefpane id="paneAdvanced" onpaneload="gAdvancedPane.init();">
     <script type="application/x-javascript" src="chrome://messenger/content/preferences/advanced.js"/>
 
@@ -60,16 +72,29 @@
 #ifdef HAVE_SHELL_SERVICE
       <preference id="mail.shell.checkDefaultClient"
                   name="mail.shell.checkDefaultClient"
                   type="bool"/>
       <preference id="pref.general.disable_button.default_mail"
                   name="pref.general.disable_button.default_mail"
                   type="bool"/>
 #endif
+      <!-- Keep one id, so that we don't have to do platform specific stuff later -->
+#ifdef XP_WIN
+      <preference id="search-enable"
+                  name="mail.winsearch.enable"
+                  type="bool"/>
+#else
+#ifdef XP_MACOSX
+      <preference id="search-enable"
+                  name="mail.spotlight.enable"
+                  type="bool"/>
+#endif
+#endif
+
       <!-- Display & Reading tab -->
       <preference id="mail.showCondensedAddresses" name="mail.showCondensedAddresses" type="bool"/>
       <preference id="mailnews.mark_message_read.auto"
                   name="mailnews.mark_message_read.auto" type="bool"/>
       <preference id="mailnews.mark_message_read.delay"
                   name="mailnews.mark_message_read.delay" type="bool"
                   onchange="gAdvancedPane.updateMarkAsReadTextbox(this.value);"/>
       <preference id="mailnews.mark_message_read.delay.interval"
@@ -128,28 +153,34 @@
           <hbox align="center">
             <description flex="1">&returnReceiptsInfo.label;</description>
             <button label="&showReturnReceipts.label;"
                     accesskey="&showReturnReceipts.accesskey;"
                     oncommand="gAdvancedPane.showReturnReceipts();"/>
           </hbox>
 
 #ifdef HAVE_SHELL_SERVICE
-          <groupbox id="systemDefaultsGroup" orient="horizontal">
-            <caption label="&systemDefaults.label;"/>
+          <groupbox id="systemDefaultsGroup" orient="vertical">
+            <caption label="&systemIntegration.label;"/>
             <hbox id="checkDefaultBox" align="center" flex="1">
               <checkbox id="alwaysCheckDefault"
                         preference="mail.shell.checkDefaultClient"
                         label="&alwaysCheckDefault.label;"
                         accesskey="&alwaysCheckDefault.accesskey;" flex="1"/>
               <button id="checkDefaultButton" label="&checkNow.label;"
                       accesskey="&checkNow.accesskey;"
                       oncommand="gAdvancedPane.checkDefaultNow();"
                       preference="pref.general.disable_button.default_mail"/>
             </hbox>
+            <hbox id="searchIntegrationContainer">
+              <checkbox id="searchIntegration"
+                        preference="search-enable"
+                        label="&searchIntegration.label;"
+                        accesskey="&searchIntegration.accesskey;"/>
+            </hbox>
           </groupbox>
 #endif
           <groupbox>
             <caption label="&configEditDesc.label;"/>
             <vbox>
               <hbox>
                 <checkbox id="enableGloda"
                           preference="mailnews.database.global.indexer.enabled"
--- a/mail/components/search/Makefile.in
+++ b/mail/components/search/Makefile.in
@@ -14,16 +14,17 @@
 # The Original Code is spotlight search integration.
 #
 # The Initial Developer of the Original Code is
 #  David Bienvenu <bienvenu@mozilla.comg>.
 # Portions created by the Initial Developer are Copyright (C) 2007
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
+#  Siddharth Agarwal <sid.bugzilla@gmail.com>
 #
 # 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
@@ -36,35 +37,41 @@
 
 DEPTH     = ../../..
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
+# Include SearchIntegration.js on all platforms
+EXTRA_PP_JS_MODULES = \
+  SearchIntegration.js \
+  $(NULL)
 
 ifneq (,$(filter cocoa mac, $(MOZ_WIDGET_TOOLKIT)))
 DIRS += mdimporter
 endif
 
 ifneq (,$(filter windows, $(MOZ_WIDGET_TOOLKIT)))
+ifndef MOZ_DISABLE_VISTA_SDK_REQUIREMENTS
 DIRS += wsenable
 endif
+endif
 
-#currently, we only build this dir on the mac, but if it gets built on other platforms,
-#make sure we still only build spotlight integration on the mac.
+# If on Mac, build Spotlight integration
 ifneq (,$(filter cocoa mac, $(MOZ_WIDGET_TOOLKIT)))
-EXTRA_PP_JS_MODULES = \
-	SpotlightIntegration.js \
-	$(NULL)
+EXTRA_PP_JS_MODULES += \
+  SpotlightIntegration.js \
+  $(NULL)
 endif
 
 # If on Windows, build Windows Search integration
 ifneq (,$(filter windows, $(MOZ_WIDGET_TOOLKIT)))
+ifndef MOZ_DISABLE_VISTA_SDK_REQUIREMENTS
 MODULE = mailwinsearch
 LIBRARY_NAME = winsearch_s
 MODULE_NAME = nsMailWinSearchHelperModule
 ifdef BUILD_STATIC_LIBS
 MOZILLA_INTERNAL_API = 1
 else
 ifneq ($(MOZ_WIDGET_TOOLKIT), gtk2)
 MOZILLA_INTERNAL_API = 1
@@ -78,16 +85,17 @@ REQUIRES = \
 
 CPPSRCS = \
   nsMailWinSearchHelper.cpp \
   $(NULL)
 
 DIRS += public
 
 # Windows Search component
-EXTRA_PP_JS_MODULES = \
+EXTRA_PP_JS_MODULES += \
   WinSearchIntegration.js \
   $(NULL)
 
 FORCE_STATIC_LIB = 1
 endif
+endif
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/mail/components/search/SearchIntegration.js
@@ -0,0 +1,49 @@
+/* ***** 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 Desktop search integration.
+ *
+ * The Initial Developer of the Original Code is mozilla.org code.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Siddharth Agarwal <sid.bugzilla@gmail.com>
+ *
+ * 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 ***** */
+
+var EXPORTED_SYMBOLS = ["SearchIntegration"];
+
+#ifdef XP_WIN
+Components.utils.import("resource://app/modules/WinSearchIntegration.js");
+#else
+#ifdef XP_MACOSX
+Components.utils.import("resource://app/modules/SpotlightIntegration.js");
+#else
+// Set SearchIntegration to null, as we don't have it
+var SearchIntegration = null;
+#endif
+#endif
--- a/mail/components/search/SpotlightIntegration.js
+++ b/mail/components/search/SpotlightIntegration.js
@@ -74,16 +74,30 @@ let SearchIntegration =
     let fixedPath = folderPath.replace(this._profileDir.path,
                                        "~/Library/Caches/Metadata/Thunderbird");
     let searchPath = Cc["@mozilla.org/file/local;1"]
                        .createInstance(Ci.nsILocalFile);
     searchPath.initWithPath(fixedPath);
     return searchPath;
   },
 
+  /**
+   * These two functions won't do anything, as Spotlight integration is handled
+   * using Info.plist files
+   */
+  register: function spotlight_register()
+  {
+    return true;
+  },
+
+  deregister: function spotlight_deregister()
+  {
+    return true;
+  },
+
   _init: function spotlight_init()
   {
     this._initLogging();
 
     let enabled;
     try {
       enabled = this._prefBranch.getBoolPref("enable");
     } catch (ex) {}
@@ -205,15 +219,9 @@ let SearchIntegration =
       catch (ex) {
         SearchIntegration._log.error(ex);
         this._onDoneStreaming(false);
       }
     }
   }
 };
 
-/* Initialize the search integration object */
-try {
-  SearchIntegration._init();
-}
-catch (ex) {
-  SearchIntegration._log.error("Could not initialize spotlight component");
-}
+SearchIntegration._init();
--- a/mail/components/search/WinSearchIntegration.js
+++ b/mail/components/search/WinSearchIntegration.js
@@ -112,27 +112,20 @@ let SearchIntegration =
   get _winSearchHelper()
   {
     if (!this.__winSearchHelper)
       this.__winSearchHelper = Cc["@mozilla.org/mail/windows-search-helper;1"]
                                  .getService(Ci.nsIMailWinSearchHelper);
     return this.__winSearchHelper;
   },
 
-  /**
-   * Whether the folders are already in the crawl scope
-   * We'll be optimistic here and assume that once the folders are in the scope,
-   * they won't be removed from it, at least while Thunderbird is open
-   */
-  __foldersInCrawlScope: false,
+  /// Whether the folders are already in the crawl scope
   get _foldersInCrawlScope()
   {
-    if (!this.__foldersInCrawlScope)
-      this.__foldersInCrawlScope = this._winSearchHelper.foldersInCrawlScope;
-    return this.__foldersInCrawlScope;
+    return this._winSearchHelper.foldersInCrawlScope;
   },
 
   /**
    * Whether all the required registry keys are present
    * We'll be optimistic here and assume that once the registry keys have been
    * added, they won't be removed, at least while Thunderbird is open
    */
   __regKeysPresent: false,
@@ -172,85 +165,88 @@ let SearchIntegration =
     this._initLogging();
     // We're currently only enabled on Vista and above
     let sysInfo = Cc["@mozilla.org/system-info;1"]
                     .getService(Ci.nsIPropertyBag2);
     let windowsVersion = sysInfo.getProperty("version");
     if (parseFloat(windowsVersion) < 6)
     {
       this._log.fatal("Windows version " + windowsVersion + " < 6.0");
+      this.osVersionTooLow = true;
       return;
     }
 
-    // enabled === undefined means that the first run hasn't occurred yet (pref
-    // isn't present).
-    // false or true means that the first run has occurred, and the user has
-    // made a decision.
-    let enabled;
-    try {
-      enabled = this._prefBranch.getBoolPref("enable");
-    } catch (ex) {}
-
     let serviceRunning = false;
     try {
       serviceRunning = this._winSearchHelper.serviceRunning;
     }
     catch (e) {}
     // If the service isn't running, then we should stay in backoff mode
     if (!serviceRunning)
     {
       this._log.info("Windows Search service not running");
+      this.osComponentsNotRunning = true;
       this._initSupport(false);
       return;
     }
-
-    if (enabled === undefined)
-      // First run has to be handled after the main mail window is open
-      return true;
+ 
+    let enabled = this.prefEnabled;
 
     if (enabled)
       this._log.info("Initializing Windows Search integration");
     this._initSupport(enabled);
   },
 
-  /// Handles first run, once the main mail window has popped up.
-  _firstRun: function winsearch_first_run(window)
+  /**
+   * Add necessary hooks to Windows
+   *
+   * @return false if registration did not succeed, because the elevation
+   * request was denied
+   */
+  register: function winsearch_register()
   {
-    window.openDialog(
-      "chrome://messenger/content/search/searchIntegrationDialog.xul", "",
-      "chrome, dialog, resizable=no, centerscreen", this);
+    // If any of the two are not present, we need to elevate.
+    if (!this._foldersInCrawlScope || !this._regKeysPresent)
+    {
+      try {
+        this._winSearchHelper.runSetup(true);
+      }
+      catch (e) { return false; }
+    }
+
+    if (!this._winSearchHelper.isFileAssociationSet)
+    {
+      try {
+        this._winSearchHelper.setFileAssociation();
+      }
+      catch (e) { this._log.warn("File association not set"); }
+    }
+    // Also set the FANCI bit to 0 for the profile directory
+    let profD = Cc["@mozilla.org/file/directory_service;1"]
+                  .getService(Ci.nsIProperties).get("ProfD", Ci.nsIFile);
+    this._winSearchHelper.setFANCIBit(profD, false, true);
+
+    return true;
   },
 
   /**
-   * Callback from the first run dialog
+   * Remove integration from Windows. The only thing removed is the directory
+   * from the index list. This will ask for elevation.
    *
-   * @param enable whether the user has chosen to enable integration
+   * @return false if deregistration did not succeed, because the elevation
+   * request was denied
    */
-  callback: function winsearch_first_run_callback(enable)
+  deregister: function winsearch_deregister()
   {
-    // If any of the two are not present, we need to elevate.
-    if (enable && (!this._foldersInCrawlScope || !this._regKeysPresent))
-    {
-      try { this._winSearchHelper.runSetup(true); }
-      catch (e) { enable = false; }
+    try {
+      this._winSearchHelper.runSetup(false);
     }
-    if (enable)
-    {
-      if (!this._winSearchHelper.isFileAssociationSet)
-      {
-        try { this._winSearchHelper.setFileAssociation(); }
-        catch (e) { this._log.warn("File association not set"); }
-      }
-      // Also set the FANCI bit to 0 for the profile directory
-      let profD = Cc["@mozilla.org/file/directory_service;1"]
-                    .getService(Ci.nsIProperties).get("ProfD", Ci.nsIFile);
-      this._winSearchHelper.setFANCIBit(profD, false, true);
-    }
-    this._prefBranch.setBoolPref("enable", enable);
-    this._initSupport(enable);
+    catch (e) { return false; }
+    
+    return true;
   },
 
   /// The stream listener to read messages
   _streamListener: {
     __proto__: SearchSupport._streamListenerBase,
 
     /// Buffer to store the message
     _message: "",
@@ -345,37 +341,9 @@ let SearchIntegration =
       catch (ex) {
         SearchIntegration._log.error(ex);
         this._onDoneStreaming(false);
       }
     }
   }
 };
 
-/**
- * Observer for first run dialog
- */
-let FirstRunObserver =
-{
-  observe: function(aSubject, aTopic, aData)
-  {
-    if (aTopic == "mail-startup-done")
-    {
-      aSubject.QueryInterface(Ci.nsIDOMWindowInternal);
-      Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService)
-        .removeObserver(this, "mail-startup-done");
-      try { SearchIntegration._firstRun(aSubject); }
-      catch(ex) { SearchIntegration._log.warn("First run unsuccessful"); }
-    }
-  }
-};
-
-/* Initialize the search integration object */
-try {
-  if (SearchIntegration._init())
-  {
-    Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService)
-      .addObserver(FirstRunObserver, "mail-startup-done", false);
-  }
-}
-catch (ex) {
-  SearchIntegration._log.error("Could not initialize winsearch component");
-}
+SearchIntegration._init();
--- a/mail/components/search/content/searchCommon.js
+++ b/mail/components/search/content/searchCommon.js
@@ -100,21 +100,63 @@ let SearchSupport =
 
   /// The preferences branch to use
   __prefBranch: null,
   get _prefBranch()
   {
     if (!this.__prefBranch)
       this.__prefBranch = Cc["@mozilla.org/preferences-service;1"]
                             .getService(Ci.nsIPrefService)
-                            .getBranch(this._prefBase);
+                            .getBranch(this._prefBase)
+                            .QueryInterface(Ci.nsIPrefBranch2);
     return this.__prefBranch;
   },
 
   /**
+   * If this is true, we won't show any UI because the OS doesn't have the
+   * support we need
+   */
+  osVersionTooLow: false,
+
+  /**
+   * If this is true, we'll show disabled UI, because while the OS does have
+   * the support we need, not all the OS components we need are running
+   */
+  osComponentsNotRunning: false,
+
+  /**
+   * Whether the preference is enabled. The module might be in a state where
+   * the preference is on but "enabled" is false, so take care of that.
+   */
+  get prefEnabled()
+  {
+    // Don't cache the value
+    return this._prefBranch.getBoolPref("enable");
+  },
+  set prefEnabled(aEnabled)
+  {
+    if (this.prefEnabled != aEnabled)
+      this._prefBranch.setBoolPref("enable", aEnabled);
+  },
+
+  /**
+   * Whether the first run has occurred. This will be used to determine if
+   * a dialog box needs to be displayed.
+   */
+  get firstRunDone()
+  {
+    // Don't cache this value either
+    return this._prefBranch.getBoolPref("firstRunDone");
+  },
+  set firstRunDone()
+  {
+    this._prefBranch.setBoolPref("firstRunDone", true);
+  },
+
+  /**
    * Last global reindex time, used to check if reindexing is required.
    * Kept in sync with the pref
    */
   _globalReindexTime: null,
   set globalReindexTime(aTime)
   {
     this._globalReindexTime = aTime;
     // Set the pref as well
@@ -250,16 +292,19 @@ let SearchSupport =
   /**
    * Init function -- this should be called from the component's init function
    */
   _initSupport: function search_init_support(enabled)
   {
     this._log.info("Search integration running in " +
                    (enabled ? "active" : "backoff") + " mode");
     this.enabled = enabled;
+
+    // Set up a pref observer
+    this._prefBranch.addObserver("enable", this, false);
   },
 
   /**
    * Current folder being indexed
    */
   _currentFolderToIndex: null,
 
   /**
@@ -479,16 +524,17 @@ let SearchSupport =
     SearchIntegration._continueSweep();
   },
 
   /**
    * Observer implementation. Consists of
    * - idle observer; starts running through folders when it receives an "idle"
    * notification, and cancels any timers when it receives a "back" notification
    * - msg displayed observer, queues the message if necessary
+   * - pref observer, to see if the preference has been poked
    */
   observe: function search_observe(aSubject, aTopic, aData)
   {
     if (aTopic == "idle")
     {
       this._log.debug("Idle detected, continuing sweep")
       this._continueSweep();
     }
@@ -514,16 +560,49 @@ let SearchSupport =
           msgHdr.setUint32Property(this._hdrIndexedProperty, reindexTime);
         }
         else
         {
           this._queueMessage(msgHdr, reindexTime);
         }
       }
     }
+    else if (aTopic == "nsPref:changed" && aData == "enable")
+    {
+      let prefEnabled = this.prefEnabled;
+      // Search integration turned on
+      if (prefEnabled && this.register())
+      {
+        this.enabled = true;
+      }
+      // Search integration turned off
+      else if (!prefEnabled && this.deregister())
+      {
+        this.enabled = false;
+      }
+      else
+      {
+        // The call to register or deregister has failed.
+        // This is a hack to handle this case
+        let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+        timer.initWithCallback(function() {
+          SearchIntegration._handleRegisterFailure(!prefEnabled);
+        }, 200, Ci.nsITimer.TYPE_ONE_SHOT);
+      }
+    }
+  },
+
+  /// Handle failure to register or deregister
+  _handleRegisterFailure: function search_handle_register_failure(enabled)
+  {
+    // Remove ourselves from the observer list, flip the pref,
+    // and add ourselves back
+    this._prefBranch.removeObserver("enable", this);
+    this.prefEnabled = enabled;
+    this._prefBranch.addObserver("enable", this, false);
   },
 
   /**
    * This object gets notifications for new/moved/copied/deleted messages/folders
    */
   _msgFolderListener: {
     msgAdded: function(aMsg)
     {
deleted file mode 100644
--- a/mail/components/search/content/searchIntegrationDialog.xul
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0"?>
-# -*- Mode: xml; indent-tabs-mode: nil; -*-
-# ***** 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 the Thunderbird Default Client Dialog
-#
-# The Initial Developer of the Original Code is
-# Scott MacGregor.
-# Portions created by the Initial Developer are Copyright (C) 2006
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#   Scott MacGregor <mscott@mozilla.org
-#   Siddharth Agarwal <sid1337@gmail.com>
-#
-# 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 *****
-
-<?xml-stylesheet href="chrome://global/skin/"?>
-
-<!DOCTYPE window [
-  <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
-  %brandDTD;
-#ifdef XP_WIN
-  <!ENTITY % searchIntegrationDTD SYSTEM "chrome://messenger/locale/search/searchIntegrationDialogWin.dtd" >
-  %searchIntegrationDTD;
-#endif
-]>
-
-
-<dialog xmlns:html="http://www.w3.org/1999/xhtml"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        id="searchIntegrationDialog"
-        buttons="accept,cancel"
-        ondialogaccept="window.arguments[0].callback(true); return true"
-        ondialogcancel="window.arguments[0].callback(false); return true"
-        title="&searchIntegration.title;"
-        buttonlabelaccept="&searchIntegration.accept;"
-        buttonlabelcancel="&searchIntegration.cancel;">
-
-  <description>
-    &searchIntegration.description;
-  </description>
-
-</dialog>
--- a/mail/components/search/content/searchOverlay.js
+++ b/mail/components/search/content/searchOverlay.js
@@ -29,15 +29,9 @@
  * 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 ***** */
 
-#ifdef XP_WIN
-Components.utils.import("resource://app/modules/WinSearchIntegration.js");
-#else
-#ifdef XP_MACOSX
-Components.utils.import("resource://app/modules/SpotlightIntegration.js");
-#endif
-#endif
+Components.utils.import("resource://app/modules/SearchIntegration.js");
--- a/mail/components/search/jar.mn
+++ b/mail/components/search/jar.mn
@@ -1,5 +1,4 @@
 messenger.jar:
 %   overlay chrome://messenger/content/messenger.xul            chrome://messenger/content/search/searchOverlay.xul
-*   content/messenger/search/searchIntegrationDialog.xul        (content/searchIntegrationDialog.xul)
     content/messenger/search/searchOverlay.xul                  (content/searchOverlay.xul)
 *   content/messenger/search/searchOverlay.js                   (content/searchOverlay.js)
--- a/mail/components/search/wsenable/WSEnable.cpp
+++ b/mail/components/search/wsenable/WSEnable.cpp
@@ -159,17 +159,16 @@ int APIENTRY wWinMain(HINSTANCE hInstanc
               hr = crawlScopeManager->AddUserScopeRule(path.c_str(), TRUE, TRUE, TRUE);
           }
         }
         else if (*argv[0] == L'0')
         {
           // This is simple, we just exclude the profile dir and override children
           std::wstring path = L"file:///";
           path.append(argv[1]);
-          path.append(L"\\*\\");
           hr = crawlScopeManager->AddUserScopeRule(path.c_str(), FALSE, TRUE, TRUE);
         }
         else
           hr = E_INVALIDARG;
 
         if (SUCCEEDED(hr))
         {
           hr = crawlScopeManager->SaveAll();
--- a/mail/locales/en-US/chrome/messenger/preferences/advanced.dtd
+++ b/mail/locales/en-US/chrome/messenger/preferences/advanced.dtd
@@ -3,19 +3,21 @@
 <!ENTITY itemUpdate.label        "Update">
 <!ENTITY itemNetworking.label    "Network &amp; Disk Space">
 <!ENTITY itemCertificates.label  "Certificates">
 
 <!-- General Settings -->
 
 <!ENTITY enableGlodaSearch.label       "Enable Global Search and Indexer">
 <!ENTITY enableGlodaSearch.accesskey   "E">
-<!ENTITY systemDefaults.label          "System Defaults">
+<!ENTITY systemIntegration.label       "System Integration">
 <!ENTITY alwaysCheckDefault.label      "Always check to see if &brandShortName; is the default mail client on startup">
 <!ENTITY alwaysCheckDefault.accesskey  "A">
+<!ENTITY searchIntegration.label       "Allow &searchIntegration.engineName; to search messages">
+<!ENTITY searchIntegration.accesskey   "S">
 <!ENTITY checkNow.label                "Check Now">
 <!ENTITY checkNow.accesskey            "N">
 <!ENTITY configEditDesc.label          "Advanced Configuration">
 <!ENTITY configEdit.label              "Config Editor…">
 <!ENTITY configEdit.accesskey          "C">
 <!ENTITY returnReceiptsInfo.label      "Determine how &brandShortName; handles return receipts">
 <!ENTITY showReturnReceipts.label      "Return Receipts…">
 <!ENTITY showReturnReceipts.accesskey  "R">
deleted file mode 100644
--- a/mail/locales/en-US/chrome/messenger/search/searchIntegrationDialogWin.dtd
+++ /dev/null
@@ -1,6 +0,0 @@
-<!ENTITY searchIntegration.engineName "Windows Search">
-<!ENTITY searchIntegration.title "&searchIntegration.engineName; Integration">
-<!ENTITY searchIntegration.description "Would you like to enable &searchIntegration.engineName; to index and search through &brandShortName; mail and news messages?">
-
-<!ENTITY searchIntegration.accept "Enable &searchIntegration.engineName;">
-<!ENTITY searchIntegration.cancel "Don't Enable &searchIntegration.engineName;">
new file mode 100644
--- /dev/null
+++ b/mail/locales/en-US/chrome/messenger/searchIntegrationDefault.dtd
@@ -0,0 +1,3 @@
+<!-- LOCALIZATION NOTE: This is the search engine name for platforms that don't
+     support it, and should be left blank -->
+<!ENTITY searchIntegration.engineName "">
new file mode 100644
--- /dev/null
+++ b/mail/locales/en-US/chrome/messenger/searchIntegrationMac.dtd
@@ -0,0 +1,1 @@
+<!ENTITY searchIntegration.engineName "Spotlight">
new file mode 100644
--- /dev/null
+++ b/mail/locales/en-US/chrome/messenger/searchIntegrationWin.dtd
@@ -0,0 +1,1 @@
+<!ENTITY searchIntegration.engineName "Windows Search">
rename from mail/locales/en-US/chrome/messenger/defaultClientDialog.dtd
rename to mail/locales/en-US/chrome/messenger/systemIntegrationDialog.dtd
--- a/mail/locales/en-US/chrome/messenger/defaultClientDialog.dtd
+++ b/mail/locales/en-US/chrome/messenger/systemIntegrationDialog.dtd
@@ -1,9 +1,12 @@
-<!ENTITY defaultClient.title  "Default Client">
+<!ENTITY systemIntegration.title  "System Integration">
 <!ENTITY defaultClient.intro  "Use &brandShortName; as the default client for:">
 
 <!ENTITY email.label "E-Mail">
 <!ENTITY newsgroups.label "Newsgroups">
 <!ENTITY feeds.label "Feeds">
 
 <!ENTITY checkOnStartup.label "Always perform this check when starting &brandShortName;">
 <!ENTITY checkOnStartup.accesskey "A">
+
+<!ENTITY searchIntegration.label "Allow &searchIntegration.engineName; to search messages">
+<!ENTITY searchIntegration.accesskey "S">
--- a/mail/locales/jar.mn
+++ b/mail/locales/jar.mn
@@ -3,17 +3,17 @@
 @AB_CD@.jar:
 % locale messenger @AB_CD@ %locale/@AB_CD@/messenger/
 % override chrome://mozapps/locale/downloads/settingsChange.dtd chrome://messenger/locale/downloads/settingsChange.dtd
 % override chrome://global/locale/netError.dtd chrome://messenger/locale/netError.dtd
   locale/@AB_CD@/messenger/credits.dtd                                  (%chrome/messenger/credits.dtd)
   locale/@AB_CD@/messenger/aboutDialog.dtd                              (%chrome/messenger/aboutDialog.dtd)
   locale/@AB_CD@/messenger/aboutRights.dtd                              (%chrome/messenger/aboutRights.dtd)
   locale/@AB_CD@/messenger/aboutRights.properties                       (%chrome/messenger/aboutRights.properties)
-  locale/@AB_CD@/messenger/defaultClientDialog.dtd                      (%chrome/messenger/defaultClientDialog.dtd)  
+  locale/@AB_CD@/messenger/systemIntegrationDialog.dtd                  (%chrome/messenger/systemIntegrationDialog.dtd)  
   locale/@AB_CD@/messenger/virtualFolderProperties.dtd                  (%chrome/messenger/virtualFolderProperties.dtd)
   locale/@AB_CD@/messenger/virtualFolderListDialog.dtd                  (%chrome/messenger/virtualFolderListDialog.dtd)
   locale/@AB_CD@/messenger/mailOverlay.dtd                              (%chrome/messenger/mailOverlay.dtd)
   locale/@AB_CD@/messenger/messenger.dtd                                (%chrome/messenger/messenger.dtd)
   locale/@AB_CD@/messenger/baseMenuOverlay.dtd                          (%chrome/messenger/baseMenuOverlay.dtd)
   locale/@AB_CD@/messenger/tabmail.dtd                                  (%chrome/messenger/tabmail.dtd)
   locale/@AB_CD@/messenger/msgAccountCentral.dtd                        (%chrome/messenger/msgAccountCentral.dtd)
   locale/@AB_CD@/messenger/SearchDialog.dtd                             (%chrome/messenger/SearchDialog.dtd)
@@ -126,17 +126,19 @@
   locale/@AB_CD@/messenger/preferences/downloadactions.dtd              (%chrome/messenger/preferences/downloadactions.dtd)
   locale/@AB_CD@/messenger/preferences/changeaction.dtd                 (%chrome/messenger/preferences/changeaction.dtd)
   locale/@AB_CD@/messenger/preferences/fonts.dtd                        (%chrome/messenger/preferences/fonts.dtd)
   locale/@AB_CD@/messenger/preferences/offline.dtd                      (%chrome/messenger/preferences/offline.dtd)
   locale/@AB_CD@/messenger/preferences/notifications.dtd                (%chrome/messenger/preferences/notifications.dtd)
   locale/@AB_CD@/messenger/preferences/preferences.properties           (%chrome/messenger/preferences/preferences.properties)
   locale/@AB_CD@/messenger/migration/migration.dtd                      (%chrome/messenger/migration/migration.dtd)
   locale/@AB_CD@/messenger/migration/migration.properties               (%chrome/messenger/migration/migration.properties)
-  locale/@AB_CD@/messenger/search/searchIntegrationDialogWin.dtd        (%chrome/messenger/search/searchIntegrationDialogWin.dtd)
+  locale/@AB_CD@/messenger/searchIntegrationWin.dtd                     (%chrome/messenger/searchIntegrationWin.dtd)
+  locale/@AB_CD@/messenger/searchIntegrationMac.dtd                     (%chrome/messenger/searchIntegrationMac.dtd)
+  locale/@AB_CD@/messenger/searchIntegrationDefault.dtd                 (%chrome/messenger/searchIntegrationDefault.dtd)
   locale/@AB_CD@/messenger/activity.dtd                                 (%chrome/messenger/activity.dtd)
   locale/@AB_CD@/messenger/activity.properties                          (%chrome/messenger/activity.properties)
   locale/@AB_CD@/messenger/downloads/settingsChange.dtd                 (%chrome/overrides/settingsChange.dtd)
   locale/@AB_CD@/messenger/netError.dtd                                 (%chrome/overrides/netError.dtd)
 % locale messenger-mapi @AB_CD@ %locale/@AB_CD@/messenger-mapi/
   locale/@AB_CD@/messenger-mapi/mapi.properties                         (%chrome/messenger-mapi/mapi.properties)
 % locale messenger-newsblog @AB_CD@ %locale/@AB_CD@/messenger-newsblog/
   locale/@AB_CD@/messenger-newsblog/newsblog.properties                 (%chrome/messenger-newsblog/newsblog.properties)
--- a/mailnews/test/performance/common/mailnewsTestPrefs.js
+++ b/mailnews/test/performance/common/mailnewsTestPrefs.js
@@ -33,11 +33,14 @@ user_pref("mail.server.server2.userName"
 user_pref("mail.smtp.defaultserver", "smtp1");
 user_pref("mail.smtpserver.smtp1.hostname", "tinderbox");
 user_pref("mail.smtpserver.smtp1.username", "tinderbox");
 user_pref("mail.smtpservers", "smtp1");
 user_pref("mail.startup.enabledMailCheckOnce", true);
 user_pref("mailnews.start_page_override.mstone", "ignore");
 user_pref("mail.shell.checkDefaultClient", false);
 user_pref("mail.winsearch.enable", false);
+user_pref("mail.winsearch.firstRunDone", true);
+user_pref("mail.spotlight.enable", false);
+user_pref("mail.spotlight.firstRunDone", true);
 // Ensure OS X and Outlook/OE books are disabled
 user_pref("ldap_2.servers.osx.position", 0);
 user_pref("ldap_2.servers.oe.position", 0);