Merge fx-team to m-c. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 18 Jul 2014 15:21:24 -0400
changeset 215714 5e5eb00a12e9ada9c727bc93c69d15862bba0d67
parent 215690 ecdb409898a63ce33b71eb92446ffcec8c42f0bc (current diff)
parent 215713 41df67208b1ba1c32fa9919d844db577e2813c2c (diff)
child 215733 50a8424cf1b8a579ba486eecc109459377a59ab3
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge fx-team to m-c. a=merge
browser/app/profile/firefox.js
browser/base/content/test/social/browser_defaults.js
browser/locales/en-US/chrome/browser/browser.properties
mobile/android/search/java/org/mozilla/search/autocomplete/AutoCompleteAgentManager.java
mobile/android/search/java/org/mozilla/search/autocomplete/AutoCompleteModel.java
mobile/android/search/java/org/mozilla/search/autocomplete/AutoCompleteWordListAgent.java
mobile/android/search/res/raw/en_us.txt
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -147,16 +147,17 @@ pref("browser.formfill.enable", true);
 /* spellcheck */
 pref("layout.spellcheckDefault", 0);
 
 /* block popups by default, and notify the user about blocked popups */
 pref("dom.disable_open_during_load", true);
 pref("privacy.popups.showBrowserMessage", true);
 
 pref("keyword.enabled", true);
+pref("browser.fixup.domainwhitelist.localhost", true);
 
 pref("accessibility.typeaheadfind", false);
 pref("accessibility.typeaheadfind.timeout", 5000);
 pref("accessibility.typeaheadfind.flashBar", 1);
 pref("accessibility.typeaheadfind.linksonly", false);
 pref("accessibility.typeaheadfind.casesensitive", 0);
 
 // SSL error page behaviour
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -254,16 +254,17 @@ pref("browser.uitour.themeOrigin", "http
 pref("browser.uitour.pinnedTabUrl", "https://support.mozilla.org/%LOCALE%/kb/pinned-tabs-keep-favorite-websites-open");
 pref("browser.uitour.url", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/tour/");
 pref("browser.uitour.whitelist.add.260", "www.mozilla.org,support.mozilla.org");
 
 pref("browser.customizemode.tip0.shown", false);
 pref("browser.customizemode.tip0.learnMoreUrl", "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/customize");
 
 pref("keyword.enabled", true);
+pref("browser.fixup.domainwhitelist.localhost", true);
 
 pref("general.useragent.locale", "@AB_CD@");
 pref("general.skins.selectedSkin", "classic/1.0");
 
 pref("general.smoothScroll", true);
 #ifdef UNIX_BUT_NOT_MAC
 pref("general.autoScroll", false);
 #else
@@ -1526,19 +1527,16 @@ pref("loop.seenToS", "unseen");
 pref("loop.do_not_disturb", false);
 pref("loop.ringtone", "chrome://browser/content/loop/shared/sounds/Firefox-Long.ogg");
 pref("loop.retry_delay.start", 60000);
 pref("loop.retry_delay.limit", 300000);
 
 // serverURL to be assigned by services team
 pref("services.push.serverURL", "wss://push.services.mozilla.com/");
 
-// Default social providers
-pref("social.manifest.facebook", "{\"origin\":\"https://www.facebook.com\",\"name\":\"Facebook Share\",\"shareURL\":\"https://www.facebook.com/sharer/sharer.php?u=%{url}\",\"iconURL\":\"data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAAX0lEQVQ4jWP4%2F%2F8%2FAyUYTFhHzjgDxP9JxGeQDSBVMxgTbUBCxer%2Fr999%2BQ8DJBuArJksA9A10s8AXIBoA0B%2BR%2FY%2FjD%2BEwoBoA1yT5v3PbdmCE8MAshhID%2FUMoDgzUYIBj0Cgi7ar4coAAAAASUVORK5CYII%3D\",\"icon32URL\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAADbklEQVRYCc1Xv08UQRj99tctexAuCEFjRE0kGBEtLDSGqIWNxkYKbTAxNlY2JhaGWltNtNFeKgsKKxITK43/gCYW+IsoRhA4D47bH7fn9+bcvdm5JR7sefolC3Ozu9978+bNN7PayUv3HN3umdY0Y6IWBtSJ0HSTarXqTOiuTep6Lj+tdxAcA8RAgSmwdd2aCDs0clldYALb/FvgYVhjmfliVA2XpjEgWo0Attn42Z6WH1RFor5ehwo9XQIUZMoVn4qlCoVMSo62EvD8Kh0b3U2Xz43R2PBO6mUCGDlAf65V6MadZzT/rUimoccc2kYA4BfPHqJb105RzjJigKhRq9kEJUBIjgYVuXeL7SAI6eD+Abp5dTwVHOmEHxT50d8WBYJqSOdPj5BjW8gZR8UNqFR2xagx/65XFYaMH+BGWwiYpi4UkBPPLxTp9v1Z+lHc4DWvCQXWmIy6EjITgKowVd5Jjv7N3Hd6y5esigoOwpkJIAmMpZpLJGdiaaC4F0UmAj6bD84GCEwmB/qxMmRilmnwb/mpjAocHh4UEoNAt5NLZB7oy9OJo0PxqkAtePdhiSqunyC1LQUwWMPQaOr6GRre258Ajn4cP7KHcEXhsxpXbj+lT19X2TMNGTLVAcjcalS8gDwsQ2UOMhH4k8FkcrEn5E5ub2sKohxLK2VR77Hl9RUcsrgeRIEiVOT6z+tDbIeLy+vk+kGTCbXxycet6xhl//3f6bJEkdHYhA+mLtDIvoH4ieev5+juoxdk5+pjhALYEdXIpEB5w+NlSKSzqVQ/+H7IO6BLtl3fngGMiqhGJgIwlM6qpyUGFjySdk8m0Zg0ubeD7X9OIDEFajltRQgUJaUKx69tdgaQa0FMADuahZPMFtcEwNPm2hA7ZI5sK4aoE2NvYI+o8hkCIe7CwTv68zS0q9Dk5vpbm/8FXxitSzmMFHpsGj0wyLUheTwD2Y9fVgh1Ae0EPUgD9241ZEnld+v5kgnVZ/8fE0brVh5BK+1oCqKKF72Dk7HwBsssB/pklU1dfChy3S659H5+uelgIb+8WRv1/uGTV9Sdb5wJFlfW6fPCalMhwhSU1j2xKwKbP838GcOwJja4TqO0bjdmXxYTy1EYjFdCWoCEYZhseH/GDL3yJPHnuW6YmT7P1SlIA4768Hke4vOcsX8BE346lLHhDUQAAAAASUVORK5CYII=\", \"icon64URL\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAACNNJREFUeNrtm3tw1NUVxz/399hHHkgCaCBGEFEEREVFYFQcSoOKdkZay4z+4dDpYIsjHWx1WoTMhFi1gzBSpVgVGbU4U1sHfPESKODwEEnRYDFAICEIeZIQshs2u/v73ds/drMsyW7YLEkl2Z6Z32yy+9v7u+fc7znne8+5KzgvAjDunzlv0M13PjDZ6c4cARj0WhEoaZ1tOn3yq9XLf/tNU0O1D5Ad7wq/OpxpaXOL1j5uZAwuaGlVgwNBhULRm0XXBG6HZrlNa9uRrzfM+3DlgjIgGMsA7rl/XDdHOnNf9vosTfVuvTsaQhdkZ4iykh2rHtqydvkxwI58BhjTfv7MmP55E9/1nLNdfU15ACkVvoAaMCRvRPa+re9+DgTaPjMAx+DrJv3M67Mz+6LybWLb4NfTHhxzx31DDhZvOtqGAgNwWbjGICV9XQJB0e/KobcOP1i8qTzaAEYgaDtNU/V5A9hSaUFLuQEt2gVQSgml+j4CUAIppYgK/m0GkCjZ9xGAUNAu0LUhgJRAAAIVzwBSqVRQH4hlAClRKZAFhOgEASoFECBR8QwgUyQGdJT/B8HzCEiBNKhUJzEgBYIgQsTJAkohe9oFZHgHKvQoHtZ9K3tewfiixXABLdoFeuSSEmkF+PH4QTz7+M3o+ENptzvGtS36uSwmjMpAYF10XCllHCYoe84FlLS555Zs5jx6J6ahY+iCl98pJiDNS1hwSZop+cm91zJmxEBefGsPlu1AxKC67V3gf5oGlZSMuz6Dp2fdhWnoAEwaN5T5hsYLb+4hKB1dcgelFDpB8ifk8thDt3DO5+fZxRvxBV0IjQR0EB3KfD1GhJS0GZnnYuGcKTgdF9ZWx4/No/BJjUUrdtJqm4iL+K5SCmSAiWMHMevhcQzNzaa6ron5SzfQ7HeiaSKx+au4m6HupcJKSYZdZVI4dypuV2yo3zoql0VP3cOiFV/Q4jdiGkGhQFqMGpbJL346kbE3DEYIQWNTC39Ysp4Gr4HQtZDyiRhA0NlmSHZbRM7pr1H0m6lckeHqdGXG3jCYoqfupeC17bT49fNRXIFSNrkDTGbNGM9dtw1D10M1DI/Xx3NLP6OqETRdDy1eglPT4rqA7K56gCIrXfHCvHwGZqUnBMtR113FS/N+xHPLtuJpDa1mVobg0emjmX7vqEjsUErhaw1Q8Mo6yk4F0A1HeOW7kIlFx/u7jworRabLpmhuPjmD+iG7YNDrrhnIS09P5cW/buOeO67lkftvJt3tDE06PE7Qsnh++QYOHPOim86wcVUS0+whJug0ghTMmcK1V2eH8m2UHP++nrwhAyIwjiXDcrN5vXAGhqGhFBeMYUvJ0re2sPfgGTTDGUZrEogVopMgmGQWUCgMEWTBE5MZPSLngnGqas/w9j92s31fJfmThvPM7HyMMKRj+qgmOiBHSsnr73/B5r1V6A53KD4k3bFS8dNgckFQoWPxu1kTGDc6N7JqzR4ff/+smE+2H8FSLkx3FluLawhaG3n2iXwcppGoV/Hemt18tK0c3UwLIfUS2nVafBeQJNUXkAF+/dht3H37cKSUBC2bTTv+w98++YazPg1dT0NoIUhruoMd+2sJrtjI7381rQM3iCVrN33N++tL0c30xFNdp0GQeFRYQhcRIO0gv5xxE/fdfSO2bfNVSTmrPtxLZW0A3XSh6VporaLG1XQHu0pOU/TaOhY8+QAuZ3w6vHnnQd74536EkZ50wOsSE0zcugolbWZOG8GM/LGUVdSw6sM97D/UgGa60QxXzMJDZAq6yb7SJgr//CkLn5pOmsvR4Z5dxUdZ9t6XoKfFjNyXkqZjuoBUCpGgCyhp8eDdQ5k++UaWrdrMlr2VSFxoZlpE8YtNWGgGXx9ppnDZpxTMfTCS8gAOlJ5g8ds7kCItTIi6j6FqMVxAC2sV2RB1ekmLCTcNpH+myeyFH7BxT1Voopoe4RKJXQqhmxw45mXh0o/xeH0opThcXs2iv2wmoFyhAnbC4yX+3PgISMDShrA5XHGa3d9UITRniIeTfHASmsGhEz7mL/mI2TPv4sU3t+KzHAnu7JKpCosOkcSIICAB5hZE0OiRCM0Iwb0b6LPQdI5W+Zn/yucoYYayRk+16eK1xqRMDAHtA0r3lep0lNAjO8kfpCpMqpTF4xZEUqA7rIlOCiKpgADVWXc4FQwgEfHPB5AiByTixIDUCYJx+wJoqdIcJV5VOAWygEZcF7BToT2upFDKtuz2BrAtf8v3mju972cBJX2exso6ok6N64BhOtM11xXXPBz6v6340PcuO+DZfaJkzWqgqY3L64Bqaaz0ZV45Mkc308dG2kd97FLSaq4v317gazr5HeCLRoACFTxbfeBw+oDhWYYj4/rw+30H+rb/VMPxXQsbKnbuABqJOi4vogyRiRB5/XNvvz3zytFTDEf61eF9b0dCKTS36c4afymTsgLeQ9Ly13X/aYnzE1Uy6PV7679trNy1xe+tKwPqAH/0Vla0qw65gH7AFeG/Y3Uy9P45o0bm3PTIaplM6lTK9jWf/OBUyQcrpdXaTIyfsXQb9QcLaAn7vJd2vxY5XxBpo8pwDmgFGsLKx1oeh8OVmUUSLXUlrWZPzbdLag9v+BjUqfDzepKAyDDcZbznGHG+1NmqSKHpVlfbadJqLW+o2LHobNX+PUB1WPkfnHwYyTmX6lI7Lehr3F576NM/+T3V3wH17f2w1xkg2ggXuSvga6p8p+bgmpVKWpXAmVh+2AsNEKogdYYAJa0GT03J4obyf60HTgKe6PTTqw0QOpcQ3wXs4LlDZyq2FXrrS4uBmjDxuCw3G5eIgA46yeC5ho11pWsWW35PWTibBC4Xf+9eBLRPg0q2+s5UvHG6bMNqJYPHw7nXutxZYvIIiMoCSgbrPVX/fv7syS+3AKfC5MOmF4iRpP6RjrId8O5vrNhS1NpUWQLUholUr6muXEoatP3emrWNR9e/avk9R8P+HuxNypPkrk93pGdnK0VtXemaN6UdOHo55vdE5b/0NKx+K4AxtAAAAABJRU5ErkJggg==\", \"description\":\"Easily share the web to your Facebook friends.\",\"author\":\"Facebook\",\"homepageURL\":\"https://www.facebook.com\",\"builtin\":\"true\",\"version\":1}");
-
 pref("social.sidebar.unload_timeout_ms", 10000);
 
 pref("dom.identity.enabled", false);
 
 // Block insecure active content on https pages
 pref("security.mixed_content.block_active_content", true);
 
 // 1 = allow MITM for certificate pinning checks.
--- a/browser/base/content/browser-plugins.js
+++ b/browser/base/content/browser-plugins.js
@@ -271,16 +271,24 @@ var gPluginHandler = {
     if (eventType == "PluginRemoved") {
       let doc = event.target;
       let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
       if (browser)
         this._setPluginNotificationIcon(browser);
       return;
     }
 
+    if (eventType == "PluginCrashed" &&
+        !(event.target instanceof Ci.nsIObjectLoadingContent)) {
+      // If the event target is not a plugin object (i.e., an <object> or
+      // <embed> element), this call is for a window-global plugin.
+      this.pluginInstanceCrashed(event.target, event);
+      return;
+    }
+
     let plugin = event.target;
     let doc = plugin.ownerDocument;
 
     if (!(plugin instanceof Ci.nsIObjectLoadingContent))
       return;
 
     if (eventType == "PluginBindingAttached") {
       // The plugin binding fires this event when it is created.
@@ -1138,17 +1146,17 @@ var gPluginHandler = {
       // Submission is async, so we can't easily show failure UI.
       propertyBag.setPropertyAsBool("submittedCrashReport", true);
     }
 #endif
   },
 
   // Crashed-plugin event listener. Called for every instance of a
   // plugin in content.
-  pluginInstanceCrashed: function (plugin, aEvent) {
+  pluginInstanceCrashed: function (target, aEvent) {
     // Ensure the plugin and event are of the right type.
     if (!(aEvent instanceof Ci.nsIDOMCustomEvent))
       return;
 
     let propBag = aEvent.detail.QueryInterface(Ci.nsIPropertyBag2);
     let submittedReport = propBag.getPropertyAsBool("submittedCrashReport");
     let doPrompt        = true; // XXX followup for .getPropertyAsBool("doPrompt");
     let submitReports   = true; // XXX followup for .getPropertyAsBool("submitReports");
@@ -1156,60 +1164,48 @@ var gPluginHandler = {
     let pluginDumpID    = propBag.getPropertyAsAString("pluginDumpID");
     let browserDumpID   = propBag.getPropertyAsAString("browserDumpID");
 
     // Remap the plugin name to a more user-presentable form.
     pluginName = this.makeNicePluginName(pluginName);
 
     let messageString = gNavigatorBundle.getFormattedString("crashedpluginsMessage.title", [pluginName]);
 
-    //
-    // Configure the crashed-plugin placeholder.
-    //
+    let plugin = null, doc;
+    if (target instanceof Ci.nsIObjectLoadingContent) {
+      plugin = target;
+      doc = plugin.ownerDocument;
+    } else {
+      doc = target.document;
+      if (!doc) {
+        return;
+      }
+      // doPrompt is specific to the crashed plugin overlay, and
+      // therefore is not applicable for window-global plugins.
+      doPrompt = false;
+    }
 
-    // Force a layout flush so the binding is attached.
-    plugin.clientTop;
-    let overlay = this.getPluginUI(plugin, "main");
-    let statusDiv = this.getPluginUI(plugin, "submitStatus");
-    let doc = plugin.ownerDocument;
+    let status;
 #ifdef MOZ_CRASHREPORTER
-    let status;
-
     // Determine which message to show regarding crash reports.
     if (submittedReport) { // submitReports && !doPrompt, handled in observer
       status = "submitted";
     }
     else if (!submitReports && !doPrompt) {
       status = "noSubmit";
     }
-    else { // doPrompt
+    else if (!pluginDumpID) {
+      // If we don't have a minidumpID, we can't (or didn't) submit anything.
+      // This can happen if the plugin is killed from the task manager.
+      status = "noReport";
+    }
+    else {
       status = "please";
-      this.getPluginUI(plugin, "submitButton").addEventListener("click",
-        function (event) {
-          if (event.button != 0 || !event.isTrusted)
-            return;
-          this.submitReport(pluginDumpID, browserDumpID, plugin);
-          pref.setBoolPref("", optInCB.checked);
-        }.bind(this));
-      let optInCB = this.getPluginUI(plugin, "submitURLOptIn");
-      let pref = Services.prefs.getBranch("dom.ipc.plugins.reportCrashURL");
-      optInCB.checked = pref.getBoolPref("");
     }
 
-    // If we don't have a minidumpID, we can't (or didn't) submit anything.
-    // This can happen if the plugin is killed from the task manager.
-    if (!pluginDumpID) {
-        status = "noReport";
-    }
-
-    statusDiv.setAttribute("status", status);
-
-    let helpIcon = this.getPluginUI(plugin, "helpIcon");
-    this.addLinkClickCallback(helpIcon, "openHelpPage");
-
     // If we're showing the link to manually trigger report submission, we'll
     // want to be able to update all the instances of the UI for this crash to
     // show an updated message when a report is submitted.
     if (doPrompt) {
       let observer = {
         QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
                                                Ci.nsISupportsWeakReference]),
         observe : function(subject, topic, data) {
@@ -1233,36 +1229,25 @@ var gPluginHandler = {
       // it from being GC. But I don't want to manually manage the reference's
       // lifetime (which should be no greater than the page).
       // Clever solution? Use a closue with an event listener on the document.
       // When the doc goes away, so do the listener references and the closure.
       doc.addEventListener("mozCleverClosureHack", observer, false);
     }
 #endif
 
-    let crashText = this.getPluginUI(plugin, "crashedText");
-    crashText.textContent = messageString;
-
     let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
-
-    let link = this.getPluginUI(plugin, "reloadLink");
-    this.addLinkClickCallback(link, "reloadPage", browser);
-
     let notificationBox = gBrowser.getNotificationBox(browser);
+    let isShowing = false;
 
-    let isShowing = this.shouldShowOverlay(plugin, overlay);
-
-    // Is the <object>'s size too small to hold what we want to show?
-    if (!isShowing) {
-      // First try hiding the crash report submission UI.
-      statusDiv.removeAttribute("status");
-
-      isShowing = this.shouldShowOverlay(plugin, overlay);
+    if (plugin) {
+      // If there's no plugin (an <object> or <embed> element), this call is
+      // for a window-global plugin. In this case, there's no overlay to show.
+      isShowing = _setUpPluginOverlay.call(this, plugin, doPrompt, browser);
     }
-    this.setVisibility(plugin, overlay, isShowing);
 
     if (isShowing) {
       // If a previous plugin on the page was too small and resulted in adding a
       // notification bar, then remove it because this plugin instance it big
       // enough to serve as in-content notification.
       hideNotificationBar();
       doc.mozNoPluginCrashedNotification = true;
     } else {
@@ -1325,10 +1310,59 @@ var gPluginHandler = {
       description.appendChild(link);
 
       // Remove the notfication when the page is reloaded.
       doc.defaultView.top.addEventListener("unload", function() {
         notificationBox.removeNotification(notification);
       }, false);
     }
 
+    // Configure the crashed-plugin placeholder.
+    // Returns true if the plugin overlay is visible.
+    function _setUpPluginOverlay(plugin, doPromptSubmit, browser) {
+      if (!plugin) {
+        return false;
+      }
+
+      // Force a layout flush so the binding is attached.
+      plugin.clientTop;
+      let overlay = this.getPluginUI(plugin, "main");
+      let statusDiv = this.getPluginUI(plugin, "submitStatus");
+
+      if (doPromptSubmit) {
+        this.getPluginUI(plugin, "submitButton").addEventListener("click",
+        function (event) {
+          if (event.button != 0 || !event.isTrusted)
+            return;
+          this.submitReport(pluginDumpID, browserDumpID, plugin);
+          pref.setBoolPref("", optInCB.checked);
+        }.bind(this));
+        let optInCB = this.getPluginUI(plugin, "submitURLOptIn");
+        let pref = Services.prefs.getBranch("dom.ipc.plugins.reportCrashURL");
+        optInCB.checked = pref.getBoolPref("");
+      }
+
+      statusDiv.setAttribute("status", status);
+
+      let helpIcon = this.getPluginUI(plugin, "helpIcon");
+      this.addLinkClickCallback(helpIcon, "openHelpPage");
+
+      let crashText = this.getPluginUI(plugin, "crashedText");
+      crashText.textContent = messageString;
+
+      let link = this.getPluginUI(plugin, "reloadLink");
+      this.addLinkClickCallback(link, "reloadPage", browser);
+
+      let isShowing = this.shouldShowOverlay(plugin, overlay);
+
+      // Is the <object>'s size too small to hold what we want to show?
+      if (!isShowing) {
+        // First try hiding the crash report submission UI.
+        statusDiv.removeAttribute("status");
+
+        isShowing = this.shouldShowOverlay(plugin, overlay);
+      }
+      this.setVisibility(plugin, overlay, isShowing);
+
+      return isShowing;
+    }
   }
 };
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -17,16 +17,20 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/BrowserUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
                                   "resource://gre/modules/Task.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "CharsetMenu",
                                   "resource://gre/modules/CharsetMenu.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ShortcutUtils",
                                   "resource://gre/modules/ShortcutUtils.jsm");
 
+XPCOMUtils.defineLazyServiceGetter(this, "gDNSService",
+                                   "@mozilla.org/network/dns-service;1",
+                                   "nsIDNSService");
+
 const nsIWebNavigation = Ci.nsIWebNavigation;
 
 var gLastBrowserCharset = null;
 var gPrevCharset = null;
 var gProxyFavIcon = null;
 var gLastValidURLStr = "";
 var gInPrintPreviewMode = false;
 var gContextMenu = null; // nsContextMenu instance
@@ -740,16 +744,111 @@ const gFormSubmitObserver = {
 
       position = "after_start";
     }
 
     this.panel.openPopup(element, position, offset, 0);
   }
 };
 
+function gKeywordURIFixup(fixupInfo, topic, data) {
+  fixupInfo.QueryInterface(Ci.nsIURIFixupInfo);
+
+  // We get called irrespective of whether we did a keyword search, or
+  // whether the original input would be vaguely interpretable as a URL,
+  // so figure that out first.
+  let alternativeURI = fixupInfo.fixedURI;
+  if (!fixupInfo.fixupUsedKeyword || !alternativeURI) {
+    return;
+  }
+
+  // We should have a document loader...
+  let docshellRef = fixupInfo.consumer;
+  try {
+    docshellRef.QueryInterface(Ci.nsIDocumentLoader);
+  } catch (ex) {
+    return;
+  }
+
+  // ... from which we can deduce the browser
+  let browser = gBrowser.getBrowserForDocument(docshellRef.document);
+  if (!browser)
+    return;
+
+  // At this point we're still only just about to load this URI.
+  // When the async DNS lookup comes back, we may be in any of these states:
+  // 1) still on the previous URI, waiting for the preferredURI (keyword
+  //    search) to respond;
+  // 2) at the keyword search URI (preferredURI)
+  // 3) at some other page because the user stopped navigation.
+  // We keep track of the currentURI to detect case (1) in the DNS lookup
+  // callback.
+  let previousURI = browser.currentURI;
+
+  // now swap for a weak ref so we don't hang on to browser needlessly
+  // even if the DNS query takes forever
+  let weakBrowser = Cu.getWeakReference(browser);
+  browser = null;
+
+  // Additionally, we need the host of the parsed url
+  let hostName = alternativeURI.host;
+  // and the ascii-only host for the pref:
+  let asciiHost = alternativeURI.asciiHost;
+
+  let onLookupComplete = (request, record, status) => {
+    let browser = weakBrowser.get();
+    if (!Components.isSuccessCode(status) || !browser)
+      return;
+
+    let currentURI = browser.currentURI;
+    // If we're in case (3) (see above), don't show an info bar.
+    if (!currentURI.equals(previousURI) &&
+        !currentURI.equals(fixupInfo.preferredURI)) {
+      return;
+    }
+
+    // show infobar offering to visit the host
+    let notificationBox = gBrowser.getNotificationBox(browser);
+    if (notificationBox.getNotificationWithValue("keyword-uri-fixup"))
+      return;
+
+    let message = gNavigatorBundle.getFormattedString(
+      "keywordURIFixup.message", [hostName]);
+    let yesMessage = gNavigatorBundle.getFormattedString(
+      "keywordURIFixup.goTo", [hostName])
+
+    let buttons = [
+      {
+        label: yesMessage,
+        accessKey: gNavigatorBundle.getString("keywordURIFixup.goTo.accesskey"),
+        callback: function() {
+          let pref = "browser.fixup.domainwhitelist." + asciiHost;
+          Services.prefs.setBoolPref(pref, true);
+          openUILinkIn(alternativeURI.spec, "current");
+        }
+      },
+      {
+        label: gNavigatorBundle.getString("keywordURIFixup.dismiss"),
+        accessKey: gNavigatorBundle.getString("keywordURIFixup.dismiss.accesskey"),
+        callback: function() {
+          let notification = notificationBox.getNotificationWithValue("keyword-uri-fixup");
+          notificationBox.removeNotification(notification, true);
+        }
+      }
+    ];
+    let notification =
+      notificationBox.appendNotification(message,"keyword-uri-fixup", null,
+                                         notificationBox.PRIORITY_INFO_HIGH,
+                                         buttons);
+    notification.persistence = 1;
+  };
+
+  gDNSService.asyncResolve(hostName, 0, onLookupComplete, Services.tm.mainThread);
+}
+
 var gBrowserInit = {
   delayedStartupFinished: false,
 
   onLoad: function() {
     gMultiProcessBrowser =
       window.QueryInterface(Ci.nsIInterfaceRequestor)
       .getInterface(Ci.nsIWebNavigation)
       .QueryInterface(Ci.nsILoadContext)
@@ -1046,16 +1145,17 @@ var gBrowserInit = {
 
     Services.obs.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
     Services.obs.addObserver(gXPInstallObserver, "addon-install-disabled", false);
     Services.obs.addObserver(gXPInstallObserver, "addon-install-started", false);
     Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false);
     Services.obs.addObserver(gXPInstallObserver, "addon-install-failed", false);
     Services.obs.addObserver(gXPInstallObserver, "addon-install-complete", false);
     Services.obs.addObserver(gFormSubmitObserver, "invalidformsubmit", false);
+    Services.obs.addObserver(gKeywordURIFixup, "keyword-uri-fixup", false);
 
     BrowserOffline.init();
     OfflineApps.init();
     IndexedDBPromptHelper.init();
     gFormSubmitObserver.init();
     gRemoteTabsUI.init();
 
     // Initialize the full zoom setting.
@@ -1349,16 +1449,17 @@ var gBrowserInit = {
 
       Services.obs.removeObserver(gSessionHistoryObserver, "browser:purge-session-history");
       Services.obs.removeObserver(gXPInstallObserver, "addon-install-disabled");
       Services.obs.removeObserver(gXPInstallObserver, "addon-install-started");
       Services.obs.removeObserver(gXPInstallObserver, "addon-install-blocked");
       Services.obs.removeObserver(gXPInstallObserver, "addon-install-failed");
       Services.obs.removeObserver(gXPInstallObserver, "addon-install-complete");
       Services.obs.removeObserver(gFormSubmitObserver, "invalidformsubmit");
+      Services.obs.removeObserver(gKeywordURIFixup, "keyword-uri-fixup");
 
       try {
         gPrefService.removeObserver(gHomeButton.prefDomain, gHomeButton);
       } catch (ex) {
         Cu.reportError(ex);
       }
 
       if (typeof WindowsPrefSync !== 'undefined') {
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -396,16 +396,17 @@ skip-if = e10s # Bug ?????? - test uses 
 [browser_urlHighlight.js]
 [browser_urlbarAutoFillTrimURLs.js]
 [browser_urlbarCopying.js]
 skip-if = e10s # Bug 932651 - getClipboardData in specialpowersAPI.js not e10s friendly
 [browser_urlbarEnter.js]
 skip-if = e10s # Bug ?????? - obscure non-windows child process crashes on try
 [browser_urlbarRevert.js]
 skip-if = e10s # Bug ?????? - ESC reverted the location bar value - Got foobar, expected example.com
+[browser_urlbarSearchSingleWordNotification.js]
 [browser_urlbarStop.js]
 skip-if = e10s # Bug ????? - test calls gBrowser.contentWindow.stop
 [browser_urlbarTrimURLs.js]
 [browser_urlbar_search_healthreport.js]
 skip-if = e10s # Bug ?????? - FHR tests failing (either with "no data for today" or "2 records for today")
 [browser_utilityOverlay.js]
 [browser_visibleFindSelection.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content
--- a/browser/base/content/test/general/browser_tabopen_reflows.js
+++ b/browser/base/content/test/general/browser_tabopen_reflows.js
@@ -102,18 +102,18 @@ function test() {
       // Remove reflow observer and clean up.
       docShell.removeWeakReflowObserver(observer);
       gBrowser.removeCurrentTab();
       finish();
     });
   });
 
   Services.prefs.setBoolPref(PREF_PRELOAD, false);
-  // set directory source to empty links
-  Services.prefs.setCharPref(PREF_NEWTAB_DIRECTORYSOURCE, "data:application/json,{}");
+  // set directory source to dummy/empty links
+  Services.prefs.setCharPref(PREF_NEWTAB_DIRECTORYSOURCE, 'data:application/json,{"test":1}');
 }
 
 let observer = {
   reflow: function (start, end) {
     // Gather information about the current code path.
     let path = (new Error().stack).split("\n").slice(1).map(line => {
       return line.replace(/:\d+:\d+$/, "");
     }).join("|");
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/browser_urlbarSearchSingleWordNotification.js
@@ -0,0 +1,80 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("browser.fixup.domainwhitelist.localhost");
+});
+
+function promiseNotificationForTab(value, expected, tab=gBrowser.selectedTab) {
+  let deferred = Promise.defer();
+  let notificationBox = gBrowser.getNotificationBox(tab.linkedBrowser);
+  if (expected) {
+    waitForCondition(() => notificationBox.getNotificationWithValue(value) !== null,
+                     deferred.resolve, "Were expecting to get a notification");
+  } else {
+    setTimeout(() => {
+      is(notificationBox.getNotificationWithValue(value), null, "We are expecting to not get a notification");
+      deferred.resolve();
+    }, 1000);
+  }
+  return deferred.promise;
+}
+
+function* runURLBarSearchTest(valueToOpen, expectSearch, expectNotification) {
+  gURLBar.value = valueToOpen;
+  let expectedURI;
+  if (!expectSearch) {
+    expectedURI = "http://" + valueToOpen + "/";
+  } else {
+    yield new Promise(resolve => {
+      Services.search.init(resolve)
+    });
+    expectedURI = Services.search.defaultEngine.getSubmission(valueToOpen, null, "keyword").uri.spec;
+  }
+  gURLBar.focus();
+  let docLoadPromise = waitForDocLoadAndStopIt(expectedURI);
+  EventUtils.synthesizeKey("VK_RETURN", {});
+
+  yield docLoadPromise;
+
+  yield promiseNotificationForTab("keyword-uri-fixup", expectNotification);
+}
+
+add_task(function* test_navigate_full_domain() {
+  let tab = gBrowser.selectedTab = gBrowser.addTab();
+  yield* runURLBarSearchTest("www.mozilla.org", false, false);
+  gBrowser.removeTab(tab);
+});
+
+add_task(function* test_navigate_single_host() {
+  Services.prefs.setBoolPref("browser.fixup.domainwhitelist.localhost", false);
+  let tab = gBrowser.selectedTab = gBrowser.addTab();
+  yield* runURLBarSearchTest("localhost", true, true);
+
+  let notificationBox = gBrowser.getNotificationBox(tab.linkedBrowser);
+  let notification = notificationBox.getNotificationWithValue("keyword-uri-fixup");
+  let docLoadPromise = waitForDocLoadAndStopIt("http://localhost/");
+  notification.querySelector(".notification-button-default").click();
+
+  // check pref value
+  let pref = "browser.fixup.domainwhitelist.localhost";
+  let prefValue = Services.prefs.getBoolPref(pref);
+  ok(prefValue, "Pref should have been toggled");
+
+  yield docLoadPromise;
+  gBrowser.removeTab(tab);
+
+  // Now try again with the pref set.
+  let tab = gBrowser.selectedTab = gBrowser.addTab();
+  yield* runURLBarSearchTest("localhost", false, false);
+  gBrowser.removeTab(tab);
+});
+
+add_task(function* test_navigate_invalid_url() {
+  let tab = gBrowser.selectedTab = gBrowser.addTab();
+  yield* runURLBarSearchTest("mozilla is awesome", true, false);
+  gBrowser.removeTab(tab);
+});
+
--- a/browser/base/content/test/newtab/head.js
+++ b/browser/base/content/test/newtab/head.js
@@ -19,18 +19,18 @@ let {Promise, NewTabUtils, Sanitizer, cl
 let uri = Services.io.newURI("about:newtab", null, null);
 let principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri);
 
 let isMac = ("nsILocalFileMac" in Ci);
 let isLinux = ("@mozilla.org/gnome-gconf-service;1" in Cc);
 let isWindows = ("@mozilla.org/windows-registry-key;1" in Cc);
 let gWindow = window;
 
-// Default to empty directory links
-let gDirectorySource = "data:application/json,{}";
+// Default to dummy/empty directory links
+let gDirectorySource = 'data:application/json,{"test":1}';
 
 // The tests assume all three rows of sites are shown, but the window may be too
 // short to actually show three rows.  Resize it if necessary.
 let requiredInnerHeight =
   40 + 32 + // undo container + bottom margin
   44 + 32 + // search bar + bottom margin
   (3 * (150 + 32)) + // 3 rows * (tile height + title and bottom margin)
   100; // breathing room
--- a/browser/base/content/test/plugins/browser.ini
+++ b/browser/base/content/test/plugins/browser.ini
@@ -57,15 +57,16 @@ run-if = crashreporter
 [browser_CTP_drag_drop.js]
 [browser_CTP_hide_overlay.js]
 [browser_CTP_iframe.js]
 [browser_CTP_multi_allow.js]
 [browser_CTP_nonplugins.js]
 [browser_CTP_notificationBar.js]
 [browser_CTP_outsideScrollArea.js]
 [browser_CTP_resize.js]
+[browser_globalplugin_crashinfobar.js]
 [browser_pageInfo_plugins.js]
 [browser_pluginnotification.js]
 [browser_pluginplaypreview.js]
 [browser_pluginplaypreview2.js]
 [browser_pluginCrashCommentAndURL.js]
 run-if = crashreporter
 [browser_plugins_added_dynamically.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/plugins/browser_globalplugin_crashinfobar.js
@@ -0,0 +1,69 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+let gTestBrowser = null;
+
+let propBagProperties = {
+  pluginName: "GlobalTestPlugin",
+  pluginDumpID: "1234",
+  browserDumpID: "5678",
+  submittedCrashReport: false
+}
+
+// Test that plugin crash submissions still work properly after
+// click-to-play activation.
+
+function test() {
+  waitForExplicitFinish();
+  let tab = gBrowser.loadOneTab("about:blank", { inBackground: false });
+  gTestBrowser = gBrowser.getBrowserForTab(tab);
+  gTestBrowser.addEventListener("PluginCrashed", onCrash, false);
+  gTestBrowser.addEventListener("load", onPageLoad, true);
+
+  registerCleanupFunction(function cleanUp() {
+    gTestBrowser.removeEventListener("PluginCrashed", onCrash, false);
+    gTestBrowser.removeEventListener("load", onPageLoad, true);
+    gBrowser.removeTab(tab);
+  });
+}
+
+function onPageLoad() {
+  executeSoon(generateCrashEvent);
+}
+
+function generateCrashEvent() {
+  let window = gTestBrowser.contentWindow;
+  let propBag = Cc["@mozilla.org/hash-property-bag;1"]
+                  .createInstance(Ci.nsIWritablePropertyBag);
+  for (let [name, val] of Iterator(propBagProperties)) {
+    propBag.setProperty(name, val);
+  }
+
+  let event = window.document.createEvent("CustomEvent");
+  event.initCustomEvent("PluginCrashed", true, true, propBag);
+  window.dispatchEvent(event);
+}
+
+
+function onCrash(event) {
+  let target = event.target;
+  is (target, gTestBrowser.contentWindow, "Event target is the window.");
+
+  let propBag = event.detail.QueryInterface(Ci.nsIPropertyBag2);
+  for (let [name, val] of Iterator(propBagProperties)) {
+    let type = typeof val;
+    let propVal = type == "string"
+                  ? propBag.getPropertyAsAString(name)
+                  : propBag.getPropertyAsBool(name);
+    is (propVal, val, "Correct property in detail propBag: " + name + ".");
+  }
+
+  let notificationBox = gBrowser.getNotificationBox(gTestBrowser);
+  let notification = notificationBox.getNotificationWithValue("plugin-crashed");
+
+  ok(notification, "Infobar was shown.");
+  is(notification.priority, notificationBox.PRIORITY_WARNING_MEDIUM, "Correct priority.");
+  is(notification.getAttribute("label"), "The GlobalTestPlugin plugin has crashed.", "Correct message.");
+  finish();
+}
--- a/browser/base/content/test/social/browser.ini
+++ b/browser/base/content/test/social/browser.ini
@@ -23,17 +23,16 @@ support-files =
   social_sidebar_empty.html
   social_window.html
   social_worker.js
   unchecked.jpg
 
 [browser_aboutHome_activation.js]
 [browser_addons.js]
 [browser_blocklist.js]
-[browser_defaults.js]
 [browser_share.js]
 [browser_social_activation.js]
 [browser_social_chatwindow.js]
 [browser_social_chatwindow_resize.js]
 [browser_social_chatwindowfocus.js]
 [browser_social_errorPage.js]
 [browser_social_flyout.js]
 [browser_social_isVisible.js]
--- a/browser/base/content/test/social/browser_addons.js
+++ b/browser/base/content/test/social/browser_addons.js
@@ -3,17 +3,17 @@
 let AddonManager = Cu.import("resource://gre/modules/AddonManager.jsm", {}).AddonManager;
 let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
 
 const ADDON_TYPE_SERVICE     = "service";
 const ID_SUFFIX              = "@services.mozilla.org";
 const STRING_TYPE_NAME       = "type.%ID%.name";
 const XPINSTALL_URL = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
 
-let manifest = { // builtin provider
+let manifest = {
   name: "provider 1",
   origin: "https://example.com",
   sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
   workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
   iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png"
 };
 let manifest2 = { // used for testing install
   name: "provider 2",
@@ -23,29 +23,25 @@ let manifest2 = { // used for testing in
   iconURL: "https://test1.example.com/browser/browser/base/content/test/general/moz.png",
   version: 1
 };
 
 function test() {
   waitForExplicitFinish();
 
   let prefname = getManifestPrefname(manifest);
-  setBuiltinManifestPref(prefname, manifest);
   // ensure that manifest2 is NOT showing as builtin
-  is(SocialService.getOriginActivationType(manifest.origin), "builtin", "manifest is builtin");
-  is(SocialService.getOriginActivationType(manifest2.origin), "foreign", "manifest2 is not builtin");
+  is(SocialService.getOriginActivationType(manifest.origin), "foreign", "manifest is foreign");
+  is(SocialService.getOriginActivationType(manifest2.origin), "foreign", "manifest2 is foreign");
 
   Services.prefs.setBoolPref("social.remote-install.enabled", true);
   runSocialTests(tests, undefined, undefined, function () {
     Services.prefs.clearUserPref("social.remote-install.enabled");
-    // clear our builtin pref
     ok(!Services.prefs.prefHasUserValue(prefname), "manifest is not in user-prefs");
-    resetBuiltinManifestPref(prefname);
     // just in case the tests failed, clear these here as well
-    Services.prefs.clearUserPref("social.whitelist");
     Services.prefs.clearUserPref("social.directories");
     finish();
   });
 }
 
 function installListener(next, aManifest) {
   let expectEvent = "onInstalling";
   let prefname = getManifestPrefname(aManifest);
@@ -164,19 +160,19 @@ var tests = {
         is(addon.manifest.origin, manifest.origin, "provider about to be disabled");
         expectEvent = "onDisabled";
       }
     };
     AddonManager.addAddonListener(listener);
 
     expectEvent = "onEnabling";
     setManifestPref(prefname, manifest);
-    SocialService.addBuiltinProvider(manifest.origin, function(provider) {
+    SocialService.enableProvider(manifest.origin, function(provider) {
       expectEvent = "onDisabling";
-      SocialService.removeProvider(provider.origin, function() {
+      SocialService.disableProvider(provider.origin, function() {
         AddonManager.removeAddonListener(listener);
         Services.prefs.clearUserPref(prefname);
         next();
       });
     });
   },
   testForeignInstall: function(next) {
     AddonManager.addAddonListener(installListener(next, manifest2));
@@ -194,93 +190,17 @@ var tests = {
     let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html"
     addTab(activationURL, function(tab) {
       let doc = tab.linkedBrowser.contentDocument;
       let installFrom = doc.nodePrincipal.origin;
       Services.prefs.setCharPref("social.whitelist", "");
       is(SocialService.getOriginActivationType(installFrom), "foreign", "testing foriegn install");
       Social.installProvider(doc, manifest2, function(addonManifest) {
         Services.prefs.clearUserPref("social.whitelist");
-        SocialService.addBuiltinProvider(addonManifest.origin, function(provider) {
-          Social.uninstallProvider(addonManifest.origin);
-          gBrowser.removeTab(tab);
-        });
-      });
-    });
-  },
-  testBuiltinInstallWithoutManifest: function(next) {
-    // send installProvider null for the manifest
-    AddonManager.addAddonListener(installListener(next, manifest));
-    let panel = document.getElementById("servicesInstall-notification");
-    PopupNotifications.panel.addEventListener("popupshown", function onpopupshown() {
-      PopupNotifications.panel.removeEventListener("popupshown", onpopupshown);
-      info("servicesInstall-notification panel opened");
-      panel.button.click();
-    });
-
-    let prefname = getManifestPrefname(manifest);
-    let activationURL = manifest.origin + "/browser/browser/base/content/test/social/social_activate.html"
-    addTab(activationURL, function(tab) {
-      let doc = tab.linkedBrowser.contentDocument;
-      let installFrom = doc.nodePrincipal.origin;
-      is(SocialService.getOriginActivationType(installFrom), "builtin", "testing builtin install");
-      ok(!Services.prefs.prefHasUserValue(prefname), "manifest is not in user-prefs");
-      Social.installProvider(doc, null, function(addonManifest) {
-        ok(Services.prefs.prefHasUserValue(prefname), "manifest is in user-prefs");
-        SocialService.addBuiltinProvider(addonManifest.origin, function(provider) {
-          Social.uninstallProvider(addonManifest.origin);
-          gBrowser.removeTab(tab);
-        });
-      });
-    });
-  },
-  testBuiltinInstall: function(next) {
-    // send installProvider a json object for the manifest
-    AddonManager.addAddonListener(installListener(next, manifest));
-    let panel = document.getElementById("servicesInstall-notification");
-    PopupNotifications.panel.addEventListener("popupshown", function onpopupshown() {
-      PopupNotifications.panel.removeEventListener("popupshown", onpopupshown);
-      info("servicesInstall-notification panel opened");
-      panel.button.click();
-    });
-
-    let prefname = getManifestPrefname(manifest);
-    let activationURL = manifest.origin + "/browser/browser/base/content/test/social/social_activate.html"
-    addTab(activationURL, function(tab) {
-      let doc = tab.linkedBrowser.contentDocument;
-      let installFrom = doc.nodePrincipal.origin;
-      is(SocialService.getOriginActivationType(installFrom), "builtin", "testing builtin install");
-      ok(!Services.prefs.prefHasUserValue(prefname), "manifest is not in user-prefs");
-      Social.installProvider(doc, manifest, function(addonManifest) {
-        ok(Services.prefs.prefHasUserValue(prefname), "manifest is in user-prefs");
-        SocialService.addBuiltinProvider(addonManifest.origin, function(provider) {
-          Social.uninstallProvider(addonManifest.origin);
-          gBrowser.removeTab(tab);
-        });
-      });
-    });
-  },
-  testWhitelistInstall: function(next) {
-    AddonManager.addAddonListener(installListener(next, manifest2));
-    let panel = document.getElementById("servicesInstall-notification");
-    PopupNotifications.panel.addEventListener("popupshown", function onpopupshown() {
-      PopupNotifications.panel.removeEventListener("popupshown", onpopupshown);
-      info("servicesInstall-notification panel opened");
-      panel.button.click();
-    });
-
-    let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html"
-    addTab(activationURL, function(tab) {
-      let doc = tab.linkedBrowser.contentDocument;
-      let installFrom = doc.nodePrincipal.origin;
-      Services.prefs.setCharPref("social.whitelist", installFrom);
-      is(SocialService.getOriginActivationType(installFrom), "whitelist", "testing whitelist install");
-      Social.installProvider(doc, manifest2, function(addonManifest) {
-        Services.prefs.clearUserPref("social.whitelist");
-        SocialService.addBuiltinProvider(addonManifest.origin, function(provider) {
+        SocialService.enableProvider(addonManifest.origin, function(provider) {
           Social.uninstallProvider(addonManifest.origin);
           gBrowser.removeTab(tab);
         });
       });
     });
   },
   testDirectoryInstall: function(next) {
     AddonManager.addAddonListener(installListener(next, manifest2));
@@ -294,17 +214,17 @@ var tests = {
     let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html"
     addTab(activationURL, function(tab) {
       let doc = tab.linkedBrowser.contentDocument;
       let installFrom = doc.nodePrincipal.origin;
       Services.prefs.setCharPref("social.directories", installFrom);
       is(SocialService.getOriginActivationType(installFrom), "directory", "testing directory install");
       Social.installProvider(doc, manifest2, function(addonManifest) {
         Services.prefs.clearUserPref("social.directories");
-        SocialService.addBuiltinProvider(addonManifest.origin, function(provider) {
+        SocialService.enableProvider(addonManifest.origin, function(provider) {
           Social.uninstallProvider(addonManifest.origin);
           gBrowser.removeTab(tab);
         });
       });
     });
   },
   testUpgradeProviderFromWorker: function(next) {
     // add the provider, change the pref, add it again. The provider at that
@@ -317,17 +237,17 @@ var tests = {
       panel.button.click();
     });
 
     addTab(activationURL, function(tab) {
       let doc = tab.linkedBrowser.contentDocument;
       let installFrom = doc.nodePrincipal.origin;
       Services.prefs.setCharPref("social.whitelist", installFrom);
       Social.installProvider(doc, manifest2, function(addonManifest) {
-        SocialService.addBuiltinProvider(addonManifest.origin, function(provider) {
+        SocialService.enableProvider(addonManifest.origin, function(provider) {
           is(provider.manifest.version, 1, "manifest version is 1");
 
           // watch for the provider-update and test the new version
           SocialService.registerProviderListener(function providerListener(topic, origin, providers) {
             if (topic != "provider-update")
               return;
             is(origin, addonManifest.origin, "provider updated")
             SocialService.unregisterProviderListener(providerListener);
--- a/browser/base/content/test/social/browser_blocklist.js
+++ b/browser/base/content/test/social/browser_blocklist.js
@@ -55,22 +55,22 @@ var tests = {
       Services.prefs.clearUserPref("social.manifest.good");
       resetBlocklist(next);
     }
     setManifestPref("social.manifest.good", manifest);
     setAndUpdateBlocklist(blocklistURL, function() {
       try {
         SocialService.addProvider(manifest, function(provider) {
           try {
-            SocialService.removeProvider(provider.origin, function() {
+            SocialService.disableProvider(provider.origin, function() {
               ok(true, "added and removed provider");
               finishTest(true);
             });
           } catch(e) {
-            ok(false, "SocialService.removeProvider threw exception: " + e);
+            ok(false, "SocialService.disableProvider threw exception: " + e);
             finishTest(false);
           }
         });
       } catch(e) {
         ok(false, "SocialService.addProvider threw exception: " + e);
         finishTest(false);
       }
     });
@@ -80,17 +80,17 @@ var tests = {
       ok(good, "Unable to add blocklisted provider");
       Services.prefs.clearUserPref("social.manifest.blocked");
       resetBlocklist(next);
     }
     setManifestPref("social.manifest.blocked", manifest_bad);
     setAndUpdateBlocklist(blocklistURL, function() {
       try {
         SocialService.addProvider(manifest_bad, function(provider) {
-          SocialService.removeProvider(provider.origin, function() {
+          SocialService.disableProvider(provider.origin, function() {
             ok(false, "SocialService.addProvider should throw blocklist exception");
             finishTest(false);
           });
         });
       } catch(e) {
         ok(true, "SocialService.addProvider should throw blocklist exception: " + e);
         finishTest(true);
       }
deleted file mode 100644
--- a/browser/base/content/test/social/browser_defaults.js
+++ /dev/null
@@ -1,14 +0,0 @@
-
-let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
-
-// this test ensures that any builtin providers have the builtin flag that we
-// need to help with "install" of a builtin.
-function test() {
-  let manifestPrefs = Services.prefs.getDefaultBranch("social.manifest.");
-  let prefs = manifestPrefs.getChildList("", []);
-  ok(prefs.length > 0, "we have builtin providers");
-  for (let pref of prefs) {
-    let manifest = JSON.parse(manifestPrefs.getComplexValue(pref, Ci.nsISupportsString).data);
-    ok(manifest.builtin, "manifest is builtin " + manifest.origin);
-  }
-}
--- a/browser/base/content/test/social/browser_share.js
+++ b/browser/base/content/test/social/browser_share.js
@@ -110,17 +110,17 @@ var tests = {
       checkSocialUI();
       // share should not be enabled since we only have about:blank page
       let shareButton = SocialShare.shareButton;
       is(shareButton.disabled, true, "share button is disabled");
       // verify the attribute for proper css
       is(shareButton.getAttribute("disabled"), "true", "share button attribute is disabled");
       // button should be visible
       is(shareButton.hidden, false, "share button is visible");
-      SocialService.removeProvider(manifest.origin, next);
+      SocialService.disableProvider(manifest.origin, next);
     });
   },
   testShareEnabledOnActivation: function(next) {
     // starting from *some* page, share should be visible and enabled when
     // activating provider
     let testData = corpus[0];
     loadURLInTab(testData.url, function(tab) {
       SocialService.addProvider(manifest, function(provider) {
@@ -158,17 +158,17 @@ var tests = {
       switch (topic) {
         case "got-share-data-message":
           gBrowser.removeTab(testTab);
           hasoptions(testData.options, e.data.result);
           testData = corpus[testIndex++];
           if (testData) {
             executeSoon(runOneTest);
           } else {
-            SocialService.removeProvider(manifest.origin, next);
+            SocialService.disableProvider(manifest.origin, next);
           }
           break;
       }
     }
     port.postMessage({topic: "test-init"});
     executeSoon(runOneTest);
   },
   testShareMicrodata: function(next) {
@@ -222,17 +222,17 @@ var tests = {
       });
 
       port.onmessage = function (e) {
         let topic = e.data.topic;
         switch (topic) {
           case "got-share-data-message":
             is(JSON.stringify(e.data.result), expecting, "microdata data ok");
             gBrowser.removeTab(testTab);
-            SocialService.removeProvider(manifest.origin, next);
+            SocialService.disableProvider(manifest.origin, next);
             break;
         }
       }
       port.postMessage({topic: "test-init"});
   
       let url = "https://example.com/browser/browser/base/content/test/social/microdata.html"
       addTab(url, function(tab) {
         testTab = tab;
--- a/browser/base/content/test/social/browser_social_activation.js
+++ b/browser/base/content/test/social/browser_social_activation.js
@@ -1,56 +1,50 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
 
 let tabsToRemove = [];
 
+
+function removeAllProviders(callback) {
+  // all the providers may have been added.
+  function removeProviders() {
+    if (Social.providers.length < 1) {
+      executeSoon(function() {
+        is(Social.providers.length, 0, "all providers removed");
+        executeSoon(callback);
+      });
+      return;
+    }
+
+    // a full install sets the manifest into a pref, addProvider alone doesn't,
+    // make sure we uninstall if the manifest was added.
+    if (Social.providers[0].manifest) {
+      SocialService.uninstallProvider(Social.providers[0].origin, removeProviders);
+    } else {
+      SocialService.disableProvider(Social.providers[0].origin, removeProviders);
+    }
+  }
+  removeProviders();
+}
+
 function postTestCleanup(callback) {
   // any tabs opened by the test.
   for (let tab of tabsToRemove)
     gBrowser.removeTab(tab);
   tabsToRemove = [];
   // theses tests use the notification panel but don't bother waiting for it
   // to fully open - the end result is that the panel might stay open
   //SocialUI.activationPanel.hidePopup();
 
-  Services.prefs.clearUserPref("social.whitelist");
-
-  // all providers may have had their manifests added.
-  for (let manifest of gProviders)
-    Services.prefs.clearUserPref("social.manifest." + manifest.origin);
-
   // all the providers may have been added.
-  let providers = gProviders.slice(0)
-  function removeProviders() {
-    if (providers.length < 1) {
-      executeSoon(function() {
-        is(Social.providers.length, 0, "all providers removed");
-        callback();
-      });
-      return;
-    }
-
-    let provider = providers.pop();
-    try {
-      SocialService.removeProvider(provider.origin, removeProviders);
-    } catch(ex) {
-      removeProviders();
-    }
-  }
-  removeProviders();
-}
-
-function addBuiltinManifest(manifest) {
-  let prefname = getManifestPrefname(manifest);
-  setBuiltinManifestPref(prefname, manifest);
-  return prefname;
+  removeAllProviders(callback);
 }
 
 function addTab(url, callback) {
   let tab = gBrowser.selectedTab = gBrowser.addTab(url, {skipAnimation: true});
   tab.linkedBrowser.addEventListener("load", function tabLoad(event) {
     tab.linkedBrowser.removeEventListener("load", tabLoad, true);
     tabsToRemove.push(tab);
     executeSoon(function() {callback(tab)});
@@ -205,120 +199,95 @@ var tests = {
     // At this stage none of our providers exist, so we expect failure.
     Services.prefs.setBoolPref("social.remote-install.enabled", false);
     activateProvider(gTestDomains[0], function() {
       is(SocialUI.enabled, false, "SocialUI is not enabled");
       let panel = document.getElementById("servicesInstall-notification");
       ok(panel.hidden, "activation panel still hidden");
       checkSocialUI();
       Services.prefs.clearUserPref("social.remote-install.enabled");
-      next();
+      removeAllProviders(next);
     });
   },
-
+  
   testIFrameActivation: function(next) {
-    Services.prefs.setCharPref("social.whitelist", gTestDomains.join(","));
     activateIFrameProvider(gTestDomains[0], function() {
       is(SocialUI.enabled, false, "SocialUI is not enabled");
       ok(!SocialSidebar.provider, "provider is not installed");
       let panel = document.getElementById("servicesInstall-notification");
       ok(panel.hidden, "activation panel still hidden");
       checkSocialUI();
-      Services.prefs.clearUserPref("social.whitelist");
-      next();
+      removeAllProviders(next);
     });
   },
-
+  
   testActivationFirstProvider: function(next) {
-    Services.prefs.setCharPref("social.whitelist", gTestDomains.join(","));
     // first up we add a manifest entry for a single provider.
     activateOneProvider(gProviders[0], false, function() {
       // we deactivated leaving no providers left, so Social is disabled.
       ok(!SocialSidebar.provider, "should be no provider left after disabling");
       checkSocialUI();
-      Services.prefs.clearUserPref("social.whitelist");
-      next();
+      removeAllProviders(next);
     });
   },
-
-  testActivationBuiltin: function(next) {
-    let prefname = addBuiltinManifest(gProviders[0]);
-    is(SocialService.getOriginActivationType(gTestDomains[0]), "builtin", "manifest is builtin");
-    // first up we add a manifest entry for a single provider.
-    activateOneProvider(gProviders[0], false, function() {
-      // we deactivated leaving no providers left, so Social is disabled.
-      ok(!SocialSidebar.provider, "should be no provider left after disabling");
-      checkSocialUI();
-      resetBuiltinManifestPref(prefname);
-      next();
-    });
-  },
-
+  
   testActivationMultipleProvider: function(next) {
     // The trick with this test is to make sure that Social.providers[1] is
     // the current provider when doing the undo - this makes sure that the
     // Social code doesn't fallback to Social.providers[0], which it will
     // do in some cases (but those cases do not include what this test does)
     // first enable the 2 providers
-    Services.prefs.setCharPref("social.whitelist", gTestDomains.join(","));
     SocialService.addProvider(gProviders[0], function() {
       SocialService.addProvider(gProviders[1], function() {
         checkSocialUI();
         // activate the last provider.
-        let prefname = addBuiltinManifest(gProviders[2]);
         activateOneProvider(gProviders[2], false, function() {
           // we deactivated - the first provider should be enabled.
           is(SocialSidebar.provider.origin, Social.providers[1].origin, "original provider should have been reactivated");
           checkSocialUI();
-          Services.prefs.clearUserPref("social.whitelist");
-          resetBuiltinManifestPref(prefname);
-          next();
+          removeAllProviders(next);
         });
       });
     });
   },
 
   testAddonManagerDoubleInstall: function(next) {
-    Services.prefs.setCharPref("social.whitelist", gTestDomains.join(","));
     // Create a new tab and load about:addons
     let blanktab = gBrowser.addTab();
     gBrowser.selectedTab = blanktab;
     BrowserOpenAddonsMgr('addons://list/service');
 
     is(blanktab, gBrowser.selectedTab, "Current tab should be blank tab");
 
     gBrowser.selectedBrowser.addEventListener("load", function tabLoad() {
       gBrowser.selectedBrowser.removeEventListener("load", tabLoad, true);
       let browser = blanktab.linkedBrowser;
       is(browser.currentURI.spec, "about:addons", "about:addons should load into blank tab.");
 
-      let prefname = addBuiltinManifest(gProviders[0]);
       activateOneProvider(gProviders[0], true, function() {
         info("first activation completed");
-        is(gBrowser.contentDocument.location.href, gProviders[0].origin + "/browser/browser/base/content/test/social/social_postActivation.html");
+        is(gBrowser.contentDocument.location.href, gProviders[0].origin + "/browser/browser/base/content/test/social/social_postActivation.html", "postActivationURL loaded");
         gBrowser.removeTab(gBrowser.selectedTab);
-        is(gBrowser.contentDocument.location.href, gProviders[0].origin + "/browser/browser/base/content/test/social/social_activate.html");
+        is(gBrowser.contentDocument.location.href, gProviders[0].origin + "/browser/browser/base/content/test/social/social_activate.html", "activation page selected");
         gBrowser.removeTab(gBrowser.selectedTab);
         tabsToRemove.pop();
         // uninstall the provider
         clickAddonRemoveButton(blanktab, function(addon) {
           checkSocialUI();
           activateOneProvider(gProviders[0], true, function() {
             info("second activation completed");
-            is(gBrowser.contentDocument.location.href, gProviders[0].origin + "/browser/browser/base/content/test/social/social_postActivation.html");
+            is(gBrowser.contentDocument.location.href, gProviders[0].origin + "/browser/browser/base/content/test/social/social_postActivation.html", "postActivationURL loaded");
             gBrowser.removeTab(gBrowser.selectedTab);
 
             // after closing the addons tab, verify provider is still installed
             gBrowser.tabContainer.addEventListener("TabClose", function onTabClose() {
               gBrowser.tabContainer.removeEventListener("TabClose", onTabClose);
               AddonManager.getAddonsByTypes(["service"], function(aAddons) {
                 is(aAddons.length, 1, "there can be only one");
-                Services.prefs.clearUserPref("social.whitelist");
-                resetBuiltinManifestPref(prefname);
-                next();
+                removeAllProviders(next);
               });
             });
 
             // verify only one provider in list
             AddonManager.getAddonsByTypes(["service"], function(aAddons) {
               is(aAddons.length, 1, "there can be only one");
 
               let doc = blanktab.linkedBrowser.contentDocument;
--- a/browser/base/content/test/social/browser_social_marks.js
+++ b/browser/base/content/test/social/browser_social_marks.js
@@ -84,17 +84,17 @@ var tests = {
       let button = document.getElementById(id);
       is(button.disabled, true, "mark button is disabled");
       // verify the attribute for proper css
       is(button.getAttribute("disabled"), "true", "mark button attribute is disabled");
       // button should be visible
       is(button.hidden, false, "mark button is visible");
 
       checkSocialUI(window);
-      SocialService.removeProvider(manifest2.origin, next);
+      SocialService.disableProvider(manifest2.origin, next);
     });
   },
   testNoButtonOnEnable: function(next) {
     // we expect the addon install dialog to appear, we need to accept the
     // install from the dialog.
     let panel = document.getElementById("servicesInstall-notification");
     PopupNotifications.panel.addEventListener("popupshown", function onpopupshown() {
       PopupNotifications.panel.removeEventListener("popupshown", onpopupshown);
@@ -102,17 +102,17 @@ var tests = {
       panel.button.click();
     });
 
     let activationURL = manifest3.origin + "/browser/browser/base/content/test/social/social_activate.html"
     addTab(activationURL, function(tab) {
       let doc = tab.linkedBrowser.contentDocument;
       Social.installProvider(doc, manifest3, function(addonManifest) {
         // enable the provider so we know the button would have appeared
-        SocialService.addBuiltinProvider(manifest3.origin, function(provider) {
+        SocialService.enableProvider(manifest3.origin, function(provider) {
           is(provider.origin, manifest3.origin, "provider is installed");
           let id = SocialMarks._toolbarHelper.idFromOrigin(provider.origin);
           let widget = CustomizableUI.getWidget(id);
           ok(!widget || !widget.forWindow(window).node, "no button added to widget set");
           Social.uninstallProvider(manifest3.origin, function() {
             gBrowser.removeTab(tab);
             next();
           });
@@ -129,17 +129,17 @@ var tests = {
       panel.button.click();
     });
 
     // enable the provider now
     let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html"
     addTab(activationURL, function(tab) {
       let doc = tab.linkedBrowser.contentDocument;
       Social.installProvider(doc, manifest2, function(addonManifest) {
-        SocialService.addBuiltinProvider(manifest2.origin, function(provider) {
+        SocialService.enableProvider(manifest2.origin, function(provider) {
           is(provider.origin, manifest2.origin, "provider is installed");
           let id = SocialMarks._toolbarHelper.idFromOrigin(manifest2.origin);
           let widget = CustomizableUI.getWidget(id).forWindow(window)
           ok(widget.node, "button added to widget set");
 
           // bypass widget go directly to dom, check attribute states
           let button = document.getElementById(id);
           is(button.disabled, false, "mark button is disabled");
@@ -329,17 +329,17 @@ var tests = {
       SocialMarks.markLink(manifest2.origin, url, target);
     });
   },
 
   testButtonOnDisable: function(next) {
     // enable the provider now
     let provider = Social._getProviderFromOrigin(manifest2.origin);
     ok(provider, "provider is installed");
-    SocialService.removeProvider(manifest2.origin, function() {
+    SocialService.disableProvider(manifest2.origin, function() {
       let id = SocialMarks._toolbarHelper.idFromOrigin(manifest2.origin);
       waitForCondition(function() {
                         // getWidget now returns null since we've destroyed the widget
                         return !CustomizableUI.getWidget(id)
                        },
                        function() {
                          checkSocialUI(window);
                          Social.uninstallProvider(manifest2.origin, next);
@@ -376,17 +376,17 @@ var tests = {
 
       let activationURL = manifest.origin + "/browser/browser/base/content/test/social/social_activate.html"
       let id = SocialMarks._toolbarHelper.idFromOrigin(manifest.origin);
       let toolbar = document.getElementById("nav-bar");
       addTab(activationURL, function(tab) {
         let doc = tab.linkedBrowser.contentDocument;
         Social.installProvider(doc, manifest, function(addonManifest) {
           // enable the provider so we know the button would have appeared
-          SocialService.addBuiltinProvider(manifest.origin, function(provider) {
+          SocialService.enableProvider(manifest.origin, function(provider) {
             waitForCondition(function() { return CustomizableUI.getWidget(id) },
                              function() {
               gBrowser.removeTab(tab);
               installed.push(manifest.origin);
               // checkSocialUI will properly check where the menus are located
               checkSocialUI(window);
               executeSoon(function() {
                 addProviders(callback);
--- a/browser/base/content/test/social/browser_social_sidebar.js
+++ b/browser/base/content/test/social/browser_social_sidebar.js
@@ -65,17 +65,17 @@ function doTest() {
     checkShown(false);
 
     browser.addEventListener("socialFrameShow", function sidebarshow() {
       browser.removeEventListener("socialFrameShow", sidebarshow);
 
       checkShown(true);
 
       // disable social.
-      SocialService.removeProvider(SocialSidebar.provider.origin, function() {
+      SocialService.disableProvider(SocialSidebar.provider.origin, function() {
         checkShown(false);
         is(Social.providers.length, 0, "no providers left");
         defaultFinishChecks();
         // Finish the test
         executeSoon(finish);
       });
     });
 
--- a/browser/base/content/test/social/browser_social_status.js
+++ b/browser/base/content/test/social/browser_social_status.js
@@ -63,17 +63,17 @@ var tests = {
       panel.button.click();
     })
 
     let activationURL = manifest3.origin + "/browser/browser/base/content/test/social/social_activate.html"
     addTab(activationURL, function(tab) {
       let doc = tab.linkedBrowser.contentDocument;
       Social.installProvider(doc, manifest3, function(addonManifest) {
         // enable the provider so we know the button would have appeared
-        SocialService.addBuiltinProvider(manifest3.origin, function(provider) {
+        SocialService.enableProvider(manifest3.origin, function(provider) {
           is(provider.origin, manifest3.origin, "provider is installed");
           let id = SocialStatus._toolbarHelper.idFromOrigin(provider.origin);
           let widget = CustomizableUI.getWidget(id);
           ok(!widget || !widget.forWindow(window).node, "no button added to widget set");
           Social.uninstallProvider(manifest3.origin, function() {
             gBrowser.removeTab(tab);
             next();
           });
@@ -89,17 +89,17 @@ var tests = {
       panel.button.click();
     });
 
     // enable the provider now
     let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html"
     addTab(activationURL, function(tab) {
       let doc = tab.linkedBrowser.contentDocument;
       Social.installProvider(doc, manifest2, function(addonManifest) {
-        SocialService.addBuiltinProvider(manifest2.origin, function(provider) {
+        SocialService.enableProvider(manifest2.origin, function(provider) {
           is(provider.origin, manifest2.origin, "provider is installed");
           let id = SocialStatus._toolbarHelper.idFromOrigin(manifest2.origin);
           let widget = CustomizableUI.getWidget(id).forWindow(window);
           ok(widget.node, "button added to widget set");
           checkSocialUI(window);
           gBrowser.removeTab(tab);
           next();
         });
@@ -151,17 +151,17 @@ var tests = {
       }
     };
     port.postMessage({topic: "test-init"});
   },
   testButtonOnDisable: function(next) {
     // enable the provider now
     let provider = Social._getProviderFromOrigin(manifest2.origin);
     ok(provider, "provider is installed");
-    SocialService.removeProvider(manifest2.origin, function() {
+    SocialService.disableProvider(manifest2.origin, function() {
       let id = SocialStatus._toolbarHelper.idFromOrigin(manifest2.origin);
       waitForCondition(function() { return !document.getElementById(id) },
                        function() {
                         Social.uninstallProvider(manifest2.origin, next);
                        }, "button does not exist after disabling the provider");
     });
   }
 }
--- a/browser/base/content/test/social/browser_social_window.js
+++ b/browser/base/content/test/social/browser_social_window.js
@@ -105,18 +105,18 @@ let tests = {
             // now init is complete, open a second window
             openWindowAndWaitForInit(window, function(w2) {
               ok(w1.SocialSidebar.opened, "w1 sidebar is open");
               ok(w2.SocialSidebar.opened, "w2 sidebar is open");
               checkSocialUI(w2);
               checkSocialUI(w1);
 
               // disable social and re-check
-              SocialService.removeProvider(manifest.origin, function() {
-                SocialService.removeProvider(manifest2.origin, function() {
+              SocialService.disableProvider(manifest.origin, function() {
+                SocialService.disableProvider(manifest2.origin, function() {
                   ok(!Social.enabled, "social is disabled");
                   is(Social.providers.length, 0, "no providers");
                   ok(!w1.SocialSidebar.opened, "w1 sidebar is closed");
                   ok(!w2.SocialSidebar.opened, "w2 sidebar is closed");
                   checkSocialUI(w2);
                   checkSocialUI(w1);
                   Services.prefs.clearUserPref("social.manifest.test");
                   cbnext();
@@ -156,17 +156,17 @@ let tests = {
               // global state should now be no sidebar gets opened on new window
               closeWindow(w1, function() {
                 ok(!Services.prefs.prefHasUserValue("social.sidebar.provider"), "3. global state unset");
                 ok(!SocialSidebar.opened, "3. main sidebar is still closed");
                 openWindowAndWaitForInit(window, function(w1) {
                   ok(!Services.prefs.prefHasUserValue("social.sidebar.provider"), "4. global state unset");
                   ok(!SocialSidebar.opened, "4. main sidebar is still closed");
                   ok(!w1.SocialSidebar.opened, "4. window sidebar is closed");
-                  SocialService.removeProvider(manifest.origin, function() {
+                  SocialService.disableProvider(manifest.origin, function() {
                     Services.prefs.clearUserPref("social.manifest.test");
                     cbnext();
                   });
                 });
               });
             });
           });
         });        
@@ -175,18 +175,18 @@ let tests = {
   },
 
   // Check per window sidebar functionality, including migration from using
   // prefs to using session state, and state inheritance of windows (new windows
   // inherit state from the opener).
   testPerWindowSidebar: function(cbnext) {
     function finishCheck() {
       // disable social and re-check
-      SocialService.removeProvider(manifest.origin, function() {
-        SocialService.removeProvider(manifest2.origin, function() {
+      SocialService.disableProvider(manifest.origin, function() {
+        SocialService.disableProvider(manifest2.origin, function() {
           ok(!Social.enabled, "social is disabled");
           is(Social.providers.length, 0, "no providers");
           Services.prefs.clearUserPref("social.manifest.test");
           cbnext();
         });
       });
     }
 
--- a/browser/base/content/test/social/head.js
+++ b/browser/base/content/test/social/head.js
@@ -101,24 +101,24 @@ function runSocialTestWithProvider(manif
     if (finishCount == manifests.length)
       Task.spawn(finishCleanUp).then(finishcallback || defaultFinishChecks);
   }
   function removeAddedProviders(cleanup) {
     manifests.forEach(function (m) {
       // If we're "cleaning up", don't call finish when done.
       let callback = cleanup ? function () {} : finishIfDone;
       // Similarly, if we're cleaning up, catch exceptions from removeProvider
-      let removeProvider = SocialService.removeProvider.bind(SocialService);
+      let removeProvider = SocialService.disableProvider.bind(SocialService);
       if (cleanup) {
         removeProvider = function (origin, cb) {
           try {
-            SocialService.removeProvider(origin, cb);
+            SocialService.disableProvider(origin, cb);
           } catch (ex) {
             // Ignore "provider doesn't exist" errors.
-            if (ex.message.indexOf("SocialService.removeProvider: no provider with origin") == 0)
+            if (ex.message.indexOf("SocialService.disableProvider: no provider with origin") == 0)
               return;
             info("Failed to clean up provider " + origin + ": " + ex);
           }
         }
       }
       removeProvider(m.origin, callback);
     });
   }
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -67,16 +67,17 @@
         this.inputField.addEventListener("mousemove", this, false);
         this.inputField.addEventListener("mouseout", this, false);
         this.inputField.addEventListener("overflow", this, false);
         this.inputField.addEventListener("underflow", this, false);
 
         try {
           if (this._prefs.getBoolPref("unifiedcomplete")) {
             this.setAttribute("autocompletesearch", "unifiedcomplete");
+            this.mSearchNames = null;
           }
         } catch (ex) {}
 
         const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
         var textBox = document.getAnonymousElementByAttribute(this,
                                                 "anonid", "textbox-input-box");
         var cxmenu = document.getAnonymousElementByAttribute(textBox,
                                             "anonid", "input-box-contextmenu");
@@ -607,16 +608,17 @@
               case "unifiedcomplete":
                 let useUnifiedComplete = false;
                 try {
                   useUnifiedComplete = this._prefs.getBoolPref(aData);
                 } catch (ex) {}
                 this.setAttribute("autocompletesearch",
                                   useUnifiedComplete ? "unifiedcomplete"
                                                      : "urlinline history");
+                this.mSearchNames = null;
             }
           }
         ]]></body>
       </method>
 
       <method name="handleEvent">
         <parameter name="aEvent"/>
         <body><![CDATA[
--- a/browser/devtools/webide/content/webide.js
+++ b/browser/devtools/webide/content/webide.js
@@ -202,19 +202,20 @@ let UI = {
     win.classList.remove("busy-undetermined");
     this.updateCommands();
     this._busyPromise = null;
   },
 
   setupBusyTimeout: function() {
     this.cancelBusyTimeout();
     this._busyTimeout = setTimeout(() => {
+      let busyPromise = this._busyPromise;
       this.unbusy();
       UI.reportError("error_operationTimeout", this._busyOperationDescription);
-      this._busyPromise.reject("promise timeout: " + this._busyOperationDescription);
+      busyPromise.reject("promise timeout: " + this._busyOperationDescription);
     }, 30000);
   },
 
   cancelBusyTimeout: function() {
     clearTimeout(this._busyTimeout);
   },
 
   busyWithProgressUntil: function(promise, operationDescription) {
@@ -805,18 +806,22 @@ let Cmds = {
       runtimeappsHeaderNode.setAttribute("hidden", "true");
     }
 
     let runtimeAppsNode = document.querySelector("#project-panel-runtimeapps");
     while (runtimeAppsNode.hasChildNodes()) {
       runtimeAppsNode.firstChild.remove();
     }
 
-    for (let i = 0; i < AppManager.webAppsStore.object.all.length; i++) {
-      let app = AppManager.webAppsStore.object.all[i];
+    let sortedApps = AppManager.webAppsStore.object.all;
+    sortedApps = sortedApps.sort((a, b) => {
+      return a.name > b.name;
+    });
+    for (let i = 0; i < sortedApps.length; i++) {
+      let app = sortedApps[i];
       let panelItemNode = document.createElement("toolbarbutton");
       panelItemNode.className = "panel-item";
       panelItemNode.setAttribute("label", app.name);
       panelItemNode.setAttribute("image", app.iconURL);
       runtimeAppsNode.appendChild(panelItemNode);
       panelItemNode.addEventListener("click", () => {
         UI.hidePanels();
         AppManager.selectedProject = {
--- a/browser/devtools/webide/webide-prefs.js
+++ b/browser/devtools/webide/webide-prefs.js
@@ -1,15 +1,15 @@
 # -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 pref("devtools.webide.showProjectEditor", true);
-pref("devtools.webide.templatesURL", "http://code.cdn.mozilla.net/templates/list.json");
+pref("devtools.webide.templatesURL", "https://code.cdn.mozilla.net/templates/list.json");
 pref("devtools.webide.autoinstallADBHelper", true);
 pref("devtools.webide.lastprojectlocation", "");
 pref("devtools.webide.restoreLastProject", true);
 pref("devtools.webide.enableLocalRuntime", false);
 pref("devtools.webide.addonsURL", "https://ftp.mozilla.org/pub/mozilla.org/labs/fxos-simulator/index.json");
 pref("devtools.webide.simulatorAddonsURL", "https://ftp.mozilla.org/pub/mozilla.org/labs/fxos-simulator/#VERSION#/#OS#/fxos_#SLASHED_VERSION#_simulator-#OS#-latest.xpi");
 pref("devtools.webide.simulatorAddonID", "fxos_#SLASHED_VERSION#_simulator@mozilla.org");
 pref("devtools.webide.adbAddonURL", "https://ftp.mozilla.org/pub/mozilla.org/labs/fxos-simulator/adb-helper/#OS#/adbhelper-#OS#-latest.xpi");
--- a/browser/experiments/Experiments.jsm
+++ b/browser/experiments/Experiments.jsm
@@ -1581,17 +1581,17 @@ Experiments.ExperimentEntry.prototype = 
         condition: () => !data.disabled },
       { name: "frozen",
         condition: () => !data.frozen || this._enabled },
       { name: "startTime",
         condition: () => now >= data.startTime },
       { name: "endTime",
         condition: () => now < data.endTime },
       { name: "maxStartTime",
-        condition: () => !data.maxStartTime || now <= data.maxStartTime },
+        condition: () => this._startDate || !data.maxStartTime || now <= data.maxStartTime },
       { name: "maxActiveSeconds",
         condition: () => !this._startDate || now <= (startSec + maxActive) },
       { name: "appName",
         condition: () => !data.appName || data.appName.indexOf(app.name) != -1 },
       { name: "minBuildID",
         condition: () => !data.minBuildID || app.platformBuildID >= data.minBuildID },
       { name: "maxBuildID",
         condition: () => !data.maxBuildID || app.platformBuildID <= data.maxBuildID },
--- a/browser/experiments/test/xpcshell/test_api.js
+++ b/browser/experiments/test/xpcshell/test_api.js
@@ -1534,16 +1534,76 @@ add_task(function* testEnabledAfterResta
   Assert.equal(addons[0].isActive, false, "And not active.");
 
   yield experiments.updateManifest();
   Assert.ok(addons[0].isActive, "It activates when the manifest is evaluated.");
 
   yield testCleanup(experiments);
 });
 
+// If experiment add-ons were ever started, maxStartTime shouldn't be evaluated
+// anymore. Ensure that if maxStartTime is passed but experiment has started
+// already, maxStartTime does not cause deactivation.
+
+add_task(function* testMaxStartTimeEvaluation() {
+
+  // Dates the following tests are based on.
+
+  let startDate    = new Date(2014, 5, 1, 12);
+  let now          = futureDate(startDate, 10   * MS_IN_ONE_DAY);
+  let maxStartDate = futureDate(startDate, 100  * MS_IN_ONE_DAY);
+  let endDate      = futureDate(startDate, 1000 * MS_IN_ONE_DAY);
+
+  defineNow(gPolicy, now);
+
+  // The manifest data we test with.
+  // We set a value for maxStartTime.
+
+  gManifestObject = {
+    "version": 1,
+    experiments: [
+      {
+        id:               EXPERIMENT1_ID,
+        xpiURL:           gDataRoot + EXPERIMENT1_XPI_NAME,
+        xpiHash:          EXPERIMENT1_XPI_SHA1,
+        startTime:        dateToSeconds(startDate),
+        endTime:          dateToSeconds(endDate),
+        maxActiveSeconds: 1000 * SEC_IN_ONE_DAY,
+        maxStartTime:     dateToSeconds(maxStartDate),
+        appName:          ["XPCShell"],
+        channel:          ["nightly"],
+      },
+    ],
+  };
+
+  let experiments = new Experiments.Experiments(gPolicy);
+
+  let addons = yield getExperimentAddons();
+  Assert.equal(addons.length, 0, "Precondition: No experiment add-ons installed.");
+
+  yield experiments.updateManifest();
+  let fromManifest = yield experiments.getExperiments();
+  Assert.equal(fromManifest.length, 1, "A single experiment is known.");
+
+  addons = yield getExperimentAddons();
+  Assert.equal(addons.length, 1, "A single experiment add-on is installed.");
+  Assert.ok(addons[0].isActive, "That experiment is active.");
+
+  dump("Setting current time to maxStartTime + 100 days and reloading manifest\n");
+  now = futureDate(maxStartDate, 100 * MS_IN_ONE_DAY);
+  defineNow(gPolicy, now);
+  yield experiments.updateManifest();
+
+  addons = yield getExperimentAddons();
+  Assert.equal(addons.length, 1, "The experiment is still there.");
+  Assert.ok(addons[0].isActive, "It is still active.");
+
+  yield testCleanup(experiments);
+});
+
 // Test coverage for an add-on uninstall disabling the experiment and that it stays
 // disabled over restarts.
 add_task(function* test_foreignUninstallAndRestart() {
   let experiments = new Experiments.Experiments(gPolicy);
 
   gManifestObject = {
     "version": 1,
     experiments: [
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -107,16 +107,27 @@ installPlugin.ignoreButton.accesskey=N
 
 crashedpluginsMessage.title=The %S plugin has crashed.
 crashedpluginsMessage.reloadButton.label=Reload page
 crashedpluginsMessage.reloadButton.accesskey=R
 crashedpluginsMessage.submitButton.label=Submit a crash report
 crashedpluginsMessage.submitButton.accesskey=S
 crashedpluginsMessage.learnMore=Learn More…
 
+# Keyword fixup messages
+# LOCALIZATION NOTE (keywordURIFixup.message): Used when the user tries to visit
+# a local host page, by the time the DNS request recognizes it, we have already
+# loaded a search page for the given word.  An infobar then asks to the user
+# whether he rather wanted to visit the host.  %S is the recognized host.
+keywordURIFixup.message=Did you mean to go to %S?
+keywordURIFixup.goTo=Yes, take me to %S
+keywordURIFixup.goTo.accesskey=Y
+keywordURIFixup.dismiss=No thanks
+keywordURIFixup.dismiss.accesskey=N
+
 ## Plugin doorhanger strings
 # LOCALIZATION NOTE (pluginActivateNew.message): Used for newly-installed
 # plugins which are not known to be unsafe. %1$S is the plugin name and %2$S
 # is the site domain.
 pluginActivateNew.message=Allow %2$S to run "%1$S"?
 pluginActivateMultiple.message=Allow %S to run plugins?
 pluginActivate.learnMore=Learn More…
 # LOCALIZATION NOTE (pluginActivateOutdated.message, pluginActivateOutdated.label):
--- a/browser/metro/profile/metro.js
+++ b/browser/metro/profile/metro.js
@@ -247,16 +247,17 @@ pref("privacy.popups.showBrowserMessage"
 
 // Metro Firefox keeps this set to -1 when donottrackheader.enabled is false.
 pref("privacy.donottrackheader.value", -1);
 
 /* disable opening windows with the dialog feature */
 pref("dom.disable_window_open_dialog_feature", true);
 
 pref("keyword.enabled", true);
+pref("browser.fixup.domainwhitelist.localhost", true);
 
 pref("accessibility.typeaheadfind", false);
 pref("accessibility.typeaheadfind.timeout", 5000);
 pref("accessibility.typeaheadfind.flashBar", 1);
 pref("accessibility.typeaheadfind.linksonly", false);
 pref("accessibility.typeaheadfind.casesensitive", 0);
 
 // Trun on F7 caret browsing hot key
--- a/browser/modules/Social.jsm
+++ b/browser/modules/Social.jsm
@@ -173,19 +173,19 @@ this.Social = {
   },
 
   uninstallProvider: function(origin, aCallback) {
     SocialService.uninstallProvider(origin, aCallback);
   },
 
   // Activation functionality
   activateFromOrigin: function (origin, callback) {
-    // For now only "builtin" providers can be activated.  It's OK if the
-    // provider has already been activated - we still get called back with it.
-    SocialService.addBuiltinProvider(origin, callback);
+    // It's OK if the provider has already been activated - we still get called
+    // back with it.
+    SocialService.enableProvider(origin, callback);
   },
 
   // Page Marking functionality
   isURIMarked: function(origin, aURI, aCallback) {
     promiseGetAnnotation(aURI).then(function(val) {
       if (val) {
         let providerList = JSON.parse(val);
         val = providerList.indexOf(origin) >= 0;
--- a/browser/modules/test/unit/social/test_social.js
+++ b/browser/modules/test/unit/social/test_social.js
@@ -15,18 +15,18 @@ function testStartupEnabled() {
   do_check_eq(Social.providers.length, 2, "two social providers enabled");
   do_check_true(Social.providers[0].enabled, "provider 0 is enabled");
   do_check_true(Social.providers[1].enabled, "provider 1 is enabled");
   run_next_test();
 }
 
 function testDisableAfterStartup() {
   let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
-  SocialService.removeProvider(Social.providers[0].origin, function() {
+  SocialService.disableProvider(Social.providers[0].origin, function() {
     do_wait_observer("social:providers-changed", function() {
       do_check_eq(Social.enabled, false, "Social is disabled");
       do_check_eq(Social.providers.length, 0, "no social providers available");
       do_test_finished();
       run_next_test();
     });
-    SocialService.removeProvider(Social.providers[0].origin)
+    SocialService.disableProvider(Social.providers[0].origin)
   });
 }
--- a/docshell/base/nsDefaultURIFixup.cpp
+++ b/docshell/base/nsDefaultURIFixup.cpp
@@ -119,21 +119,34 @@ nsDefaultURIFixup::CreateExposableURI(ns
     return NS_OK;
 }
 
 /* nsIURI createFixupURI (in nsAUTF8String aURIText, in unsigned long aFixupFlags); */
 NS_IMETHODIMP
 nsDefaultURIFixup::CreateFixupURI(const nsACString& aStringURI, uint32_t aFixupFlags,
                                   nsIInputStream **aPostData, nsIURI **aURI)
 {
+  nsCOMPtr<nsIURIFixupInfo> fixupInfo;
+  nsresult rv = GetFixupURIInfo(aStringURI, aFixupFlags, aPostData,
+                                getter_AddRefs(fixupInfo));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  fixupInfo->GetPreferredURI(aURI);
+  return rv;
+}
+
+NS_IMETHODIMP
+nsDefaultURIFixup::GetFixupURIInfo(const nsACString& aStringURI, uint32_t aFixupFlags,
+                                   nsIInputStream **aPostData, nsIURIFixupInfo **aInfo)
+{
     NS_ENSURE_ARG(!aStringURI.IsEmpty());
-    NS_ENSURE_ARG_POINTER(aURI);
 
     nsresult rv;
-    *aURI = nullptr;
+    nsRefPtr<nsDefaultURIFixupInfo> info = new nsDefaultURIFixupInfo(aStringURI);
+    NS_ADDREF(*aInfo = info);
 
     nsAutoCString uriString(aStringURI);
     uriString.Trim(" ");  // Cleanup the empty spaces that might be on each end.
 
     // Eliminate embedded newlines, which single-line text fields now allow:
     uriString.StripChars("\r\n");
 
     NS_ENSURE_TRUE(!uriString.IsEmpty(), NS_ERROR_FAILURE);
@@ -144,36 +157,45 @@ nsDefaultURIFixup::CreateFixupURI(const 
     ioService->ExtractScheme(aStringURI, scheme);
     
     // View-source is a pseudo scheme. We're interested in fixing up the stuff
     // after it. The easiest way to do that is to call this method again with the
     // "view-source:" lopped off and then prepend it again afterwards.
 
     if (scheme.LowerCaseEqualsLiteral("view-source"))
     {
-        nsCOMPtr<nsIURI> uri;
+        nsCOMPtr<nsIURIFixupInfo> uriInfo;
         uint32_t newFixupFlags = aFixupFlags & ~FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
 
-        rv =  CreateFixupURI(Substring(uriString,
+        rv = GetFixupURIInfo(Substring(uriString,
                                        sizeof("view-source:") - 1,
                                        uriString.Length() -
                                          (sizeof("view-source:") - 1)),
-                             newFixupFlags, aPostData, getter_AddRefs(uri));
+                             newFixupFlags, aPostData, getter_AddRefs(uriInfo));
         if (NS_FAILED(rv))
             return NS_ERROR_FAILURE;
         nsAutoCString spec;
+        nsCOMPtr<nsIURI> uri;
+        uriInfo->GetPreferredURI(getter_AddRefs(uri));
+        if (!uri)
+            return NS_ERROR_FAILURE;
         uri->GetSpec(spec);
         uriString.AssignLiteral("view-source:");
         uriString.Append(spec);
     }
     else {
         // Check for if it is a file URL
-        FileURIFixup(uriString, aURI);
-        if(*aURI)
+        nsCOMPtr<nsIURI> uri;
+        FileURIFixup(uriString, getter_AddRefs(uri));
+        if (uri)
+        {
+            uri.swap(info->mFixedURI);
+            info->mPreferredURI = info->mFixedURI;
             return NS_OK;
+        }
 
 #if defined(XP_WIN)
         // Not a file URL, so translate '\' to '/' for convenience in the common protocols
         // e.g. catch
         //
         //   http:\\broken.com\address
         //   http:\\broken.com/blah
         //   broken.com\blah
@@ -218,16 +240,18 @@ nsDefaultURIFixup::CreateFixupURI(const 
                 "Failed to observe \"browser.fixup.typo.scheme\"");
 
       rv = Preferences::AddBoolVarCache(&sFixupKeywords, "keyword.enabled",
                                         sFixupKeywords);
       MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed to observe \"keyword.enabled\"");
       sInitializedPrefCaches = true;
     }
 
+    info->mInputHasProtocol = !scheme.IsEmpty();
+
     // Fix up common scheme typos.
     if (sFixTypos && (aFixupFlags & FIXUP_FLAG_FIX_SCHEME_TYPOS)) {
 
         // Fast-path for common cases.
         if (scheme.IsEmpty() ||
             scheme.LowerCaseEqualsLiteral("http") ||
             scheme.LowerCaseEqualsLiteral("https") ||
             scheme.LowerCaseEqualsLiteral("ftp") ||
@@ -261,120 +285,107 @@ nsDefaultURIFixup::CreateFixupURI(const 
     }
 
     // Now we need to check whether "scheme" is something we don't
     // really know about.
     nsCOMPtr<nsIProtocolHandler> ourHandler, extHandler;
     
     ioService->GetProtocolHandler(scheme.get(), getter_AddRefs(ourHandler));
     extHandler = do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX"default");
-    
+
+    nsCOMPtr<nsIURI> uri;
     if (ourHandler != extHandler || !PossiblyHostPortUrl(uriString)) {
         // Just try to create an URL out of it
-        rv = NS_NewURI(aURI, uriString, nullptr);
+        rv = NS_NewURI(getter_AddRefs(uri), uriString, nullptr);
+        if (NS_SUCCEEDED(rv)) {
+            info->mFixedURI = uri;
+            // Figure out whether this had a domain or just a single hostname:
+            nsAutoCString host;
+            uri->GetHost(host);
+            info->mInputHostHasDot = host.FindChar('.') != kNotFound;
+        }
 
-        if (!*aURI && rv != NS_ERROR_MALFORMED_URI) {
+        if (!uri && rv != NS_ERROR_MALFORMED_URI) {
             return rv;
         }
     }
 
-    if (*aURI && ourHandler == extHandler && sFixupKeywords &&
+    if (uri && ourHandler == extHandler && sFixupKeywords &&
         (aFixupFlags & FIXUP_FLAG_FIX_SCHEME_TYPOS)) {
         nsCOMPtr<nsIExternalProtocolService> extProtService =
             do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID);
         if (extProtService) {
             bool handlerExists = false;
             rv = extProtService->ExternalProtocolHandlerExists(scheme.get(), &handlerExists);
             if (NS_FAILED(rv)) {
                 return rv;
             }
             // This basically means we're dealing with a theoretically valid
             // URI... but we have no idea how to load it. (e.g. "christmas:humbug")
             // It's more likely the user wants to search, and so we
             // chuck this over to their preferred search provider instead:
             if (!handlerExists) {
-                NS_RELEASE(*aURI);
-                KeywordToURI(uriString, aPostData, aURI);
+                nsresult rv = KeywordToURI(uriString, aPostData, getter_AddRefs(uri));
+                if (NS_SUCCEEDED(rv) && uri) {
+                  info->mFixupUsedKeyword = true;
+                }
             }
         }
     }
     
-    if (*aURI) {
+    if (uri) {
         if (aFixupFlags & FIXUP_FLAGS_MAKE_ALTERNATE_URI)
-            MakeAlternateURI(*aURI);
+            MakeAlternateURI(uri);
+        info->mPreferredURI = uri;
         return NS_OK;
     }
 
+    // Fix up protocol string before calling KeywordURIFixup, because
+    // it cares about the hostname of such URIs:
+    nsCOMPtr<nsIURI> uriWithProtocol;
+    // NB: this rv gets returned at the end of this method if we never
+    // do a keyword fixup after this (because the pref or the flags passed
+    // might not let us).
+    rv = FixupURIProtocol(uriString, getter_AddRefs(uriWithProtocol));
+    if (uriWithProtocol) {
+        info->mFixedURI = uriWithProtocol;
+        nsAutoCString host;
+        uriWithProtocol->GetHost(host);
+        info->mInputHostHasDot = host.FindChar('.') != kNotFound;
+    }
+
     // See if it is a keyword
     // Test whether keywords need to be fixed up
     if (sFixupKeywords && (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP)) {
-        KeywordURIFixup(uriString, aPostData, aURI);
-        if(*aURI)
+        KeywordURIFixup(uriString, info, aPostData);
+        if (info->mPreferredURI)
             return NS_OK;
     }
 
-    // Prune duff protocol schemes
-    //
-    //   ://totallybroken.url.com
-    //   //shorthand.url.com
-    //
-    if (StringBeginsWith(uriString, NS_LITERAL_CSTRING("://")))
-    {
-        uriString = StringTail(uriString, uriString.Length() - 3);
-    }
-    else if (StringBeginsWith(uriString, NS_LITERAL_CSTRING("//")))
-    {
-        uriString = StringTail(uriString, uriString.Length() - 2);
-    }
-
-    // Add ftp:// or http:// to front of url if it has no spec
-    //
-    // Should fix:
-    //
-    //   no-scheme.com
-    //   ftp.no-scheme.com
-    //   ftp4.no-scheme.com
-    //   no-scheme.com/query?foo=http://www.foo.com
-    //
-    int32_t schemeDelim = uriString.Find("://",0);
-    int32_t firstDelim = uriString.FindCharInSet("/:");
-    if (schemeDelim <= 0 ||
-        (firstDelim != -1 && schemeDelim > firstDelim)) {
-        // find host name
-        int32_t hostPos = uriString.FindCharInSet("/:?#");
-        if (hostPos == -1) 
-            hostPos = uriString.Length();
-
-        // extract host name
-        nsAutoCString hostSpec;
-        uriString.Left(hostSpec, hostPos);
-
-        // insert url spec corresponding to host name
-        if (IsLikelyFTP(hostSpec))
-            uriString.InsertLiteral("ftp://", 0);
-        else 
-            uriString.InsertLiteral("http://", 0);
-    } // end if checkprotocol
-
-    rv = NS_NewURI(aURI, uriString, nullptr);
-
     // Did the caller want us to try an alternative URI?
     // If so, attempt to fixup http://foo into http://www.foo.com
 
-    if (*aURI && aFixupFlags & FIXUP_FLAGS_MAKE_ALTERNATE_URI) {
-        MakeAlternateURI(*aURI);
+    if (info->mFixedURI && aFixupFlags & FIXUP_FLAGS_MAKE_ALTERNATE_URI) {
+        MakeAlternateURI(info->mFixedURI);
     }
 
     // If we still haven't been able to construct a valid URI, try to force a
     // keyword match.  This catches search strings with '.' or ':' in them.
-    if (!*aURI && sFixupKeywords)
+    if (info->mFixedURI)
+    {
+        info->mPreferredURI = info->mFixedURI;
+    }
+    else if (sFixupKeywords && (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP))
     {
-        KeywordToURI(aStringURI, aPostData, aURI);
-        if(*aURI)
+        rv = KeywordToURI(aStringURI, aPostData, getter_AddRefs(info->mPreferredURI));
+        if (NS_SUCCEEDED(rv) && info->mPreferredURI)
+        {
+            info->mFixupUsedKeyword = true;
             return NS_OK;
+        }
     }
 
     return rv;
 }
 
 NS_IMETHODIMP nsDefaultURIFixup::KeywordToURI(const nsACString& aKeyword,
                                               nsIInputStream **aPostData,
                                               nsIURI **aURI)
@@ -703,16 +714,71 @@ nsresult nsDefaultURIFixup::ConvertFileT
             NS_GetURLSpecFromFile(filePath, aOut);
             return NS_OK;
         }
     }
 
     return NS_ERROR_FAILURE;
 }
 
+
+nsresult
+nsDefaultURIFixup::FixupURIProtocol(const nsACString & aURIString,
+                                         nsIURI** aURI)
+{
+    nsAutoCString uriString(aURIString);
+    *aURI = nullptr;
+
+    // Prune duff protocol schemes
+    //
+    //   ://totallybroken.url.com
+    //   //shorthand.url.com
+    //
+    if (StringBeginsWith(uriString, NS_LITERAL_CSTRING("://")))
+    {
+        uriString = StringTail(uriString, uriString.Length() - 3);
+    }
+    else if (StringBeginsWith(uriString, NS_LITERAL_CSTRING("//")))
+    {
+        uriString = StringTail(uriString, uriString.Length() - 2);
+    }
+
+    // Add ftp:// or http:// to front of url if it has no spec
+    //
+    // Should fix:
+    //
+    //   no-scheme.com
+    //   ftp.no-scheme.com
+    //   ftp4.no-scheme.com
+    //   no-scheme.com/query?foo=http://www.foo.com
+    //
+    int32_t schemeDelim = uriString.Find("://",0);
+    int32_t firstDelim = uriString.FindCharInSet("/:");
+    if (schemeDelim <= 0 ||
+        (firstDelim != -1 && schemeDelim > firstDelim)) {
+        // find host name
+        int32_t hostPos = uriString.FindCharInSet("/:?#");
+        if (hostPos == -1)
+            hostPos = uriString.Length();
+
+        // extract host name
+        nsAutoCString hostSpec;
+        uriString.Left(hostSpec, hostPos);
+
+        // insert url spec corresponding to host name
+        if (IsLikelyFTP(hostSpec))
+            uriString.InsertLiteral("ftp://", 0);
+        else
+            uriString.InsertLiteral("http://", 0);
+    } // end if checkprotocol
+
+    return NS_NewURI(aURI, uriString, nullptr);
+}
+
+
 bool nsDefaultURIFixup::PossiblyHostPortUrl(const nsACString &aUrl)
 {
     // Oh dear, the protocol is invalid. Test if the protocol might
     // actually be a url without a protocol:
     //
     //   http://www.faqs.org/rfcs/rfc1738.html
     //   http://www.faqs.org/rfcs/rfc2396.html
     //
@@ -825,26 +891,27 @@ bool nsDefaultURIFixup::PossiblyByteExpa
         if (*iter >= 0x0080 && *iter <= 0x00FF)
             return true;
         ++iter;
     }
     return false;
 }
 
 void nsDefaultURIFixup::KeywordURIFixup(const nsACString & aURIString,
-                                        nsIInputStream **aPostData,
-                                        nsIURI** aURI)
+                                        nsDefaultURIFixupInfo* aFixupInfo,
+                                        nsIInputStream **aPostData)
 {
     // These are keyword formatted strings
     // "what is mozilla"
     // "what is mozilla?"
     // "docshell site:mozilla.org" - has no dot/colon in the first space-separated substring
     // "?mozilla" - anything that begins with a question mark
     // "?site:mozilla.org docshell"
     // Things that have a quote before the first dot/colon
+    // "mozilla" - checked against a whitelist to see if it's a host or not
 
     // These are not keyword formatted strings
     // "www.blah.com" - first space-separated substring contains a dot, doesn't start with "?"
     // "www.blah.com stuff"
     // "nonQualifiedHost:80" - first space-separated substring contains a colon, doesn't start with "?"
     // "nonQualifiedHost:80 args"
     // "nonQualifiedHost?"
     // "nonQualifiedHost?args"
@@ -860,28 +927,133 @@ void nsDefaultURIFixup::KeywordURIFixup(
     if (spaceLoc == 0) {
         // Treat this as not found
         spaceLoc = uint32_t(kNotFound);
     }
     uint32_t qMarkLoc = uint32_t(aURIString.FindChar('?'));
     uint32_t quoteLoc = std::min(uint32_t(aURIString.FindChar('"')),
                                uint32_t(aURIString.FindChar('\'')));
 
+    nsresult rv;
     if (((spaceLoc < dotLoc || quoteLoc < dotLoc) &&
          (spaceLoc < colonLoc || quoteLoc < colonLoc) &&
          (spaceLoc < qMarkLoc || quoteLoc < qMarkLoc)) ||
         qMarkLoc == 0)
     {
-        KeywordToURI(aURIString, aPostData, aURI);
+        rv = KeywordToURI(aURIString, aPostData,
+                          getter_AddRefs(aFixupInfo->mPreferredURI));
+        if (NS_SUCCEEDED(rv) && aFixupInfo->mPreferredURI)
+        {
+            aFixupInfo->mFixupUsedKeyword = true;
+        }
+    }
+    else if (dotLoc == uint32_t(kNotFound) && colonLoc == uint32_t(kNotFound) &&
+             qMarkLoc == uint32_t(kNotFound))
+    {
+        nsAutoCString asciiHost;
+        if (NS_SUCCEEDED(aFixupInfo->mFixedURI->GetAsciiHost(asciiHost)) &&
+            !asciiHost.IsEmpty())
+        {
+            // Check if this domain is whitelisted as an actual
+            // domain (which will prevent a keyword query)
+            nsAutoCString pref("browser.fixup.domainwhitelist.");
+            pref.Append(asciiHost);
+            if (Preferences::GetBool(pref.get(), false))
+            {
+                return;
+            }
+        }
+        // If we get here, we don't have a valid URI, or we did but the
+        // host is not whitelisted, so we do a keyword search *anyway*:
+        rv = KeywordToURI(aURIString, aPostData,
+                          getter_AddRefs(aFixupInfo->mPreferredURI));
+        if (NS_SUCCEEDED(rv) && aFixupInfo->mPreferredURI)
+        {
+            aFixupInfo->mFixupUsedKeyword = true;
+        }
     }
 }
 
-
 nsresult NS_NewURIFixup(nsIURIFixup **aURIFixup)
 {
     nsDefaultURIFixup *fixup = new nsDefaultURIFixup;
     if (fixup == nullptr)
     {
         return NS_ERROR_OUT_OF_MEMORY;
     }
     return fixup->QueryInterface(NS_GET_IID(nsIURIFixup), (void **) aURIFixup);
 }
 
+
+/* Implementation of nsIURIFixupInfo */
+NS_IMPL_ISUPPORTS(nsDefaultURIFixupInfo, nsIURIFixupInfo)
+
+nsDefaultURIFixupInfo::nsDefaultURIFixupInfo(const nsACString& aOriginalInput):
+    mFixupUsedKeyword(false),
+    mInputHasProtocol(false),
+    mInputHostHasDot(false)
+{
+  mOriginalInput = aOriginalInput;
+}
+
+
+nsDefaultURIFixupInfo::~nsDefaultURIFixupInfo()
+{
+}
+
+NS_IMETHODIMP
+nsDefaultURIFixupInfo::GetConsumer(nsISupports** aConsumer)
+{
+    *aConsumer = mConsumer;
+    NS_IF_ADDREF(*aConsumer);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDefaultURIFixupInfo::SetConsumer(nsISupports* aConsumer)
+{
+    mConsumer = aConsumer;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDefaultURIFixupInfo::GetPreferredURI(nsIURI** aPreferredURI)
+{
+    *aPreferredURI = mPreferredURI;
+    NS_IF_ADDREF(*aPreferredURI);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDefaultURIFixupInfo::GetFixedURI(nsIURI** aFixedURI)
+{
+    *aFixedURI = mFixedURI;
+    NS_IF_ADDREF(*aFixedURI);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDefaultURIFixupInfo::GetFixupUsedKeyword(bool* aOut)
+{
+    *aOut = mFixupUsedKeyword;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDefaultURIFixupInfo::GetInputHasProtocol(bool* aOut)
+{
+    *aOut = mInputHasProtocol;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDefaultURIFixupInfo::GetInputHostHasDot(bool* aOut)
+{
+    *aOut = mInputHostHasDot;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDefaultURIFixupInfo::GetOriginalInput(nsACString& aInput)
+{
+    aInput = mOriginalInput;
+    return NS_OK;
+}
--- a/docshell/base/nsDefaultURIFixup.h
+++ b/docshell/base/nsDefaultURIFixup.h
@@ -4,32 +4,59 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef NSDEFAULTURIFIXUP_H
 #define NSDEFAULTURIFIXUP_H
 
 #include "nsIURIFixup.h"
 
+class nsDefaultURIFixupInfo;
+
 /* Header file */
 class nsDefaultURIFixup : public nsIURIFixup
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIURIFIXUP
 
     nsDefaultURIFixup();
 
 protected:
     virtual ~nsDefaultURIFixup();
 
 private:
     /* additional members */
     nsresult FileURIFixup(const nsACString &aStringURI, nsIURI** aURI);
     nsresult ConvertFileToStringURI(const nsACString& aIn, nsCString& aOut);
-    void KeywordURIFixup(const nsACString &aStringURI, nsIInputStream** aPostData, nsIURI** aURI);
+    nsresult FixupURIProtocol(const nsACString& aIn, nsIURI** aURI);
+    void KeywordURIFixup(const nsACString &aStringURI,
+                         nsDefaultURIFixupInfo* aFixupInfo,
+                         nsIInputStream** aPostData);
     bool PossiblyByteExpandedFileName(const nsAString& aIn);
     bool PossiblyHostPortUrl(const nsACString& aUrl);
     bool MakeAlternateURI(nsIURI *aURI);
     bool IsLikelyFTP(const nsCString& aHostSpec);
 };
 
+class nsDefaultURIFixupInfo : public nsIURIFixupInfo
+{
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIURIFIXUPINFO
+
+    nsDefaultURIFixupInfo(const nsACString& aOriginalInput);
+
+    friend class nsDefaultURIFixup;
+
+protected:
+    virtual ~nsDefaultURIFixupInfo();
+
+private:
+    nsCOMPtr<nsISupports> mConsumer;
+    nsCOMPtr<nsIURI> mPreferredURI;
+    nsCOMPtr<nsIURI> mFixedURI;
+    bool mFixupUsedKeyword;
+    bool mInputHasProtocol;
+    bool mInputHostHasDot;
+    nsAutoCString mOriginalInput;
+};
 #endif
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -4357,25 +4357,39 @@ nsDocShell::LoadURIWithBase(const char16
         uint32_t fixupFlags = 0;
         if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
           fixupFlags |= nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
         }
         if (aLoadFlags & LOAD_FLAGS_FIXUP_SCHEME_TYPOS) {
           fixupFlags |= nsIURIFixup::FIXUP_FLAG_FIX_SCHEME_TYPOS;
         }
         nsCOMPtr<nsIInputStream> fixupStream;
-        rv = sURIFixup->CreateFixupURI(uriString, fixupFlags,
-                                       getter_AddRefs(fixupStream),
-                                       getter_AddRefs(uri));
+        nsCOMPtr<nsIURIFixupInfo> fixupInfo;
+        rv = sURIFixup->GetFixupURIInfo(uriString, fixupFlags,
+                                        getter_AddRefs(fixupStream),
+                                        getter_AddRefs(fixupInfo));
+
+        if (NS_SUCCEEDED(rv)) {
+            fixupInfo->GetPreferredURI(getter_AddRefs(uri));
+            fixupInfo->SetConsumer(GetAsSupports(this));
+        }
+
         if (fixupStream) {
             // CreateFixupURI only returns a post data stream if it succeeded
             // and changed the URI, in which case we should override the
             // passed-in post data.
             postStream = fixupStream;
         }
+
+        if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
+            nsCOMPtr<nsIObserverService> serv = services::GetObserverService();
+            if (serv) {
+                serv->NotifyObservers(fixupInfo, "keyword-uri-fixup", aURI);
+            }
+        }
     }
     // else no fixup service so just use the URI we created and see
     // what happens
 
     if (NS_ERROR_MALFORMED_URI == rv) {
         DisplayLoadError(rv, uri, aURI, nullptr);
     }
 
--- a/docshell/base/nsIURIFixup.idl
+++ b/docshell/base/nsIURIFixup.idl
@@ -5,19 +5,70 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIURI;
 interface nsIInputStream;
 
 /**
+ * Interface indicating what we found/corrected when fixing up a URI
+ */
+[scriptable, uuid(c9b6cc32-c24e-4283-adaa-9290577fd609)]
+interface nsIURIFixupInfo : nsISupports
+{
+  /**
+   * Consumer that asked for fixed up URI.
+   */
+  attribute nsISupports consumer;
+
+  /**
+   * Our best guess as to what URI the consumer will want. Might
+   * be null if we couldn't salvage anything (for instance, because
+   * the input was invalid as a URI and FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP
+   * was not passed)
+   */
+  readonly attribute nsIURI preferredURI;
+
+  /**
+   * The fixed-up original input, *never* using a keyword search.
+   * (might be null if the original input was not recoverable as
+   * a URL, e.g. "foo bar"!)
+   */
+  readonly attribute nsIURI fixedURI;
+
+  /**
+   * Whether the preferred option ended up using a keyword search.
+   */
+  readonly attribute boolean fixupUsedKeyword;
+
+  /**
+   * Whether we think there was a protocol specified in some way,
+   * even if we corrected it (e.g. "ttp://foo.com/bar")
+   */
+  readonly attribute boolean inputHasProtocol;
+
+  /**
+   * Whether the input included a dot in the hostname, e.g. "mozilla.org"
+   * rather than just "mozilla". This makes a difference in terms of when we
+   * decide to do a keyword search or not.
+   */
+  readonly attribute boolean inputHostHasDot;
+
+  /**
+   * The original input
+   */
+  readonly attribute AUTF8String originalInput;
+};
+
+
+/**
  * Interface implemented by objects capable of fixing up strings into URIs
  */
-[scriptable, uuid(731877f8-973b-414c-b772-9ca1f3fffb7e)]
+[scriptable, uuid(80d4932e-bb2e-4afb-98e0-de9cc9ea7d82)]
 interface nsIURIFixup : nsISupports
 {
     /** No fixup flags. */
     const unsigned long FIXUP_FLAG_NONE = 0;
 
     /**
      * Allow the fixup to use a keyword lookup service to complete the URI.
      * The fixup object implementer should honour this flag and only perform
@@ -59,16 +110,30 @@ interface nsIURIFixup : nsISupports
      * @param aFixupFlags Flags that govern ways the URI may be fixed up.
      * @param aPostData   The POST data to submit with the returned
      *                    URI (see nsISearchSubmission).
      */
     nsIURI createFixupURI(in AUTF8String aURIText, in unsigned long aFixupFlags,
                           [optional] out nsIInputStream aPostData);
 
     /**
+     * Same as createFixupURI, but returns information about what it corrected
+     * (e.g. whether we could rescue the URI or "just" generated a keyword
+     * search URI instead).
+     *
+     * @param aURIText    Candidate URI.
+     * @param aFixupFlags Flags that govern ways the URI may be fixed up.
+     * @param aPostData   The POST data to submit with the returned
+     *                    URI (see nsISearchSubmission).
+     */
+    nsIURIFixupInfo getFixupURIInfo(in AUTF8String aURIText,
+                                    in unsigned long aFixupFlags,
+                                    [optional] out nsIInputStream aPostData);
+
+    /**
      * Converts the specified keyword string into a URI.  Note that it's the
      * caller's responsibility to check whether keywords are enabled and
      * whether aKeyword is a sensible keyword.
      *
      * @param aKeyword  The keyword string to convert into a URI
      * @param aPostData The POST data to submit to the returned URI
      *                  (see nsISearchSubmission).
      *
new file mode 100644
--- /dev/null
+++ b/docshell/test/unit/test_nsDefaultURIFixup_info.js
@@ -0,0 +1,147 @@
+let urifixup = Cc["@mozilla.org/docshell/urifixup;1"].
+               getService(Ci.nsIURIFixup);
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+let prefList = ["browser.fixup.typo.scheme", "keyword.enabled"];
+for (let pref of prefList) {
+  Services.prefs.setBoolPref(pref, true);
+}
+
+const kSearchEngineID = "test_urifixup_search_engine";
+const kSearchEngineURL = "http://www.example.org/?search={searchTerms}";
+Services.search.addEngineWithDetails(kSearchEngineID, "", "", "", "get",
+                                     kSearchEngineURL);
+
+let oldDefaultEngine = Services.search.defaultEngine;
+Services.search.defaultEngine = Services.search.getEngineByName(kSearchEngineID);
+
+let selectedName = Services.search.defaultEngine.name;
+do_check_eq(selectedName, kSearchEngineID);
+
+do_register_cleanup(function() {
+  if (oldDefaultEngine) {
+    Services.search.defaultEngine = oldDefaultEngine;
+  }
+  let engine = Services.search.getEngineByName(kSearchEngineID);
+  if (engine) {
+    Services.search.removeEngine(engine);
+  }
+  Services.prefs.clearUserPref("keyword.enabled");
+  Services.prefs.clearUserPref("browser.fixup.typo.scheme");
+});
+
+let flagInputs = [
+  urifixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP,
+  urifixup.FIXUP_FLAGS_MAKE_ALTERNATE_URI,
+  urifixup.FIXUP_FLAG_FIX_SCHEME_TYPOS
+];
+
+flagInputs.concat([
+  flagInputs[0] | flagInputs[1],
+  flagInputs[1] | flagInputs[2],
+  flagInputs[0] | flagInputs[2],
+  flagInputs[0] | flagInputs[1] | flagInputs[2]
+]);
+
+let testcases = [
+  ["http://www.mozilla.org", "http://www.mozilla.org/"],
+  ["://www.mozilla.org", "http://www.mozilla.org/"],
+  ["www.mozilla.org", "http://www.mozilla.org/"],
+  ["http://mozilla/", "http://mozilla/"],
+  ["127.0.0.1", "http://127.0.0.1/"],
+  ["1234", "http://1234/"],
+  ["host/foo.txt", "http://host/foo.txt"],
+  ["mozilla", "http://mozilla/"],
+  ["mozilla is amazing", null],
+  ["", null],
+];
+
+if (Services.appinfo.OS.toLowerCase().startsWith("win")) {
+  testcases.push(["C:\\some\\file.txt", "file:///C:/some/file.txt"]);
+} else {
+  testcases.push(["/some/file.txt", "file:///some/file.txt"]);
+}
+
+function run_test() {
+  for (let [testInput, expectedFixedURI] of testcases) {
+    for (let flags of flagInputs) {
+      let info;
+      let fixupURIOnly = null;
+      try {
+        fixupURIOnly = urifixup.createFixupURI(testInput, flags);
+      } catch (ex) {
+        do_check_eq(expectedFixedURI, null);
+      }
+
+      try {
+        info = urifixup.getFixupURIInfo(testInput, flags);
+      } catch (ex) {
+        // Both APIs should return an error in the same cases.
+        do_check_eq(expectedFixedURI, null);
+        do_check_eq(fixupURIOnly, null);
+        continue;
+      }
+
+      // Both APIs should then also be using the same spec.
+      do_check_eq(fixupURIOnly.spec, info.preferredURI.spec);
+
+      let isFileURL = expectedFixedURI && expectedFixedURI.startsWith("file");
+
+      // Check the fixedURI:
+      let alternateURI = flags & urifixup.FIXUP_FLAGS_MAKE_ALTERNATE_URI;
+      if (!isFileURL && alternateURI && !info.inputHostHasDot && info.fixedURI) {
+        let originalURI = Services.io.newURI(expectedFixedURI, null, null);
+        do_check_eq(info.fixedURI.host, "www." + originalURI.host + ".com");
+      } else {
+        do_check_eq(info.fixedURI && info.fixedURI.spec, expectedFixedURI);
+      }
+
+      // Check booleans on input:
+      if (isFileURL) {
+        do_check_eq(info.inputHasProtocol, testInput.startsWith("file:"));
+        do_check_eq(info.inputHostHasDot, false);
+      } else {
+        // The duff protocol doesn't count, so > 0 rather than -1:
+        do_check_eq(info.inputHasProtocol, testInput.indexOf(":") > 0);
+        let dotIndex = testInput.indexOf(".");
+        let slashIndex = testInput.replace("://", "").indexOf("/");
+        slashIndex = slashIndex == -1 ? testInput.length : slashIndex;
+        do_check_eq(info.inputHostHasDot, dotIndex != -1 && slashIndex > dotIndex);
+      }
+
+      let couldDoKeywordLookup = flags & urifixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
+      // Check the preferred URI
+      if (info.inputHostHasDot || info.inputHasProtocol) {
+        // In these cases, we should never be doing a keyword lookup and
+        // the fixed URI should be preferred:
+        do_check_eq(info.preferredURI.spec, info.fixedURI.spec);
+      } else if (!isFileURL && couldDoKeywordLookup && testInput.indexOf(".") == -1) {
+        // Otherwise, and assuming we're allowed, there will be a search URI:
+        let urlparamInput = testInput.replace(/ /g, '+');
+        let searchURL = kSearchEngineURL.replace("{searchTerms}", urlparamInput);
+        do_check_eq(info.preferredURI.spec, searchURL);
+      } else if (info.fixedURI) {
+        // This is for lack of keyword lookup, combined with hostnames with no
+        // protocol:
+        do_check_eq(info.fixedURI, info.preferredURI);
+        if (isFileURL) {
+          do_check_eq(info.fixedURI.host, "");
+        } else {
+          let hostMatch = testInput.match(/(?:[^:\/]*:\/\/)?([^\/]+)(\/|$)/);
+          let host = hostMatch ? hostMatch[1] : "";
+          if (alternateURI) {
+            do_check_eq(info.fixedURI.host, "www." + host + ".com");
+          } else {
+            do_check_eq(info.fixedURI.host, host);
+          }
+        }
+      } else {
+        do_check_true(false, "There should be no cases where we got here, " +
+                             "there's no keyword lookup, and no fixed URI." +
+                             "Offending input: " + testInput);
+      }
+      do_check_eq(testInput, info.originalInput);
+    }
+  }
+}
--- a/docshell/test/unit/xpcshell.ini
+++ b/docshell/test/unit/xpcshell.ini
@@ -2,13 +2,15 @@
 head = head_docshell.js
 tail = 
 
 [test_bug414201_jfif.js]
 [test_bug442584.js]
 [test_nsDefaultURIFixup.js]
 [test_nsDefaultURIFixup_search.js]
 skip-if = os == 'android'
+[test_nsDefaultURIFixup_info.js]
+skip-if = os == 'android'
 [test_nsIDownloadHistory.js]
 [test_pb_notification.js]
 # Bug 751575: unrelated JS changes cause timeouts on random platforms
 skip-if = true
 [test_privacy_transition.js]
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -225,16 +225,17 @@ pref("privacy.popups.showBrowserMessage"
 
 /* disable opening windows with the dialog feature */
 pref("dom.disable_window_open_dialog_feature", true);
 pref("dom.disable_window_showModalDialog", true);
 pref("dom.disable_window_print", true);
 pref("dom.disable_window_find", true);
 
 pref("keyword.enabled", true);
+pref("browser.fixup.domainwhitelist.localhost", true);
 
 pref("accessibility.typeaheadfind", false);
 pref("accessibility.typeaheadfind.timeout", 5000);
 pref("accessibility.typeaheadfind.flashBar", 1);
 pref("accessibility.typeaheadfind.linksonly", false);
 pref("accessibility.typeaheadfind.casesensitive", 0);
 pref("accessibility.browsewithcaret_shortcut.enabled", false);
 
--- a/mobile/android/base/AndroidManifest.xml.in
+++ b/mobile/android/base/AndroidManifest.xml.in
@@ -101,17 +101,23 @@
              setSoftInputMode call in BrowserSearch#onStop must also be updated. -->
         <activity android:name="org.mozilla.gecko.BrowserApp"
                   android:label="@string/moz_app_displayname"
                   android:taskAffinity="@ANDROID_PACKAGE_NAME@.BROWSER"
                   android:alwaysRetainTaskState="true"
                   android:configChanges="keyboard|keyboardHidden|mcc|mnc|orientation|screenSize|locale|layoutDirection"
                   android:windowSoftInputMode="stateUnspecified|adjustResize"
                   android:launchMode="singleTask"
+                  android:exported="true"
                   android:theme="@style/Gecko.App">
+          <!-- We export this activity so that it can be launched by explicit
+               intents, in particular homescreen shortcuts.  See Bug 1032217.
+               In future we would prefer to move all intent filters off the .App
+               alias and onto BrowserApp so that we can deprecate activities
+               that refer to pre-processed class names. -->
         </activity>
 
         <!-- Fennec is shipped as the Android package named
              org.mozilla.{fennec,firefox,firefox_beta}.  The internal Java package
              hierarchy inside the Android package has both an
              org.mozilla.{fennec,firefox,firefox_beta} subtree *and* an
              org.mozilla.gecko subtree.  The non-org.mozilla.gecko is deprecated
              and we would like to get rid of it entirely.  Until that happens, we
@@ -250,20 +256,26 @@
         <activity android:name="org.mozilla.gecko.Webapp"
                   android:label="@string/webapp_generic_name"
                   android:configChanges="keyboard|keyboardHidden|mcc|mnc|orientation|screenSize"
                   android:windowSoftInputMode="stateUnspecified|adjustResize"
                   android:launchMode="singleTask"
                   android:taskAffinity="org.mozilla.gecko.WEBAPP"
                   android:process=":@ANDROID_PACKAGE_NAME@.Webapp"
                   android:excludeFromRecents="true"
+                  android:exported="true"
                   android:theme="@style/Gecko.App">
+          <!-- We export this activity so that it can be launched by explicit
+               intents, in particular old-style WebApp launching homescreen
+               shortcuts. Such shortcuts were made before the new "synthetic
+               APK" WebApps were deployed. See Bug 1032217. -->
         </activity>
 
-        <!-- Alias Webapp so we can launch it from the package namespace. -->
+        <!-- Alias Webapp so we can launch it from the package namespace. Prefer
+             to launch with the fully qualified name "org.mozilla.gecko.Webapp". -->
         <activity-alias android:name=".Webapp"
                         android:label="@string/webapp_generic_name"
                         android:targetActivity="org.mozilla.gecko.Webapp">
             <intent-filter>
                 <action android:name="org.mozilla.gecko.WEBAPP" />
             </intent-filter>
             <intent-filter>
                 <action android:name="org.mozilla.gecko.ACTION_ALERT_CALLBACK" />
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -1,27 +1,22 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko;
 
-import java.io.BufferedOutputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
 import java.net.HttpURLConnection;
 import java.net.URL;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
@@ -76,31 +71,23 @@ import android.graphics.BitmapFactory;
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.location.Location;
 import android.location.LocationListener;
 import android.net.Uri;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiManager;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.StrictMode;
 import android.provider.ContactsContract;
 import android.provider.MediaStore.Images.Media;
-import android.telephony.CellLocation;
-import android.telephony.NeighboringCellInfo;
-import android.telephony.PhoneStateListener;
-import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
-import android.telephony.gsm.GsmCellLocation;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Base64;
 import android.util.Log;
 import android.util.SparseBooleanArray;
 import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.Menu;
@@ -160,18 +147,16 @@ public abstract class GeckoApp
     public static final String PREFS_VERSION_CODE          = "versionCode";
     public static final String PREFS_WAS_STOPPED           = "wasStopped";
     public static final String PREFS_CRASHED               = "crashed";
     public static final String PREFS_CLEANUP_TEMP_FILES    = "cleanupTempFiles";
 
     public static final String SAVED_STATE_IN_BACKGROUND   = "inBackground";
     public static final String SAVED_STATE_PRIVATE_SESSION = "privateSession";
 
-    static private final String LOCATION_URL = "https://location.services.mozilla.com/v1/submit";
-
     // Delay before running one-time "cleanup" tasks that may be needed
     // after a version upgrade.
     private static final int CLEANUP_DEFERRAL_SECONDS = 15;
 
     protected RelativeLayout mMainLayout;
     protected RelativeLayout mGeckoLayout;
     private View mCameraView;
     private OrientationEventListener mCameraOrientationEventListener;
@@ -202,19 +187,16 @@ public abstract class GeckoApp
     private Telemetry.Timer mJavaUiStartupTimer;
     private Telemetry.Timer mGeckoReadyStartupTimer;
 
     private String mPrivateBrowsingSession;
 
     private volatile HealthRecorder mHealthRecorder = null;
     private volatile Locale mLastLocale = null;
 
-    private int mSignalStrenth;
-    private PhoneStateListener mPhoneStateListener = null;
-    private boolean mShouldReportGeoData;
     private EventListener mWebappEventListener;
 
     abstract public int getLayout();
     abstract public boolean hasTabsSideBar();
     abstract protected String getDefaultProfileName() throws NoMozillaDirectoryException;
 
     private static final String RESTARTER_ACTION = "org.mozilla.gecko.restart";
     private static final String RESTARTER_CLASS = "org.mozilla.gecko.Restarter";
@@ -244,25 +226,16 @@ public abstract class GeckoApp
         return GeckoSharedPrefs.forApp(this);
     }
 
     public Activity getActivity() {
         return this;
     }
 
     public LocationListener getLocationListener() {
-        if (mShouldReportGeoData && mPhoneStateListener == null) {
-            mPhoneStateListener = new PhoneStateListener() {
-                public void onSignalStrengthsChanged(SignalStrength signalStrength) {
-                    setCurrentSignalStrenth(signalStrength);
-                }
-            };
-            TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
-            tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
-        }
         return this;
     }
 
     public SensorEventListener getSensorEventListener() {
         return this;
     }
 
     public View getCameraView() {
@@ -1573,20 +1546,17 @@ public abstract class GeckoApp
         PrefsHelper.getPref("app.update.autodownload", new PrefsHelper.PrefHandlerBase() {
             @Override public void prefValue(String pref, String value) {
                 UpdateServiceHelper.registerForUpdates(GeckoApp.this, value);
             }
         });
 
         PrefsHelper.getPref("app.geo.reportdata", new PrefsHelper.PrefHandlerBase() {
             @Override public void prefValue(String pref, int value) {
-                if (value == 1)
-                    mShouldReportGeoData = true;
-                else
-                    mShouldReportGeoData = false;
+                // Acting on this pref is Bug 1036508; for now, do nothing.
             }
         });
 
         // Trigger the completion of the telemetry timer that wraps activity startup,
         // then grab the duration to give to FHR.
         mJavaUiStartupTimer.stop();
         final long javaDuration = mJavaUiStartupTimer.getElapsed();
 
@@ -2368,207 +2338,16 @@ public abstract class GeckoApp
         GeckoAppShell.sendEventToGecko(GeckoEvent.createSensorEvent(event));
     }
 
     // Geolocation.
     @Override
     public void onLocationChanged(Location location) {
         // No logging here: user-identifying information.
         GeckoAppShell.sendEventToGecko(GeckoEvent.createLocationEvent(location));
-        if (mShouldReportGeoData)
-            collectAndReportLocInfo(location);
-    }
-
-    public void setCurrentSignalStrenth(SignalStrength ss) {
-        if (ss.isGsm())
-            mSignalStrenth = ss.getGsmSignalStrength();
-    }
-
-    private int getCellInfo(JSONArray cellInfo) {
-        TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
-        if (tm == null)
-            return TelephonyManager.PHONE_TYPE_NONE;
-        List<NeighboringCellInfo> cells = tm.getNeighboringCellInfo();
-        CellLocation cl = tm.getCellLocation();
-        String mcc = "", mnc = "";
-        if (cl instanceof GsmCellLocation) {
-            JSONObject obj = new JSONObject();
-            GsmCellLocation gcl = (GsmCellLocation)cl;
-            try {
-                obj.put("lac", gcl.getLac());
-                obj.put("cid", gcl.getCid());
-
-                int psc = (Build.VERSION.SDK_INT >= 9) ? gcl.getPsc() : -1;
-                obj.put("psc", psc);
-
-                switch(tm.getNetworkType()) {
-                case TelephonyManager.NETWORK_TYPE_GPRS:
-                case TelephonyManager.NETWORK_TYPE_EDGE:
-                    obj.put("radio", "gsm");
-                    break;
-                case TelephonyManager.NETWORK_TYPE_UMTS:
-                case TelephonyManager.NETWORK_TYPE_HSDPA:
-                case TelephonyManager.NETWORK_TYPE_HSUPA:
-                case TelephonyManager.NETWORK_TYPE_HSPA:
-                case TelephonyManager.NETWORK_TYPE_HSPAP:
-                    obj.put("radio", "umts");
-                    break;
-                }
-                String mcc_mnc = tm.getNetworkOperator();
-                if (mcc_mnc.length() > 3) {
-                    mcc = mcc_mnc.substring(0, 3);
-                    mnc = mcc_mnc.substring(3);
-                    obj.put("mcc", mcc);
-                    obj.put("mnc", mnc);
-                }
-                obj.put("asu", mSignalStrenth);
-            } catch(JSONException jsonex) {}
-            cellInfo.put(obj);
-        }
-        if (cells != null) {
-            for (NeighboringCellInfo nci : cells) {
-                try {
-                    JSONObject obj = new JSONObject();
-                    obj.put("lac", nci.getLac());
-                    obj.put("cid", nci.getCid());
-                    obj.put("psc", nci.getPsc());
-                    obj.put("mcc", mcc);
-                    obj.put("mnc", mnc);
-
-                    int dbm;
-                    switch(nci.getNetworkType()) {
-                    case TelephonyManager.NETWORK_TYPE_GPRS:
-                    case TelephonyManager.NETWORK_TYPE_EDGE:
-                        obj.put("radio", "gsm");
-                        break;
-                    case TelephonyManager.NETWORK_TYPE_UMTS:
-                    case TelephonyManager.NETWORK_TYPE_HSDPA:
-                    case TelephonyManager.NETWORK_TYPE_HSUPA:
-                    case TelephonyManager.NETWORK_TYPE_HSPA:
-                    case TelephonyManager.NETWORK_TYPE_HSPAP:
-                        obj.put("radio", "umts");
-                        break;
-                    }
-
-                    obj.put("asu", nci.getRssi());
-                    cellInfo.put(obj);
-                } catch(JSONException jsonex) {}
-            }
-        }
-        return tm.getPhoneType();
-    }
-
-    private static boolean shouldLog(final ScanResult sr) {
-        return sr.SSID == null || !sr.SSID.endsWith("_nomap");
-    }
-
-    private void collectAndReportLocInfo(Location location) {
-        final JSONObject locInfo = new JSONObject();
-        WifiManager wm = (WifiManager)getSystemService(Context.WIFI_SERVICE);
-        wm.startScan();
-        try {
-            JSONArray cellInfo = new JSONArray();
-
-            String radioType = getRadioTypeName(getCellInfo(cellInfo));
-            if (radioType != null) {
-                locInfo.put("radio", radioType);
-            }
-
-            locInfo.put("lon", location.getLongitude());
-            locInfo.put("lat", location.getLatitude());
-
-            // If we have an accuracy, round it up to the next meter.
-            if (location.hasAccuracy()) {
-                locInfo.put("accuracy", (int) Math.ceil(location.getAccuracy()));
-            }
-
-            // If we have an altitude, round it to the nearest meter.
-            if (location.hasAltitude()) {
-                locInfo.put("altitude", Math.round(location.getAltitude()));
-            }
-
-            // Reduce timestamp precision so as to expose less PII.
-            DateFormat df = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
-            locInfo.put("time", df.format(new Date(location.getTime())));
-            locInfo.put("cell", cellInfo);
-
-            JSONArray wifiInfo = new JSONArray();
-            List<ScanResult> aps = wm.getScanResults();
-            if (aps != null) {
-                for (ScanResult ap : aps) {
-                    if (!shouldLog(ap))
-                        continue;
-
-                    JSONObject obj = new JSONObject();
-                    obj.put("key", ap.BSSID);
-                    obj.put("frequency", ap.frequency);
-                    obj.put("signal", ap.level);
-                    wifiInfo.put(obj);
-                }
-            }
-            locInfo.put("wifi", wifiInfo);
-        } catch (JSONException jsonex) {
-            Log.w(LOGTAG, "json exception", jsonex);
-            return;
-        }
-
-        ThreadUtils.postToBackgroundThread(new Runnable() {
-            public void run() {
-                try {
-                    URL url = new URL(LOCATION_URL);
-                    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
-                    try {
-                        urlConnection.setDoOutput(true);
-
-                        // Workaround for a bug in Android HttpURLConnection. When the library
-                        // reuses a stale connection, the connection may fail with an EOFException.
-                        if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT <= 18) {
-                            urlConnection.setRequestProperty("Connection", "Close");
-                        }
-
-                        JSONArray batch = new JSONArray();
-                        batch.put(locInfo);
-                        JSONObject wrapper = new JSONObject();
-                        wrapper.put("items", batch);
-                        byte[] bytes = wrapper.toString().getBytes();
-                        urlConnection.setFixedLengthStreamingMode(bytes.length);
-                        OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
-                        out.write(bytes);
-                        out.flush();
-                    } catch (JSONException jsonex) {
-                        Log.e(LOGTAG, "error wrapping data as a batch", jsonex);
-                    } catch (IOException ioex) {
-                        Log.e(LOGTAG, "error submitting data", ioex);
-                    } finally {
-                        urlConnection.disconnect();
-                    }
-                } catch (IOException ioex) {
-                    Log.e(LOGTAG, "error submitting data", ioex);
-                }
-            }
-        });
-    }
-
-    private static String getRadioTypeName(int phoneType) {
-        switch (phoneType) {
-            case TelephonyManager.PHONE_TYPE_CDMA:
-                return "cdma";
-
-            case TelephonyManager.PHONE_TYPE_GSM:
-                return "gsm";
-
-            case TelephonyManager.PHONE_TYPE_NONE:
-            case TelephonyManager.PHONE_TYPE_SIP:
-                // These devices have no radio.
-                return null;
-
-            default:
-                Log.e(LOGTAG, "", new IllegalArgumentException("Unexpected PHONE_TYPE: " + phoneType));
-                return null;
-        }
     }
 
     @Override
     public void onProviderDisabled(String provider)
     {
     }
 
     @Override
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1519,18 +1519,18 @@ var BrowserApp = {
         break;
       }
 
       case "Tab:Load": {
         let data = JSON.parse(aData);
         let url = data.url;
         let flags;
 
-        if (!data.engine && /^[0-9]+$/.test(url)) {
-          // If the query is a number and we're not using a search engine,
+        if (!data.engine && /^\w+$/.test(url.trim())) {
+          // If the query is a single word and we're not using a search engine,
           // force a search (see bug 993705; workaround for bug 693808).
           url = URIFixup.keywordToURI(url).spec;
         } else {
           flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
                    Ci.nsIWebNavigation.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
         }
 
         // Pass LOAD_FLAGS_DISALLOW_INHERIT_OWNER to prevent any loads from
--- a/mobile/android/search/java/org/mozilla/search/Constants.java
+++ b/mobile/android/search/java/org/mozilla/search/Constants.java
@@ -15,13 +15,11 @@ package org.mozilla.search;
  * https://github.com/ericedens/FirefoxSearch/issues/3
  */
 public class Constants {
 
     public static final String POSTSEARCH_FRAGMENT = "org.mozilla.search.POSTSEARCH_FRAGMENT";
     public static final String PRESEARCH_FRAGMENT = "org.mozilla.search.PRESEARCH_FRAGMENT";
     public static final String SEARCH_FRAGMENT = "org.mozilla.search.SEARCH_FRAGMENT";
 
-    public static final String AUTOCOMPLETE_ROW_LIMIT = "5";
-
     public static final String YAHOO_WEB_SEARCH_BASE_URL = "https://search.yahoo.com/search?p=";
     public static final String YAHOO_WEB_SEARCH_RESULTS_FILTER = "//search.yahoo.com";
 }
--- a/mobile/android/search/java/org/mozilla/search/autocomplete/AutoCompleteAdapter.java
+++ b/mobile/android/search/java/org/mozilla/search/autocomplete/AutoCompleteAdapter.java
@@ -4,42 +4,58 @@
 
 package org.mozilla.search.autocomplete;
 
 import android.content.Context;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
 
+import java.util.List;
+
 /**
  * The adapter that is used to populate the autocomplete rows.
  */
-class AutoCompleteAdapter extends ArrayAdapter<AutoCompleteModel> {
+class AutoCompleteAdapter extends ArrayAdapter<String> {
 
     private final AcceptsJumpTaps acceptsJumpTaps;
 
     public AutoCompleteAdapter(Context context, AcceptsJumpTaps acceptsJumpTaps) {
         // Uses '0' for the template id since we are overriding getView
         // and supplying our own view.
         super(context, 0);
         this.acceptsJumpTaps = acceptsJumpTaps;
+
+        // Disable notifying on change. We will notify ourselves in update.
+        setNotifyOnChange(false);
     }
 
     @Override
     public View getView(int position, View convertView, ViewGroup parent) {
         AutoCompleteRowView view;
 
         if (convertView == null) {
             view = new AutoCompleteRowView(getContext());
         } else {
             view = (AutoCompleteRowView) convertView;
         }
 
         view.setOnJumpListener(acceptsJumpTaps);
-
-
-        AutoCompleteModel model = getItem(position);
-
-        view.setMainText(model.getMainText());
+        view.setMainText(getItem(position));
 
         return view;
     }
+
+    /**
+     * Updates adapter content with new list of search suggestions.
+     *
+     * @param suggestions List of search suggestions.
+     */
+    public void update(List<String> suggestions) {
+        clear();
+        if (suggestions != null) {
+            for (String s : suggestions) {
+                add(s);
+            }
+        }
+        notifyDataSetChanged();
+    }
 }
deleted file mode 100644
--- a/mobile/android/search/java/org/mozilla/search/autocomplete/AutoCompleteAgentManager.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.search.autocomplete;
-
-import android.app.Activity;
-import android.database.Cursor;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import java.util.ArrayList;
-
-/**
- * A single entry point for querying all agents.
- * <p/>
- * An agent is responsible for querying some underlying data source. It could be a
- * flat file, or a REST endpoint, or a content provider.
- */
-class AutoCompleteAgentManager {
-
-    private final Handler mainUiHandler;
-    private final Handler localHandler;
-    private final AutoCompleteWordListAgent autoCompleteWordListAgent;
-
-    public AutoCompleteAgentManager(Activity activity, Handler mainUiHandler) {
-        HandlerThread thread = new HandlerThread("org.mozilla.search.autocomplete.SuggestionAgent");
-        // TODO: Where to kill this thread?
-        thread.start();
-        Log.i("AUTOCOMPLETE", "Starting thread");
-        this.mainUiHandler = mainUiHandler;
-        localHandler = new SuggestionMessageHandler(thread.getLooper());
-        autoCompleteWordListAgent = new AutoCompleteWordListAgent(activity);
-    }
-
-    /**
-     * Process the next incoming query.
-     */
-    public void search(String queryString) {
-        // TODO check if there's a pending search.. not sure how to handle that.
-        localHandler.sendMessage(localHandler.obtainMessage(0, queryString));
-    }
-
-    /**
-     * This background thread runs the queries; the results get sent back through mainUiHandler
-     * <p/>
-     * TODO: Refactor this wordlist search and add other search providers (eg: Yahoo)
-     */
-    private class SuggestionMessageHandler extends Handler {
-
-        private SuggestionMessageHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            super.handleMessage(msg);
-            if (null == msg.obj) {
-                return;
-            }
-
-            Cursor cursor =
-                    autoCompleteWordListAgent.getWordMatches(((String) msg.obj).toLowerCase());
-            ArrayList<AutoCompleteModel> res = new ArrayList<AutoCompleteModel>();
-
-            if (null == cursor) {
-                return;
-            }
-
-            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
-                res.add(new AutoCompleteModel(cursor.getString(
-                        cursor.getColumnIndex(AutoCompleteWordListAgent.COL_WORD))));
-            }
-
-
-            mainUiHandler.sendMessage(Message.obtain(mainUiHandler, 0, res));
-        }
-
-    }
-
-}
deleted file mode 100644
--- a/mobile/android/search/java/org/mozilla/search/autocomplete/AutoCompleteModel.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.search.autocomplete;
-
-/**
- * The SuggestionModel is the data model behind the autocomplete rows. Right now it
- * only has a text field. In the future, this could be extended to include other
- * types of rows. For example, a row that has a URL and the name of a website.
- */
-class AutoCompleteModel {
-
-    // The text that should immediately jump out to the user;
-    // for example, the name of a restaurant or the title
-    // of a website.
-    private final String mainText;
-
-    public AutoCompleteModel(String mainText) {
-        this.mainText = mainText;
-    }
-
-    public String getMainText() {
-        return mainText;
-    }
-
-    public String toString() {
-        return mainText;
-    }
-
-}
deleted file mode 100644
--- a/mobile/android/search/java/org/mozilla/search/autocomplete/AutoCompleteWordListAgent.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.search.autocomplete;
-
-import android.app.Activity;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.database.sqlite.SQLiteStatement;
-import android.util.Log;
-import android.widget.Toast;
-
-import org.mozilla.search.Constants;
-import org.mozilla.search.R;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-
-/**
- * Helper to search a word dictionary.
- * From: https://developer.android.com/training/search/search.html
- */
-class AutoCompleteWordListAgent {
-
-    public static final String COL_WORD = "WORD";
-    private static final String TAG = "DictionaryDatabase";
-    private static final String DATABASE_NAME = "DICTIONARY";
-    private static final String FTS_VIRTUAL_TABLE = "FTS";
-    private static final int DATABASE_VERSION = 1;
-
-    private final DatabaseOpenHelper databaseOpenHelper;
-
-    public AutoCompleteWordListAgent(Activity activity) {
-        databaseOpenHelper = new DatabaseOpenHelper(activity);
-        // DB helper uses lazy initialization, so this forces the db helper to start indexing the
-        // wordlist
-        databaseOpenHelper.getReadableDatabase();
-    }
-
-    public Cursor getWordMatches(String query) {
-        String selection = COL_WORD + " MATCH ?";
-        String[] selectionArgs = new String[]{query + "*"};
-        return query(selection, selectionArgs);
-    }
-
-    private Cursor query(String selection, String[] selectionArgs) {
-        SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
-        builder.setTables(FTS_VIRTUAL_TABLE);
-
-        Cursor cursor = builder.query(databaseOpenHelper.getReadableDatabase(), null, selection,
-                selectionArgs, null, null, null, Constants.AUTOCOMPLETE_ROW_LIMIT);
-
-        if (cursor == null) {
-            return null;
-        } else if (!cursor.moveToFirst()) {
-            cursor.close();
-            return null;
-        }
-        return cursor;
-    }
-
-    private static class DatabaseOpenHelper extends SQLiteOpenHelper {
-
-        private final Activity activity;
-
-        private SQLiteDatabase database;
-
-        private static final String FTS_TABLE_CREATE =
-                "CREATE VIRTUAL TABLE " + FTS_VIRTUAL_TABLE + " USING fts3 (" + COL_WORD + ")";
-
-        DatabaseOpenHelper(Activity activity) {
-            super(activity, DATABASE_NAME, null, DATABASE_VERSION);
-            this.activity = activity;
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            database = db;
-            database.execSQL(FTS_TABLE_CREATE);
-
-            loadDictionary();
-        }
-
-        private void loadDictionary() {
-            new Thread(new Runnable() {
-                public void run() {
-                    try {
-
-                        activity.runOnUiThread(new Runnable() {
-                            @Override
-                            public void run() {
-                                Toast.makeText(activity, "Starting post-install indexing",
-                                        Toast.LENGTH_SHORT).show();
-                                Toast.makeText(activity,
-                                        "Don't worry; Mark & Ian we'll figure out a way around " +
-                                                "this :)", Toast.LENGTH_SHORT
-                                ).show();
-                            }
-                        });
-                        loadWords();
-                        activity.runOnUiThread(new Runnable() {
-                            @Override
-                            public void run() {
-                                Toast.makeText(activity, "All done!", Toast.LENGTH_SHORT).show();
-                            }
-                        });
-                    } catch (IOException e) {
-                        throw new RuntimeException(e);
-                    }
-                }
-            }).start();
-        }
-
-        private void loadWords() throws IOException {
-            final Resources resources = activity.getResources();
-            InputStream inputStream = resources.openRawResource(R.raw.en_us);
-            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
-
-
-            String sql = "INSERT INTO " + FTS_VIRTUAL_TABLE + " VALUES (?);";
-            SQLiteStatement statement = database.compileStatement(sql);
-            database.beginTransaction();
-
-            try {
-                String line;
-                while (null != (line = reader.readLine())) {
-                    statement.clearBindings();
-                    statement.bindString(1, line.trim());
-                    statement.execute();
-                }
-            } finally {
-                database.setTransactionSuccessful();
-                database.endTransaction();
-            }
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-            Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion +
-                    ", which will destroy all old data");
-            db.execSQL("DROP TABLE IF EXISTS " + FTS_VIRTUAL_TABLE);
-            onCreate(db);
-        }
-
-
-    }
-}
\ No newline at end of file
--- a/mobile/android/search/java/org/mozilla/search/autocomplete/SearchFragment.java
+++ b/mobile/android/search/java/org/mozilla/search/autocomplete/SearchFragment.java
@@ -2,19 +2,20 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.search.autocomplete;
 
 
 import android.content.Context;
 import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
 import android.support.v4.app.Fragment;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.AsyncTaskLoader;
+import android.support.v4.content.Loader;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
@@ -22,71 +23,85 @@ import android.widget.AdapterView;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.FrameLayout;
 import android.widget.ListView;
 import android.widget.TextView;
 
 import org.mozilla.search.R;
 
+import java.util.List;
+
 /**
  * A fragment to handle autocomplete. Its interface with the outside
  * world should be very very limited.
  * <p/>
  * TODO: Add more search providers (other than the dictionary)
  */
-public class SearchFragment extends Fragment implements AdapterView.OnItemClickListener,
-        TextView.OnEditorActionListener, AcceptsJumpTaps {
+public class SearchFragment extends Fragment
+        implements TextView.OnEditorActionListener, AcceptsJumpTaps {
+
+    private static final int LOADER_ID_SUGGESTION = 0;
+    private static final String KEY_SEARCH_TERM = "search_term";
+
+    // Timeout for the suggestion client to respond
+    private static final int SUGGESTION_TIMEOUT = 3000;
+
+    // Maximum number of results returned by the suggestion client
+    private static final int SUGGESTION_MAX = 5;
 
     private View mainView;
     private FrameLayout backdropFrame;
     private EditText searchBar;
     private ListView suggestionDropdown;
     private InputMethodManager inputMethodManager;
+
     private AutoCompleteAdapter autoCompleteAdapter;
-    private AutoCompleteAgentManager autoCompleteAgentManager;
+
+    private SuggestClient suggestClient;
+    private SuggestionLoaderCallbacks suggestionLoaderCallbacks;
+
     private State state;
 
     private enum State {
         WAITING,  // The user is doing something else in the app.
         RUNNING   // The user is in search mode.
     }
 
     public SearchFragment() {
         // Required empty public constructor
     }
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
                              Bundle savedInstanceState) {
 
-
         mainView = inflater.inflate(R.layout.search_auto_complete, container, false);
         backdropFrame = (FrameLayout) mainView.findViewById(R.id.auto_complete_backdrop);
         searchBar = (EditText) mainView.findViewById(R.id.auto_complete_search_bar);
         suggestionDropdown = (ListView) mainView.findViewById(R.id.auto_complete_dropdown);
 
         inputMethodManager =
                 (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
 
         // Attach a listener for the "search" key on the keyboard.
         searchBar.addTextChangedListener(new TextWatcher() {
             @Override
             public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-
             }
 
             @Override
             public void onTextChanged(CharSequence s, int start, int before, int count) {
-
             }
 
             @Override
             public void afterTextChanged(Editable s) {
-                autoCompleteAgentManager.search(s.toString());
+                final Bundle args = new Bundle();
+                args.putString(KEY_SEARCH_TERM, s.toString());
+                getLoaderManager().restartLoader(LOADER_ID_SUGGESTION, args, suggestionLoaderCallbacks);
             }
         });
         searchBar.setOnEditorActionListener(this);
         searchBar.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 if (v.hasFocus()) {
                     return;
@@ -101,91 +116,68 @@ public class SearchFragment extends Frag
             public void onClick(View v) {
                 searchBar.setText("");
             }
         });
 
         backdropFrame.setOnClickListener(new BackdropClickListener());
 
         autoCompleteAdapter = new AutoCompleteAdapter(getActivity(), this);
-
-        // Disable notifying on change. We're going to be changing the entire dataset, so
-        // we don't want multiple re-draws.
-        autoCompleteAdapter.setNotifyOnChange(false);
-
         suggestionDropdown.setAdapter(autoCompleteAdapter);
 
-        initRows();
-
-        autoCompleteAgentManager =
-                new AutoCompleteAgentManager(getActivity(), new MainUiHandler(autoCompleteAdapter));
-
         // This will hide the autocomplete box and background frame.
         transitionToWaiting();
 
         // Attach listener for tapping on a suggestion.
         suggestionDropdown.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                String query = ((AutoCompleteModel) suggestionDropdown.getItemAtPosition(position))
-                        .getMainText();
+                String query = (String) suggestionDropdown.getItemAtPosition(position);
                 startSearch(query);
             }
         });
 
+        // TODO: Don't hard-code this template string (bug 1039758)
+        final String template = "https://search.yahoo.com/sugg/ff?" +
+                "output=fxjson&appid=ffm&command=__searchTerms__&nresults=" + SUGGESTION_MAX;
+
+        suggestClient = new SuggestClient(getActivity(), template, SUGGESTION_TIMEOUT, SUGGESTION_MAX);
+        suggestionLoaderCallbacks = new SuggestionLoaderCallbacks();
+
         return mainView;
     }
 
     @Override
     public void onDestroyView() {
         super.onDestroyView();
         inputMethodManager = null;
         mainView = null;
         searchBar = null;
         if (null != suggestionDropdown) {
             suggestionDropdown.setOnItemClickListener(null);
             suggestionDropdown.setAdapter(null);
             suggestionDropdown = null;
         }
         autoCompleteAdapter = null;
-    }
-
-    /**
-     * Handler for clicks of individual items.
-     */
-    @Override
-    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-        // TODO: Right now each row has its own click handler.
-        // Can we
+        suggestClient = null;
+        suggestionLoaderCallbacks = null;
     }
 
     /**
      * Handler for the "search" button on the keyboard.
      */
     @Override
     public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
         if (actionId == EditorInfo.IME_ACTION_SEARCH) {
             startSearch(v.getText().toString());
             return true;
         }
         return false;
     }
 
-
-    private void initRows() {
-        // TODO: Query history for these items.
-        autoCompleteAdapter.add(new AutoCompleteModel("banana"));
-        autoCompleteAdapter.add(new AutoCompleteModel("cat pics"));
-        autoCompleteAdapter.add(new AutoCompleteModel("mexican food"));
-        autoCompleteAdapter.add(new AutoCompleteModel("cuba libre"));
-
-        autoCompleteAdapter.notifyDataSetChanged();
-    }
-
-
     /**
      * Send a search intent and put the widget into waiting.
      */
     private void startSearch(String queryString) {
         if (getActivity() instanceof AcceptsSearchQuery) {
             searchBar.setText(queryString);
             searchBar.setSelection(queryString.length());
             transitionToWaiting();
@@ -221,51 +213,88 @@ public class SearchFragment extends Frag
         state = State.RUNNING;
     }
 
     @Override
     public void onJumpTap(String suggestion) {
         searchBar.setText(suggestion);
         // Move cursor to end of search input.
         searchBar.setSelection(suggestion.length());
-        autoCompleteAgentManager.search(suggestion);
     }
 
+    private class SuggestionLoaderCallbacks implements LoaderManager.LoaderCallbacks<List<String>> {
+        @Override
+        public Loader<List<String>> onCreateLoader(int id, Bundle args) {
+            // suggestClient is set to null in onDestroyView(), so using it
+            // safely here relies on the fact that onCreateLoader() is called
+            // synchronously in restartLoader().
+            return new SuggestionAsyncLoader(getActivity(), suggestClient, args.getString(KEY_SEARCH_TERM));
+        }
 
-    /**
-     * Receives messages from the SuggestionAgent's background thread.
-     */
-    private static class MainUiHandler extends Handler {
-
-        final AutoCompleteAdapter autoCompleteAdapter1;
-
-        public MainUiHandler(AutoCompleteAdapter autoCompleteAdapter) {
-            autoCompleteAdapter1 = autoCompleteAdapter;
+        @Override
+        public void onLoadFinished(Loader<List<String>> loader, List<String> suggestions) {
+            autoCompleteAdapter.update(suggestions);
         }
 
         @Override
-        public void handleMessage(Message msg) {
-            super.handleMessage(msg);
-            if (null == msg.obj) {
-                return;
+        public void onLoaderReset(Loader<List<String>> loader) {
+            if (autoCompleteAdapter != null) {
+                autoCompleteAdapter.update(null);
             }
+        }
+    }
 
-            if (!(msg.obj instanceof Iterable)) {
-                return;
+    private static class SuggestionAsyncLoader extends AsyncTaskLoader<List<String>> {
+        private final SuggestClient suggestClient;
+        private final String searchTerm;
+        private List<String> suggestions;
+
+        public SuggestionAsyncLoader(Context context, SuggestClient suggestClient, String searchTerm) {
+            super(context);
+            this.suggestClient = suggestClient;
+            this.searchTerm = searchTerm;
+            this.suggestions = null;
+        }
+
+        @Override
+        public List<String> loadInBackground() {
+            return suggestClient.query(searchTerm);
+        }
+
+        @Override
+        public void deliverResult(List<String> suggestions) {
+            this.suggestions = suggestions;
+
+            if (isStarted()) {
+                super.deliverResult(suggestions);
+            }
+        }
+
+        @Override
+        protected void onStartLoading() {
+            if (suggestions != null) {
+                deliverResult(suggestions);
             }
 
-            autoCompleteAdapter1.clear();
+            if (takeContentChanged() || suggestions == null) {
+                forceLoad();
+            }
+        }
 
-            for (Object obj : (Iterable) msg.obj) {
-                if (obj instanceof AutoCompleteModel) {
-                    autoCompleteAdapter1.add((AutoCompleteModel) obj);
-                }
-            }
-            autoCompleteAdapter1.notifyDataSetChanged();
+        @Override
+        protected void onStopLoading() {
+            cancelLoad();
+        }
 
+        @Override
+        protected void onReset() {
+            super.onReset();
+
+            onStopLoading();
+            suggestions = null;
         }
     }
 
     /**
      * Click handler for the backdrop. This should:
      * - Remove focus from the search bar
      * - Hide the keyboard
      * - Hide the backdrop
new file mode 100644
--- /dev/null
+++ b/mobile/android/search/java/org/mozilla/search/autocomplete/SuggestClient.java
@@ -0,0 +1,145 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.search.autocomplete;
+
+import org.json.JSONArray;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+
+/**
+ * Use network-based search suggestions.
+ */
+public class SuggestClient {
+    private static final String LOGTAG = "GeckoSuggestClient";
+    private static final String USER_AGENT = "";
+
+    private final Context mContext;
+    private final int mTimeout;
+
+    // should contain the string "__searchTerms__", which is replaced with the query
+    private final String mSuggestTemplate;
+
+    // the maximum number of suggestions to return
+    private final int mMaxResults;
+
+    // used by robocop for testing
+    private boolean mCheckNetwork;
+
+    // used to make suggestions appear instantly after opt-in
+    private String mPrevQuery;
+    private ArrayList<String> mPrevResults;
+
+    public SuggestClient(Context context, String suggestTemplate, int timeout, int maxResults) {
+        mContext = context;
+        mMaxResults = maxResults;
+        mSuggestTemplate = suggestTemplate;
+        mTimeout = timeout;
+        mCheckNetwork = true;
+    }
+
+    /**
+     * Queries for a given search term and returns an ArrayList of suggestions.
+     */
+    public ArrayList<String> query(String query) {
+        if (query.equals(mPrevQuery))
+            return mPrevResults;
+
+        ArrayList<String> suggestions = new ArrayList<String>();
+        if (TextUtils.isEmpty(mSuggestTemplate) || TextUtils.isEmpty(query)) {
+            return suggestions;
+        }
+
+        if (!isNetworkConnected() && mCheckNetwork) {
+            Log.i(LOGTAG, "Not connected to network");
+            return suggestions;
+        }
+
+        try {
+            String encoded = URLEncoder.encode(query, "UTF-8");
+            String suggestUri = mSuggestTemplate.replace("__searchTerms__", encoded);
+
+            URL url = new URL(suggestUri);
+            String json = null;
+            HttpURLConnection urlConnection = null;
+            InputStream in = null;
+            try {
+                urlConnection = (HttpURLConnection) url.openConnection();
+                urlConnection.setConnectTimeout(mTimeout);
+                urlConnection.setRequestProperty("User-Agent", USER_AGENT);
+                in = new BufferedInputStream(urlConnection.getInputStream());
+                json = convertStreamToString(in);
+            } finally {
+                if (urlConnection != null)
+                    urlConnection.disconnect();
+                if (in != null) {
+                    try {
+                        in.close();
+                    } catch (IOException e) {
+                        Log.e(LOGTAG, "error", e);
+                    }
+                }
+            }
+
+            if (json != null) {
+                /*
+                 * Sample result:
+                 * ["foo",["food network","foothill college","foot locker",...]]
+                 */
+                JSONArray results = new JSONArray(json);
+                JSONArray jsonSuggestions = results.getJSONArray(1);
+
+                int added = 0;
+                for (int i = 0; (i < jsonSuggestions.length()) && (added < mMaxResults); i++) {
+                    String suggestion = jsonSuggestions.getString(i);
+                    if (!suggestion.equalsIgnoreCase(query)) {
+                        suggestions.add(suggestion);
+                        added++;
+                    }
+                }
+            } else {
+                Log.e(LOGTAG, "Suggestion query failed");
+            }
+        } catch (Exception e) {
+            Log.e(LOGTAG, "Error", e);
+        }
+
+        mPrevQuery = query;
+        mPrevResults = suggestions;
+        return suggestions;
+    }
+
+    private boolean isNetworkConnected() {
+        NetworkInfo networkInfo = getActiveNetworkInfo();
+        return networkInfo != null && networkInfo.isConnected();
+    }
+
+    private NetworkInfo getActiveNetworkInfo() {
+        ConnectivityManager connectivity = (ConnectivityManager) mContext
+                .getSystemService(Context.CONNECTIVITY_SERVICE);
+        if (connectivity == null)
+            return null;
+        return connectivity.getActiveNetworkInfo();
+    }
+
+    private String convertStreamToString(java.io.InputStream is) {
+        try {
+            return new java.util.Scanner(is).useDelimiter("\\A").next();
+        } catch (java.util.NoSuchElementException e) {
+            return "";
+        }
+    }
+}
deleted file mode 100644
--- a/mobile/android/search/res/raw/en_us.txt
+++ /dev/null
@@ -1,46988 +0,0 @@
-46987
-0
-0th
-1
-1st
-1th
-2
-2nd
-2th
-3
-3rd
-3th
-4
-48245
-4th
-5
-5th
-6
-6th
-7
-7th
-8
-8th
-9
-9th
-a
-aa
-aaa
-aachen
-aah
-aaliyah
-aardvark
-aaron
-ab
-aba
-aback
-abacus
-abaft
-abalone
-abandon
-abandonment
-abase
-abasement
-abash
-abashed
-abashment
-abate
-abated
-abatement
-abattoir
-abbas
-abbasid
-abbe
-abbess
-abbey
-abbot
-abbott
-abbr
-abbrev
-abbreviate
-abbreviation
-abby
-abc
-abdicate
-abdication
-abdomen
-abdominal
-abduct
-abduction
-abductor
-abdul
-abe
-abeam
-abel
-abelard
-abelson
-aberdeen
-abernathy
-aberrant
-aberration
-aberrational
-abet
-abetted
-abetting
-abettor
-abeyance
-abhor
-abhorred
-abhorrence
-abhorrent
-abhorring
-abidance
-abide
-abiding
-abidjan
-abigail
-abilene
-ability
-abject
-abjection
-abjectness
-abjuration
-abjuratory
-abjure
-abjurer
-ablate
-ablation
-ablative
-ablaze
-able
-abler
-abloom
-ablution
-abm
-abnegate
-abnegation
-abner
-abnormal
-abnormality
-aboard
-abode
-abolish
-abolition
-abolitionism
-abolitionist
-abominable
-abominably
-abominate
-abomination
-aboriginal
-aborigine
-aborning
-abort
-abortion
-abortionist
-abortive
-abound
-about
-above
-aboveboard
-abracadabra
-abrade
-abraham
-abram
-abrasion
-abrasive
-abrasiveness
-abreast
-abridge
-abridgment
-abroad
-abrogate
-abrogation
-abrogator
-abrupt
-abruptness
-abs
-absalom
-abscess
-abscissa
-abscission
-abscond
-absconder
-abseil
-absence
-absent
-absentee
-absenteeism
-absentminded
-absentmindedness
-absinthe
-absolute
-absoluteness
-absolution
-absolutism
-absolutist
-absolve
-absorb
-absorbency
-absorbent
-absorbing
-absorption
-absorptive
-abstain
-abstainer
-abstemious
-abstemiousness
-abstention
-abstinence
-abstinent
-abstract
-abstracted
-abstractedness
-abstraction
-abstractness
-abstruse
-abstruseness
-absurd
-absurdity
-absurdness
-abuja
-abundance
-abundant
-abuse
-abuse's
-abuser
-abusive
-abusiveness
-abut
-abutment
-abutted
-abutting
-abuzz
-abysmal
-abyss
-abyssal
-abyssinia
-abyssinian
-ac
-acacia
-academe
-academia
-academic
-academical
-academician
-academy
-acadia
-acanthus
-acapulco
-accede
-accelerate
-acceleration
-accelerator
-accent
-accented
-accentual
-accentuate
-accentuation
-accenture
-accept
-acceptability
-acceptableness
-acceptably
-acceptance
-acceptation
-accepted
-access
-accessibility
-accessible
-accessibly
-accession
-accessorize
-accessory
-accident
-accidental
-acclaim
-acclamation
-acclimate
-acclimation
-acclimatization
-acclimatize
-acclivity
-accolade
-accommodate
-accommodating
-accommodation
-accompanied
-accompaniment
-accompanist
-accompany
-accomplice
-accomplish
-accomplished
-accomplishment
-accord
-accordance
-accordant
-according
-accordion
-accordionist
-accost
-account
-accountability
-accountable
-accountancy
-accountant
-accounted
-accounting
-accouter
-accouterments
-accra
-accredit
-accreditation
-accredited
-accretion
-accrual
-accrue
-acct
-acculturate
-acculturation
-accumulate
-accumulation
-accumulator
-accuracy
-accurate
-accurateness
-accursed
-accursedness
-accusation
-accusative
-accusatory
-accuse
-accuser
-accusing
-accustom
-accustomed
-ace
-acerbate
-acerbic
-acerbically
-acerbity
-acetaminophen
-acetate
-acetic
-acetone
-acetonic
-acetylene
-acevedo
-achaean
-ache
-achebe
-achene
-achernar
-acheson
-achieve
-achievement
-achiever
-achilles
-aching
-achoo
-achromatic
-achy
-acid
-acidic
-acidify
-acidity
-acidosis
-acidulous
-acknowledge
-acknowledged
-acknowledgment
-aclu
-acme
-acne
-acolyte
-aconcagua
-aconite
-acorn
-acosta
-acoustic
-acoustical
-acoustics
-acquaint
-acquaintance
-acquaintanceship
-acquainted
-acquiesce
-acquiescence
-acquiescent
-acquire
-acquirement
-acquisition
-acquisitive
-acquisitiveness
-acquit
-acquittal
-acquitted
-acquitting
-acre
-acreage
-acrid
-acridity
-acridness
-acrimonious
-acrimoniousness
-acrimony
-acrobat
-acrobatic
-acrobatically
-acrobatics
-acronym
-acrophobia
-acropolis
-across
-acrostic
-acrux
-acrylic
-act
-act's
-actaeon
-acth
-acting
-actinium
-action
-actionable
-activate
-activation
-activator
-active
-active's
-activeness
-actives
-activism
-activist
-activities
-activity
-acton
-actor
-actress
-acts
-actual
-actuality
-actualization
-actualize
-actuarial
-actuary
-actuate
-actuation
-actuator
-acuff
-acuity
-acumen
-acupressure
-acupuncture
-acupuncturist
-acute
-acuteness
-acyclovir
-ad
-ada
-adage
-adagio
-adam
-adamant
-adan
-adana
-adapt
-adaptability
-adaptation
-adapter
-adaption
-adar
-adc
-add
-addams
-addend
-addenda
-addendum
-adder
-adderley
-addict
-addiction
-addie
-addison
-addition
-additional
-additive
-addle
-address
-address's
-addressable
-addressee
-adduce
-adela
-adelaide
-adele
-adeline
-aden
-adenauer
-adenine
-adenoid
-adenoidal
-adept
-adeptness
-adequacy
-adequate
-adequateness
-adhara
-adhere
-adherence
-adherent
-adhesion
-adhesive
-adhesiveness
-adiabatic
-adidas
-adieu
-adios
-adipose
-adirondack
-adirondacks
-adj
-adjacency
-adjacent
-adjectival
-adjective
-adjoin
-adjourn
-adjournment
-adjudge
-adjudicate
-adjudication
-adjudicator
-adjudicatory
-adjunct
-adjuration
-adjure
-adjust
-adjustable
-adjuster
-adjustment
-adjutant
-adkins
-adler
-adm
-adman
-admen
-admin
-administer
-administrate
-administration
-administrative
-administrator
-admirably
-admiral
-admiralty
-admiration
-admire
-admirer
-admiring
-admissibility
-admissible
-admissibly
-admission
-admissions
-admit
-admittance
-admitted
-admitting
-admix
-admixture
-admonish
-admonishment
-admonition
-admonitory
-ado
-adobe
-adolescence
-adolescent
-adolf
-adolfo
-adolph
-adonis
-adopt
-adoptable
-adopter
-adoption
-adorableness
-adorably
-adoration
-adore
-adorer
-adoring
-adorn
-adorned
-adornment
-adp
-adrenal
-adrenalin
-adrenaline
-adrian
-adriana
-adriatic
-adrienne
-adrift
-adroit
-adroitness
-adsorb
-adsorbent
-adsorption
-adulate
-adulation
-adulator
-adulatory
-adult
-adulterant
-adulterate
-adulterated
-adulteration
-adulterer
-adulteress
-adulterous
-adultery
-adulthood
-adumbrate
-adumbration
-adv
-advance
-advancement
-advantage
-advantageous
-advent
-adventist
-adventitious
-adventure
-adventurer
-adventuresome
-adventuress
-adventurism
-adventurist
-adventurous
-adventurousness
-adverb
-adverbial
-adversarial
-adversary
-adverse
-adverseness
-adversity
-advert
-advertise
-advertised
-advertisement
-advertiser
-advertising
-advertorial
-advice
-advil
-advisability
-advisable
-advisably
-advise
-advised
-advisement
-adviser
-advisory
-advocacy
-advocate
-advt
-adze
-aegean
-aegis
-aelfric
-aeneas
-aeneid
-aeolus
-aerate
-aeration
-aerator
-aerial
-aerialist
-aerie
-aerobatic
-aerobatics
-aerobic
-aerobically
-aerobics
-aerodrome
-aerodynamic
-aerodynamically
-aerodynamics
-aeroflot
-aerogram
-aeronautic
-aeronautical
-aeronautics
-aerosol
-aerospace
-aeschylus
-aesculapius
-aesop
-aesthete
-aesthetic
-aesthetically
-aestheticism
-aesthetics
-af
-afaik
-afar
-afb
-afc
-afdc
-affability
-affable
-affably
-affair
-affect
-affect's
-affectation
-affected
-affecting
-affection
-affectionate
-affections
-afferent
-affiance
-affidavit
-affiliate
-affiliate's
-affiliated
-affiliation
-affiliations
-affinity
-affirm
-affirmation
-affirmative
-affix
-afflatus
-afflict
-affliction
-affluence
-affluent
-afford
-affordability
-afforest
-afforestation
-affray
-affront
-afghan
-afghanistan
-aficionado
-afield
-afire
-aflame
-afloat
-aflutter
-afn
-afoot
-aforementioned
-aforesaid
-aforethought
-afoul
-afr
-afraid
-afresh
-africa
-african
-afrikaans
-afrikaner
-afro
-afrocentric
-afrocentrism
-aft
-afterbirth
-afterbirths
-afterburner
-aftercare
-aftereffect
-afterglow
-afterimage
-afterlife
-afterlives
-aftermarket
-aftermath
-aftermaths
-afternoon
-aftershave
-aftershock
-aftertaste
-afterthought
-afterward
-afterword
-ag
-again
-against
-agamemnon
-agana
-agape
-agar
-agassi
-agassiz
-agate
-agatha
-agave
-age
-ageism
-ageist
-ageless
-agelessness
-agency
-agenda
-agent
-ageratum
-aggie
-agglomerate
-agglomeration
-agglutinate
-agglutination
-aggrandize
-aggrandizement
-aggravate
-aggravating
-aggravation
-aggregate
-aggregation
-aggression
-aggressive
-aggressiveness
-aggressor
-aggrieve
-aggro
-aghast
-agile
-agility
-aging
-agitate
-agitation
-agitator
-agitprop
-aglaia
-agleam
-aglitter
-aglow
-agnes
-agnew
-agni
-agnostic
-agnosticism
-ago
-agog
-agonize
-agonizing
-agony
-agoraphobia
-agoraphobic
-agra
-agrarian
-agrarianism
-agree
-agreeableness
-agreeably
-agreeing
-agreement
-agribusiness
-agricola
-agricultural
-agriculturalist
-agriculture
-agriculturist
-agrippa
-agrippina
-agronomic
-agronomist
-agronomy
-aground
-aguascalientes
-ague
-aguilar
-aguinaldo
-aguirre
-agustin
-ah
-aha
-ahab
-ahchoo
-ahead
-ahem
-ahmad
-ahmadabad
-ahmadinejad
-ahmed
-ahoy
-ahriman
-ai
-aid
-aida
-aide
-aided
-aids
-aidses
-aigrette
-aiken
-ail
-aileen
-aileron
-ailment
-aim
-aimee
-aimless
-aimlessness
-ain't
-ainu
-air
-airbag
-airbase
-airbed
-airborne
-airbrush
-airbus
-aircraft
-aircraftman
-aircraftmen
-aircrew
-airdrome
-airdrop
-airdropped
-airdropping
-airedale
-airfare
-airfield
-airflow
-airfoil
-airfreight
-airguns
-airhead
-airily
-airiness
-airing
-airless
-airlessness
-airletters
-airlift
-airline
-airliner
-airlock
-airmail
-airman
-airmen
-airplane
-airplay
-airport
-airship
-airshow
-airsick
-airsickness
-airspace
-airspeed
-airstrike
-airstrip
-airtight
-airtime
-airwaves
-airway
-airwoman
-airwomen
-airworthiness
-airworthy
-airy
-aisha
-aisle
-aitch
-ajar
-ajax
-ak
-aka
-akbar
-akhmatova
-akihito
-akimbo
-akin
-akita
-akiva
-akkad
-akron
-al
-ala
-alabama
-alabaman
-alabamian
-alabaster
-alack
-alacrity
-aladdin
-alamo
-alamogordo
-alan
-alana
-alar
-alaric
-alarm
-alarming
-alarmist
-alas
-alaska
-alaskan
-alb
-alba
-albacore
-albania
-albanian
-albany
-albatross
-albee
-albeit
-alberio
-albert
-alberta
-albertan
-alberto
-albigensian
-albinism
-albino
-albion
-albireo
-album
-albumen
-albumin
-albuminous
-albuquerque
-alcatraz
-alcestis
-alchemist
-alchemy
-alcibiades
-alcindor
-alcmena
-alcoa
-alcohol
-alcoholic
-alcoholically
-alcoholism
-alcott
-alcove
-alcuin
-alcyone
-aldan
-aldebaran
-alden
-alder
-alderamin
-alderman
-aldermen
-alderwoman
-alderwomen
-aldo
-aldrin
-ale
-aleatory
-alec
-alehouse
-aleichem
-alejandra
-alejandro
-alembert
-alembic
-aleppo
-alert
-alertness
-aleut
-aleutian
-alewife
-alewives
-alex
-alexander
-alexandra
-alexandria
-alexandrian
-alexei
-alexis
-alfalfa
-alfonso
-alfonzo
-alford
-alfred
-alfreda
-alfredo
-alfresco
-alga
-algae
-algal
-algebra
-algebraic
-algebraically
-algenib
-alger
-algeria
-algerian
-algieba
-algiers
-algol
-algonquian
-algonquin
-algorithm
-algorithmic
-alhambra
-alhena
-ali
-alias
-alibi
-alice
-alicia
-alien
-alienable
-alienate
-alienation
-alienist
-alighieri
-alight
-align
-aligned
-aligner
-alignment
-alike
-aliment
-alimentary
-alimony
-aline
-alioth
-alisa
-alisha
-alison
-alissa
-alistair
-aliveness
-aliyah
-aliyahs
-alkaid
-alkali
-alkalies
-alkaline
-alkalinity
-alkalize
-alkaloid
-alkyd
-all
-allah
-allahabad
-allan
-allay
-allegation
-allege
-alleged
-alleghenies
-allegheny
-allegiance
-allegoric
-allegorical
-allegorist
-allegory
-allegra
-allegretto
-allegro
-allele
-alleluia
-allen
-allende
-allentown
-allergen
-allergenic
-allergic
-allergically
-allergist
-allergy
-alleviate
-alleviation
-alley
-alleyway
-allhallows
-alliance
-allie
-alligator
-allison
-alliterate
-alliteration
-alliterative
-allocate
-allocation
-allocations
-allot
-allotment
-allotted
-allotting
-allover
-allow
-allowable
-allowably
-allowance
-alloy
-alloyed
-allspice
-allstate
-allude
-allure
-allurement
-alluring
-allusion
-allusive
-allusiveness
-alluvial
-alluvium
-ally
-allyson
-alma
-almach
-almanac
-almaty
-almighty
-almohad
-almond
-almoner
-almoravid
-almost
-alms
-almshouse
-alnilam
-alnitak
-aloe
-aloft
-aloha
-alone
-along
-alongshore
-alongside
-alonzo
-aloof
-aloofness
-aloud
-alp
-alpaca
-alpert
-alpha
-alphabet
-alphabetic
-alphabetical
-alphabetization
-alphabetize
-alphabetizer
-alphanumeric
-alphanumerical
-alphard
-alphecca
-alpheratz
-alphonse
-alphonso
-alpine
-alpo
-alps
-already
-alright
-alsace
-alsatian
-also
-alsop
-alston
-alt
-alta
-altai
-altaic
-altair
-altamira
-altar
-altarpiece
-alter
-alterable
-alteration
-altercation
-altered
-alternate
-alternation
-alternative
-alternator
-althea
-although
-altimeter
-altiplano
-altitude
-altman
-alto
-altogether
-altoids
-alton
-altruism
-altruist
-altruistic
-altruistically
-aludra
-alum
-alumina
-aluminum
-alumna
-alumnae
-alumni
-alumnus
-alva
-alvarado
-alvarez
-alvaro
-alveolar
-alvin
-always
-alyce
-alyson
-alyssa
-alzheimer
-am
-ama
-amadeus
-amado
-amalgam
-amalgamate
-amalgamation
-amalia
-amanda
-amanuenses
-amanuensis
-amaranth
-amaranths
-amaretto
-amarillo
-amaru
-amaryllis
-amass
-amaterasu
-amateur
-amateurish
-amateurishness
-amateurism
-amati
-amatory
-amaze
-amazement
-amazing
-amazon
-amazonian
-ambassador
-ambassadorial
-ambassadorship
-ambassadress
-amber
-ambergris
-ambiance
-ambidexterity
-ambidextrous
-ambient
-ambiguity
-ambiguous
-ambit
-ambition
-ambitious
-ambitiousness
-ambivalence
-ambivalent
-amble
-ambler
-ambrosia
-ambrosial
-ambulance
-ambulanceman
-ambulancemen
-ambulancewoman
-ambulancewomen
-ambulant
-ambulate
-ambulation
-ambulatory
-ambuscade
-ambush
-amelia
-ameliorate
-amelioration
-amen
-amenability
-amenably
-amend
-amendment
-amenhotep
-amenity
-amerasian
-amerce
-amercement
-america
-american
-americana
-americanism
-americanization
-americanize
-americium
-amerind
-amerindian
-ameslan
-amethyst
-amharic
-amherst
-amiability
-amiable
-amiably
-amicability
-amicable
-amicably
-amid
-amide
-amidships
-amie
-amiga
-amigo
-amish
-amiss
-amity
-amman
-ammeter
-ammo
-ammonia
-ammunition
-amnesia
-amnesiac
-amnesic
-amnesty
-amniocenteses
-amniocentesis
-amnion
-amniotic
-amoco
-amoeba
-amoebae
-amoebic
-amok
-among
-amontillado
-amoral
-amorality
-amorous
-amorousness
-amorphous
-amorphousness
-amortization
-amortize
-amos
-amount
-amour
-amp
-amparo
-amperage
-ampere
-ampersand
-amphetamine
-amphibian
-amphibious
-amphitheater
-amphora
-amphorae
-ample
-amplification
-amplifier
-amplify
-amplitude
-ampule
-amputate
-amputation
-amputee
-amritsar
-amsterdam
-amt
-amtrak
-amulet
-amundsen
-amur
-amuse
-amusement
-amusing
-amway
-amy
-amylase
-an
-ana
-anabaptist
-anabel
-anabolism
-anachronism
-anachronistic
-anachronistically
-anacin
-anaconda
-anacreon
-anaerobe
-anaerobic
-anaerobically
-anagram
-anaheim
-anal
-analects
-analgesia
-analgesic
-analog
-analogical
-analogize
-analogous
-analogousness
-analogue
-analogy
-analysand
-analyses
-analysis
-analyst
-analytic
-analytically
-analyzable
-analyze
-analyzer
-ananias
-anapest
-anapestic
-anarchic
-anarchically
-anarchism
-anarchist
-anarchistic
-anarchy
-anasazi
-anastasia
-anathema
-anathematize
-anatole
-anatolia
-anatolian
-anatomic
-anatomical
-anatomist
-anatomize
-anatomy
-anaxagoras
-ancestor
-ancestral
-ancestress
-ancestry
-anchor
-anchorage
-anchorite
-anchorman
-anchormen
-anchorpeople
-anchorperson
-anchorwoman
-anchorwomen
-anchovy
-ancient
-ancientness
-ancillary
-and
-andalusia
-andalusian
-andaman
-andante
-andean
-andersen
-anderson
-andes
-andiron
-andorra
-andorran
-andre
-andrea
-andrei
-andretti
-andrew
-andrianampoinimerina
-androgen
-androgenic
-androgynous
-androgyny
-android
-andromache
-andromeda
-andropov
-andy
-anecdotal
-anecdote
-anemia
-anemic
-anemically
-anemometer
-anemone
-anent
-anesthesia
-anesthesiologist
-anesthesiology
-anesthetic
-anesthetist
-anesthetization
-anesthetize
-aneurysm
-anew
-angara
-angel
-angela
-angelfish
-angelia
-angelic
-angelica
-angelical
-angelico
-angelina
-angeline
-angelique
-angelita
-angelo
-angelou
-anger
-angevin
-angie
-angina
-angioplasty
-angiosperm
-angkor
-angle
-angler
-angleworm
-anglia
-anglican
-anglicanism
-anglicism
-anglicization
-anglicize
-angling
-anglo
-anglophile
-anglophobe
-anglophone
-angola
-angolan
-angora
-angostura
-angrily
-angry
-angst
-angstrom
-anguilla
-anguish
-angular
-angularity
-angus
-anhydrous
-aniakchak
-anibal
-aniline
-animadversion
-animadvert
-animal
-animalcule
-animate
-animated
-animation
-animations
-animator
-animism
-animist
-animistic
-animosity
-animus
-anion
-anionic
-anise
-aniseed
-anisette
-anita
-ankara
-ankh
-ankhs
-ankle
-anklebone
-anklet
-ann
-anna
-annabel
-annabelle
-annalist
-annals
-annam
-annapolis
-annapurna
-anne
-anneal
-annelid
-annette
-annex
-annexation
-annie
-annihilate
-annihilation
-annihilator
-anniversary
-annmarie
-annotate
-annotation
-annotator
-announce
-announced
-announcement
-announcer
-annoy
-annoyance
-annoying
-annoyware
-annual
-annualized
-annuitant
-annuity
-annul
-annular
-annulled
-annulling
-annulment
-annunciation
-anode
-anodize
-anodyne
-anoint
-anointment
-anomalous
-anomaly
-anon
-anonymity
-anonymous
-anopheles
-anorak
-anorectic
-anorexia
-anorexic
-another
-anouilh
-anselm
-anselmo
-anshan
-ansi
-answer
-answerable
-answered
-answerphone
-ant
-antacid
-antaeus
-antagonism
-antagonist
-antagonistic
-antagonistically
-antagonize
-antananarivo
-antarctic
-antarctica
-antares
-ante
-anteater
-antebellum
-antecedence
-antecedent
-antechamber
-antedate
-antediluvian
-anteing
-antelope
-antenatal
-antenna
-antennae
-anterior
-anteroom
-anthem
-anther
-anthill
-anthologist
-anthologize
-anthology
-anthony
-anthracite
-anthrax
-anthropocentric
-anthropoid
-anthropological
-anthropologist
-anthropology
-anthropomorphic
-anthropomorphically
-anthropomorphism
-anthropomorphous
-anti
-antiabortion
-antiabortionist
-antiaircraft
-antibacterial
-antibiotic
-antibody
-antic
-anticancer
-antichrist
-anticipate
-anticipated
-anticipation
-anticipatory
-anticked
-anticking
-anticlerical
-anticlimactic
-anticlimactically
-anticlimax
-anticline
-anticlockwise
-anticoagulant
-anticommunism
-anticommunist
-anticyclone
-anticyclonic
-antidemocratic
-antidepressant
-antidote
-antietam
-antifascist
-antifreeze
-antigen
-antigenic
-antigenicity
-antigone
-antigua
-antihero
-antiheroes
-antihistamine
-antiknock
-antilabor
-antillean
-antilles
-antilogarithm
-antimacassar
-antimalarial
-antimatter
-antimicrobial
-antimissile
-antimony
-antinuclear
-antioch
-antioxidant
-antiparticle
-antipas
-antipasti
-antipasto
-antipathetic
-antipathy
-antipersonnel
-antiperspirant
-antiphon
-antiphonal
-antipodal
-antipodean
-antipodes
-antipollution
-antipoverty
-antiquarian
-antiquarianism
-antiquary
-antiquate
-antique
-antiquity
-antirrhinum
-antisemitic
-antisemitism
-antisepsis
-antiseptic
-antiseptically
-antiserum
-antislavery
-antisocial
-antispasmodic
-antisubmarine
-antitank
-antitheses
-antithesis
-antithetic
-antithetical
-antitoxin
-antitrust
-antivenin
-antiviral
-antivivisectionist
-antiwar
-antler
-antofagasta
-antoine
-antoinette
-anton
-antone
-antonia
-antoninus
-antonio
-antonius
-antony
-antonym
-antonymous
-antsy
-antwan
-antwerp
-anubis
-anus
-anvil
-anxiety
-anxious
-anxiousness
-any
-anybody
-anyhow
-anymore
-anyone
-anyplace
-anything
-anytime
-anyway
-anywhere
-anywise
-anzac
-anzus
-aol
-aorta
-aortic
-ap
-apace
-apache
-apalachicola
-apart
-apartheid
-apartment
-apathetic
-apathetically
-apathy
-apatite
-apb
-ape
-apelike
-apennines
-aperitif
-aperture
-apex
-aphasia
-aphasic
-aphelia
-aphelion
-aphid
-aphorism
-aphoristic
-aphoristically
-aphrodisiac
-aphrodite
-apia
-apiarist
-apiary
-apical
-apiece
-apish
-aplenty
-aplomb
-apo
-apocalypse
-apocalyptic
-apocrypha
-apocryphal
-apogee
-apolitical
-apollinaire
-apollo
-apollonian
-apologetic
-apologetically
-apologia
-apologist
-apologize
-apology
-apoplectic
-apoplexy
-apostasy
-apostate
-apostatize
-apostle
-apostleship
-apostolic
-apostrophe
-apothecary
-apothegm
-apotheoses
-apotheosis
-app
-appalachia
-appalachian
-appall
-appalling
-appaloosa
-apparatchik
-apparatus
-apparel
-apparent
-apparition
-appeal
-appealing
-appear
-appearance
-appease
-appeasement
-appeaser
-appellant
-appellate
-appellation
-append
-appendage
-appendectomy
-appendices
-appendicitis
-appendix
-appertain
-appetite
-appetizer
-appetizing
-applaud
-applauder
-applause
-apple
-applejack
-applesauce
-appleseed
-applet
-appleton
-appliance
-applicability
-applicable
-applicably
-applicant
-application
-applicator
-applier
-applique
-appliqueing
-apply
-appoint
-appointee
-appointment
-appointment's
-appomattox
-apportion
-apportionment
-appose
-apposite
-appositeness
-apposition
-appositive
-appraisal
-appraise
-appraiser
-appreciable
-appreciably
-appreciate
-appreciated
-appreciation
-appreciative
-appreciator
-appreciatory
-apprehend
-apprehension
-apprehensive
-apprehensiveness
-apprentice
-apprenticeship
-apprise
-approach
-approachable
-approbation
-approbations
-appropriate
-appropriated
-appropriateness
-appropriation
-appropriator
-approval
-approvals
-approve
-approved
-approving
-approx
-approximate
-approximation
-appurtenance
-appurtenant
-apr
-apricot
-april
-apron
-apropos
-apse
-apt
-apter
-aptitude
-aptness
-apuleius
-aqua
-aquaculture
-aquafresh
-aqualung
-aquamarine
-aquanaut
-aquaplane
-aquarium
-aquarius
-aquatic
-aquatically
-aquatics
-aquatint
-aquavit
-aqueduct
-aqueous
-aquifer
-aquila
-aquiline
-aquinas
-aquino
-aquitaine
-ar
-ara
-arab
-arabesque
-arabia
-arabian
-arabic
-arability
-arabist
-araby
-araceli
-arachnid
-arachnophobia
-arafat
-araguaya
-aral
-aramaic
-aramco
-arapaho
-arapahoes
-ararat
-araucanian
-arawak
-arawakan
-arbiter
-arbitrage
-arbitrager
-arbitrageur
-arbitrament
-arbitrarily
-arbitrariness
-arbitrary
-arbitrate
-arbitration
-arbitrator
-arbitron
-arbor
-arboreal
-arboretum
-arborvitae
-arbutus
-arc
-arcade
-arcadia
-arcadian
-arcane
-arch
-archaeological
-archaeologist
-archaeology
-archaic
-archaically
-archaism
-archaist
-archangel
-archbishop
-archbishopric
-archdeacon
-archdiocesan
-archdiocese
-archduchess
-archduke
-archean
-archenemy
-archer
-archery
-archetypal
-archetype
-archfiend
-archibald
-archie
-archiepiscopal
-archimedes
-archipelago
-architect
-architectonic
-architectonics
-architectural
-architecture
-architrave
-archival
-archive
-archivist
-archness
-archway
-arctic
-arcturus
-ardabil
-arden
-ardent
-ardor
-arduous
-arduousness
-are
-area
-areal
-aren't
-arena
-arequipa
-ares
-argent
-argentina
-argentine
-argentinean
-argentinian
-argo
-argon
-argonaut
-argonne
-argosy
-argot
-arguable
-arguably
-argue
-arguer
-argument
-argumentation
-argumentative
-argumentativeness
-argus
-argyle
-aria
-ariadne
-arianism
-arid
-aridity
-ariel
-aries
-aright
-ariosto
-arise
-arisen
-aristarchus
-aristides
-aristocracy
-aristocrat
-aristocratic
-aristocratically
-aristophanes
-aristotelian
-aristotle
-arithmetic
-arithmetical
-arithmetician
-arius
-ariz
-arizona
-arizonan
-arizonian
-arjuna
-ark
-arkansan
-arkansas
-arkhangelsk
-arkwright
-arlene
-arline
-arlington
-arm
-arm's
-armada
-armadillo
-armageddon
-armagnac
-armament
-armaments
-armand
-armando
-armani
-armature
-armband
-armchair
-armed
-armenia
-armenian
-armful
-armhole
-arminius
-armistice
-armlet
-armload
-armonk
-armor
-armored
-armorer
-armorial
-armory
-armour
-armpit
-armrest
-armstrong
-army
-arneb
-arnhem
-arno
-arnold
-arnulfo
-aroma
-aromatherapist
-aromatherapy
-aromatic
-aromatically
-aron
-arose
-around
-arousal
-arouse
-arpeggio
-arr
-arraign
-arraignment
-arrange
-arrangement
-arrangement's
-arranger
-arrant
-arras
-array
-arrears
-arrest
-arrhenius
-arrhythmia
-arrhythmic
-arrhythmical
-arrival
-arrive
-arrogance
-arrogant
-arrogate
-arrogation
-arron
-arrow
-arrowhead
-arrowroot
-arroyo
-arsed
-arsenal
-arsenic
-arsing
-arson
-arsonist
-art
-artaxerxes
-artemis
-arterial
-arteriole
-arteriosclerosis
-artery
-artful
-artfulness
-arthritic
-arthritis
-arthropod
-arthroscope
-arthroscopic
-arthur
-arthurian
-artichoke
-article
-articulacy
-articular
-articulate
-articulateness
-articulation
-artie
-artifact
-artifice
-artificer
-artificial
-artificiality
-artillery
-artilleryman
-artillerymen
-artiness
-artisan
-artist
-artiste
-artistic
-artistically
-artistry
-artless
-artlessness
-artsy
-arturo
-artwork
-arty
-aruba
-arugula
-arum
-aryan
-asama
-asap
-asbestos
-ascella
-ascend
-ascendance
-ascendancy
-ascendant
-ascension
-ascent
-ascertain
-ascertainment
-ascetic
-ascetically
-asceticism
-ascii
-ascot
-ascribe
-ascription
-aseptic
-aseptically
-asexual
-asexuality
-asgard
-ash
-ashamed
-ashanti
-ashcan
-ashcroft
-ashe
-ashgabat
-ashikaga
-ashkenazim
-ashkhabad
-ashlar
-ashlee
-ashley
-ashmolean
-ashore
-ashram
-ashtray
-ashurbanipal
-ashy
-asia
-asian
-asiatic
-aside
-asimov
-asinine
-asininity
-ask
-askance
-asked
-askew
-asl
-aslant
-asleep
-asmara
-asocial
-asoka
-asp
-asparagus
-aspartame
-aspca
-aspect
-aspell
-aspen
-asperity
-aspersion
-asphalt
-asphodel
-asphyxia
-asphyxiate
-asphyxiation
-aspic
-aspidiske
-aspidistra
-aspirant
-aspirate
-aspiration
-aspirator
-aspire
-aspirin
-asquith
-ass
-assad
-assail
-assailable
-assailant
-assam
-assamese
-assassin
-assassinate
-assassination
-assault
-assay
-assayer
-assemblage
-assemble
-assembler
-assemblies
-assembly
-assemblyman
-assemblymen
-assemblywoman
-assemblywomen
-assent
-assert
-assertion
-assertions
-assertive
-assertiveness
-assess
-assessment
-assessor
-asset
-asseverate
-asseveration
-asshole
-assiduity
-assiduous
-assiduousness
-assign
-assign's
-assignable
-assignation
-assigned
-assigner
-assignment
-assignor
-assimilate
-assimilation
-assisi
-assist
-assistance
-assistant
-assisted
-assize
-assn
-assoc
-associate
-associate's
-association
-associations
-assonance
-assonant
-assort
-assortment
-asst
-assuage
-assume
-assumption
-assumptive
-assurance
-assure
-assured
-assyria
-assyrian
-astaire
-astana
-astarte
-astatine
-aster
-asterisk
-astern
-asteroid
-asthma
-asthmatic
-asthmatically
-astigmatic
-astigmatism
-astir
-aston
-astonish
-astonishing
-astonishment
-astor
-astoria
-astound
-astounding
-astraddle
-astrakhan
-astral
-astray
-astride
-astringency
-astringent
-astrolabe
-astrologer
-astrological
-astrologist
-astrology
-astronaut
-astronautic
-astronautical
-astronautics
-astronomer
-astronomic
-astronomical
-astronomy
-astrophysical
-astrophysicist
-astrophysics
-astroturf
-asturias
-astute
-astuteness
-asuncion
-asunder
-aswan
-asylum
-asymmetric
-asymmetrical
-asymmetry
-asymptomatic
-asymptotic
-asymptotically
-asynchronous
-at
-atacama
-atahualpa
-atalanta
-atari
-ataturk
-atavism
-atavist
-atavistic
-ataxia
-ataxic
-ate
-atelier
-athabasca
-athabaskan
-atheism
-atheist
-atheistic
-athena
-athene
-athenian
-athens
-atherosclerosis
-athirst
-athlete
-athletic
-athletically
-athleticism
-athletics
-athwart
-atilt
-atishoo
-atkins
-atkinson
-atlanta
-atlantes
-atlantic
-atlantis
-atlas
-atm
-atman
-atmosphere
-atmospheric
-atmospherically
-atmospherics
-atoll
-atom
-atomic
-atomically
-atomize
-atomizer
-atonal
-atonality
-atone
-atonement
-atop
-atp
-atreus
-atria
-atrial
-atrium
-atrocious
-atrociousness
-atrocity
-atrophy
-atropine
-atropos
-attach
-attache
-attached
-attachment
-attachments
-attack
-attacker
-attain
-attainability
-attainable
-attainder
-attainment
-attar
-attempt
-attempt's
-attend
-attendance
-attendant
-attended
-attendee
-attention
-attentions
-attentive
-attentiveness
-attenuate
-attenuation
-attest
-attestation
-attested
-attic
-attica
-attila
-attire
-attitude
-attitudinal
-attitudinize
-attlee
-attn
-attorney
-attract
-attractant
-attraction
-attractive
-attractiveness
-attribute
-attributed
-attribution
-attributive
-attrition
-attucks
-attune
-atty
-atv
-atwitter
-atwood
-atypical
-au
-aubergine
-aubrey
-auburn
-auckland
-auction
-auctioneer
-audacious
-audaciousness
-audacity
-auden
-audi
-audibility
-audible
-audibly
-audience
-audio
-audiological
-audiologist
-audiology
-audiometer
-audion
-audiophile
-audiotape
-audiovisual
-audiovisuals
-audit
-audition
-auditor
-auditorium
-auditory
-audra
-audrey
-audubon
-aug
-augean
-auger
-aught
-augment
-augmentation
-augmentative
-augmenter
-augsburg
-augur
-augury
-august
-augusta
-augustan
-augustine
-augustinian
-augustness
-augustus
-auk
-aunt
-auntie
-aura
-aural
-aurangzeb
-aurelia
-aurelio
-aurelius
-aureole
-aureomycin
-auricle
-auricular
-auriga
-aurora
-auschwitz
-auscultate
-auscultation
-auspice
-auspicious
-auspiciousness
-aussie
-austen
-austere
-austerity
-austerlitz
-austin
-austral
-australasia
-australasian
-australia
-australian
-australoid
-australopithecus
-austria
-austrian
-austronesian
-authentic
-authentically
-authenticate
-authenticated
-authentication
-authenticity
-author
-authoress
-authorial
-authoritarian
-authoritarianism
-authoritative
-authoritativeness
-authority
-authorization
-authorize
-authorized
-authorship
-autism
-autistic
-auto
-autobahn
-autobiographer
-autobiographic
-autobiographical
-autobiography
-autoclave
-autocracy
-autocrat
-autocratic
-autocratically
-autocross
-autodidact
-autograph
-autographs
-autoimmune
-autoimmunity
-automaker
-automate
-automatic
-automatically
-automation
-automatism
-automatize
-automaton
-automobile
-automotive
-autonomic
-autonomous
-autonomy
-autopilot
-autopsy
-autosuggestion
-autoworker
-autumn
-autumnal
-aux
-auxiliary
-auxin
-av
-ava
-avail
-availability
-available
-avalanche
-avalon
-avarice
-avaricious
-avast
-avatar
-avaunt
-avdp
-ave
-avenge
-avenger
-aventine
-avenue
-average
-avernus
-averred
-averring
-averroes
-averse
-aversion
-avert
-avery
-avesta
-avg
-avian
-aviary
-aviation
-aviator
-aviatrices
-aviatrix
-avicenna
-avid
-avidity
-avignon
-avila
-avionic
-avionics
-avior
-avis
-avitaminosis
-avocado
-avocation
-avocational
-avogadro
-avoid
-avoidable
-avoidably
-avoidance
-avoirdupois
-avon
-avouch
-avow
-avowal
-avowed
-avuncular
-aw
-awacs
-await
-awake
-awaken
-awakening
-award
-aware
-awareness
-awash
-away
-awe
-aweigh
-awesome
-awesomeness
-awestruck
-awful
-awfuller
-awfullest
-awfulness
-awhile
-awkward
-awkwardness
-awl
-awn
-awning
-awoke
-awoken
-awol
-awry
-ax
-axial
-axiom
-axiomatic
-axiomatically
-axis
-axle
-axletree
-axolotl
-axon
-axum
-ayah
-ayahs
-ayala
-ayatollah
-ayatollahs
-aye
-ayers
-aymara
-ayrshire
-ayurveda
-ayyubid
-az
-azalea
-azana
-azania
-azazel
-azerbaijan
-azerbaijani
-azimuth
-azimuths
-azores
-azov
-azt
-aztec
-aztecan
-aztlan
-azure
-b
-ba
-baa
-baal
-baath
-baathist
-babbage
-babbitt
-babble
-babbler
-babe
-babel
-baboon
-babushka
-baby
-babyhood
-babyish
-babylon
-babylonia
-babylonian
-babysat
-babysit
-babysitter
-babysitting
-bacall
-bacardi
-baccalaureate
-baccarat
-bacchanal
-bacchanalia
-bacchanalian
-bacchic
-bacchus
-baccy
-bach
-bachelor
-bachelorhood
-bacillary
-bacilli
-bacillus
-back
-backache
-backbench
-backbit
-backbite
-backbiter
-backbitten
-backboard
-backbone
-backbreaking
-backchat
-backcloth
-backcloths
-backcomb
-backdate
-backdoor
-backdrop
-backer
-backfield
-backfire
-backgammon
-background
-backgrounder
-backhand
-backhanded
-backhander
-backhoe
-backing
-backlash
-backless
-backlog
-backlogged
-backlogging
-backpack
-backpacker
-backpacking
-backpedal
-backrest
-backroom
-backscratching
-backseat
-backside
-backslapper
-backslapping
-backslash
-backslid
-backslide
-backslider
-backspace
-backspin
-backstabber
-backstabbing
-backstage
-backstair
-backstop
-backstopped
-backstopping
-backstreet
-backstretch
-backstroke
-backtalk
-backtrack
-backup
-backus
-backward
-backwardness
-backwash
-backwater
-backwoods
-backwoodsman
-backwoodsmen
-backyard
-bacon
-bacteria
-bacterial
-bactericidal
-bactericide
-bacteriologic
-bacteriological
-bacteriologist
-bacteriology
-bacterium
-bactria
-bad
-badder
-baddest
-baddie
-bade
-baden
-badge
-badger
-badinage
-badlands
-badman
-badmen
-badminton
-badmouth
-badmouths
-badness
-baedeker
-baez
-baffin
-baffle
-bafflement
-baffler
-bag
-bagatelle
-bagel
-bagful
-baggage
-bagged
-baggie
-baggies
-baggily
-bagginess
-bagging
-baggy
-baghdad
-bagpipe
-bagpiper
-baguette
-baguio
-bah
-baha'i
-baha'ullah
-bahama
-bahamanian
-bahamas
-bahamian
-bahia
-bahrain
-baht
-baikal
-bail
-bailey
-bailiff
-bailiwick
-bailout
-bailsman
-bailsmen
-baird
-bairn
-bait
-baize
-bake
-baked
-bakelite
-baker
-bakersfield
-bakery
-bakeshop
-baklava
-baksheesh
-baku
-bakunin
-balaclava
-balalaika
-balance
-balance's
-balanchine
-balaton
-balboa
-balcony
-bald
-balder
-balderdash
-baldfaced
-baldness
-baldric
-baldwin
-baldy
-bale
-balearic
-baleen
-baleful
-balefulness
-baler
-balfour
-bali
-balinese
-balk
-balkan
-balkhash
-balky
-ball
-ballad
-balladeer
-balladry
-ballard
-ballast
-ballcock
-ballerina
-ballet
-balletic
-ballgame
-ballgirl
-ballgown
-ballistic
-ballistics
-balloon
-balloonist
-ballot
-ballpark
-ballplayer
-ballpoint
-ballroom
-balls
-ballsy
-bally
-ballyhoo
-balm
-balminess
-balmy
-baloney
-balsa
-balsam
-balsamic
-balthazar
-baltic
-baltimore
-baluchistan
-baluster
-balustrade
-balzac
-bamako
-bambi
-bamboo
-bamboozle
-ban
-banach
-banal
-banality
-banana
-bancroft
-band
-band's
-bandage
-bandanna
-bandbox
-bandeau
-bandeaux
-bandit
-banditry
-bandleader
-bandmaster
-bandoleer
-bandsman
-bandsmen
-bandstand
-bandung
-bandwagon
-bandwidth
-bandwidths
-bandy
-bane
-baneful
-bang
-bangalore
-bangkok
-bangladesh
-bangladeshi
-bangle
-bangor
-bangui
-bani
-banish
-banishment
-banister
-banjarmasin
-banjo
-banjoist
-banjul
-bank
-bankbook
-bankcard
-banker
-banking
-banknote
-bankroll
-bankrupt
-bankruptcy
-banks
-banned
-banneker
-banner
-banning
-bannister
-bannock
-banns
-banquet
-banqueter
-banquette
-banshee
-bantam
-bantamweight
-banter
-bantering
-banting
-bantu
-banyan
-banzai
-baobab
-baotou
-bap
-baptism
-baptismal
-baptist
-baptiste
-baptistery
-baptize
-baptized
-baptizer
-bar
-bar's
-barabbas
-barack
-barb
-barbadian
-barbados
-barbara
-barbarella
-barbarian
-barbarianism
-barbaric
-barbarically
-barbarism
-barbarity
-barbarize
-barbarossa
-barbarous
-barbary
-barbecue
-barbel
-barbell
-barber
-barberry
-barbershop
-barbie
-barbiturate
-barbour
-barbra
-barbuda
-barbwire
-barcarole
-barcelona
-barclay
-bard
-bardeen
-bardic
-bare
-bareback
-barefaced
-barefoot
-barehanded
-bareheaded
-barelegged
-bareness
-barents
-barf
-barfly
-bargain
-bargainer
-barge
-bargeman
-bargemen
-barhop
-barhopped
-barhopping
-baritone
-barium
-bark
-bark's
-barkeep
-barkeeper
-barker
-barkley
-barley
-barlow
-barmaid
-barman
-barmen
-barmy
-barn
-barnabas
-barnaby
-barnacle
-barnard
-barnaul
-barnes
-barnett
-barney
-barnstorm
-barnstormer
-barnum
-barnyard
-baroda
-barometer
-barometric
-barometrically
-baron
-baronage
-baroness
-baronet
-baronetcy
-baronial
-barony
-baroque
-barque
-barquisimeto
-barr
-barrack
-barracuda
-barrage
-barranquilla
-barre
-barred
-barrel
-barren
-barrenness
-barrera
-barrett
-barrette
-barricade
-barrie
-barrier
-barring
-barrio
-barrister
-barron
-barroom
-barrow
-barry
-barrymore
-bart
-bartender
-barter
-barterer
-barth
-bartholdi
-bartholomew
-bartlett
-bartok
-barton
-baruch
-baryon
-baryshnikov
-basal
-basalt
-basaltic
-base
-base's
-baseball
-baseboard
-basel
-baseless
-baseline
-basely
-baseman
-basemen
-basement
-baseness
-baser
-bash
-bashful
-bashfulness
-bashing
-basho
-basic
-basically
-basie
-basil
-basilica
-basilisk
-basin
-basinful
-basis
-bask
-basket
-basketball
-basketry
-basketwork
-basque
-basra
-bass
-basset
-basseterre
-bassinet
-bassist
-basso
-bassoon
-bassoonist
-basswood
-bast
-bastard
-bastardization
-bastardize
-bastardy
-baste
-baster
-bastille
-bastion
-basutoland
-bat
-bataan
-batch
-bate
-bates
-bath
-bathe
-bather
-bathetic
-bathhouse
-bathing
-bathmat
-bathos
-bathrobe
-bathroom
-baths
-bathsheba
-bathtub
-bathwater
-bathyscaphe
-bathysphere
-batik
-batista
-batiste
-batman
-batmen
-baton
-batsman
-batsmen
-battalion
-batted
-batten
-batter
-batterer
-battery
-batting
-battle
-battleaxe
-battledore
-battledress
-battlefield
-battlefront
-battleground
-battlement
-battler
-battleship
-batty
-batu
-bauble
-baud
-baudelaire
-baudouin
-bauer
-bauhaus
-baum
-bauxite
-bavaria
-bavarian
-bawd
-bawdily
-bawdiness
-bawdy
-bawl
-baxter
-bay
-bayamon
-bayberry
-bayer
-bayes
-bayesian
-bayeux
-baylor
-bayonet
-bayonne
-bayou
-bayreuth
-baywatch
-bazaar
-bazillion
-bazooka
-bb
-bbb
-bbc
-bbl
-bbq
-bbs
-bbses
-bc
-bdrm
-be
-beach
-beachcomber
-beachfront
-beachhead
-beachwear
-beacon
-bead
-beading
-beadle
-beady
-beagle
-beak
-beaker
-beam
-bean
-beanbag
-beanfeast
-beanie
-beanpole
-beansprout
-beanstalk
-bear
-bearable
-bearably
-beard
-beardless
-beardmore
-beardsley
-bearer
-bearing
-bearish
-bearishness
-bearlike
-bearnaise
-bearskin
-beasley
-beast
-beastliness
-beastly
-beat
-beatable
-beaten
-beater
-beatific
-beatifically
-beatification
-beatify
-beating
-beatitude
-beatlemania
-beatles
-beatnik
-beatrice
-beatrix
-beatriz
-beau
-beaufort
-beaujolais
-beaumarchais
-beaumont
-beauregard
-beaut
-beauteous
-beautician
-beautification
-beautifier
-beautiful
-beautify
-beauty
-beauvoir
-beaver
-bebop
-becalm
-became
-because
-bechtel
-beck
-becker
-becket
-beckett
-beckon
-becky
-becloud
-become
-becoming
-becquerel
-bed
-bedaub
-bedazzle
-bedazzlement
-bedbug
-bedchamber
-bedclothes
-bedded
-bedder
-bedding
-bede
-bedeck
-bedevil
-bedevilment
-bedfellow
-bedhead
-bedim
-bedimmed
-bedimming
-bedizen
-bedlam
-bedouin
-bedpan
-bedpost
-bedraggle
-bedridden
-bedrock
-bedroll
-bedroom
-bedside
-bedsit
-bedsitter
-bedsore
-bedspread
-bedstead
-bedtime
-bee
-beebe
-beebread
-beech
-beecher
-beechnut
-beef
-beefaroni
-beefburger
-beefcake
-beefiness
-beefsteak
-beefy
-beehive
-beekeeper
-beekeeping
-beeline
-beelzebub
-been
-beep
-beeper
-beer
-beerbohm
-beery
-beeswax
-beet
-beethoven
-beetle
-beeton
-beetroot
-beeves
-befall
-befell
-befit
-befitted
-befitting
-befog
-befogged
-befogging
-before
-beforehand
-befoul
-befriend
-befuddle
-befuddlement
-beg
-began
-begat
-beget
-begetter
-begetting
-beggar
-beggary
-begged
-begging
-begin
-beginner
-beginning
-begone
-begonia
-begot
-begotten
-begrime
-begrudge
-begrudging
-beguile
-beguilement
-beguiler
-beguiling
-beguine
-begum
-begun
-behalf
-behalves
-behan
-behave
-behavior
-behavioral
-behaviorism
-behaviorist
-behead
-beheld
-behemoth
-behemoths
-behest
-behind
-behindhand
-behold
-beholder
-behoove
-behring
-beiderbecke
-beige
-beijing
-being
-beirut
-bejewel
-bekesy
-bela
-belabor
-belarus
-belated
-belau
-belay
-belch
-beleaguer
-belem
-belfast
-belfry
-belg
-belgian
-belgium
-belgrade
-belie
-belief
-beliefs
-believable
-believably
-believe
-believer
-believing
-belinda
-belittle
-belittlement
-belize
-bell
-bella
-belladonna
-bellamy
-bellatrix
-bellboy
-belle
-belled
-belleek
-belletrist
-belletristic
-bellhop
-bellicose
-bellicosity
-belligerence
-belligerency
-belligerent
-belling
-bellini
-bellman
-bellmen
-bellow
-bellwether
-belly
-bellyache
-bellybutton
-bellyful
-belmont
-belmopan
-belong
-belonging
-belorussian
-beloved
-below
-belshazzar
-belt
-beltane
-beltway
-beluga
-belushi
-belying
-bemire
-bemoan
-bemuse
-bemused
-bemusement
-ben
-benacerraf
-bench
-benchley
-benchmark
-bend
-bender
-bendix
-bendy
-beneath
-benedict
-benedictine
-benediction
-benedictory
-benefaction
-benefactor
-benefactress
-benefice
-beneficence
-beneficent
-beneficial
-beneficiary
-benefit
-benelux
-benet
-benetton
-benevolence
-benevolent
-bengal
-bengali
-benghazi
-benighted
-benign
-benignant
-benignity
-benin
-beninese
-benita
-benito
-benjamin
-bennett
-bennie
-benny
-benson
-bent
-bentham
-bentley
-benton
-bentwood
-benumb
-benz
-benzedrine
-benzene
-benzine
-beowulf
-bequeath
-bequeaths
-bequest
-berate
-berber
-bereave
-bereavement
-bereft
-berenice
-beret
-beretta
-berg
-bergen
-berger
-bergerac
-bergman
-bergson
-beria
-beriberi
-bering
-berk
-berkeley
-berkelium
-berkshire
-berle
-berlin
-berliner
-berlioz
-berlitz
-berm
-bermuda
-bermudan
-bermudian
-bern
-bernadette
-bernadine
-bernanke
-bernard
-bernardo
-bernays
-bernbach
-bernese
-bernhardt
-bernice
-bernie
-bernini
-bernoulli
-bernstein
-berra
-berry
-berrylike
-berserk
-bert
-berta
-bertelsmann
-berth
-bertha
-berths
-bertie
-bertillon
-bertram
-bertrand
-beryl
-beryllium
-berzelius
-beseech
-beseecher
-beseeching
-beseem
-beset
-besetting
-beside
-besiege
-besieger
-besmear
-besmirch
-besom
-besot
-besotted
-besotting
-besought
-bespangle
-bespatter
-bespeak
-bespectacled
-bespoke
-bespoken
-bess
-bessel
-bessemer
-bessie
-best
-bestial
-bestiality
-bestiary
-bestir
-bestirred
-bestirring
-bestow
-bestowal
-bestrew
-bestrewn
-bestridden
-bestride
-bestrode
-bestseller
-bestselling
-bet
-beta
-betake
-betaken
-betcha
-betel
-betelgeuse
-beth
-bethany
-bethe
-bethesda
-bethink
-bethlehem
-bethought
-bethune
-betide
-betimes
-betoken
-betook
-betray
-betrayal
-betrayer
-betroth
-betrothal
-betrothed
-betroths
-betsy
-bette
-better
-betterment
-bettie
-betting
-bettor
-betty
-bettye
-between
-betwixt
-beulah
-bevel
-beverage
-beverley
-beverly
-bevvy
-bevy
-bewail
-beware
-bewhiskered
-bewigged
-bewilder
-bewildering
-bewilderment
-bewitch
-bewitching
-bewitchment
-bey
-beyer
-beyond
-bezel
-bf
-bhaji
-bhopal
-bhutan
-bhutanese
-bhutto
-bi
-bia
-bialystok
-bianca
-biannual
-bias
-biased
-biathlon
-bib
-bible
-biblical
-bibliographer
-bibliographic
-bibliographical
-bibliography
-bibliophile
-bibulous
-bic
-bicameral
-bicameralism
-bicarb
-bicarbonate
-bicentenary
-bicentennial
-bicep
-biceps
-bicker
-bickerer
-biconcave
-biconvex
-bicuspid
-bicycle
-bicycler
-bicyclist
-bid
-biddable
-bidden
-bidder
-bidding
-biddle
-biddy
-bide
-biden
-bidet
-bidirectional
-biennial
-biennium
-bier
-bierce
-biff
-bifocal
-bifocals
-bifurcate
-bifurcation
-big
-bigamist
-bigamous
-bigamy
-bigfoot
-bigger
-biggest
-biggie
-biggish
-biggles
-bighead
-bighearted
-bigheartedness
-bighorn
-bight
-bigmouth
-bigmouths
-bigness
-bigot
-bigotry
-bigwig
-bijou
-bijoux
-bike
-biker
-bikini
-biko
-bilabial
-bilateral
-bilbao
-bilberry
-bilbo
-bile
-bilge
-bilingual
-bilingualism
-bilious
-biliousness
-bilk
-bilker
-bill
-billboard
-billet
-billfold
-billhook
-billiard
-billiards
-billie
-billing
-billings
-billingsgate
-billion
-billionaire
-billionth
-billionths
-billow
-billowy
-billy
-billycan
-bimbo
-bimetallic
-bimetallism
-bimini
-bimonthly
-bin
-binary
-bind
-bind's
-binder
-bindery
-binding
-bindweed
-binge
-bingo
-binman
-binmen
-binnacle
-binned
-binning
-binocular
-binomial
-bio
-biochemical
-biochemist
-biochemistry
-biodegradability
-biodegrade
-biodiversity
-bioethics
-biofeedback
-biog
-biographer
-biographic
-biographical
-biography
-bioko
-biol
-biologic
-biological
-biologist
-biology
-biomass
-bionic
-bionically
-bionics
-biophysical
-biophysicist
-biophysics
-biopic
-biopsy
-biorhythm
-bios
-biosphere
-biotechnological
-biotechnology
-biotin
-bipartisan
-bipartisanship
-bipartite
-biped
-bipedal
-biplane
-bipolar
-bipolarity
-biracial
-birch
-bird
-birdbath
-birdbaths
-birdbrain
-birdcage
-birder
-birdhouse
-birdie
-birdieing
-birdlike
-birdlime
-birdseed
-birdseye
-birdsong
-birdwatcher
-birdying
-biretta
-birkenstock
-birmingham
-biro
-birth
-birthday
-birthmark
-birthplace
-birthrate
-birthright
-births
-birthstone
-biscay
-biscayne
-biscuit
-bisect
-bisection
-bisector
-bisexual
-bisexuality
-bishkek
-bishop
-bishopric
-bismarck
-bismark
-bismuth
-bison
-bisque
-bisquick
-bissau
-bistro
-bit
-bitch
-bitchily
-bitchiness
-bitchy
-bite
-biter
-biting
-bitmap
-bitnet
-bitten
-bitter
-bittern
-bitterness
-bitters
-bittersweet
-bitty
-bitumen
-bituminous
-bivalent
-bivalve
-bivouac
-bivouacked
-bivouacking
-biweekly
-biyearly
-biz
-bizarre
-bizet
-bjerknes
-bjork
-bk
-bl
-blab
-blabbed
-blabber
-blabbermouth
-blabbermouths
-blabbing
-black
-blackamoor
-blackball
-blackbeard
-blackberry
-blackbird
-blackboard
-blackburn
-blackcurrant
-blacken
-blackfeet
-blackfoot
-blackguard
-blackhead
-blacking
-blackish
-blackjack
-blackleg
-blacklist
-blackmail
-blackmailer
-blackness
-blackout
-blackpool
-blackshirt
-blacksmith
-blacksmiths
-blacksnake
-blackstone
-blackthorn
-blacktop
-blacktopped
-blacktopping
-blackwell
-bladder
-blade
-blag
-blagged
-blagging
-blah
-blahs
-blaine
-blair
-blake
-blame
-blameless
-blamelessness
-blameworthiness
-blameworthy
-blammo
-blanca
-blanch
-blanchard
-blanche
-blancmange
-bland
-blandish
-blandishment
-blandness
-blank
-blankenship
-blanket
-blankness
-blantyre
-blare
-blarney
-blase
-blaspheme
-blasphemer
-blasphemous
-blasphemy
-blast
-blaster
-blastoff
-blat
-blatancy
-blatant
-blather
-blatz
-blavatsky
-blaze
-blazer
-blazon
-bldg
-bleach
-bleached
-bleacher
-bleak
-bleakness
-blear
-blearily
-bleariness
-bleary
-bleat
-bleed
-bleeder
-bleeding
-bleep
-bleeper
-blemish
-blemished
-blench
-blend
-blender
-blenheim
-bless
-blessed
-blessedness
-blessing
-bletch
-blevins
-blew
-bligh
-blight
-blimey
-blimp
-blimpish
-blind
-blinder
-blindfold
-blinding
-blindness
-blindside
-blini
-blink
-blinker
-blintz
-blintze
-blip
-bliss
-blissful
-blissfulness
-blister
-blistering
-blistery
-blithe
-blitheness
-blither
-blithesome
-blitz
-blitzkrieg
-blivet
-blizzard
-bloat
-bloatware
-blob
-blobbed
-blobbing
-bloc
-bloch
-block
-block's
-blockade
-blockader
-blockage
-blockbuster
-blockbusting
-blocker
-blockhead
-blockhouse
-bloemfontein
-blog
-blogged
-blogger
-blogging
-bloke
-blokish
-blond
-blonde
-blondel
-blondie
-blondish
-blondness
-blood
-bloodbath
-bloodbaths
-bloodcurdling
-bloodhound
-bloodily
-bloodiness
-bloodless
-bloodlessness
-bloodletting
-bloodline
-bloodmobile
-bloodshed
-bloodshot
-bloodstain
-bloodstock
-bloodstream
-bloodsucker
-bloodsucking
-bloodthirstily
-bloodthirstiness
-bloodthirsty
-bloody
-bloom
-bloomer
-bloomfield
-bloomingdale
-bloomsbury
-bloop
-blooper
-blossom
-blossomy
-blot
-blotch
-blotchy
-blotted
-blotter
-blotting
-blotto
-blouse
-blow
-blower
-blowfly
-blowgun
-blowhard
-blowhole
-blowlamp
-blown
-blowout
-blowpipe
-blowtorch
-blowup
-blowy
-blowzy
-blt
-blu
-blubber
-blubbery
-blucher
-bludgeon
-blue
-bluebeard
-bluebell
-blueberry
-bluebird
-bluebonnet
-bluebottle
-bluefish
-bluegill
-bluegrass
-blueish
-bluejacket
-bluejeans
-blueness
-bluenose
-bluepoint
-blueprint
-bluestocking
-bluesy
-bluet
-bluetooth
-bluff
-bluffer
-bluffness
-bluing
-bluish
-blunder
-blunderbuss
-blunderer
-blunt
-bluntness
-blur
-blurb
-blurred
-blurriness
-blurring
-blurry
-blurt
-blush
-blusher
-bluster
-blusterer
-blusterous
-blustery
-blvd
-blythe
-bm
-bmw
-bo
-boa
-boadicea
-boar
-board
-boarder
-boarding
-boardinghouse
-boardroom
-boardwalk
-boas
-boast
-boaster
-boastful
-boastfulness
-boat
-boater
-boathouse
-boating
-boatload
-boatman
-boatmen
-boatswain
-boatyard
-bob
-bobbed
-bobbi
-bobbie
-bobbin
-bobbing
-bobbitt
-bobble
-bobby
-bobbysoxer
-bobcat
-bobolink
-bobsled
-bobsledded
-bobsledder
-bobsledding
-bobsleigh
-bobsleighs
-bobtail
-bobwhite
-boccaccio
-boccie
-bock
-bod
-bodacious
-bode
-bodega
-bodge
-bodhidharma
-bodhisattva
-bodice
-bodily
-bodkin
-body
-bodybuilder
-bodybuilding
-bodyguard
-bodysuit
-bodywork
-boeing
-boeotia
-boeotian
-boer
-boethius
-boffin
-boffo
-bog
-boga
-bogart
-bogey
-bogeyman
-bogeymen
-bogged
-bogging
-boggle
-boggy
-bogie
-bogometer
-bogon
-bogosity
-bogota
-bogotify
-bogus
-bogyman
-bogymen
-bohemia
-bohemian
-bohemianism
-bohr
-boil
-boiler
-boilermaker
-boilerplate
-boink
-boise
-boisterous
-boisterousness
-bojangles
-bola
-bold
-boldface
-boldness
-bole
-bolero
-boleyn
-bolivar
-bolivares
-bolivia
-bolivian
-boll
-bollard
-bollix
-bollocking
-bollocks
-bollywood
-bologna
-bolshevik
-bolshevism
-bolshevist
-bolshie
-bolshoi
-bolster
-bolt
-bolt's
-bolthole
-bolton
-boltzmann
-bolus
-bomb
-bombard
-bombardier
-bombardment
-bombast
-bombastic
-bombastically
-bombay
-bomber
-bombproof
-bombshell
-bombsite
-bonanza
-bonaparte
-bonaventure
-bonbon
-bonce
-bond
-bondage
-bondholder
-bonding
-bondman
-bondmen
-bondsman
-bondsmen
-bondwoman
-bondwomen
-bone
-bonehead
-boneless
-boner
-boneshaker
-bonfire
-bong
-bongo
-bonhoeffer
-bonhomie
-boniface
-boniness
-bonita
-bonito
-bonk
-bonn
-bonner
-bonnet
-bonneville
-bonnie
-bonny
-bono
-bonsai
-bonus
-bony
-boo
-boob
-booby
-boodle
-booger
-boogeyman
-boogeymen
-boogie
-boogieing
-boogieman
-boohoo
-book
-bookbinder
-bookbindery
-bookbinding
-bookcase
-bookend
-booker
-bookie
-booking
-bookish
-bookkeeper
-bookkeeping
-booklet
-bookmaker
-bookmaking
-bookmark
-bookmobile
-bookplate
-bookseller
-bookshelf
-bookshelves
-bookshop
-bookstall
-bookstore
-bookworm
-boole
-boolean
-boom
-boombox
-boomerang
-boon
-boondocks
-boondoggle
-boondoggler
-boone
-boonies
-boor
-boorish
-boorishness
-boost
-booster
-boot
-boot's
-bootblack
-bootee
-bootes
-booth
-booths
-bootlace
-bootleg
-bootlegged
-bootlegger
-bootlegging
-bootless
-bootstrap
-bootstrapped
-bootstrapping
-booty
-booze
-boozer
-boozy
-bop
-bopped
-bopping
-borax
-bordeaux
-bordello
-borden
-border
-borderland
-borderline
-bordon
-bore
-boreas
-boredom
-borehole
-borer
-borg
-borges
-borgia
-borglum
-boring
-boris
-bork
-borlaug
-born
-borne
-borneo
-borobudur
-borodin
-boron
-borough
-boroughs
-borrow
-borrower
-borrowing
-borscht
-borstal
-boru
-borzoi
-bosch
-bose
-bosh
-bosnia
-bosnian
-bosom
-bosom's
-bosomy
-bosporus
-boss
-bossily
-bossiness
-bossism
-bossy
-boston
-bostonian
-boswell
-bot
-botanic
-botanical
-botanist
-botany
-botch
-botcher
-both
-bother
-botheration
-bothersome
-botswana
-botticelli
-bottle
-bottleneck
-bottler
-bottom
-bottomless
-botulism
-boudoir
-bouffant
-bougainvillea
-bough
-boughs
-bought
-bouillabaisse
-bouillon
-boulder
-boules
-boulevard
-boulez
-bounce
-bouncer
-bouncily
-bounciness
-bouncy
-bound
-boundary
-bounden
-bounder
-boundless
-boundlessness
-bounteous
-bounteousness
-bountiful
-bountifulness
-bounty
-bouquet
-bourbaki
-bourbon
-bourgeois
-bourgeoisie
-bournemouth
-boustrophedon
-bout
-boutique
-boutonniere
-bouzouki
-bovary
-bovine
-bovver
-bow
-bowditch
-bowdlerization
-bowdlerize
-bowed
-bowel
-bowell
-bowen
-bower
-bowers
-bowery
-bowie
-bowl
-bowleg
-bowlegged
-bowler
-bowlful
-bowline
-bowling
-bowman
-bowmen
-bowsprit
-bowstring
-bowwow
-box
-boxcar
-boxer
-boxing
-boxlike
-boxroom
-boxwood
-boxy
-boy
-boycott
-boyd
-boyer
-boyfriend
-boyhood
-boyish
-boyishness
-boyle
-boysenberry
-bozo
-bp
-bpoe
-bps
-br
-bra
-brace
-bracelet
-bracer
-bracero
-bracken
-bracket
-brackish
-brackishness
-bract
-brad
-bradawl
-bradbury
-braddock
-bradford
-bradley
-bradly
-bradshaw
-bradstreet
-brady
-brae
-brag
-bragg
-braggadocio
-braggart
-bragged
-bragger
-bragging
-brahe
-brahma
-brahmagupta
-brahman
-brahmani
-brahmanism
-brahmaputra
-brahms
-braid
-braiding
-braille
-brain
-brainchild
-brainchildren
-braininess
-brainless
-brainpower
-brainstorm
-brainstorming
-brainteaser
-brainwash
-brainwashing
-brainwave
-brainy
-braise
-brake
-brakeman
-brakemen
-bramble
-brambly
-brampton
-bran
-branch
-branchlike
-brand
-branded
-brandeis
-branden
-brandenburg
-brander
-brandi
-brandie
-brandish
-brando
-brandon
-brandt
-brandy
-brant
-braque
-brash
-brashness
-brasilia
-brass
-brasserie
-brassiere
-brassily
-brassiness
-brassy
-brat
-bratislava
-brattain
-bratty
-bratwurst
-bravado
-brave
-braveness
-bravery
-bravo
-bravura
-brawl
-brawler
-brawn
-brawniness
-brawny
-bray
-braze
-brazen
-brazenness
-brazer
-brazier
-brazil
-brazilian
-brazos
-brazzaville
-breach
-bread
-breadbasket
-breadboard
-breadbox
-breadcrumb
-breadfruit
-breadline
-breadth
-breadths
-breadwinner
-break
-breakable
-breakage
-breakaway
-breakdown
-breaker
-breakfast
-breakfront
-breakneck
-breakout
-breakpoints
-breakspear
-breakthrough
-breakthroughs
-breakup
-breakwater
-bream
-breast
-breastbone
-breastfed
-breastfeed
-breastplate
-breaststroke
-breastwork
-breath
-breathalyze
-breathalyzer
-breathe
-breather
-breathing
-breathless
-breathlessness
-breaths
-breathtaking
-breathy
-brecht
-breckenridge
-bred
-breech
-breed
-breeder
-breeding
-breeze
-breezeway
-breezily
-breeziness
-breezy
-bremen
-brenda
-brendan
-brennan
-brenner
-brent
-brenton
-bret
-brethren
-breton
-brett
-breve
-brevet
-brevetted
-brevetting
-breviary
-brevity
-brew
-brewer
-brewery
-brewpub
-brewster
-brezhnev
-brian
-briana
-brianna
-bribe
-briber
-bribery
-brice
-brick
-brickbat
-brickie
-bricklayer
-bricklaying
-brickwork
-brickyard
-bridal
-bridalveil
-bride
-bridegroom
-bridesmaid
-bridge
-bridgeable
-bridgehead
-bridgeport
-bridger
-bridges
-bridget
-bridgetown
-bridgett
-bridgette
-bridgework
-bridgman
-bridle
-bridled
-bridleway
-brie
-brief
-brief's
-briefcase
-briefer
-briefing
-briefly
-briefness
-brier
-brig
-brigade
-brigadier
-brigadoon
-brigand
-brigandage
-brigantine
-briggs
-brigham
-bright
-brighten
-brightener
-brightness
-brighton
-brights
-brigid
-brigitte
-brill
-brilliance
-brilliancy
-brilliant
-brilliantine
-brillo
-brim
-brimful
-brimless
-brimmed
-brimming
-brimstone
-brindle
-brine
-bring
-bringer
-brininess
-brink
-brinkley
-brinkmanship
-briny
-brioche
-briquette
-brisbane
-brisk
-brisket
-briskness
-bristle
-bristly
-bristol
-brit
-britain
-britannia
-britannic
-britannica
-britches
-briticism
-british
-britisher
-britney
-briton
-britt
-brittany
-brittle
-brittleness
-brittney
-brno
-bro
-broach
-broad
-broadband
-broadcast
-broadcaster
-broadcasting
-broadcloth
-broaden
-broadloom
-broadminded
-broadness
-broadsheet
-broadside
-broadsword
-broadway
-brobdingnag
-brobdingnagian
-brocade
-broccoli
-brochette
-brochure
-brock
-brogan
-brogue
-broil
-broiler
-brokaw
-broke
-broken
-brokenhearted
-brokenness
-broker
-brokerage
-brolly
-bromide
-bromidic
-bromine
-bronc
-bronchi
-bronchial
-bronchitic
-bronchitis
-bronchus
-bronco
-broncobuster
-bronson
-bronte
-brontosaur
-brontosaurus
-bronx
-bronze
-brooch
-brood
-brooder
-broodily
-brooding
-broodmare
-broody
-brook
-brooke
-brooklet
-brooklyn
-brooks
-broom
-broomstick
-bros
-broth
-brothel
-brother
-brotherhood
-brotherliness
-broths
-brougham
-brought
-brouhaha
-brow
-browbeat
-brown
-browne
-brownfield
-brownian
-brownie
-brownish
-brownness
-brownout
-brownshirt
-brownstone
-brownsville
-browse
-browser
-brr
-brubeck
-bruce
-bruckner
-bruegel
-bruin
-bruise
-bruiser
-bruising
-bruit
-brummel
-brunch
-brunei
-bruneian
-brunelleschi
-brunet
-brunette
-brunhilde
-bruno
-brunswick
-brunt
-brush
-brushoff
-brushstroke
-brushwood
-brushwork
-brusque
-brusqueness
-brussels
-brut
-brutal
-brutality
-brutalization
-brutalize
-brute
-brutish
-brutishness
-brutus
-bryan
-bryant
-bryce
-brynner
-bryon
-brzezinski
-bs
-bsa
-bsd
-btu
-btw
-bu
-bub
-bubble
-bubblegum
-bubbly
-buber
-bubo
-buboes
-buccaneer
-buchanan
-bucharest
-buchenwald
-buchwald
-buck
-buckaroo
-buckboard
-bucket
-bucketful
-buckeye
-buckingham
-buckle
-buckle's
-buckler
-buckley
-buckner
-buckram
-bucksaw
-buckshot
-buckskin
-buckteeth
-bucktooth
-buckwheat
-bucolic
-bucolically
-bud
-budapest
-budded
-buddha
-buddhism
-buddhist
-budding
-buddy
-budge
-budgerigar
-budget
-budgetary
-budgie
-budweiser
-buff
-buffalo
-buffaloes
-buffer
-buffet
-buffoon
-buffoonery
-buffoonish
-buffy
-buford
-bug
-bug's
-bugaboo
-bugatti
-bugbear
-bugged
-bugger
-buggery
-bugging
-buggy
-bugle
-bugler
-bugzilla
-buick
-build
-builder
-building
-buildup
-built
-bujumbura
-bukhara
-bukharin
-bulawayo
-bulb
-bulbous
-bulfinch
-bulganin
-bulgar
-bulgari
-bulgaria
-bulgarian
-bulge
-bulgy
-bulimarexia
-bulimia
-bulimic
-bulk
-bulkhead
-bulkiness
-bulky
-bull
-bulldog
-bulldogged
-bulldogging
-bulldoze
-bulldozer
-bullet
-bulletin
-bulletproof
-bullfight
-bullfighter
-bullfighting
-bullfinch
-bullfrog
-bullhead
-bullheaded
-bullheadedness
-bullhorn
-bullion
-bullish
-bullishness
-bullock
-bullpen
-bullring
-bullshit
-bullshitted
-bullshitter
-bullshitting
-bullwhip
-bullwinkle
-bully
-bulrush
-bultmann
-bulwark
-bum
-bumbag
-bumble
-bumblebee
-bumbler
-bumf
-bummed
-bummer
-bummest
-bumming
-bump
-bumper
-bumph
-bumpiness
-bumpkin
-bumppo
-bumptious
-bumptiousness
-bumpy
-bun
-bunch
-bunche
-bunchy
-bunco
-bundesbank
-bundestag
-bundle
-bung
-bungalow
-bungee
-bunghole
-bungle
-bungler
-bunin
-bunion
-bunk
-bunk's
-bunker
-bunkhouse
-bunkum
-bunny
-bunsen
-bunt
-bunting
-bunuel
-bunyan
-buoy
-buoyancy
-buoyant
-bur
-burbank
-burberry
-burble
-burbs
-burch
-burden
-burden's
-burdensome
-burdock
-bureau
-bureaucracy
-bureaucrat
-bureaucratic
-bureaucratically
-bureaucratization
-bureaucratize
-burg
-burgeon
-burger
-burgess
-burgh
-burgher
-burghs
-burglar
-burglarize
-burglarproof
-burglary
-burgle
-burgomaster
-burgoyne
-burgundian
-burgundy
-burial
-burke
-burks
-burl
-burlap
-burlesque
-burliness
-burlington
-burly
-burma
-burmese
-burn
-burnable
-burner
-burnett
-burnish
-burnisher
-burnoose
-burnout
-burns
-burnside
-burnt
-burp
-burr
-burris
-burrito
-burro
-burroughs
-burrow
-burrower
-bursa
-bursae
-bursar
-bursary
-bursitis
-burst
-burt
-burton
-burundi
-burundian
-bury
-bus
-busboy
-busby
-busch
-bused
-busgirl
-bush
-bushel
-bushido
-bushiness
-bushing
-bushman
-bushmaster
-bushmen
-bushnell
-bushwhack
-bushwhacker
-bushy
-busily
-business
-businesslike
-businessman
-businessmen
-businessperson
-businesswoman
-businesswomen
-busing
-busk
-buskin
-busload
-buss
-bust
-buster
-bustle
-busty
-busy
-busybody
-busyness
-busywork
-but
-butane
-butch
-butcher
-butchery
-butler
-butt
-butte
-butted
-butter
-butterball
-buttercup
-butterfat
-butterfingered
-butterfingers
-butterfly
-buttermilk
-butternut
-butterscotch
-buttery
-butting
-buttock
-button
-button's
-buttonhole
-buttonwood
-buttress
-butty
-buxom
-buxtehude
-buy
-buyback
-buyer
-buyout
-buzz
-buzzard
-buzzer
-buzzword
-bx
-bxs
-by
-byblos
-bye
-byers
-bygone
-bylaw
-byline
-byob
-bypass
-bypath
-bypaths
-byplay
-byproduct
-byrd
-byre
-byroad
-byron
-byronic
-bystander
-byte
-byway
-byword
-byzantine
-byzantium
-c
-ca
-cab
-cabal
-cabala
-caballero
-cabana
-cabaret
-cabbage
-cabbed
-cabbing
-cabby
-cabdriver
-cabernet
-cabin
-cabinet
-cabinetmaker
-cabinetmaking
-cabinetry
-cabinetwork
-cable
-cablecast
-cablegram
-cabochon
-caboodle
-caboose
-cabot
-cabral
-cabrera
-cabrini
-cabriolet
-cabstand
-cacao
-cache
-cachepot
-cachet
-cackle
-cackler
-cacophonous
-cacophony
-cacti
-cactus
-cad
-cadaver
-cadaverous
-caddie
-caddish
-caddishness
-caddying
-cadence
-cadenza
-cadet
-cadette
-cadge
-cadger
-cadillac
-cadiz
-cadmium
-cadre
-caducei
-caduceus
-caedmon
-caerphilly
-caesar
-caesura
-cafe
-cafeteria
-cafetiere
-caff
-caffeinated
-caffeine
-caftan
-cage
-cagey
-cagier
-cagiest
-cagily
-caginess
-cagney
-cagoule
-cahokia
-cahoot
-cai
-caiaphas
-caiman
-cain
-cairn
-cairo
-caisson
-caitiff
-caitlin
-cajole
-cajolement
-cajoler
-cajolery
-cajun
-cake
-cakewalk
-cal
-calabash
-calaboose
-calais
-calamari
-calamine
-calamitous
-calamity
-calcareous
-calciferous
-calcification
-calcify
-calcimine
-calcine
-calcite
-calcium
-calculable
-calculate
-calculated
-calculating
-calculation
-calculator
-calculi
-calculus
-calcutta
-calder
-caldera
-calderon
-caldwell
-caleb
-caledonia
-calendar
-calender
-calf
-calfskin
-calgary
-calhoun
-cali
-caliban
-caliber
-calibrate
-calibration
-calibrator
-calico
-calicoes
-calif
-california
-californian
-californium
-caligula
-caliper
-caliph
-caliphate
-caliphs
-calisthenic
-calisthenics
-calk
-call
-calla
-callable
-callaghan
-callahan
-callao
-callas
-callback
-called
-caller
-callie
-calligrapher
-calligraphic
-calligraphist
-calligraphy
-calling
-calliope
-callisto
-callosity
-callous
-callousness
-callow
-callowness
-callus
-calm
-calmness
-caloocan
-caloric
-calorie
-calorific
-calumet
-calumniate
-calumniation
-calumniator
-calumnious
-calumny
-calvary
-calve
-calvert
-calvin
-calvinism
-calvinist
-calvinistic
-calypso
-calyx
-cam
-camacho
-camaraderie
-camber
-cambial
-cambium
-cambodia
-cambodian
-cambrian
-cambric
-cambridge
-camcorder
-camden
-came
-camel
-camelhair
-camellia
-camelopardalis
-camelot
-camembert
-cameo
-camera
-cameraman
-cameramen
-camerawoman
-camerawomen
-camerawork
-cameron
-cameroon
-cameroonian
-camiknickers
-camilla
-camille
-camisole
-camoens
-camouflage
-camouflager
-camp
-camp's
-campaign
-campaigner
-campanella
-campanile
-campanologist
-campanology
-campbell
-camper
-campfire
-campground
-camphor
-campinas
-camping
-campos
-campsite
-campus
-campy
-camry
-camshaft
-camus
-can
-can't
-canaan
-canaanite
-canad
-canada
-canadian
-canadianism
-canal
-canaletto
-canalization
-canalize
-canape
-canard
-canaries
-canary
-canasta
-canaveral
-canberra
-cancan
-cancel
-canceler
-cancellation
-cancer
-cancerous
-cancun
-candace
-candelabra
-candelabrum
-candice
-candid
-candida
-candidacy
-candidate
-candidature
-candide
-candidness
-candle
-candlelight
-candlelit
-candlepower
-candler
-candlestick
-candlewick
-candor
-candy
-candyfloss
-cane
-canebrake
-caner
-canine
-canister
-canker
-cankerous
-cannabis
-canned
-cannelloni
-cannery
-cannes
-cannibal
-cannibalism
-cannibalistic
-cannibalization
-cannibalize
-cannily
-canniness
-canning
-cannon
-cannonade
-cannonball
-cannot
-canny
-canoe
-canoeing
-canoeist
-canola
-canon
-canonical
-canonization
-canonize
-canoodle
-canopus
-canopy
-canst
-cant
-cant's
-cantabile
-cantabrigian
-cantaloupe
-cantankerous
-cantankerousness
-cantata
-canteen
-canter
-canterbury
-cantered
-cantering
-canticle
-cantilever
-canto
-canton
-cantonal
-cantonese
-cantonment
-cantor
-cantrell
-cantu
-canute
-canvas
-canvasback
-canvass
-canvasser
-canyon
-cap
-capabilities
-capability
-capablanca
-capable
-capably
-capacious
-capaciousness
-capacitance
-capacities
-capacitor
-capacity
-caparison
-cape
-capek
-capella
-caper
-capeskin
-capet
-capetian
-capetown
-caph
-capillarity
-capillary
-capistrano
-capital
-capitalism
-capitalist
-capitalistic
-capitalistically
-capitalization
-capitalize
-capitation
-capitol
-capitoline
-capitulate
-capitulation
-caplet
-capo
-capon
-capone
-capote
-capped
-capping
-cappuccino
-capra
-capri
-caprice
-capricious
-capriciousness
-capricorn
-capsicum
-capsize
-capstan
-capstone
-capsular
-capsule
-capsulize
-capt
-captain
-captaincy
-caption
-captious
-captiousness
-captivate
-captivation
-captivator
-captive
-captivity
-captor
-capture
-capuchin
-capulet
-car
-cara
-caracalla
-caracas
-carafe
-caramel
-caramelize
-carapace
-carat
-caravaggio
-caravan
-caravansary
-caravel
-caraway
-carbide
-carbine
-carbohydrate
-carbolic
-carboloy
-carbon
-carbonaceous
-carbonate
-carbonation
-carboniferous
-carbonize
-carborundum
-carboy
-carbuncle
-carbuncular
-carburetor
-carcass
-carcinogen
-carcinogenic
-carcinogenicity
-carcinoma
-card
-cardamom
-cardamon
-cardboard
-cardenas
-carder
-cardholder
-cardiac
-cardie
-cardiff
-cardigan
-cardin
-cardinal
-cardiogram
-cardiograph
-cardiographs
-cardiologist
-cardiology
-cardiopulmonary
-cardiovascular
-cardozo
-cardsharp
-cardsharper
-care
-careen
-career
-careerism
-careerist
-carefree
-careful
-carefuller
-carefullest
-carefulness
-caregiver
-careless
-carelessness
-carer
-caress
-caret
-caretaker
-careworn
-carey
-carfare
-cargo
-cargoes
-carhop
-carib
-caribbean
-caribou
-caricature
-caricaturist
-caries
-carillon
-carina
-caring
-carious
-carissa
-carjack
-carjacker
-carjacking
-carl
-carla
-carlene
-carlin
-carlo
-carload
-carlsbad
-carlson
-carlton
-carly
-carlyle
-carmela
-carmella
-carmelo
-carmen
-carmichael
-carmine
-carnage
-carnal
-carnality
-carnap
-carnation
-carnegie
-carnelian
-carney
-carnival
-carnivore
-carnivorous
-carnivorousness
-carnot
-carny
-carob
-carol
-carole
-caroler
-carolina
-caroline
-carolingian
-carolinian
-carolyn
-carom
-carotene
-carotid
-carousal
-carouse
-carousel
-carouser
-carp
-carpal
-carpathian
-carpel
-carpenter
-carpentry
-carper
-carpet
-carpetbag
-carpetbagged
-carpetbagger
-carpetbagging
-carpeting
-carpi
-carpool
-carport
-carpus
-carr
-carranza
-carrel
-carriage
-carriageway
-carrie
-carrier
-carrillo
-carrion
-carroll
-carrot
-carroty
-carry
-carryall
-carrycot
-carryout
-carryover
-carsick
-carsickness
-carson
-cart
-cartage
-cartel
-carter
-cartesian
-carthage
-carthaginian
-carthorse
-cartier
-cartilage
-cartilaginous
-cartload
-cartographer
-cartographic
-cartography
-carton
-cartoon
-cartoonist
-cartridge
-cartwheel
-cartwright
-caruso
-carve
-carver
-carvery
-carving
-cary
-caryatid
-casaba
-casablanca
-casals
-casandra
-casanova
-cascade
-cascades
-cascara
-case
-casebook
-cased
-caseharden
-casein
-caseload
-casement
-casework
-caseworker
-casey
-cash
-cashbook
-cashew
-cashier
-cashless
-cashmere
-casing
-casino
-casio
-cask
-casket
-caspar
-caspian
-cassandra
-cassatt
-cassava
-casserole
-cassette
-cassia
-cassie
-cassiopeia
-cassius
-cassock
-cassowary
-cast
-castaneda
-castanet
-castaway
-caste
-castellated
-caster
-castigate
-castigation
-castigator
-castillo
-casting
-castle
-castlereagh
-castoff
-castor
-castrate
-castration
-castries
-castro
-casual
-casualness
-casualty
-casuist
-casuistic
-casuistry
-cat
-cataclysm
-cataclysmal
-cataclysmic
-catacomb
-catafalque
-catalan
-catalepsy
-cataleptic
-catalina
-catalog
-cataloger
-catalonia
-catalpa
-catalysis
-catalyst
-catalytic
-catalyze
-catamaran
-catapult
-cataract
-catarrh
-catastrophe
-catastrophic
-catastrophically
-catatonia
-catatonic
-catawba
-catbird
-catboat
-catcall
-catch
-catchall
-catcher
-catchment
-catchpenny
-catchphrase
-catchword
-catchy
-catechism
-catechist
-catechize
-categorical
-categorization
-categorize
-category
-cater
-catercorner
-caterer
-caterpillar
-caterwaul
-catfish
-catgut
-catharses
-catharsis
-cathartic
-cathay
-cathedral
-cather
-catherine
-catheter
-catheterize
-cathleen
-cathode
-cathodic
-catholic
-catholicism
-catholicity
-cathryn
-cathy
-catiline
-cation
-catkin
-catlike
-catnap
-catnapped
-catnapping
-catnip
-cato
-catskill
-catskills
-catsuit
-catt
-cattail
-catted
-cattery
-cattily
-cattiness
-catting
-cattle
-cattleman
-cattlemen
-catty
-catullus
-catv
-catwalk
-caucasian
-caucasoid
-caucasus
-cauchy
-caucus
-caudal
-caught
-cauldron
-cauliflower
-caulk
-caulker
-causal
-causality
-causation
-causative
-cause
-causeless
-causer
-causerie
-causeway
-caustic
-caustically
-causticity
-cauterization
-cauterize
-caution
-cautionary
-cautious
-cautiousness
-cavalcade
-cavalier
-cavalry
-cavalryman
-cavalrymen
-cave
-caveat
-caveman
-cavemen
-cavendish
-cavern
-cavernous
-caviar
-cavil
-caviler
-caving
-cavity
-cavort
-cavour
-caw
-caxton
-cay
-cayenne
-cayman
-cayuga
-cayuse
-cb
-cbc
-cbs
-cc
-cctv
-ccu
-cd
-cdc
-cdt
-ce
-cease
-ceasefire
-ceaseless
-ceaselessness
-ceausescu
-cebu
-cebuano
-ceca
-cecal
-cecelia
-cecil
-cecile
-cecilia
-cecily
-cecum
-cedar
-cede
-ceder
-cedilla
-cedric
-ceilidh
-ceilidhs
-ceiling
-celandine
-celeb
-celebrant
-celebrate
-celebration
-celebrator
-celebratory
-celebrity
-celeriac
-celerity
-celery
-celesta
-celeste
-celestial
-celia
-celibacy
-celibate
-celina
-cell
-cellar
-cellini
-cellist
-cellmate
-cello
-cellophane
-cellphone
-cellular
-cellulite
-celluloid
-cellulose
-celsius
-celt
-celtic
-cement
-cementer
-cementum
-cemetery
-cenobite
-cenobitic
-cenotaph
-cenotaphs
-cenozoic
-censer
-censor
-censored
-censorial
-censorious
-censoriousness
-censorship
-censure
-censurer
-census
-cent
-centaur
-centaurus
-centavo
-centenarian
-centenary
-centennial
-center
-centerboard
-centerfold
-centerpiece
-centigrade
-centigram
-centiliter
-centime
-centimeter
-centipede
-central
-centralism
-centralist
-centrality
-centralization
-centralize
-centralizer
-centrifugal
-centrifuge
-centripetal
-centrism
-centrist
-centurion
-century
-ceo
-cephalic
-cepheid
-cepheus
-ceramic
-ceramicist
-ceramics
-ceramist
-cerberus
-cereal
-cerebellar
-cerebellum
-cerebra
-cerebral
-cerebrate
-cerebration
-cerebrum
-cerement
-ceremonial
-ceremonious
-ceremoniousness
-ceremony
-cerenkov
-ceres
-cerf
-cerise
-cerium
-cermet
-cert
-certain
-certainty
-certifiable
-certifiably
-certificate
-certification
-certify
-certitude
-certitudes
-cerulean
-cervantes
-cervical
-cervices
-cervix
-cesar
-cesarean
-cesium
-cessation
-cession
-cessna
-cesspit
-cesspool
-cetacean
-cetus
-ceylon
-ceylonese
-cezanne
-cf
-cfc
-cfo
-cg
-ch
-ch'in
-chablis
-chad
-chadian
-chadwick
-chafe
-chaff
-chaffinch
-chagall
-chagrin
-chain
-chain's
-chainsaw
-chair
-chairlift
-chairman
-chairmanship
-chairmen
-chairperson
-chairwoman
-chairwomen
-chaise
-chaitanya
-chaitin
-chalcedony
-chaldea
-chaldean
-chalet
-chalice
-chalk
-chalkboard
-chalkiness
-chalky
-challenge
-challenged
-challenger
-challis
-chamber
-chamberlain
-chambermaid
-chambers
-chambray
-chameleon
-chamois
-chamomile
-champ
-champagne
-champion
-championship
-champlain
-champollion
-chan
-chance
-chancel
-chancellery
-chancellor
-chancellorship
-chancellorsville
-chancery
-chanciness
-chancre
-chancy
-chandelier
-chandigarh
-chandler
-chandon
-chandra
-chandragupta
-chandrasekhar
-chanel
-chaney
-chang
-changchun
-change
-changeability
-changeable
-changeableness
-changeably
-changed
-changeless
-changeling
-changeover
-changer
-changing
-changsha
-channel
-channelization
-channelize
-chanson
-chant
-chanter
-chanteuse
-chantey
-chanticleer
-chantilly
-chaos
-chaotic
-chaotically
-chap
-chaparral
-chapati
-chapatti
-chapbook
-chapeau
-chapel
-chaperon
-chaperonage
-chaperoned
-chaplain
-chaplaincy
-chaplet
-chaplin
-chapman
-chappaquiddick
-chapped
-chapping
-chappy
-chapter
-chapultepec
-char
-charabanc
-character
-characterful
-characteristic
-characteristically
-characterization
-characterize
-characterless
-charade
-charbray
-charbroil
-charcoal
-chard
-chardonnay
-charge
-chargeable
-charged
-charger
-charily
-chariness
-chariot
-charioteer
-charisma
-charismatic
-charitable
-charitableness
-charitably
-charity
-charlady
-charlatan
-charlatanism
-charlatanry
-charlemagne
-charlene
-charles
-charleston
-charley
-charlie
-charlotte
-charlottetown
-charm
-charmaine
-charmer
-charmin
-charming
-charmless
-charolais
-charon
-charred
-charring
-chart
-charted
-charter
-charter's
-charterer
-chartism
-chartres
-chartreuse
-charwoman
-charwomen
-chary
-charybdis
-chase
-chaser
-chasity
-chasm
-chassis
-chaste
-chasten
-chasteness
-chastise
-chastisement
-chastiser
-chastity
-chasuble
-chat
-chateau
-chateaubriand
-chateaux
-chatelaine
-chatline
-chattahoochee
-chattanooga
-chatted
-chattel
-chatter
-chatterbox
-chatterer
-chatterley
-chatterton
-chattily
-chattiness
-chatting
-chatty
-chaucer
-chauffeur
-chauncey
-chautauqua
-chauvinism
-chauvinist
-chauvinistic
-chauvinistically
-chavez
-chayefsky
-che
-cheap
-cheapen
-cheapness
-cheapo
-cheapskate
-cheat
-cheater
-chechen
-chechnya
-check
-checkbook
-checked
-checker
-checkerboard
-checkers
-checklist
-checkmate
-checkoff
-checkout
-checkpoint
-checkroom
-checkup
-cheddar
-cheek
-cheekbone
-cheekily
-cheekiness
-cheeky
-cheep
-cheer
-cheerer
-cheerful
-cheerfuller
-cheerfullest
-cheerfulness
-cheerily
-cheeriness
-cheerio
-cheerios
-cheerleader
-cheerless
-cheerlessness
-cheery
-cheese
-cheeseboard
-cheeseburger
-cheesecake
-cheesecloth
-cheeseparing
-cheesiness
-cheesy
-cheetah
-cheetahs
-cheetos
-cheever
-chef
-chekhov
-chekhovian
-chelsea
-chelyabinsk
-chem
-chemical
-chemise
-chemist
-chemistry
-chemo
-chemotherapeutic
-chemotherapy
-chemurgy
-chen
-cheney
-chengdu
-chenille
-chennai
-cheops
-cheri
-cherie
-cherish
-chernenko
-chernobyl
-chernomyrdin
-cherokee
-cheroot
-cherry
-chert
-cherub
-cherubic
-cherubim
-chervil
-cheryl
-chesapeake
-cheshire
-chess
-chessboard
-chessman
-chessmen
-chest
-chester
-chesterfield
-chesterton
-chestful
-chestnut
-chesty
-chevalier
-cheviot
-chevrolet
-chevron
-chevy
-chew
-chewer
-chewiness
-chewy
-cheyenne
-chg
-chge
-chi
-chianti
-chiaroscuro
-chiba
-chibcha
-chic
-chicago
-chicagoan
-chicana
-chicane
-chicanery
-chicano
-chichi
-chick
-chickadee
-chickasaw
-chicken
-chickenfeed
-chickenhearted
-chickenpox
-chickenshit
-chickpea
-chickweed
-chicle
-chiclets
-chicness
-chicory
-chide
-chiding
-chief
-chiefdom
-chieftain
-chieftainship
-chiffon
-chiffonier
-chigger
-chignon
-chihuahua
-chilblain
-child
-childbearing
-childbirth
-childbirths
-childcare
-childhood
-childish
-childishness
-childless
-childlessness
-childlike
-childminder
-childminding
-childproof
-children
-chile
-chilean
-chili
-chilies
-chill
-chiller
-chilliness
-chilling
-chillness
-chilly
-chimborazo
-chime
-chimer
-chimera
-chimeric
-chimerical
-chimney
-chimp
-chimpanzee
-chimu
-chin
-china
-chinatown
-chinaware
-chinchilla
-chine
-chinese
-chink
-chinless
-chinned
-chinning
-chino
-chinook
-chinstrap
-chintz
-chintzy
-chinwag
-chip
-chipboard
-chipewyan
-chipmunk
-chipolata
-chipped
-chippendale
-chipper
-chippewa
-chippie
-chipping
-chippy
-chiquita
-chirico
-chirography
-chiropodist
-chiropody
-chiropractic
-chiropractor
-chirp
-chirpily
-chirpy
-chirrup
-chisel
-chiseler
-chisholm
-chisinau
-chit
-chitchat
-chitchatted
-chitchatting
-chitin
-chitinous
-chittagong
-chitterlings
-chi