Merge from Tracemonkey.
authorDavid Mandelin <dmandelin@mozilla.com>
Mon, 02 Aug 2010 15:55:29 -0700
changeset 53282 6e65c8d205ae157b7efbbe889c1a0d2f2d0e81d9
parent 53275 957152c7f3893905ec2c5f8b9bce8296c5e9aa4a (current diff)
parent 48808 617b92ed8ced5c32228b5bf6b420d44afec5aef3 (diff)
child 53283 8eaa9d6031b32e755c574f96224fa9d2109494ac
push id15660
push userrsayre@mozilla.com
push dateSat, 11 Sep 2010 19:16:24 +0000
treeherdermozilla-central@f1bd314e64ac [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone2.0b3pre
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 from Tracemonkey.
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload.js
browser/themes/pinstripe/browser/places/livemarkFolder.png
build/automation.py.in
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
content/events/src/nsEventListenerManager.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/interfaces/html/nsIDOMNSHTMLAreaElement.idl
dom/interfaces/html/nsIDOMNSHTMLAreaElement2.idl
dom/interfaces/html/nsIDOMNSHTMLButtonElement.idl
dom/interfaces/html/nsIDOMNSHTMLLabelElement.idl
dom/interfaces/html/nsIDOMNSHTMLOptionElement.idl
dom/interfaces/html/nsIDOMNSHTMLScriptElement.idl
dom/interfaces/html/nsIDOMNSHTMLSelectElement.idl
intl/chardet/public/nsMetaCharsetCID.h
js/src/Makefile.in
js/src/config/autoconf.mk.in
js/src/config/rules.mk
js/src/configure.in
js/src/jsapi-tests/tests.h
js/src/jsapi.cpp
js/src/jsarray.cpp
js/src/jsarray.h
js/src/jsatom.cpp
js/src/jsatom.h
js/src/jsbuiltins.cpp
js/src/jsbuiltins.h
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jsdbgapi.cpp
js/src/jsdbgapi.h
js/src/jsemit.cpp
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsgcchunk.cpp
js/src/jshashtable.h
js/src/jsinterp.cpp
js/src/jsinterp.h
js/src/jsnum.cpp
js/src/jsnum.h
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/json.cpp
js/src/jsopcode.cpp
js/src/jsopcode.tbl
js/src/jsparse.cpp
js/src/jsproxy.cpp
js/src/jsscan.cpp
js/src/jsscope.cpp
js/src/jsscope.h
js/src/jsscopeinlines.h
js/src/jsscript.cpp
js/src/jsstr.cpp
js/src/jsstr.h
js/src/jstracer.cpp
js/src/jstypedarray.cpp
js/src/jsval.h
js/src/jsvalue.h
js/src/jsvector.h
js/src/jsxdrapi.h
js/src/methodjit/Compiler.cpp
js/src/methodjit/Compiler.h
js/src/methodjit/FastOps.cpp
js/src/methodjit/StubCalls.cpp
js/src/methodjit/StubCalls.h
js/src/njs
js/src/shell/js.cpp
js/src/tests/jstests.py
js/src/xpconnect/src/dom_quickstubs.qsconf
modules/libpr0n/src/imgContainerRequest.cpp
modules/libpr0n/src/imgContainerRequest.h
netwerk/test/unit/test_redirect_caching.js
toolkit/components/ctypes/Module.cpp
toolkit/components/ctypes/Module.h
toolkit/mozapps/installer/windows/nsis/preprocess-locale.pl
toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin
--- a/accessible/src/Makefile.in
+++ b/accessible/src/Makefile.in
@@ -70,9 +70,9 @@ endif
 
 ifndef DISABLE_XFORMS_HOOKS
 DIRS +=   xforms
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 libs::
-	$(INSTALL) $(PLATFORM_DIR)/$(LIB_PREFIX)accessibility_toolkit_s.$(LIB_SUFFIX) .
+	$(INSTALL) $(PLATFORM_DIR)/$(LIB_PREFIX)accessibility_toolkit_s.$(LIB_SUFFIX) $(wildcard $(PLATFORM_DIR)/$(LIB_PREFIX)accessibility_toolkit_s.$(LIB_SUFFIX).fake) .
--- a/accessible/src/html/nsHTMLFormControlAccessible.cpp
+++ b/accessible/src/html/nsHTMLFormControlAccessible.cpp
@@ -43,17 +43,16 @@
 #include "nsRelUtils.h"
 #include "nsTextEquivUtils.h"
 
 #include "nsIDOMDocument.h"
 #include "nsIDOMNSHTMLInputElement.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMNSHTMLElement.h"
 #include "nsIDOMNSEditableElement.h"
-#include "nsIDOMNSHTMLButtonElement.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMHTMLLegendElement.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsIEditor.h"
 #include "nsIFrame.h"
 #include "nsINameSpaceManager.h"
 #include "nsISelectionController.h"
 #include "jsapi.h"
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/content/all-studies-window.js
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/content/all-studies-window.js
@@ -366,17 +366,28 @@ var TestPilotXulWindow = {
       if (task.status >= TaskConstants.STATUS_SUBMITTED) {
         if (task.taskType == TaskConstants.TYPE_RESULTS) {
           let maintask = TestPilotSetup.getTaskById(task.relatedStudyId);
           if (maintask && maintask.status >= TaskConstants.STATUS_SUBMITTED) {
             this.addThanksMessage(statusVbox);
           }
         } else {
           if (task.status == TaskConstants.STATUS_MISSED) {
-            // TODO use Sean's icon for missed studies
+            // Icon for missed studies
+            let hbox = document.createElement("hbox");
+            newRow.setAttribute("class", "tp-opted-out");
+            statusVbox.appendChild(this.makeSpacer());
+            statusVbox.appendChild(hbox);
+            this.addLabel(
+              statusVbox,
+              this._stringBundle.getString("testpilot.studiesWindow.missedStudy"));
+            statusVbox.appendChild(this.makeSpacer());
+            hbox.appendChild(this.makeSpacer());
+            this.addImg(hbox, "study-missed");
+            hbox.appendChild(this.makeSpacer());
           } else {
             this.addThanksMessage(statusVbox);
             numFinishedStudies ++;
           }
         }
       }
       let spacer = document.createElement("spacer");
       spacer.setAttribute("flex", "1");
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/content/browser.css
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/content/browser.css
@@ -95,16 +95,23 @@ image.study-submitted {
 
 image.study-canceled {
   list-style-image: url("chrome://testpilot/skin/status-ejected.png");
   height: 32px;
   width: 64px;
   margin-right: 8px;
 }
 
+image.study-missed {
+  list-style-image: url("chrome://testpilot/skin/status-missed.png");
+  height: 32px;
+  width: 64px;
+  margin-right: 8px;
+}
+
 image.new-study {
   list-style-image: url("chrome://testpilot/skin/tp-study-48x48.png");
   height: 48px;
   width: 48px;
   margin-right: 8px;
 }
 
 image.new-results {
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/install.rdf
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/install.rdf
@@ -1,24 +1,24 @@
 <?xml version="1.0"?>
 
 <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
      xmlns:em="http://www.mozilla.org/2004/em-rdf#">
   <Description about="urn:mozilla:install-manifest">
     <em:id>testpilot@labs.mozilla.com</em:id>
-    <em:version>1.0</em:version>
+    <em:version>1.0.1</em:version>
     <em:type>2</em:type>
 
     <!-- Target Application this extension can install into, 
          with minimum and maximum supported versions. --> 
     <em:targetApplication>
       <Description>
         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
         <em:minVersion>3.5</em:minVersion>
-        <em:maxVersion>4.0b2</em:maxVersion>
+        <em:maxVersion>4.0b3</em:maxVersion>
       </Description>
     </em:targetApplication>
    
     <!-- Front End MetaData -->
     <em:name>Feedback</em:name>
     <em:description>Help make Firefox better by giving feedback.</em:description>
     <em:creator>Mozilla Corporation</em:creator>
     <em:homepageURL>http://testpilot.mozillalabs.com/</em:homepageURL>
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/jar-code-store.js
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/jar-code-store.js
@@ -125,48 +125,52 @@ JarStore.prototype = {
     // s now contains your hash in hex
 
     return (s == expectedHash);
   },
 
   saveJarFile: function( filename, rawData, expectedHash ) {
     console.info("Saving a JAR file as " + filename + " hash = " + expectedHash);
     // rawData is a string of binary data representing a jar file
+    let jarFile;
     try {
-    let jarFile = this._baseDir.clone();
+      jarFile = this._baseDir.clone();
       // filename may have directories in it; use just the last part
       jarFile.append(filename.split("/").pop());
 
       // If a file of that name already exists, remove it!
       if (jarFile.exists()) {
         jarFile.remove(false);
       }
-    // From https://developer.mozilla.org/en/Code_snippets/File_I%2f%2fO#Getting_special_files
-    jarFile.create( Ci.nsIFile.NORMAL_FILE_TYPE, 600);
-    let stream = Cc["@mozilla.org/network/safe-file-output-stream;1"].
-                    createInstance(Ci.nsIFileOutputStream);
-    stream.init(jarFile, 0x04 | 0x08 | 0x20, 0600, 0); // readwrite, create, truncate
-
-    stream.write(rawData, rawData.length);
-    if (stream instanceof Ci.nsISafeOutputStream) {
-      stream.finish();
-    } else {
-      stream.close();
-    }
-    // Verify hash; if it's good, index and set last modified time.
-    // If not good, remove it.
-    if (this._verifyJar(jarFile, expectedHash)) {
-      this._indexJar(jarFile);
-      this._lastModified[jarFile.leafName] = jarFile.lastModifiedTime;
-    } else {
-      console.warn("Bad JAR file, doesn't match hash: " + expectedHash);
-      jarFile.remove(false);
-    }
+      // From https://developer.mozilla.org/en/Code_snippets/File_I%2f%2fO#Getting_special_files
+      jarFile.create( Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
+      let stream = Cc["@mozilla.org/network/safe-file-output-stream;1"].
+                      createInstance(Ci.nsIFileOutputStream);
+      stream.init(jarFile, 0x04 | 0x08 | 0x20, 0600, 0); // readwrite, create, truncate
+      stream.write(rawData, rawData.length);
+      if (stream instanceof Ci.nsISafeOutputStream) {
+        stream.finish();
+      } else {
+        stream.close();
+      }
+      // Verify hash; if it's good, index and set last modified time.
+      // If not good, remove it.
+      if (this._verifyJar(jarFile, expectedHash)) {
+        this._indexJar(jarFile);
+        this._lastModified[jarFile.leafName] = jarFile.lastModifiedTime;
+      } else {
+        console.warn("Bad JAR file, doesn't match hash: " + expectedHash);
+        jarFile.remove(false);
+      }
     } catch(e) {
       console.warn("Error in saving jar file: " + e);
+      // Remove any partially saved file
+      if (jarFile.exists()) {
+        jarFile.remove(false);
+      }
     }
   },
 
   resolveModule: function(root, path) {
     // Root will be null if require() was done by absolute path.
     if (root != null) {
       // TODO I don't think we need to do anything special here.
     }
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/remote-experiment-loader.js
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/remote-experiment-loader.js
@@ -242,83 +242,226 @@ exports.RemoteExperimentLoader.prototype
       if(set["default"]) {
         studiesToLoad.push(set["default"]);
       }
       // If none of those are there, load nothing.
     }
     return studiesToLoad;
   },
 
+  _executeFreshIndexFile: function(data, callback) {
+    try {
+      data = JSON.parse(data);
+    } catch (e) {
+      this._logger.warn("Error parsing index.json: " + e );
+      callback(false);
+      return;
+    }
+
+    // Cache study results and legacy studies.
+    this._studyResults = data.results;
+    this._legacyStudies = data.legacy;
+
+    /* Go through each record indicated in index.json for our locale;
+     * download the specified .jar file (replacing any version on disk)
+     */
+    let jarFiles = this.getLocalizedStudyInfo(data.new_experiments);
+    let numFilesToDload = jarFiles.length;
+    let self = this;
+
+    for each (let j in jarFiles) {
+      let filename = j.jarfile;
+      let hash = j.hash;
+      if (j.studyfile) {
+        this._experimentFileNames.push(j.studyfile);
+      }
+      this._logger.trace("I'm gonna go try to get the code for " + filename);
+      let modDate = this._jarStore.getFileModifiedDate(filename);
+
+      this._fileGetter(resolveUrl(this._baseUrl, filename),
+      function onDone(code) {
+        // code will be non-null if there is actually new code to download.
+        if (code) {
+          self._logger.info("Downloaded jar file " + filename);
+          self._jarStore.saveJarFile(filename, code, hash);
+          self._logger.trace("Saved code for: " + filename);
+        } else {
+          self._logger.info("Nothing to download for " + filename);
+        }
+        numFilesToDload--;
+        if (numFilesToDload == 0) {
+          self._logger.trace("Calling callback.");
+          callback(true);
+        }
+      }, modDate);
+    }
+  },
+
+  _executeCachedIndexFile: function(data) {
+    /* Working with a cached index file = follow its instructions except
+     * don't try to download anything - just work with the jar files already
+     * on disk. There's a lot of shared code between this and _executeFreshIndexFile;
+     * refactor?*/
+    try {
+      data = JSON.parse(data);
+    } catch (e) {
+      this._logger.warn("Error parsing index.json: " + e );
+      return false;
+    }
+    // Read study results and legacy studies from index.
+    this._studyResults = data.results;
+    this._legacyStudies = data.legacy;
+
+    // Read names of experiment modules from index.
+    let jarFiles = this.getLocalizedStudyInfo(data.new_experiments);
+    for each (let j in jarFiles) {
+      let filename = j.jarfile;
+      let hash = j.hash;
+      if (j.studyfile) {
+        this._experimentFileNames.push(j.studyfile);
+      }
+    }
+    return true;
+  },
+
+  // TODO a bad thing that can go wrong: If we have a net connection but the index file
+  // has not changed, we currently don't try to download anything...
+
+  // Another bad thing: If there's a jar download that's corrupt or unreadable or has
+    // the wrong permissions or something, we need to kill it and download a new one.
+
+  // WTF every jar file I'm downloading appears as 0 bytes with __x__x___ permissions!
+
+  _cachedIndexNsiFile: null,
+  get cachedIndexNsiFile() {
+    if (!this._cachedIndexNsiFile) {
+      try {
+        let file = Cc["@mozilla.org/file/directory_service;1"].
+                         getService(Ci.nsIProperties).
+                         get("ProfD", Ci.nsIFile);
+        file.append("TestPilotExperimentFiles"); // TODO this name should go in pref?
+        // Make sure there's a directory with this name; delete any non-directory
+        // file that's in the way.
+        if (file.exists() && !file.isDirectory()) {
+          file.remove(false);
+        }
+        if (!file.exists()) {
+          file.create(Ci.nsIFile.DIRECTORY_TYPE, 0777);
+        }
+        file.append("index.json");
+        this._cachedIndexNsiFile = file;
+      } catch(e) {
+        console.warn("Error creating directory for cached index file: " + e);
+      }
+    }
+    return this._cachedIndexNsiFile;
+  },
+
+  _cacheIndexFile: function(data) {
+    // write data to disk as basedir/index.json
+    try {
+      let file = this.cachedIndexNsiFile;
+      if (file == null) {
+        console.warn("Can't cache index file because directory does not exist.");
+        return;
+      }
+      if (file.exists()) {
+        file.remove(false);
+      }
+      file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
+      // file is nsIFile, data is a string
+      let foStream = Cc["@mozilla.org/network/file-output-stream;1"].
+                               createInstance(Ci.nsIFileOutputStream);
+
+      foStream.init(file, 0x02 | 0x08 | 0x20, 0666, 0);
+      // write, create, truncate
+      let converter = Cc["@mozilla.org/intl/converter-output-stream;1"].
+                                createInstance(Ci.nsIConverterOutputStream);
+      converter.init(foStream, "UTF-8", 0, 0);
+      converter.writeString(data);
+      converter.close(); // this closes foStream too
+    } catch(e) {
+      console.warn("Error cacheing index file: " + e);
+    }
+  },
+
+  // https://developer.mozilla.org/en/Table_Of_Errors
+  _loadCachedIndexFile: function() {
+    // If basedir/index.json exists, read it and return its data
+    // Otherwise, return false
+    let file = this.cachedIndexNsiFile;
+    if (file == null) {
+      console.warn("Can't load cached index file because directory does not exist.");
+      return false;
+    }
+    if (file.exists()) {
+      try {
+        let data = "";
+        let fstream = Cc["@mozilla.org/network/file-input-stream;1"].
+                          createInstance(Ci.nsIFileInputStream);
+        let cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].
+                          createInstance(Ci.nsIConverterInputStream);
+        fstream.init(file, -1, 0, 0);
+        cstream.init(fstream, "UTF-8", 0, 0);
+        let str = {};
+        while (cstream.readString(4096, str) != 0) {
+          data += str.value;
+        }
+        cstream.close(); // this closes fstream too
+        return data;
+      } catch(e) {
+        console.warn("Error occured in reading cached index file: " + e);
+        return false;
+      }
+    } else {
+      console.warn("Trying to load cached index file but it does not exist.");
+      return false;
+    }
+  },
+
   checkForUpdates: function(callback) {
+    // Check for surveys and studies.  Entry point for all download and execution of
+    // remote code.
     /* Callback will be called with true or false
      * to let us know whether there are any updates, so that client code can
      * restart any experiment whose code has changed. */
     let prefs = require("preferences-service");
     let indexFileName = prefs.get("extensions.testpilot.indexFileName",
                                   "index.json");
     let self = this;
     // Unload everything before checking for updates, to be sure we
     // get the newest stuff.
     this._logger.info("Unloading everything to prepare to check for updates.");
     this._refreshLoader();
 
-    // Check for surveys and studies
+    let modDate = 0;
+    if (this.cachedIndexNsiFile) {
+      if (this.cachedIndexNsiFile.exists()) {
+        modDate = this.cachedIndexNsiFile.lastModifiedTime;
+      }
+    }
     let url = resolveUrl(self._baseUrl, indexFileName);
     self._fileGetter(url, function onDone(data) {
       if (data) {
-        try {
-          data = JSON.parse(data);
-        } catch (e) {
-          self._logger.warn("Error parsing index.json: " + e );
+        self._executeFreshIndexFile(data, callback);
+        // cache index file contents so we can read them later if we can't get online.
+        self._cacheIndexFile(data);
+      } else {
+        self._logger.info("Could not download index.json, using cached version.");
+        let data = self._loadCachedIndexFile();
+        if (data) {
+          let success = self._executeCachedIndexFile(data);
+          callback(success);
+        } else {
+          self._logger.warn("Could not download index.json and no cached version.");
+          // TODO Should display an error message to the user in this case.
           callback(false);
-          return;
         }
-
-        // Cache study results and legacy studies.
-        self._studyResults = data.results;
-        self._legacyStudies = data.legacy;
-
-        /* Go through each record indicated in index.json for our locale;
-         * download the specified .jar file (replacing any version on disk)
-         */
-        let jarFiles = self.getLocalizedStudyInfo(data.new_experiments);
-        let numFilesToDload = jarFiles.length;
-
-        for each (let j in jarFiles) {
-          let filename = j.jarfile;
-          let hash = j.hash;
-          if (j.studyfile) {
-            self._experimentFileNames.push(j.studyfile);
-          }
-          self._logger.trace("I'm gonna go try to get the code for " + filename);
-          let modDate = self._jarStore.getFileModifiedDate(filename);
-
-          self._fileGetter(resolveUrl(self._baseUrl, filename),
-            function onDone(code) {
-              // code will be non-null if there is actually new code to download.
-              if (code) {
-                self._logger.info("Downloaded jar file " + filename);
-                self._jarStore.saveJarFile(filename, code, hash);
-                self._logger.trace("Saved code for: " + filename);
-              } else {
-                self._logger.info("Nothing to download for " + filename);
-              }
-              numFilesToDload--;
-              if (numFilesToDload == 0) {
-                self._logger.trace("Calling callback.");
-                callback(true);
-              }
-            }, modDate);
-        }
-
-      } else {
-        self._logger.warn("Could not download index.json from test pilot server.");
-        callback(false);
       }
-    });
+    }, modDate);
   },
 
   getExperiments: function() {
     /* Load up and return all studies/surveys (not libraries)
      * already stored in codeStorage.  Returns a dict with key =
      * the module name and value = the module object. */
     this._logger.trace("GetExperiments called.");
     let remoteExperiments = {};
@@ -341,27 +484,15 @@ exports.RemoteExperimentLoader.prototype
 
   getLegacyStudies: function() {
     return this._legacyStudies;
   }
 };
 
 // TODO purge the pref store of anybody who has one.
 
-// TODO i realized that right now there is no way for experiments
-// on disk to get loaded if the index file is not accessible for
-// any reason. getExperiments needs to be able to return names of
-// experiment modules on disk even if connection to server fails.  But
-// we can't just load everything; some modules in the jar are not
-// experiments.  Right now the information as to which modules are
-// experiments lives ONLY in index.json.  What if we put it into the .jar
-// file itself somehow?  Like calling one of the files "study.js".  Or
-// "survey.js"  Hey, that would be neat - one .jar file containing both
-// the study.js and the survey.js.  Or there could be a mini-manifest in the
-// jar telling which files are experiments.
-
 // TODO Also, if user has a study id foo that is not expired yet, and
 // a LegacyStudy appears with the same id, they should keep their "real"
 // version of id foo and not load the LegacyStudy version.
 
 // TODO but once the study is expired, should delete the jar for it and
 // just load the LegacyStudy version.
 
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/tests/test_data_store.js
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/tests/test_data_store.js
@@ -284,22 +284,48 @@ function testRemoteLoader() {
 
 function testRemotelyLoadTabsExperiment() {
 
   // TODO: Stub out the function downloadFile in remote-experiment-loader with
   // something that will give us the files from the local repo on the disk.
   // (~/testpilot/website/testcases/tab-open-close/tabs_experiment.js)
 }
 
+function testRemoteLoaderIndexCache() {
+  var Cuddlefish = {};
+  Cu.import("resource://testpilot/modules/lib/cuddlefish.js",
+                          Cuddlefish);
+  let cfl = new Cuddlefish.Loader({rootPaths: ["resource://testpilot/modules/",
+                                               "resource://testpilot/modules/lib/"]});
+  let remoteLoaderModule = cfl.require("remote-experiment-loader");
+
+  let getFileFunc = function(url, callback) {
+    callback(null);
+  };
+
+  let stubLogger = {
+    getLogger: function() { return {trace: function() {},
+                                    warn: function() {},
+                                    info: function() {},
+                                    debug: function() {}};}
+  };
+
+  let remoteLoader = new remoteLoaderModule.RemoteExperimentLoader(stubLogger, getFileFunc);
+  let data = "Foo bar baz quux";
+  remoteLoader._cacheIndexFile(data);
+  cheapAssertEqual(remoteLoader._loadCachedIndexFile(), data);
+}
+
 function runAllTests() {
   testTheDataStore();
   testFirefoxVersionCheck();
   testStringSanitizer();
   //testTheCuddlefishPreferencesFilesystem();
   //testRemoteLoader();
+  testRemoteLoaderIndexCache();
   dump("TESTING COMPLETE.  " + testsPassed + " out of " + testsRun +
        " tests passed.");
 }
 
 //exports.runAllTests = runAllTests;
 
 
 // Test that observers get installed on any windows that are already open.
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -49,16 +49,17 @@ tabbrowser {
 .tabbrowser-tab[fadein] > .tab-text,
 .tabbrowser-tab[fadein] > .tab-icon-image,
 .tabbrowser-tab[fadein] > .tab-close-button {
   -moz-transition: opacity .25s;
 }
 
 .tabbrowser-tab[pinned] {
   position: fixed;
+  display: block; /* position:fixed already does this (bug 579776), but let's be explicit */
 }
 
 .tabbrowser-tab[pinned] > .tab-text {
   display: none;
 }
 
 #alltabs-popup {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-alltabs-popup");
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -638,19 +638,22 @@ const gXPInstallObserver = {
                    .getInterface(Components.interfaces.nsIWebNavigation)
                    .QueryInterface(Components.interfaces.nsIDocShell);
     var browser = this._getBrowser(shell);
     if (!browser)
       return;
     const anchorID = "addons-notification-icon";
     var messageString, action;
     var brandShortName = brandBundle.getString("brandShortName");
-    var host = installInfo.originatingURI ? installInfo.originatingURI.host : browser.currentURI.host;
 
     var notificationID = aTopic;
+    // Make notifications persist a minimum of 30 seconds
+    var options = {
+      timeout: Date.now() + 30000
+    };
 
     switch (aTopic) {
     case "addon-install-blocked":
       var enabled = true;
       try {
         enabled = gPrefService.getBoolPref("xpinstall.enabled");
       }
       catch (e) {
@@ -661,66 +664,72 @@ const gXPInstallObserver = {
         if (PopupNotifications.getNotification(notificationID, browser))
           return;
 
         if (gPrefService.prefIsLocked("xpinstall.enabled")) {
           messageString = gNavigatorBundle.getString("xpinstallDisabledMessageLocked");
           buttons = [];
         }
         else {
-          messageString = gNavigatorBundle.getFormattedString("xpinstallDisabledMessage",
-                                                              [brandShortName, host]);
+          messageString = gNavigatorBundle.getString("xpinstallDisabledMessage");
 
           action = {
             label: gNavigatorBundle.getString("xpinstallDisabledButton"),
             accessKey: gNavigatorBundle.getString("xpinstallDisabledButton.accesskey"),
             callback: function editPrefs() {
               gPrefService.setBoolPref("xpinstall.enabled", true);
             }
           };
         }
       }
       else {
         if (PopupNotifications.getNotification(notificationID, browser))
           return;
 
         messageString = gNavigatorBundle.getFormattedString("xpinstallPromptWarning",
-                                                            [brandShortName, host]);
+                          [brandShortName, installInfo.originatingURI.host]);
 
         action = {
           label: gNavigatorBundle.getString("xpinstallPromptAllowButton"),
           accessKey: gNavigatorBundle.getString("xpinstallPromptAllowButton.accesskey"),
           callback: function() {
             installInfo.install();
           }
         };
       }
 
       PopupNotifications.show(browser, notificationID, messageString, anchorID,
-                              action);
+                              action, null, options);
       break;
     case "addon-install-failed":
       // TODO This isn't terribly ideal for the multiple failure case
       installInfo.installs.forEach(function(aInstall) {
-        var error = "addonError";
+        var host = (installInfo.originatingURI instanceof Ci.nsIStandardURL) &&
+                   installInfo.originatingURI.host;
+        if (!host)
+          host = (aInstall.sourceURI instanceof Ci.nsIStandardURL) &&
+                 aInstall.sourceURI.host;
+
+        var error = (host || aInstall.error == 0) ? "addonError" : "addonLocalError";
         if (aInstall.error != 0)
           error += aInstall.error;
         else if (aInstall.addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED)
           error += "Blocklisted";
         else
           error += "Incompatible";
 
         messageString = gNavigatorBundle.getString(error);
         messageString = messageString.replace("#1", aInstall.name);
-        messageString = messageString.replace("#2", host);
+        if (host)
+          messageString = messageString.replace("#2", host);
         messageString = messageString.replace("#3", brandShortName);
         messageString = messageString.replace("#4", Services.appinfo.version);
 
         PopupNotifications.show(browser, notificationID, messageString, anchorID,
-                                action);
+                                action, null, options);
       });
       break;
     case "addon-install-complete":
       var notification = PopupNotifications.getNotification(notificationID, browser);
       if (notification)
         PopupNotifications.remove(notification);
 
       var needsRestart = installInfo.installs.some(function(i) {
@@ -762,17 +771,17 @@ const gXPInstallObserver = {
       }
 
       messageString = PluralForm.get(installInfo.installs.length, messageString);
       messageString = messageString.replace("#1", installInfo.installs[0].name);
       messageString = messageString.replace("#2", installInfo.installs.length);
       messageString = messageString.replace("#3", brandShortName);
 
       PopupNotifications.show(browser, notificationID, messageString, anchorID,
-                              action);
+                              action, null, options);
       break;
     }
   }
 };
 
 // Simple gestures support
 //
 // As per bug #412486, web content must not be allowed to receive any
@@ -3086,17 +3095,18 @@ const DOMLinkHandler = {
           }
           break;
         case "search":
           if (!searchAdded) {
             var type = link.type && link.type.toLowerCase();
             type = type.replace(/^\s+|\s*(?:;.*)?$/g, "");
 
             if (type == "application/opensearchdescription+xml" && link.title &&
-                /^(?:https?|ftp):/i.test(link.href)) {
+                /^(?:https?|ftp):/i.test(link.href) &&
+                !gPrivateBrowsingUI.privateBrowsingEnabled) {
               var engine = { title: link.title, href: link.href };
               BrowserSearch.addEngine(engine, link.ownerDocument);
               searchAdded = true;
             }
           }
           break;
       }
     }
@@ -7025,17 +7035,17 @@ var gIdentityHandler = {
     // Push the appropriate strings out to the UI
     this._identityBox.tooltipText = tooltip;
     this._identityIconLabel.value = icon_label;
     this._identityIconCountryLabel.value = icon_country_label;
     // Set cropping and direction
     this._identityIconLabel.crop = icon_country_label ? "end" : "center";
     this._identityIconLabel.parentNode.style.direction = icon_labels_dir;
     // Hide completely if the organization label is empty
-    this._identityIconLabel.parentNode.hidden = icon_label ? false : true;
+    this._identityIconLabel.parentNode.collapsed = icon_label ? false : true;
   },
 
   /**
    * Set up the title and content messages for the identity message popup,
    * based on the specified mode, and the details of the SSL cert, where
    * applicable
    *
    * @param newMode The newly set identity mode.  Should be one of the IDENTITY_MODE_* constants.
@@ -7760,23 +7770,21 @@ var TabContextMenu = {
     document.getElementById("context_closeTab").disabled =
       disabled && gBrowser.tabContainer._closeWindowWithLastTab;
 
     var menuItems = aPopupMenu.getElementsByAttribute("tbattr", "tabbrowser-multiple");
     for (var i = 0; i < menuItems.length; i++)
       menuItems[i].disabled = disabled;
 
     // Session store
-    // XXXzeniko should't we just disable this item as we disable
-    // the tabbrowser-multiple items above - for consistency?
-    document.getElementById("context_undoCloseTab").hidden =
+    document.getElementById("context_undoCloseTab").disabled =
       Cc["@mozilla.org/browser/sessionstore;1"].
       getService(Ci.nsISessionStore).
       getClosedTabCount(window) == 0;
-      
+
     // Only one of pin/unpin should be visible
     document.getElementById("context_pinTab").hidden = this.contextTab.pinned;
     document.getElementById("context_unpinTab").hidden = !this.contextTab.pinned;
 
     // Disable "Close other Tabs" if there is only one unpinned tab and
     // hide it when the user rightclicked on a pinned tab.
     var unpinnedTabs = gBrowser.tabs.length - gBrowser._numPinnedTabs;
     document.getElementById("context_closeOtherTabs").disabled = unpinnedTabs <= 1;
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -29,16 +29,17 @@
 #   Joe Hewitt <hewitt@netscape.com>
 #   Pierre Chanial <chanial@noos.fr>
 #   Dean Tessman <dean_tessman@hotmail.com>
 #   Johnathan Nightingale <johnath@mozilla.com>
 #   Dão Gottwald <dao@mozilla.com>
 #   Ehsan Akhgari <ehsan.akhgari@gmail.com>
 #   Robert Strong <robert.bugzilla@gmail.com>
 #   Rob Campbell <rcampbell@mozilla.com>
+#   Patrick Walton <pcwalton@mozilla.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -135,17 +136,17 @@
                 accesskey="&bookmarkAllTabs.accesskey;"
                 command="Browser:BookmarkAllTabs"/>
       <menuseparator/>
       <menuitem id="context_closeOtherTabs" label="&closeOtherTabs.label;" accesskey="&closeOtherTabs.accesskey;"
                 oncommand="gBrowser.removeAllTabsBut(TabContextMenu.contextTab);"/>
       <menuitem id="context_undoCloseTab"
                 label="&undoCloseTab.label;"
                 accesskey="&undoCloseTab.accesskey;"
-                command="History:UndoCloseTab"/>
+                observes="History:UndoCloseTab"/>
       <menuitem id="context_closeTab" label="&closeTab.label;" accesskey="&closeTab.accesskey;"
                 oncommand="gBrowser.removeTab(TabContextMenu.contextTab);"/>
     </menupopup>
 
     <menupopup id="backForwardMenu"
                onpopupshowing="return FillHistoryMenu(event.target);"
                oncommand="gotoHistoryIndex(event);"
                onclick="checkForMiddleClick(this, event);"/>
@@ -224,17 +225,19 @@
            onmousemove="InspectorUI.highlighter.handleMouseMove(event);"/>
 
     <panel id="inspector-panel"
            orient="vertical"
            hidden="true"
            ignorekeys="true"
            noautofocus="true"
            noautohide="true"
-           level="top">
+           level="top"
+           titlebar="normal"
+           label="&inspectPanelTitle.label;">
       <toolbar id="inspector-toolbar"
                nowindowdrag="true">
         <toolbarbutton id="inspector-inspect-toolbutton"
                        label="&inspectButton.label;"
                        accesskey="&inspectButton.accesskey;"
                        class="toolbarbutton-text"
                        command="Inspector:Inspect"/>
         <toolbarbutton id="inspector-previous-toolbutton"
@@ -274,21 +277,19 @@
     </panel>
 
     <panel id="inspector-style-panel"
            hidden="true"
            orient="vertical"
            ignorekeys="true"
            noautofocus="true"
            noautohide="true"
-           level="top">
-        <toolbar id="inspector-style-toolbar"
-                 nowindowdrag="true">
-          <label>&inspectStylePanelTitle.label;</label>
-        </toolbar>
+           level="top"
+           titlebar="normal"
+           label="&inspectStylePanelTitle.label;">
         <listbox id="inspector-style-listbox" flex="1"/>
         <hbox align="end">
           <spacer flex="1" />
           <resizer dir="bottomend" />
         </hbox>
     </panel>
 
     <menupopup id="toolbar-context-menu"
@@ -319,17 +320,22 @@
                 oncommand="FullScreen.setAutohide();"/>
       <menuseparator/>
       <menuitem label="&fullScreenExit.label;"
                 accesskey="&fullScreenExit.accesskey;"
                 oncommand="BrowserFullScreen();"/>
     </menupopup>
 
     <menupopup id="contentAreaContextMenu"
-               onpopupshowing="if (event.target != this) return true; updateEditUIVisibility(); gContextMenu = new nsContextMenu(this, window.getBrowser()); return gContextMenu.shouldDisplay;"
+               onpopupshowing="if (event.target != this)
+                                 return true;
+                               gContextMenu = new nsContextMenu(this, gBrowser);
+                               if (gContextMenu.shouldDisplay)
+                                 updateEditUIVisibility();
+                               return gContextMenu.shouldDisplay;"
                onpopuphiding="if (event.target == this) { gContextMenu = null; updateEditUIVisibility(); }">
 #include browser-context.inc
     </menupopup>
 
     <menupopup id="placesContext"/>
 
     <panel id="notification-popup" position="after_start" noautofocus="true" hidden="true"/>
 
@@ -485,16 +491,32 @@
             <menuitem id="appmenu_showAllHistory"
                       label="&showAllHistoryCmd2.label;"
                       key="showAllHistoryKb"
                       command="Browser:ShowAllHistory"/>
             <menuseparator class="hide-if-empty-places-result"/>
           </menupopup>
         </menu>
         <menuseparator/>
+        <menu id="appmenu_developer"
+              label="&developerMenu.label;">
+          <menupopup id="appmenu_developer_popup">
+            <menuitem id="appmenu_pageSource"
+                      label="&pageSourceCmd.label;"
+                      command="View:PageSource"/>
+            <menuseparator/>
+            <menuitem id="appmenu_pageInspect"
+                      label="&inspectMenu.label;"
+                      command="Tools:Inspect"/>
+            <menuitem id="appmenu_webConsole"
+                      label="&webConsoleCmd.label;"
+                      oncommand="HUDConsoleUI.toggleHUD();"/>
+          </menupopup>
+        </menu>
+        <menuseparator/>
         <menu id="appmenu_customize"
               label="&appMenuCustomize.label;">
           <menupopup id="appmenu_customizeMenu"
                      onpopupshowing="onViewToolbarsPopupShowing(event);">
             <menuseparator/>
             <menuitem command="cmd_ToggleTabsOnTop"
                       type="checkbox"
                       label="&viewTabsOnTop.label;"/>
--- a/browser/base/content/inspector.js
+++ b/browser/base/content/inspector.js
@@ -18,16 +18,17 @@
  *
  * The Initial Developer of the Original Code is
  * The Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2010
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Rob Campbell <rcampbell@mozilla.com> (original author)
+ *   Mihai Șucan <mihai.sucan@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -255,17 +256,18 @@ PanelHighlighter.prototype = {
     let b = {
       x: clientRect.right - browserRect.left,
       y: clientRect.bottom - browserRect.top
     };
 
     // Get midpoint of diagonal line.
     let midpoint = this.midPoint(a, b);
 
-    return this.win.document.elementFromPoint(midpoint.x, midpoint.y);
+    return InspectorUI.elementFromPoint(this.win.document, midpoint.x,
+      midpoint.y);
   },
 
   /**
    * Is this.node highlightable?
    *
    * @returns boolean
    */
   isNodeHighlightable: function PanelHighlighter_isNodeHighlightable()
@@ -307,18 +309,18 @@ PanelHighlighter.prototype = {
    *        The MouseEvent triggering the method.
    */
   handleMouseMove: function PanelHighlighter_handleMouseMove(aEvent)
   {
     if (!InspectorUI.inspecting) {
       return;
     }
     let browserRect = this.browser.getBoundingClientRect();
-    let element = this.win.document.elementFromPoint(aEvent.clientX -
-      browserRect.left, aEvent.clientY - browserRect.top);
+    let element = InspectorUI.elementFromPoint(this.win.document,
+      aEvent.clientX - browserRect.left, aEvent.clientY - browserRect.top);
     if (element && element != this.node) {
       InspectorUI.inspectNode(element);
     }
   },
 };
 
 ///////////////////////////////////////////////////////////////////////////
 //// InspectorTreeView
@@ -852,18 +854,18 @@ var InspectorUI = {
         switch (event.keyCode) {
           case KeyEvent.DOM_VK_RETURN:
           case KeyEvent.DOM_VK_ESCAPE:
             this.stopInspecting();
             break;
         }
         break;
       case "mousemove":
-        let element = this.win.document.elementFromPoint(event.clientX,
-          event.clientY);
+        let element = this.elementFromPoint(event.target.ownerDocument,
+          event.clientX, event.clientY);
         if (element && element != this.node) {
           this.inspectNode(element);
         }
         break;
       case "click":
         this.stopInspecting();
         break;
       case "scroll":
@@ -926,16 +928,45 @@ var InspectorUI = {
   {
     this.highlighter.highlightNode(aNode);
     this.selectEventsSuppressed = true;
     this.treeView.selectedNode = aNode;
     this.selectEventsSuppressed = false;
     this.updateStylePanel(aNode);
   },
 
+  /**
+   * Find an element from the given coordinates. This method descends through 
+   * frames to find the element the user clicked inside frames.
+   *
+   * @param DOMDocument aDocument the document to look into.
+   * @param integer aX
+   * @param integer aY
+   * @returns Node|null the element node found at the given coordinates.
+   */
+  elementFromPoint: function IUI_elementFromPoint(aDocument, aX, aY)
+  {
+    let node = aDocument.elementFromPoint(aX, aY);
+    if (node && node.contentDocument) {
+      switch (node.nodeName.toLowerCase()) {
+        case "iframe":
+          let rect = node.getBoundingClientRect();
+          aX -= rect.left;
+          aY -= rect.top;
+
+        case "frame":
+          let subnode = this.elementFromPoint(node.contentDocument, aX, aY);
+          if (subnode) {
+            node = subnode;
+          }
+      }
+    }
+    return node;
+  },
+
   ///////////////////////////////////////////////////////////////////////////
   //// Utility functions
 
   /**
    * debug logging facility
    * @param msg
    *        text message to send to the log
    */
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -56,66 +56,36 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 function nsContextMenu(aXulMenu, aBrowser) {
-  this.target            = null;
-  this.browser           = null;
-  this.menu              = null;
-  this.isFrameImage      = false;
-  this.onTextInput       = false;
-  this.onKeywordField    = false;
-  this.onImage           = false;
-  this.onLoadedImage     = false;
-  this.onCompletedImage  = false;
-  this.onCanvas          = false;
-  this.onVideo           = false;
-  this.onAudio           = false;
-  this.onLink            = false;
-  this.onMailtoLink      = false;
-  this.onSaveableLink    = false;
-  this.onMathML          = false;
-  this.link              = false;
-  this.linkURL           = "";
-  this.linkURI           = null;
-  this.linkProtocol      = null;
-  this.inFrame           = false;
-  this.hasBGImage        = false;
-  this.isTextSelected    = false;
-  this.isContentSelected = false;
-  this.shouldDisplay     = true;
-  this.isDesignMode      = false;
-  this.onEditableArea = false;
-  this.ellipsis = "\u2026";
-  try {
-    this.ellipsis = gPrefService.getComplexValue("intl.ellipsis",
-                                                 Ci.nsIPrefLocalizedString).data;
-  } catch (e) { }
-
-  // Initialize new menu.
-  this.initMenu(aXulMenu, aBrowser);
+  this.shouldDisplay = true;
+  this.initMenu(aBrowser);
 }
 
 // Prototype for nsContextMenu "class."
 nsContextMenu.prototype = {
-  // Initialize context menu.
-  initMenu: function CM_initMenu(aPopup, aBrowser) {
-    this.menu = aPopup;
-    this.browser = aBrowser;
-
-    this.isFrameImage = document.getElementById("isFrameImage");
-
+  initMenu: function CM_initMenu(aBrowser) {
     // Get contextual info.
     this.setTarget(document.popupNode, document.popupRangeParent,
                    document.popupRangeOffset);
+    if (!this.shouldDisplay)
+      return;
 
+    this.browser = aBrowser;
+    this.isFrameImage = document.getElementById("isFrameImage");
+    this.ellipsis = "\u2026";
+    try {
+      this.ellipsis = gPrefService.getComplexValue("intl.ellipsis",
+                                                   Ci.nsIPrefLocalizedString).data;
+    } catch (e) { }
     this.isTextSelected = this.isTextSelection();
     this.isContentSelected = this.isContentSelection();
 
     // Initialize (disable/remove) menu items.
     this.initItems();
   },
 
   initItems: function CM_initItems() {
@@ -343,20 +313,21 @@ nsContextMenu.prototype = {
               .setAttribute("checked", InlineSpellCheckerUI.enabled);
     }
 
     this.showItem("spell-add-to-dictionary", onMisspelling);
 
     // suggestion list
     this.showItem("spell-suggestions-separator", onMisspelling);
     if (onMisspelling) {
-      var menu = document.getElementById("contentAreaContextMenu");
       var suggestionsSeparator =
         document.getElementById("spell-add-to-dictionary");
-      var numsug = InlineSpellCheckerUI.addSuggestionsToMenu(menu, suggestionsSeparator, 5);
+      var numsug =
+        InlineSpellCheckerUI.addSuggestionsToMenu(suggestionsSeparator.parentNode,
+                                                  suggestionsSeparator, 5);
       this.showItem("spell-no-suggestions", numsug == 0);
     }
     else
       this.showItem("spell-no-suggestions", false);
 
     // dictionary list
     this.showItem("spell-dictionaries", InlineSpellCheckerUI.enabled);
     if (canSpell) {
@@ -447,38 +418,43 @@ nsContextMenu.prototype = {
   },
 
   // Set various context menu attributes based on the state of the world.
   setTarget: function (aNode, aRangeParent, aRangeOffset) {
     const xulNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
     if (aNode.namespaceURI == xulNS ||
         this.isTargetAFormControl(aNode)) {
       this.shouldDisplay = false;
+      return;
     }
 
     // Initialize contextual info.
     this.onImage           = false;
     this.onLoadedImage     = false;
     this.onCompletedImage  = false;
     this.onStandaloneImage = false;
     this.onCanvas          = false;
     this.onVideo           = false;
     this.onAudio           = false;
     this.onTextInput       = false;
     this.onKeywordField    = false;
     this.mediaURL          = "";
     this.onLink            = false;
+    this.onMailtoLink      = false;
+    this.onSaveableLink    = false;
+    this.link              = null;
     this.linkURL           = "";
     this.linkURI           = null;
     this.linkProtocol      = "";
     this.onMathML          = false;
     this.inFrame           = false;
     this.hasBGImage        = false;
     this.bgImageURL        = "";
-    this.onEditableArea = false;
+    this.onEditableArea    = false;
+    this.isDesignMode      = false;
 
     // Clear any old spellchecking items from the menu, this used to
     // be in the menu hiding code but wasn't getting called in all
     // situations. Here, we can ensure it gets cleaned up any time the
     // menu is shown. Note: must be before uninit because that clears the
     // internal vars
     InlineSpellCheckerUI.clearSuggestionsFromMenu();
     InlineSpellCheckerUI.clearDictionaryListFromMenu();
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1454,28 +1454,41 @@
 
               // update tab close buttons state
               this.tabContainer.adjustTabstrip();
             }
 
             // update first-tab/last-tab/beforeselected/afterselected attributes
             this.selectedTab._selected = true;
 
+            // Removing the panel requires fixing up selectedPanel immediately
+            // (see below), which would be hindered by the potentially expensive
+            // browser removal. So we remove the browser and the panel in two
+            // steps.
+            var panel = browser.parentNode;
+
             // This will unload the document. An unload handler could remove
             // dependant tabs, so it's important that the tabbrowser is now in
             // a consistent state (tab removed, tab positions updated, etc.).
-            // Also, it's important that another tab has been selected before
-            // the panel is removed; otherwise, a random sibling panel can flash.
-            this.mPanelContainer.removeChild(browser.parentNode);
-
-            // As the panel is removed, the removal of a dependent document can
+            panel.removeChild(browser);
+
+            // As the browser is removed, the removal of a dependent document can
             // cause the whole window to close. So at this point, it's possible
             // that the binding is destructed.
-            if (this.mTabBox)
-              this.mTabBox.selectedPanel = this.getBrowserForTab(this.mCurrentTab).parentNode;
+            if (this.mTabBox) {
+              let selectedPanel = this.mTabBox.selectedPanel;
+
+              this.mPanelContainer.removeChild(panel);
+
+              // Under the hood, a selectedIndex attribute controls which panel
+              // is displayed. Removing a panel A which precedes the selected
+              // panel B makes selectedIndex point to the panel next to B. We
+              // need to explicitly preserve B as the selected panel.
+              this.mTabBox.selectedPanel = selectedPanel;
+            }
 
             if (aCloseWindow)
               this._windowIsClosing = closeWindow(true);
           ]]>
         </body>
       </method>
 
       <method name="_blurTab">
@@ -2869,21 +2882,16 @@
           }
           else {
             let tabRect = this.childNodes[newIndex].getBoundingClientRect();
             if (ltr)
               newMargin = tabRect.left - rect.left;
             else
               newMargin = rect.right - tabRect.right;
           }
-          // ensure we never place the drop indicator beyond our limits
-          if (newMargin < minMargin)
-            newMargin = minMargin;
-          else if (newMargin > maxMargin)
-            newMargin = maxMargin;
         }
 
         ind.collapsed = false;
 
         newMargin += ind.clientWidth / 2;
         if (!ltr)
           newMargin *= -1;
 
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -132,26 +132,28 @@ endif
                  browser_bug550565.js \
                  browser_bug553455.js \
                  browser_bug555224.js \
                  browser_bug555767.js \
                  browser_bug556061.js \
                  browser_bug562649.js \
                  browser_bug563588.js \
                  browser_bug577121.js \
+                 browser_bug580956.js \
                  browser_contextSearchTabPosition.js \
                  browser_ctrlTab.js \
                  browser_discovery.js \
                  browser_drag.js \
                  browser_gestureSupport.js \
                  browser_getshortcutoruri.js \
                  browser_inspector_initialization.js \
                  browser_inspector_treeSelection.js \
                  browser_inspector_highlighter.js \
                  browser_inspector_stylePanel.js \
+                 browser_inspector_iframeTest.js \
                  browser_pageInfo.js \
                  browser_page_style_menu.js \
                  browser_pinnedTabs.js \
                  browser_plainTextLinks.js \
                  browser_pluginnotification.js \
                  browser_popupUI.js \
                  browser_relatedTabs.js \
                  browser_sanitize-passwordDisabledHosts.js \
--- a/browser/base/content/test/browser_bug553455.js
+++ b/browser/base/content/test/browser_bug553455.js
@@ -1,15 +1,20 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 const TESTROOT = "http://example.com/browser/toolkit/mozapps/extensions/test/xpinstall/";
+const TESTROOT2 = "http://example.org/browser/toolkit/mozapps/extensions/test/xpinstall/";
+const CHROMEROOT = "chrome://mochikit/content/browser/toolkit/mozapps/extensions/test/xpinstall/";
 const XPINSTALL_URL = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
 
+var gApp = document.getElementById("bundle_brand").getString("brandShortName");
+var gVersion = Services.appinfo.version;
+
 function wait_for_notification(aCallback) {
   PopupNotifications.panel.addEventListener("popupshown", function() {
     PopupNotifications.panel.removeEventListener("popupshown", arguments.callee, false);
     aCallback(PopupNotifications.panel);
   }, false);
 }
 
 function wait_for_install_dialog(aCallback) {
@@ -51,29 +56,36 @@ function test_blocked_install() {
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 
   // Wait for the blocked notification
   wait_for_notification(function(aPanel) {
     let notification = aPanel.childNodes[0];
     is(notification.id, "addon-install-blocked", "Should have seen the install blocked");
     is(notification.button.label, "Allow", "Should have seen the right button");
+    is(notification.getAttribute("label"),
+       gApp + " prevented this site (example.com) from asking you to install " +
+       "software on your computer.",
+       "Should have seen the right message");
 
     // Click on Allow
     EventUtils.synthesizeMouse(notification.button, 20, 10, {});
 
     // Wait for the install confirmation dialog
     wait_for_install_dialog(function(aWindow) {
       aWindow.document.documentElement.acceptDialog();
 
       // Wait for the complete notification
       wait_for_notification(function(aPanel) {
         let notification = aPanel.childNodes[0];
         is(notification.id, "addon-install-complete", "Should have seen the install complete");
         is(notification.button.label, "Restart Now", "Should have seen the right button");
+        is(notification.getAttribute("label"), 
+           "XPI Test will be installed after you restart " + gApp + ".",
+           "Should have seen the right message");
 
         AddonManager.getAllInstalls(function(aInstalls) {
         is(aInstalls.length, 1, "Should be one pending install");
           aInstalls[0].cancel();
 
           gBrowser.removeTab(gBrowser.selectedTab);
           runNextTest();
         });
@@ -96,16 +108,19 @@ function test_whitelisted_install() {
   wait_for_install_dialog(function(aWindow) {
     aWindow.document.documentElement.acceptDialog();
 
     // Wait for the complete notification
     wait_for_notification(function(aPanel) {
       let notification = aPanel.childNodes[0];
       is(notification.id, "addon-install-complete", "Should have seen the install complete");
       is(notification.button.label, "Restart Now", "Should have seen the right button");
+      is(notification.getAttribute("label"),
+         "XPI Test will be installed after you restart " + gApp + ".",
+         "Should have seen the right message");
 
       AddonManager.getAllInstalls(function(aInstalls) {
         is(aInstalls.length, 1, "Should be one pending install");
         aInstalls[0].cancel();
 
         gBrowser.removeTab(gBrowser.selectedTab);
         Services.perms.remove("example.com", "install");
         runNextTest();
@@ -123,16 +138,20 @@ function test_failed_download() {
   }));
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 
   // Wait for the failed notification
   wait_for_notification(function(aPanel) {
     let notification = aPanel.childNodes[0];
     is(notification.id, "addon-install-failed", "Should have seen the install fail");
+    is(notification.getAttribute("label"),
+       "The add-on could not be downloaded because of a connection failure " +
+       "on example.com.",
+       "Should have seen the right message");
 
     gBrowser.removeTab(gBrowser.selectedTab);
     Services.perms.remove("example.com", "install");
     runNextTest();
   });
 },
 
 function test_corrupt_file() {
@@ -144,16 +163,20 @@ function test_corrupt_file() {
   }));
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 
   // Wait for the failed notification
   wait_for_notification(function(aPanel) {
     let notification = aPanel.childNodes[0];
     is(notification.id, "addon-install-failed", "Should have seen the install fail");
+    is(notification.getAttribute("label"),
+       "The add-on downloaded from example.com could not be installed " +
+       "because it appears to be corrupt.",
+       "Should have seen the right message");
 
     gBrowser.removeTab(gBrowser.selectedTab);
     Services.perms.remove("example.com", "install");
     runNextTest();
   });
 },
 
 function test_incompatible() {
@@ -165,16 +188,20 @@ function test_incompatible() {
   }));
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 
   // Wait for the failed notification
   wait_for_notification(function(aPanel) {
     let notification = aPanel.childNodes[0];
     is(notification.id, "addon-install-failed", "Should have seen the install fail");
+    is(notification.getAttribute("label"),
+       "XPI Test could not be installed because it is not compatible with " +
+       gApp + " " + gVersion + ".",
+       "Should have seen the right message");
 
     gBrowser.removeTab(gBrowser.selectedTab);
     Services.perms.remove("example.com", "install");
     runNextTest();
   });
 },
 
 function test_restartless() {
@@ -191,16 +218,19 @@ function test_restartless() {
   wait_for_install_dialog(function(aWindow) {
     aWindow.document.documentElement.acceptDialog();
 
     // Wait for the complete notification
     wait_for_notification(function(aPanel) {
       let notification = aPanel.childNodes[0];
       is(notification.id, "addon-install-complete", "Should have seen the install complete");
       is(notification.button.label, "Open Add-ons Manager", "Should have seen the right button");
+      is(notification.getAttribute("label"),
+         "XPI Test has been installed successfully.",
+         "Should have seen the right message");
 
       AddonManager.getAllInstalls(function(aInstalls) {
         is(aInstalls.length, 0, "Should be no pending installs");
 
         AddonManager.getAddonByID("restartless-xpi@tests.mozilla.org", function(aAddon) {
           aAddon.uninstall();
 
           gBrowser.removeTab(gBrowser.selectedTab);
@@ -227,44 +257,178 @@ function test_multiple() {
   wait_for_install_dialog(function(aWindow) {
     aWindow.document.documentElement.acceptDialog();
 
     // Wait for the complete notification
     wait_for_notification(function(aPanel) {
       let notification = aPanel.childNodes[0];
       is(notification.id, "addon-install-complete", "Should have seen the install complete");
       is(notification.button.label, "Restart Now", "Should have seen the right button");
+      is(notification.getAttribute("label"),
+         "2 add-ons will be installed after you restart " + gApp + ".",
+         "Should have seen the right message");
 
       AddonManager.getAllInstalls(function(aInstalls) {
         is(aInstalls.length, 1, "Should be one pending install");
         aInstalls[0].cancel();
 
         AddonManager.getAddonByID("restartless-xpi@tests.mozilla.org", function(aAddon) {
           aAddon.uninstall();
 
           gBrowser.removeTab(gBrowser.selectedTab);
           Services.perms.remove("example.com", "install");
           runNextTest();
         });
       });
     });
   });
+},
+
+function test_url() {
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.loadURI(TESTROOT + "unsigned.xpi");
+
+  // Wait for the install confirmation dialog
+  wait_for_install_dialog(function(aWindow) {
+    aWindow.document.documentElement.acceptDialog();
+
+    // Wait for the complete notification
+    wait_for_notification(function(aPanel) {
+      let notification = aPanel.childNodes[0];
+      is(notification.id, "addon-install-complete", "Should have seen the install complete");
+      is(notification.button.label, "Restart Now", "Should have seen the right button");
+      is(notification.getAttribute("label"),
+         "XPI Test will be installed after you restart " + gApp + ".",
+         "Should have seen the right message");
+
+      AddonManager.getAllInstalls(function(aInstalls) {
+        is(aInstalls.length, 1, "Should be one pending install");
+        aInstalls[0].cancel();
+
+        gBrowser.removeTab(gBrowser.selectedTab);
+        runNextTest();
+      });
+    });
+  });
+},
+
+function test_localfile() {
+  var cr = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
+                     .getService(Components.interfaces.nsIChromeRegistry);
+  var path = cr.convertChromeURL(makeURI(CHROMEROOT + "corrupt.xpi")).spec;
+
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.loadURI(path);
+
+  // Wait for the complete notification
+  wait_for_notification(function(aPanel) {
+    let notification = aPanel.childNodes[0];
+    is(notification.id, "addon-install-failed", "Should have seen the install fail");
+    is(notification.getAttribute("label"),
+       "This add-on could not be installed because it appears to be corrupt.",
+       "Should have seen the right message");
+
+    gBrowser.removeTab(gBrowser.selectedTab);
+    runNextTest();
+  });
+},
+
+function test_wronghost() {
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.addEventListener("load", function() {
+    if (gBrowser.currentURI.spec != TESTROOT2 + "enabled.html")
+      return;
+
+    gBrowser.removeEventListener("load", arguments.callee, true);
+
+    gBrowser.loadURI(TESTROOT + "corrupt.xpi");
+
+    // Wait for the complete notification
+    wait_for_notification(function(aPanel) {
+      let notification = aPanel.childNodes[0];
+      is(notification.id, "addon-install-failed", "Should have seen the install fail");
+      is(notification.getAttribute("label"),
+         "The add-on downloaded from example.com could not be installed " +
+         "because it appears to be corrupt.",
+         "Should have seen the right message");
+
+      gBrowser.removeTab(gBrowser.selectedTab);
+      runNextTest();
+    });
+  }, true);
+  gBrowser.loadURI(TESTROOT2 + "enabled.html");
+},
+
+function test_reload() {
+  var pm = Services.perms;
+  pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
+
+  var triggers = encodeURIComponent(JSON.stringify({
+    "Unsigned XPI": "unsigned.xpi"
+  }));
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
+
+  // Wait for the install confirmation dialog
+  wait_for_install_dialog(function(aWindow) {
+    aWindow.document.documentElement.acceptDialog();
+
+    // Wait for the complete notification
+    wait_for_notification(function(aPanel) {
+      let notification = aPanel.childNodes[0];
+      is(notification.id, "addon-install-complete", "Should have seen the install complete");
+      is(notification.button.label, "Restart Now", "Should have seen the right button");
+      is(notification.getAttribute("label"),
+         "XPI Test will be installed after you restart " + gApp + ".",
+         "Should have seen the right message");
+
+      function test_fail() {
+        ok(false, "Reloading should not have hidden the notification");
+      }
+
+      PopupNotifications.panel.addEventListener("popuphiding", test_fail, false);
+
+      gBrowser.addEventListener("load", function() {
+        if (gBrowser.currentURI.spec != TESTROOT2 + "enabled.html")
+          return;
+
+        gBrowser.removeEventListener("load", arguments.callee, true);
+
+        PopupNotifications.panel.removeEventListener("popuphiding", test_fail, false);
+
+        AddonManager.getAllInstalls(function(aInstalls) {
+          is(aInstalls.length, 1, "Should be one pending install");
+          aInstalls[0].cancel();
+
+          gBrowser.removeTab(gBrowser.selectedTab);
+          Services.perms.remove("example.com", "install");
+          runNextTest();
+        });
+      }, true);
+      gBrowser.loadURI(TESTROOT2 + "enabled.html");
+    });
+  });
 }
 ];
 
 function runNextTest() {
   AddonManager.getAllInstalls(function(aInstalls) {
     is(aInstalls.length, 0, "Should be no active installs");
 
     if (TESTS.length == 0) {
+      Services.prefs.setBoolPref("extensions.logging.enabled", false);
+
       finish();
       return;
     }
 
+    info("Running " + TESTS[0].name);
     TESTS.shift()();
   });
-}
+};
 
 function test() {
   waitForExplicitFinish();
 
+  Services.prefs.setBoolPref("extensions.logging.enabled", true);
+
   runNextTest();
 }
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_bug580956.js
@@ -0,0 +1,27 @@
+function numClosedTabs()
+  Cc["@mozilla.org/browser/sessionstore;1"].
+    getService(Ci.nsISessionStore).
+    getClosedTabCount(window);
+
+function isUndoCloseEnabled() {
+  document.popupNode = gBrowser.tabs[0];
+  TabContextMenu.updateContextMenu(document.getElementById("tabContextMenu"));
+  return !document.getElementById("context_undoCloseTab").disabled;
+}
+
+function test() {
+  waitForExplicitFinish();
+
+  gPrefService.setIntPref("browser.sessionstore.max_tabs_undo", 0);
+  gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
+  is(numClosedTabs(), 0, "There should be 0 closed tabs.");
+  ok(!isUndoCloseEnabled(), "Undo Close Tab should be disabled.");
+
+  var tab = gBrowser.addTab("http://mochi.test:8888/");
+  var browser = gBrowser.getBrowserForTab(tab);
+  browser.addEventListener("load", function() {
+    gBrowser.removeTab(tab);
+    ok(isUndoCloseEnabled(), "Undo Close Tab should be enabled.");
+    finish();
+  }, true);
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_inspector_iframeTest.js
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Inspector iframe Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Rob Campbell <rcampbell@mozilla.com>
+ *   Mihai Șucan <mihai.sucan@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+let doc;
+let div1;
+let div2;
+let iframe1;
+let iframe2;
+
+function createDocument()
+{
+  doc.title = "Inspector iframe Tests";
+
+  iframe1 = doc.createElement('iframe');
+
+  iframe1.addEventListener("load", function () {
+    iframe1.removeEventListener("load", arguments.callee, false);
+
+    div1 = iframe1.contentDocument.createElement('div');
+    div1.textContent = 'little div';
+    iframe1.contentDocument.body.appendChild(div1);
+
+    iframe2 = iframe1.contentDocument.createElement('iframe');
+
+    iframe2.addEventListener('load', function () {
+      iframe2.removeEventListener("load", arguments.callee, false);
+
+      div2 = iframe2.contentDocument.createElement('div');
+      div2.textContent = 'nested div';
+      iframe2.contentDocument.body.appendChild(div2);
+
+      setupIframeTests();
+    }, false);
+
+    iframe2.src = 'data:text/html,nested iframe';
+    iframe1.contentDocument.body.appendChild(iframe2);
+  }, false);
+
+  iframe1.src = 'data:text/html,little iframe';
+  doc.body.appendChild(iframe1);
+}
+
+function setupIframeTests()
+{
+  document.addEventListener("popupshown", runIframeTests, false);
+  InspectorUI.toggleInspectorUI();
+}
+
+function runIframeTests(evt)
+{
+  if (evt.target.id != "inspector-panel")
+    return true;
+
+  document.removeEventListener("popupshown", runIframeTests, false);
+  document.addEventListener("popupshown", performTestComparisons1, false);
+
+  EventUtils.synthesizeMouse(div1, 2, 2, {type: "mousemove"},
+    iframe1.contentWindow);
+}
+
+function performTestComparisons1(evt)
+{
+  if (evt.target.id != "highlighter-panel")
+    return true;
+
+  document.removeEventListener("popupshown", performTestComparisons1, false);
+
+  is(InspectorUI.treeView.selectedNode, div1, "selection matches div1 node");
+  is(InspectorUI.highlighter.highlitNode, div1, "highlighter matches selection");
+
+  document.addEventListener("popupshown", performTestComparisons2, false);
+
+  EventUtils.synthesizeMouse(div2, 2, 2, {type: "mousemove"},
+    iframe2.contentWindow);
+}
+
+function performTestComparisons2(evt)
+{
+  if (evt.target.id != "highlighter-panel")
+    return true;
+
+  document.removeEventListener("popupshown", performTestComparisons2, false);
+
+  is(InspectorUI.treeView.selectedNode, div2, "selection matches div2 node");
+  is(InspectorUI.highlighter.highlitNode, div2, "highlighter matches selection");
+
+  executeSoon(finishUp);
+}
+
+function finishUp() {
+  InspectorUI.closeInspectorUI();
+  gBrowser.removeCurrentTab();
+  finish();
+}
+
+function test()
+{
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function() {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+    doc = content.document;
+    waitForFocus(createDocument, content);
+  }, true);
+  
+  content.location = "data:text/html,iframe tests for inspector";
+}
+
--- a/browser/base/content/test/browser_popupNotification.js
+++ b/browser/base/content/test/browser_popupNotification.js
@@ -339,25 +339,100 @@ var tests = [
       isnot(document.getElementById("geo-notification-icon").boxObject.width, 0,
             "geo anchor should be visible");
       dismissNotification(popup);
     },
     onHidden: function (popup) {
       this.notification.remove();
     }
   },
+  // Test that persistence allows the notification to persist across reloads
+  { // Test #12
+    run: function () {
+      this.oldSelectedTab = gBrowser.selectedTab;
+      gBrowser.selectedTab = gBrowser.addTab("about:blank");
+
+      let self = this;
+      loadURI("http://example.com/", function() {
+        self.notifyObj = new basicNotification();
+        self.notifyObj.options = {
+          persistence: 2
+        };
+        self.notification = showNotification(self.notifyObj);
+      });
+    },
+    onShown: function (popup) {
+      this.complete = false;
+
+      let self = this;
+      loadURI("http://example.org/", function() {
+        loadURI("http://example.com/", function() {
+
+          // Next load will hide the notification
+          self.complete = true;
+
+          loadURI("http://example.org/");
+        });
+      });
+    },
+    onHidden: function (popup) {
+      ok(this.complete, "Should only have hidden the notification after 3 page loads");
+      this.notification.remove();
+      gBrowser.removeTab(gBrowser.selectedTab);
+      gBrowser.selectedTab = this.oldSelectedTab;
+    }
+  },
+  // Test that a timeout allows the notification to persist across reloads
+  { // Test #13
+    run: function () {
+      this.oldSelectedTab = gBrowser.selectedTab;
+      gBrowser.selectedTab = gBrowser.addTab("about:blank");
+
+      let self = this;
+      loadURI("http://example.com/", function() {
+        self.notifyObj = new basicNotification();
+        // Set a timeout of 10 minutes that should never be hit
+        self.notifyObj.options = {
+          timeout: Date.now() + 600000
+        };
+        self.notification = showNotification(self.notifyObj);
+      });
+    },
+    onShown: function (popup) {
+      this.complete = false;
+
+      let self = this;
+      loadURI("http://example.org/", function() {
+        loadURI("http://example.com/", function() {
+
+          // Next load will hide the notification
+          self.notification.options.timeout = Date.now() - 1;
+          self.complete = true;
+
+          loadURI("http://example.org/");
+        });
+      });
+    },
+    onHidden: function (popup) {
+      ok(this.complete, "Should only have hidden the notification after the timeout was passed");
+      this.notification.remove();
+      gBrowser.removeTab(gBrowser.selectedTab);
+      gBrowser.selectedTab = this.oldSelectedTab;
+    }
+  },
 ];
 
 function showNotification(notifyObj) {
   return PopupNotifications.show(notifyObj.browser,
                                  notifyObj.id,
                                  notifyObj.message,
                                  notifyObj.anchorID,
                                  notifyObj.mainAction,
-                                 notifyObj.secondaryActions);
+                                 notifyObj.secondaryActions,
+                                 notifyObj.options);
 }
 
 function checkPopup(popup, notificationObj) {
   info("[Test #" + gTestIndex + "] checking popup");
   let notifications = popup.childNodes;
 
   is(notifications.length, 1, "only one notification displayed");
   let notification = notifications[0];
@@ -404,14 +479,27 @@ function triggerSecondaryCommand(popup, 
     // Activate
     EventUtils.synthesizeKey("VK_ENTER", {});
   }, false);
 
   // One down event to open the popup
   EventUtils.synthesizeKey("VK_DOWN", { altKey: (navigator.platform.indexOf("Mac") == -1) });
 }
 
+function loadURI(uri, callback) {
+  gBrowser.addEventListener("load", function() {
+    // Ignore the about:blank load
+    if (gBrowser.currentURI.spec != uri)
+      return;
+
+    gBrowser.removeEventListener("load", arguments.callee, true);
+
+    callback();
+  }, true);
+  gBrowser.loadURI(uri);
+}
+
 function dismissNotification(popup) {
   info("[Test #" + gTestIndex + "] dismissing notification");
   executeSoon(function () {
     EventUtils.synthesizeKey("VK_ESCAPE", {});
   });
 }
--- a/browser/components/preferences/tabs.js
+++ b/browser/components/preferences/tabs.js
@@ -55,18 +55,37 @@ var gTabsPane = {
    * - true if display should switch to a new tab which has been opened from a
    *   link, false if display shouldn't switch
    * browser.tabs.warnOnClose
    * - true if when closing a window with multiple tabs the user is warned and
    *   allowed to cancel the action, false to just close the window
    * browser.tabs.warnOnOpen
    * - true if the user should be warned if he attempts to open a lot of tabs at
    *   once (e.g. a large folder of bookmarks), false otherwise
+   * browser.taskbar.previews.enable
+   * - true if tabs are to be shown in the Windows 7 taskbar
    */
 
+#ifdef XP_WIN
+  /**
+   * Initialize any platform-specific UI.
+   */
+  init: function () {
+    const Cc = Components.classes;
+    const Ci = Components.interfaces;
+    try {
+      let sysInfo = Cc["@mozilla.org/system-info;1"].
+                    getService(Ci.nsIPropertyBag2);
+      let ver = parseFloat(sysInfo.getProperty("version"));
+      let showTabsInTaskbar = document.getElementById("showTabsInTaskbar");
+      showTabsInTaskbar.hidden = ver < 6.1;
+    } catch (ex) {}
+  },
+#endif
+
   /**
    * Determines where a link which opens a new window will open.
    *
    * @returns |true| if such links should be opened in new tabs
    */
   readLinkTarget: function() {
     var openNewWindow = document.getElementById("browser.link.open_newwindow");
     return openNewWindow.value != 2;
--- a/browser/components/preferences/tabs.xul
+++ b/browser/components/preferences/tabs.xul
@@ -45,24 +45,30 @@
 <!ENTITY % tabsDTD SYSTEM "chrome://browser/locale/preferences/tabs.dtd">
 %tabsDTD;
 ]>
 
 <overlay id="TabsPaneOverlay"
          xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <prefpane id="paneTabs"
+#ifdef XP_WIN
+            onpaneload="gTabsPane.init();"
+#endif
             helpTopic="prefs-tabs">
 
     <preferences id="tabsPreferences">
       <preference id="browser.link.open_newwindow"     name="browser.link.open_newwindow"     type="int"/>
       <preference id="browser.tabs.autoHide"           name="browser.tabs.autoHide"           type="bool" inverted="true"/>
       <preference id="browser.tabs.loadInBackground"   name="browser.tabs.loadInBackground"   type="bool" inverted="true"/>
       <preference id="browser.tabs.warnOnClose"        name="browser.tabs.warnOnClose"        type="bool"/>
       <preference id="browser.tabs.warnOnOpen"         name="browser.tabs.warnOnOpen"         type="bool"/>
+#ifdef XP_WIN
+      <preference id="browser.taskbar.previews.enable" name="browser.taskbar.previews.enable" type="bool"/>
+#endif
     </preferences>
     
     <script type="application/javascript" src="chrome://browser/content/preferences/tabs.js"/>
 
     <!-- XXX flex below is a hack because wrapping checkboxes don't reflow
              properly; see bug 349098 -->
     <vbox id="tabPrefsBox" align="start" flex="1">
       <checkbox id="linkTargeting" label="&newWindowsAsTabs.label;"
@@ -77,13 +83,18 @@
                 accesskey="&warnOpenManyTabs.accesskey;"
                 preference="browser.tabs.warnOnOpen"/>
       <checkbox id="showTabBar" label="&showTabBar.label;"
                 accesskey="&showTabBar.accesskey;"
                 preference="browser.tabs.autoHide"/>
       <checkbox id="switchToNewTabs" label="&switchToNewTabs.label;"
                 accesskey="&switchToNewTabs.accesskey;"
                 preference="browser.tabs.loadInBackground"/>
+#ifdef XP_WIN
+      <checkbox id="showTabsInTaskbar" label="&showTabsInTaskbar.label;"
+                accesskey="&showTabsInTaskbar.accesskey;"
+                preference="browser.taskbar.previews.enable"/>
+#endif
     </vbox>
 
   </prefpane>
 
 </overlay>
--- a/browser/components/privatebrowsing/test/browser/Makefile.in
+++ b/browser/components/privatebrowsing/test/browser/Makefile.in
@@ -41,17 +41,18 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = browser/components/privatebrowsing/test/browser
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_TEST_FILES =  \
 		browser_console_clear.js \
-		browser_privatebrowsing_beforeunload.js \
+		browser_privatebrowsing_beforeunload_enter.js \
+		browser_privatebrowsing_beforeunload_exit.js \
 		browser_privatebrowsing_certexceptionsui.js \
 		browser_privatebrowsing_commandline_toggle.js \
 		browser_privatebrowsing_cookieacceptdialog.js \
 		browser_privatebrowsing_crh.js \
 		browser_privatebrowsing_downloadmonitor.js \
 		browser_privatebrowsing_fastswitch.js \
 		browser_privatebrowsing_findbar.js \
 		browser_privatebrowsing_forgetthissite.js \
rename from browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload_enter.js
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload_enter.js
@@ -93,73 +93,21 @@ function test() {
          "Incorrect number of tabs after transition into private browsing");
       gBrowser.selectedBrowser.addEventListener("load", function() {
         gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
         is(gBrowser.currentURI.spec, "about:privatebrowsing",
            "Incorrect page displayed after private browsing transition");
         is(acceptDialog, 0, "Two confirm dialogs should have been accepted");
 
-        gBrowser.selectedBrowser.addEventListener("load", function() {
-          gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
-
-          gBrowser.selectedTab = gBrowser.addTab();
-          gBrowser.selectedBrowser.addEventListener("load", function() {
-            gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
-
-            confirmCalls = 0;
-            rejectDialog = 1;
-            pb.privateBrowsingEnabled = false;
-
-            ok(pb.privateBrowsingEnabled, "Private browsing mode should not have been deactivated");
-            is(confirmCalls, 1, "Only one confirm box should be shown");
-            is(gBrowser.tabs.length, 2,
-               "No tabs should be closed because private browsing mode transition was canceled");
-            is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild).currentURI.spec, TEST_PAGE_1,
-               "The first tab should be the same one we opened");
-            is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, TEST_PAGE_2,
-               "The last tab should be the same one we opened");
-            is(rejectDialog, 0, "Only one confirm dialog should have been rejected");
-
-            confirmCalls = 0;
-            acceptDialog = 2;
-            pb.privateBrowsingEnabled = false;
-
-            ok(!pb.privateBrowsingEnabled, "Private browsing mode should have been deactivated");
-            is(confirmCalls, 2, "Only two confirm boxes should be shown");
-            is(gBrowser.tabs.length, 3,
-               "Incorrect number of tabs after transition into private browsing");
-
-            let loads = 0;
-            function waitForLoad(event) {
-              gBrowser.removeEventListener("load", arguments.callee, true);
-
-              if (++loads != 3)
-                return;
-
-              is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild).currentURI.spec, "about:blank",
-                 "The first tab should be a blank tab");
-              is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild.nextSibling).currentURI.spec, TEST_PAGE_1,
-                 "The middle tab should be the same one we opened");
-              is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, TEST_PAGE_2,
-                 "The last tab should be the same one we opened");
-              is(acceptDialog, 0, "Two confirm dialogs should have been accepted");
-              is(acceptDialog, 0, "Two prompts should have been raised");
-
-              acceptDialog = 2;
-              gBrowser.removeTab(gBrowser.tabContainer.lastChild);
-              gBrowser.removeTab(gBrowser.tabContainer.lastChild);
-
-              Services.obs.removeObserver(promptObserver, "common-dialog-loaded", false);
-              finish();
-            }
-            for (let i = 0; i < gBrowser.browsers.length; ++i)
-              gBrowser.browsers[i].addEventListener("load", waitForLoad, true);
-          }, true);
-          gBrowser.selectedBrowser.loadURI(TEST_PAGE_2);
-        }, true);
-        gBrowser.selectedBrowser.loadURI(TEST_PAGE_1);
+        gBrowser.addTab();
+        gBrowser.removeTab(gBrowser.selectedTab);
+        Services.prefs.setBoolPref("browser.privatebrowsing.keep_current_session", true);
+        pb.privateBrowsingEnabled = false;
+        Services.prefs.clearUserPref("browser.privatebrowsing.keep_current_session");
+        Services.obs.removeObserver(promptObserver, "common-dialog-loaded", false);
+        finish();
       }, true);
     }, true);
     browser2.loadURI(TEST_PAGE_2);
   }, true);
   browser1.loadURI(TEST_PAGE_1);
 }
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload_exit.js
@@ -0,0 +1,124 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Nochum Sossonko.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Nochum Sossonko <highmind63@gmail.com> (Original Author)
+ *   Ehsan Akhgari <ehsan@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test makes sure that cancelling the unloading of a page with a beforeunload
+// handler prevents the private browsing mode transition.
+
+function test() {
+  const TEST_PAGE_1 = "data:text/html,<body%20onbeforeunload='return%20false;'>first</body>";
+  const TEST_PAGE_2 = "data:text/html,<body%20onbeforeunload='return%20false;'>second</body>";
+  let pb = Cc["@mozilla.org/privatebrowsing;1"]
+             .getService(Ci.nsIPrivateBrowsingService);
+
+  let rejectDialog = 0;
+  let acceptDialog = 0;
+  let confirmCalls = 0;
+  function promptObserver(aSubject, aTopic, aData) {
+    let dialogWin = aSubject.QueryInterface(Ci.nsIDOMWindow);
+    confirmCalls++;
+    if (acceptDialog-- > 0)
+      dialogWin.document.documentElement.getButton("accept").click();
+    else if (rejectDialog-- > 0)
+      dialogWin.document.documentElement.getButton("cancel").click();
+  }
+
+  Services.obs.addObserver(promptObserver, "common-dialog-loaded", false);
+  pb.privateBrowsingEnabled = true;
+
+  waitForExplicitFinish();
+  let browser1 = gBrowser.getBrowserForTab(gBrowser.addTab());
+  browser1.addEventListener("load", function() {
+    browser1.removeEventListener("load", arguments.callee, true);
+
+    let browser2 = gBrowser.getBrowserForTab(gBrowser.addTab());
+    browser2.addEventListener("load", function() {
+      browser2.removeEventListener("load", arguments.callee, true);
+
+      confirmCalls = 0;
+      rejectDialog = 1;
+      pb.privateBrowsingEnabled = false;
+
+      ok(pb.privateBrowsingEnabled, "Private browsing mode should not have been deactivated");
+      is(confirmCalls, 1, "Only one confirm box should be shown");
+      is(gBrowser.tabs.length, 3,
+         "No tabs should be closed because private browsing mode transition was canceled");
+      is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild).currentURI.spec, "about:privatebrowsing",
+         "The first tab should be the same one we opened");
+      is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, TEST_PAGE_2,
+         "The last tab should be the same one we opened");
+      is(rejectDialog, 0, "Only one confirm dialog should have been rejected");
+
+      confirmCalls = 0;
+      acceptDialog = 2;
+      pb.privateBrowsingEnabled = false;
+
+      ok(!pb.privateBrowsingEnabled, "Private browsing mode should have been deactivated");
+      is(confirmCalls, 2, "Only two confirm boxes should be shown");
+      is(gBrowser.tabs.length, 3,
+         "Incorrect number of tabs after transition into private browsing");
+
+      let loads = 0;
+      function waitForLoad(event) {
+        gBrowser.removeEventListener("load", arguments.callee, true);
+
+        if (++loads != 3)
+          return;
+
+        is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild).currentURI.spec, "about:blank",
+           "The first tab should be a blank tab");
+        is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild.nextSibling).currentURI.spec, TEST_PAGE_1,
+           "The middle tab should be the same one we opened");
+        is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, TEST_PAGE_2,
+           "The last tab should be the same one we opened");
+        is(acceptDialog, 0, "Two confirm dialogs should have been accepted");
+        is(acceptDialog, 0, "Two prompts should have been raised");
+
+        acceptDialog = 2;
+        gBrowser.removeTab(gBrowser.tabContainer.lastChild);
+        gBrowser.removeTab(gBrowser.tabContainer.lastChild);
+
+        Services.obs.removeObserver(promptObserver, "common-dialog-loaded", false);
+        finish();
+      }
+      for (let i = 0; i < gBrowser.browsers.length; ++i)
+        gBrowser.browsers[i].addEventListener("load", waitForLoad, true);
+    }, true);
+    browser2.loadURI(TEST_PAGE_2);
+  }, true);
+  browser1.loadURI(TEST_PAGE_1);
+}
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_searchbar.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_searchbar.js
@@ -35,16 +35,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 // This test makes sure that the search bar is cleared when leaving the
 // private browsing mode.
 
 function test() {
   // initialization
+  waitForExplicitFinish();
   gPrefService.setBoolPref("browser.privatebrowsing.keep_current_session", true);
   let pb = Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
 
   // fill in the search bar with something
   const kTestSearchString = "privatebrowsing";
   let searchBar = BrowserSearch.searchBar;
   searchBar.value = kTestSearchString;
@@ -63,11 +64,29 @@ function test() {
   // leave private browsing mode
   pb.privateBrowsingEnabled = false;
 
   is(searchBar.value, kTestSearchString,
     "leaving the private browsing mode should restore the search bar contents");
   is(searchBar.textbox.editor.transactionManager.numberOfUndoItems, 1,
     "leaving the private browsing mode should only leave 1 item in the undo list of the searchbar control");
 
-  // cleanup
-  gPrefService.clearUserPref("browser.privatebrowsing.keep_current_session");
+  // enter private browsing mode
+  pb.privateBrowsingEnabled = true;
+
+  const TEST_URL =
+    "data:text/html,<head><link rel=search type='application/opensearchdescription+xml' href='http://foo.bar' title=dummy></head>";
+  gBrowser.selectedTab = gBrowser.addTab(TEST_URL);
+  gBrowser.selectedBrowser.addEventListener("load", function(e) {
+    e.currentTarget.removeEventListener("load", arguments.callee, true);
+
+    var browser = gBrowser.selectedBrowser;
+    is(typeof browser.engines, "undefined",
+       "An engine should not be discovered in private browsing mode");
+
+    gBrowser.removeTab(gBrowser.selectedTab);
+    pb.privateBrowsingEnabled = false;
+
+    // cleanup
+    gPrefService.clearUserPref("browser.privatebrowsing.keep_current_session");
+    finish();
+  }, true);
 }
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -60,20 +60,16 @@ endif
 
 MOZ_NONLOCALIZED_PKG_LIST = \
 	xpcom \
 	browser \
 	$(NULL)
 
 MOZ_LOCALIZED_PKG_LIST = $(AB_CD)
 
-MOZ_OPTIONAL_PKG_LIST = \
-	adt \
-	$(NULL)
-
 DEFINES += -DAB_CD=$(AB_CD) -DMOZ_APP_NAME=$(MOZ_APP_NAME) -DPREF_DIR=$(PREF_DIR)
 ifdef MOZ_ENABLE_GNOME_COMPONENT
 DEFINES += -DMOZ_ENABLE_GNOME_COMPONENT=1
 endif
 
 ifeq (gtk2, $(MOZ_WIDGET_TOOLKIT))
 DEFINES += -DMOZ_GTK2=1
 endif
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -400,132 +400,17 @@
 
 ; [Browser Chrome Files]
 @BINPATH@/chrome/browser.jar
 @BINPATH@/chrome/browser.manifest
 @BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
 @BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/icon.png
 @BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/preview.png
 #if MOZ_UPDATE_CHANNEL == beta
-@BINPATH@/extensions/testpilot@labs.mozilla.com/chrome.manifest
-@BINPATH@/extensions/testpilot@labs.mozilla.com/components/TestPilot.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/all-studies-window.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/all-studies-window.xul
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/browser.css
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/browser.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/debug.html
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/experiment-page.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/feedback-browser.xul
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.colorhelpers.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.colorhelpers.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.crosshair.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.crosshair.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.image.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.image.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.navigate.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.navigate.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.selection.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.selection.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.stack.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.stack.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.threshold.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.threshold.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/flot/jquery.min.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/raw-data-dialog.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/raw-data-dialog.xul
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/screen.css
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/status-quit.html
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/status.html
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/survey-generator.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/take-survey.html
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/tp-browser.xul
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/welcome-page.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/welcome.html
-@BINPATH@/extensions/testpilot@labs.mozilla.com/content/window-utils.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/defaults/preferences/preferences.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/install.rdf
-@BINPATH@/extensions/testpilot@labs.mozilla.com/instrument/chrome.manifest
-@BINPATH@/extensions/testpilot@labs.mozilla.com/instrument/install.rdf
-@BINPATH@/extensions/testpilot@labs.mozilla.com/instrument/instrument.jsm
-@BINPATH@/extensions/testpilot@labs.mozilla.com/instrument/instrument.xul
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/dbutils.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/experiment_data_store.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/extension-update.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/feedback.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/jar-code-store.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/cuddlefish.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/memory.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/observer-service.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/plain-text-console.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/preferences-service.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/securable-module.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/timer.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/traceback.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/unit-test.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/unload.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/lib/url.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/log4moz.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/metadata.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/Observers.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/remote-experiment-loader.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/setup.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/string_sanitizer.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/modules/tasks.js
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/badge-default.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/bg.jpg
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/css/screen-standalone.css
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/dino_32x32.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/bg-status.jpg
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/callout.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/callout_continue.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/data1.jpg
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/data2.jpg
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/home_comments.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/home_computer.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/home_continue.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/home_quit.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/home_results.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/home_twitter.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/images/home_upcoming.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/logo.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/mozilla-logo.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/status-completed.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/status-ejected.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/status-missed.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/testpilot_16x16.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/testPilot_200x200.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/testpilot_32x32.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-completedstudies-32x32.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-currentstudies-32x32.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-generic-32x32.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-learned-32x32.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-results-48x48.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-settings-32x32.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-study-48x48.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/all/tp-submit-48x48.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/linux/close_button.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/linux/feedback-frown-16x16.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/linux/feedback-smile-16x16.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/linux/feedback.css
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/mac/close_button.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/mac/feedback-frown-16x16.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/mac/feedback-smile-16x16.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/mac/feedback.css
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/mac/notification-tail-down.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/mac/notification-tail-up.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/win/close_button.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/win/feedback-frown-16x16.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/win/feedback-smile-16x16.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/win/feedback.css
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/win/notification-tail-down.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/skin/win/notification-tail-up.png
-@BINPATH@/extensions/testpilot@labs.mozilla.com/tests/test_data_store.js
+@BINPATH@/extensions/testpilot@labs.mozilla.com/*
 #endif
 @BINPATH@/chrome/toolkit.jar
 @BINPATH@/chrome/toolkit.manifest
 @BINPATH@/@PREF_DIR@/reporter.js
 #ifdef XP_UNIX
 #ifndef XP_MACOSX
 @BINPATH@/chrome/icons/default/default16.png
 @BINPATH@/chrome/icons/default/default32.png
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -53,16 +53,17 @@ components/nsBackgroundUpdateService.js
 components/nsBookmarkTransactionManager.js
 components/nsCloseAllWindows.js
 components/nsDictionary.js
 components/nsExtensionManager.js
 components/nsInterfaceInfoToIDL.js
 components/nsScriptableIO.js
 components/nsUrlClassifierTable.js
 components/nsXmlRpcClient.js
+components/pluginGlue.js
 components/sidebar.xpt
 components/xmlextras.xpt
 components/xpcom.xpt
 components/xpti.dat
 components/xptitemp.dat
 defaults/pref/all.js
 defaults/pref/bug259708.js
 defaults/pref/bug307259.js
@@ -702,16 +703,17 @@ xpicleanup@BIN_SUFFIX@
   components/xpinstall.xpt
   components/xulapp.xpt
   components/xuldoc.xpt
   components/xultmpl.xpt
   components/zipwriter.xpt
   extensions/inspector@mozilla.org/chrome/chromelist.txt
   init.d/README
   libwidget.rsrc
+  plugin-container
   plugins/Default Plugin.plugin/Contents/Info.plist
   plugins/Default Plugin.plugin/Contents/MacOS/Default Plugin
   plugins/Default Plugin.plugin/Contents/PkgInfo
   plugins/Default Plugin.plugin/Contents/Resources/Default Plugin.rsrc
   plugins/Default Plugin.plugin/Contents/Resources/English.lproj/InfoPlist.strings
   plugins/DefaultPlugin.plugin/
   plugins/DefaultPlugin.plugin/Contents/Info.plist
   plugins/DefaultPlugin.plugin/Contents/MacOS/
--- a/browser/installer/windows/Makefile.in
+++ b/browser/installer/windows/Makefile.in
@@ -49,35 +49,25 @@ include $(topsrcdir)/toolkit/mozapps/ins
 
 CONFIG_DIR = instgen
 SFX_MODULE = $(topsrcdir)/other-licenses/7zstub/firefox/7zSD.sfx
 APP_VERSION := $(shell cat $(srcdir)/../../config/version.txt)
 DEFINES += -DAPP_VERSION=$(APP_VERSION)
 PRE_RELEASE_SUFFIX := $(shell $(PYTHON) $(topsrcdir)/config/printprereleasesuffix.py $(APP_VERSION))
 DEFINES += -DPRE_RELEASE_SUFFIX="$(PRE_RELEASE_SUFFIX)"
 
-# All script and locale files used by the Unicode version of NSIS need to be
-# converted from UTF-8 to UTF-16LE
-INSTALLER_FILES_CONV = \
+INSTALLER_FILES = \
+	app.tag \
 	nsis/installer.nsi \
 	nsis/uninstaller.nsi \
 	nsis/shared.nsh \
 	$(NULL)
 
-INSTALLER_FILES = \
-	app.tag \
-	$(NULL)
-
-# All script and locale files used by the Unicode version of NSIS need to be
-# converted from UTF-8 to UTF-16LE
-BRANDING_FILES_CONV = \
+BRANDING_FILES = \
 	branding.nsi \
-	$(NULL)
-
-BRANDING_FILES = \
 	wizHeader.bmp \
 	wizHeaderRTL.bmp \
 	wizWatermark.bmp \
 	$(NULL)
 
 DEFINES += \
 	-DAB_CD=$(AB_CD) \
 	-DMOZ_APP_NAME=$(MOZ_APP_NAME) \
@@ -90,52 +80,28 @@ include $(topsrcdir)/config/config.mk
 installer::
 	$(MAKE) -C .. installer-stage
 	$(MAKE) $(CONFIG_DIR)/setup.exe
 
 # For building the uninstaller during the application build so it can be
 # included for mar file generation.
 uninstaller::
 	$(RM) -rf $(CONFIG_DIR) && mkdir $(CONFIG_DIR)
-	for i in $(INSTALLER_FILES_CONV); do \
-	  iconv -f UTF-8 -t UTF-16LE $(srcdir)/$$i | \
-	    cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
-	    $(CONFIG_DIR)/`basename $$i`; \
-	done
 	$(INSTALL) $(addprefix $(srcdir)/,$(INSTALLER_FILES)) $(CONFIG_DIR)
-	for i in $(BRANDING_FILES_CONV); do \
-	  iconv -f UTF-8 -t UTF-16LE $(DIST)/branding/$$i | \
-	    cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
-	    $(CONFIG_DIR)/$$i; \
-	done
 	$(INSTALL) $(addprefix $(DIST)/branding/,$(BRANDING_FILES)) $(CONFIG_DIR)
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py -Fsubstitution $(DEFINES) $(ACDEFINES) \
-	  $(srcdir)/nsis/defines.nsi.in | iconv -f UTF-8 -t UTF-16LE | \
-	  cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
-	  $(CONFIG_DIR)/defines.nsi
-	$(PERL) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.pl \
-	  $(topsrcdir) $(call EXPAND_LOCALE_SRCDIR,browser/locales)/installer $(AB_CD) \
-	  $(CONFIG_DIR)
+	  $(srcdir)/nsis/defines.nsi.in > $(CONFIG_DIR)/defines.nsi
+	$(PYTHON) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.py \
+	  --preprocess-locale $(topsrcdir) \
+	  $(call EXPAND_LOCALE_SRCDIR,browser/locales)/installer $(AB_CD) $(CONFIG_DIR)
 
 $(CONFIG_DIR)/setup.exe::
 	$(RM) -rf $(CONFIG_DIR) && mkdir $(CONFIG_DIR)
-	for i in $(INSTALLER_FILES_CONV); do \
-	  iconv -f UTF-8 -t UTF-16LE $(srcdir)/$$i | \
-	    cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
-	    $(CONFIG_DIR)/`basename $$i`; \
-	done
 	$(INSTALL) $(addprefix $(srcdir)/,$(INSTALLER_FILES)) $(CONFIG_DIR)
-	for i in $(BRANDING_FILES_CONV); do \
-	  iconv -f UTF-8 -t UTF-16LE $(DIST)/branding/$$i | \
-	    cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
-	    $(CONFIG_DIR)/$$i; \
-	done
 	$(INSTALL) $(addprefix $(DIST)/branding/,$(BRANDING_FILES)) $(CONFIG_DIR)
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py -Fsubstitution $(DEFINES) $(ACDEFINES) \
-	  $(srcdir)/nsis/defines.nsi.in | iconv -f UTF-8 -t UTF-16LE | \
-	  cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
-	  $(CONFIG_DIR)/defines.nsi
-	$(PERL) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.pl \
-	  $(topsrcdir) $(call EXPAND_LOCALE_SRCDIR,browser/locales)/installer $(AB_CD) \
-	  $(CONFIG_DIR)
+	  $(srcdir)/nsis/defines.nsi.in > $(CONFIG_DIR)/defines.nsi
+	$(PYTHON) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.py \
+	  --preprocess-locale $(topsrcdir) \
+	  $(call EXPAND_LOCALE_SRCDIR,browser/locales)/installer $(AB_CD) $(CONFIG_DIR)
 
 include $(topsrcdir)/config/rules.mk
 include $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/makensis.mk
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -170,16 +170,17 @@
 <!ENTITY webConsoleCmd.label          "Web Console">
 <!ENTITY webConsoleCmd.accesskey      "W">
 <!ENTITY webConsoleCmd.commandkey     "k">
 
 <!ENTITY inspectMenu.label            "Inspect">
 <!ENTITY inspectMenu.accesskey        "T">
 <!ENTITY inspectMenu.commandkey       "I">
 
+<!ENTITY inspectPanelTitle.label      "HTML">
 <!ENTITY inspectButton.label          "Inspect">
 <!ENTITY inspectButton.accesskey      "I">
 <!ENTITY inspectNextButton.label      "Next">
 <!ENTITY inspectNextButton.accesskey  "N">
 <!ENTITY inspectPreviousButton.label  "Previous">
 <!ENTITY inspectPreviousButton.accesskey "P">
 <!ENTITY inspectStyleButton.label     "Style">
 <!ENTITY inspectStyleButton.accesskey "S">
@@ -251,16 +252,18 @@
 <!ENTITY showAllHistoryCmd.commandkey "H">
 
 <!ENTITY appMenuPrintCmd.label "Print">
 <!ENTITY appMenuCustomize.label "Customize">
 <!ENTITY appMenuToolbarLayout.label "Toolbar Layout…">
 <!ENTITY appMenuSidebars.label "Sidebars">
 <!ENTITY appMenuHelp.label "Help">
 
+<!ENTITY developerMenu.label "Developer">
+
 <!ENTITY openCmd.commandkey           "l">
 <!ENTITY urlbar.placeholder           "Go to a Web Site">
 <!ENTITY urlbar.accesskey             "d">
 <!ENTITY urlbar.switchToTab.label     "Switch to tab:">
 
 <!-- 
   Comment duplicated from browser-sets.inc:
 
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -39,23 +39,30 @@ xpinstallDisabledButton.accesskey=n
 # #1 first add-on's name, #2 number of add-ons, #3 application name
 addonsInstalled=#1 has been installed successfully.;#2 add-ons have been installed successfully.
 addonsInstalledNeedsRestart=#1 will be installed after you restart #3.;#2 add-ons will be installed after you restart #3.
 addonInstallRestartButton=Restart Now
 addonInstallRestartButton.accesskey=R
 addonInstallManage=Open Add-ons Manager
 addonInstallManage.accesskey=O
 
-# LOCALIZATION NOTE (addonError-1, addonError-2, addonError-3, addonError-4, addonErrorIncompatible, addonErrorBlocklisted):
+# LOCALIZATION NOTE (addonError-1, addonError-2, addonError-3, addonError-4):
 # #1 is the add-on name, #2 is the host name, #3 is the application name
 # #4 is the application version
 addonError-1=The add-on could not be downloaded because of a connection failure on #2.
 addonError-2=The add-on from #2 could not be installed because it does not match the add-on #3 expected.
 addonError-3=The add-on downloaded from #2 could not be installed because it appears to be corrupt.
 addonError-4=#1 could not be installed because #3 cannot modify the needed file.
+
+# LOCALIZATION NOTE (addonLocalError-1, addonLocalError-2, addonLocalError-3, addonLocalError-4, addonErrorIncompatible, addonErrorBlocklisted):
+# #1 is the add-on name, #3 is the application name, #4 is the application version
+addonLocalError-1=This add-on could not be installed because of a filesystem error.
+addonLocalError-2=This add-on could not be installed because it does not match the add-on #3 expected.
+addonLocalError-3=This add-on could not be installed because it appears to be corrupt.
+addonLocalError-4=#1 could not be installed because #3 cannot modify the needed file.
 addonErrorIncompatible=#1 could not be installed because it is not compatible with #3 #4.
 addonErrorBlocklisted=#1 could not be installed because it has a high risk of causing stability or security problems.
 
 # LOCALIZATION NOTE (lwthemeInstallRequest.message): %S will be replaced with
 # the host name of the site.
 lwthemeInstallRequest.message=This site (%S) attempted to install a theme.
 lwthemeInstallRequest.allowButton=Allow
 lwthemeInstallRequest.allowButton.accesskey=a
--- a/browser/locales/en-US/chrome/browser/preferences/tabs.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/tabs.dtd
@@ -7,8 +7,11 @@
 <!ENTITY warnOpenManyTabs.label       "Warn me when opening multiple tabs might slow down &brandShortName;">
 <!ENTITY warnOpenManyTabs.accesskey   "o">
 
 <!ENTITY showTabBar.label             "Always show the tab bar">
 <!ENTITY showTabBar.accesskey         "b">
 
 <!ENTITY switchToNewTabs.label        "When I open a link in a new tab, switch to it immediately">
 <!ENTITY switchToNewTabs.accesskey    "s">
+
+<!ENTITY showTabsInTaskbar.label          "Show tab previews in the Windows taskbar">
+<!ENTITY showTabsInTaskbar.accesskey      "k">
--- a/browser/locales/en-US/feedback/main.properties
+++ b/browser/locales/en-US/feedback/main.properties
@@ -10,16 +10,17 @@ testpilot.turnOff = Turn Off User Studie
 
 # studies window
 testpilot.studiesWindow.noStudies = We are working on a new study now; it will knock on your door soon! Stay Tuned!
 testpilot.studiesWindow.uploading = Uploading…
 testpilot.studiesWindow.unableToReachServer = Unable to reach Mozilla; please try again later.
 testpilot.studiesWindow.thanksForContributing = Thanks for contributing!
 testpilot.studiesWindow.finishedOn = Finished on %S
 testpilot.studiesWindow.canceledStudy = (You canceled this study)
+testpilot.studiesWindow.missedStudy = (You missed this study)
 testpilot.studiesWindow.willStart = Will start on %S
 testpilot.studiesWindow.gatheringData = Currently gathering data.
 testpilot.studiesWindow.willFinish = Will finish on %S
 testpilot.studiesWindow.proposeStudy = Propose your own study
 
 # for pages
 testpilot.page.commentsAndDiscussions = Comments & Discussions »
 testpilot.page.proposeATest = Propose a Test »
--- a/browser/locales/filter.py
+++ b/browser/locales/filter.py
@@ -1,14 +1,15 @@
 def test(mod, path, entity = None):
   import re
   # ignore anyhting but Firefox
   if mod not in ("netwerk", "dom", "toolkit", "security/manager",
                  "browser", "extensions/reporter", "extensions/spellcheck",
-                 "other-licenses/branding/firefox"):
+                 "other-licenses/branding/firefox",
+                 "services/sync"):
     return False
   if mod != "browser" and mod != "extensions/spellcheck":
     # we only have exceptions for browser and extensions/spellcheck
     return True
   if not entity:
     if mod == "extensions/spellcheck":
       return False
     # browser
--- a/browser/themes/gnomestripe/browser/places/editBookmarkOverlay.css
+++ b/browser/themes/gnomestripe/browser/places/editBookmarkOverlay.css
@@ -55,30 +55,22 @@
 
 .expander-up,
 .expander-down {
   min-width: 0;
   padding: 2px 0;
   -moz-padding-start: 2px;
 }
 
-.expander-up {
-	list-style-image: url("chrome://global/skin/arrow/arrow-up.gif");
+.expander-up > .button-box {
+  -moz-appearance: button-arrow-up;
 }
 
-.expander-down {
-  list-style-image: url("chrome://global/skin/arrow/arrow-dn.gif");
-}
-
-.expander-down:hover:active {
-	list-style-image: url("chrome://global/skin/arrow/arrow-dn-hov.gif");
-}
-
-.expander-up:hover:active {
-	list-style-image: url("chrome://global/skin/arrow/arrow-up-hov.gif");
+.expander-down > .button-box {
+  -moz-appearance: button-arrow-down;
 }
 
 #editBookmarkPanelContent {
   min-width: 23em;
 }
 
 #editBMPanel_folderTree {
   margin-top: 2px;
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -163,17 +163,16 @@ toolbarbutton.chevron:-moz-locale-dir(rt
 
 toolbarbutton.bookmark-item {
   font-weight: bold;
   color: #222;
   border: 0;
   -moz-border-radius: 100%;
   padding: 0 8px;
   margin: 0 0 1px;
-  height: 16px;
 }
 
 .bookmark-item > .toolbarbutton-menu-dropmarker {
   list-style-image: url("chrome://browser/skin/places/folderDropArrow.png");
   -moz-image-region: rect(0, 7px, 5px, 0);
   margin-top: 1px;
   -moz-margin-start: 3px;
   -moz-margin-end: -2px;
@@ -206,28 +205,24 @@ toolbarbutton.bookmark-item[open="true"]
   background-color: rgba(0, 0, 0, .5);
 }
 
 toolbarbutton.bookmark-item > menupopup {
   margin-top: 2px;
   -moz-margin-start: 3px;
 }
 
-.bookmark-item[livemark] > .toolbarbutton-menu-dropmarker {
-  list-style-image: url("chrome://browser/skin/places/livemarkFolder.png");
-  -moz-image-region: rect(0, 9px, 10px, 0);
+.bookmark-item > .toolbarbutton-icon {
+  width: 16px;
+  min-height: 16px;
 }
 
-.bookmark-item[livemark]:hover > .toolbarbutton-menu-dropmarker,
-.bookmark-item[livemark][open="true"] > .toolbarbutton-menu-dropmarker {
-  -moz-image-region: rect(0, 18px, 10px, 9px);
-}
-
-.bookmark-item > .toolbarbutton-icon {
-  display: none !important;
+.bookmark-item > .toolbarbutton-icon[label]:not([label=""]),
+.bookmark-item > .toolbarbutton-icon[type="menu"] {
+  -moz-margin-end: 5px;
 }
 
 .bookmark-item[container] {
   list-style-image: url("chrome://global/skin/tree/folder.png");
 }
 
 .query-item[container] {
   list-style-image: url("chrome://browser/skin/places/history.png");
@@ -562,16 +557,17 @@ toolbar[iconsize="small"][mode="icons"] 
   -moz-image-region: rect(20px, 180px, 40px, 160px);
 }
 
 #bookmarks-button[checked="true"]:active:hover {
   -moz-image-region: rect(40px, 180px, 60px, 160px);
 }
 
 #bookmarks-menu-button.bookmark-item {
+  -moz-image-region: rect(2px, 178px, 18px, 162px);
   list-style-image: url("chrome://browser/skin/Toolbar.png");
 }
 
 #bookmarks-menu-button.toolbarbutton-1 {
   -moz-box-orient: horizontal;
 }
 
 /* print button */
@@ -1357,20 +1353,17 @@ toolbarbutton.chevron > .toolbarbutton-m
 .tabbrowser-tabbox {
   margin: 0;
 }
 
 .tab-icon-image {
   width: 16px;
   height: 16px;
   list-style-image: url("chrome://global/skin/tree/item.png");
-}
-
-.tabbrowser-tab[pinned] > .tab-icon-image {
-  margin-top: 2px;
+  vertical-align: middle; /* for pinned tabs - those are display:block */
 }
 
 .tabbrowser-tab[busy] > .tab-icon-image {
   list-style-image: url("chrome://browser/skin/tabbrowser/progress.png") !important;
   -moz-image-region: rect(0, 16px, 16px, 0);
 }
 .tabbrowser-tab[busy][stalled] > .tab-icon-image {
   list-style-image: url("chrome://browser/skin/tabbrowser/progress-pulsing.png") !important;
--- a/browser/themes/pinstripe/browser/jar.mn
+++ b/browser/themes/pinstripe/browser/jar.mn
@@ -68,17 +68,16 @@ browser.jar:
   skin/classic/browser/places/livemarkItem.png              (places/livemarkItem.png)
   skin/classic/browser/places/bookmarksMenu.png             (places/bookmarksMenu.png)
   skin/classic/browser/places/bookmarksToolbar.png          (places/bookmarksToolbar.png)
   skin/classic/browser/places/history.png                   (places/history.png)
   skin/classic/browser/places/star-icons.png                (places/star-icons.png)
   skin/classic/browser/places/toolbar.png                   (places/toolbar.png)
   skin/classic/browser/places/toolbarDropMarker.png         (places/toolbarDropMarker.png)
   skin/classic/browser/places/folderDropArrow.png           (places/folderDropArrow.png)
-  skin/classic/browser/places/livemarkFolder.png            (places/livemarkFolder.png)
   skin/classic/browser/places/editBookmarkOverlay.css       (places/editBookmarkOverlay.css)
   skin/classic/browser/places/minus.png                     (places/minus.png)
   skin/classic/browser/places/minus-active.png              (places/minus-active.png)
   skin/classic/browser/places/plus.png                      (places/plus.png)
   skin/classic/browser/places/plus-active.png               (places/plus-active.png)
   skin/classic/browser/places/starPage.png                  (places/starPage.png)
   skin/classic/browser/places/pageStarred.png               (places/pageStarred.png)
   skin/classic/browser/places/searching_16.png              (places/searching_16.png)
deleted file mode 100644
index 5e73536673c8cc561e0e580e2efe957a5ac94130..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/pinstripe/browser/places/organizer.css
+++ b/browser/themes/pinstripe/browser/places/organizer.css
@@ -103,20 +103,18 @@
                    inset 0 0 0 20px @toolbarbuttonPressedBackgroundColor@;
 }
 
 #placesToolbar > toolbarbutton:-moz-window-inactive {
   border-color: @toolbarbuttonInactiveBorderColor@;
   background-image: @toolbarbuttonInactiveBackgroundImage@;
 }
 
-#placesToolbar > toolbarbutton[disabled="true"] > .toolbarbutton-icon,
-#placesToolbar > toolbarbutton > .toolbarbutton-icon:-moz-window-inactive,
-#placesToolbar > toolbarbutton > .toolbarbutton-menu-dropmarker:-moz-window-inactive {
-  opacity: 0.5; /* remove the second and third selector when we support click-through (bug 392188) */
+#placesToolbar > toolbarbutton[disabled="true"] > .toolbarbutton-icon {
+  opacity: 0.5;
 }
 
 #placesToolbar > toolbarbutton > .toolbarbutton-icon {
   margin: 0 4px;
 }
 
 #placesToolbar > toolbarbutton > .toolbarbutton-text {
   display: none;
@@ -170,22 +168,16 @@
   -moz-image-region: rect(0px, 64px, 16px, 48px);
 }
 
 /* maintenance button */
 #maintenanceButton {
   -moz-image-region: rect(0px, 80px, 16px, 64px);
 }
 
-/* Search field */
-
-#searchFilter:-moz-window-inactive {
-  opacity: 0.7; /* remove this when we support click-through (bug 392188) */
-}
-
 /* Root View */
 #placesView {
   border-top: 1px solid ThreeDDarkShadow;
   -moz-user-focus: ignore;
 }
 
 /* Place List, Place Content */
 .placesTree {
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -55,17 +55,16 @@ import zipfile
 SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0])))
 sys.path.insert(0, SCRIPT_DIR)
 import automationutils
 
 _DEFAULT_WEB_SERVER = "127.0.0.1"
 _DEFAULT_HTTP_PORT = 8888
 _DEFAULT_SSL_PORT = 4443
 _DEFAULT_WEBSOCKET_PORT = 9988
-_DEFAULT_WEBSOCKET_PROXY_PORT = 7777
 
 #expand _DIST_BIN = __XPC_BIN_PATH__
 #expand _IS_WIN32 = len("__WIN32__") != 0
 #expand _IS_MAC = __IS_MAC__ != 0
 #expand _IS_LINUX = __IS_LINUX__ != 0
 #ifdef IS_CYGWIN
 #expand _IS_CYGWIN = __IS_CYGWIN__ == 1
 #else
@@ -150,33 +149,30 @@ class Automation(object):
   CRASHREPORTER = _CRASHREPORTER
 
   # timeout, in seconds
   DEFAULT_TIMEOUT = 60.0
   DEFAULT_WEB_SERVER = _DEFAULT_WEB_SERVER
   DEFAULT_HTTP_PORT = _DEFAULT_HTTP_PORT
   DEFAULT_SSL_PORT = _DEFAULT_SSL_PORT
   DEFAULT_WEBSOCKET_PORT = _DEFAULT_WEBSOCKET_PORT
-  DEFAULT_WEBSOCKET_PROXY_PORT = _DEFAULT_WEBSOCKET_PROXY_PORT
 
   def __init__(self):
     self.log = _log
     self.lastTestSeen = "automation.py"
 
   def setServerInfo(self, 
                     webServer = _DEFAULT_WEB_SERVER, 
                     httpPort = _DEFAULT_HTTP_PORT, 
                     sslPort = _DEFAULT_SSL_PORT,
-                    webSocketPort = _DEFAULT_WEBSOCKET_PORT,
-                    webSocketProxyPort = _DEFAULT_WEBSOCKET_PROXY_PORT):
+                    webSocketPort = _DEFAULT_WEBSOCKET_PORT):
     self.webServer = webServer
     self.httpPort = httpPort
     self.sslPort = sslPort
     self.webSocketPort = webSocketPort
-    self.webSocketProxyPort = webSocketProxyPort
 
   @property
   def __all__(self):
     return [
            "UNIXISH",
            "IS_WIN32",
            "IS_MAC",
            "log",
@@ -402,26 +398,23 @@ function FindProxyForURL(url, host)
   if (isWebSocket)
     matches[1] = 'http';
 
   var origin = matches[1] + '://' + matches[2] + ':' + matches[3];
   if (origins.indexOf(origin) < 0)
     return 'DIRECT';
   if (isHttp)
     return 'PROXY %(remote)s:%(httpport)s';
-  if (isHttps)
+  if (isHttps || isWebSocket)
     return 'PROXY %(remote)s:%(sslport)s';
-  if (isWebSocket)
-    return 'PROXY %(remote)s:%(websocketproxyport)s';
   return 'DIRECT';
 }""" % { "origins": origins,
          "remote":  self.webServer,
          "httpport":self.httpPort,
-         "sslport": self.sslPort,
-         "websocketproxyport": self.webSocketProxyPort }
+         "sslport": self.sslPort }
       pacURL = "".join(pacURL.splitlines())
 
       part += """
 user_pref("network.proxy.type", 2);
 user_pref("network.proxy.autoconfig_url", "%(pacURL)s");
 
 user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless to others
 """ % {"pacURL": pacURL}
@@ -458,18 +451,17 @@ user_pref("camino.use_system_proxy_setti
 
     # Create head of the ssltunnel configuration file
     sslTunnelConfigPath = os.path.join(profileDir, "ssltunnel.cfg")
     sslTunnelConfig = open(sslTunnelConfigPath, "w")
   
     sslTunnelConfig.write("httpproxy:1\n")
     sslTunnelConfig.write("certdbdir:%s\n" % certPath)
     sslTunnelConfig.write("forward:127.0.0.1:%s\n" % self.httpPort)
-    sslTunnelConfig.write("proxy:%s:%s:%s\n" % 
-      (self.webSocketProxyPort, self.webServer, self.webSocketPort))
+    sslTunnelConfig.write("websocketserver:%s:%s\n" % (self.webServer, self.webSocketPort))
     sslTunnelConfig.write("listen:*:%s:pgo server certificate\n" % self.sslPort)
 
     # Configure automatic certificate and bind custom certificates, client authentication
     locations = self.readLocations()
     locations.pop(0)
     for loc in locations:
       if loc.scheme == "https" and "nocert" not in loc.options:
         customCertRE = re.compile("^cert=(?P<nickname>[0-9a-zA-Z_ ]+)")
--- a/config/Expression.py
+++ b/config/Expression.py
@@ -104,20 +104,17 @@ class Expression:
     Production: ( [0-9]+ | \w+)
     Note that the order is important, and the expression is kind-of
     ambiguous as \w includes 0-9. One could make it unambiguous by
     removing 0-9 from the first char of a string literal.
     """
     rv = None
     word_len = re.match('[0-9]*', self.content).end()
     if word_len:
-      if self.content[0] == '0':
-        value = int(self.content[:word_len], 8)
-      else:
-        value = int(self.content[:word_len])
+      value = int(self.content[:word_len])
       rv = Expression.__ASTLeaf('int', value)
     else:
       word_len = re.match('\w*', self.content).end()
       if word_len:
         rv = Expression.__ASTLeaf('string', self.content[:word_len])
       else:
         raise Expression.ParseError, self
     self.__strip(word_len)
--- a/config/Preprocessor.py
+++ b/config/Preprocessor.py
@@ -177,20 +177,17 @@ class Preprocessor:
     def handleD(option, opt, value, parser):
       vals = value.split('=', 1)
       if len(vals) == 1:
         vals.append(1)
       elif unescapeDefines and escapedValue.match(vals[1]):
         # strip escaped string values
         vals[1] = vals[1][1:-1]
       elif numberValue.match(vals[1]):
-        if vals[1][0] == '0':
-          vals[1] = int(vals[1], 8)
-        else:
-          vals[1] = int(vals[1])
+        vals[1] = int(vals[1])
       self.context[vals[0]] = vals[1]
     def handleU(option, opt, value, parser):
       del self.context[value]
     def handleF(option, opt, value, parser):
       self.do_filter(value)
     def handleLE(option, opt, value, parser):
       self.setLineEndings(value)
     def handleMarker(option, opt, value, parser):
@@ -242,20 +239,17 @@ class Preprocessor:
   def do_define(self, args):
     m = re.match('(?P<name>\w+)(?:\s(?P<value>.*))?', args, re.U)
     if not m:
       raise Preprocessor.Error(self, 'SYNTAX_DEF', args)
     val = 1
     if m.group('value'):
       val = m.group('value')
       try:
-        if val[0] == '0':
-          val = int(val, 8)
-        else:
-          val = int(val)
+        val = int(val)
       except:
         pass
     self.context[m.group('name')] = val
   def do_undef(self, args):
     m = re.match('(?P<name>\w+)$', args, re.U)
     if not m:
       raise Preprocessor.Error(self, 'SYNTAX_DEF', args)
     if args in self.context:
--- a/config/config.mk
+++ b/config/config.mk
@@ -75,16 +75,21 @@ CHECK_VARS := \
 # checks for internal spaces or trailing spaces in the variable
 # named by $x
 check-variable = $(if $(filter-out 0 1,$(words $($(x))z)),$(error Spaces are not allowed in $(x)))
 
 $(foreach x,$(CHECK_VARS),$(check-variable))
 
 core_abspath = $(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(CURDIR)/$(1)))
 
+nullstr :=
+space :=$(nullstr) # EOL
+
+core_winabspath = $(firstword $(subst /, ,$(call core_abspath,$(1)))):$(subst $(space),,$(patsubst %,\\%,$(wordlist 2,$(words $(subst /, ,$(call core_abspath,$(1)))), $(strip $(subst /, ,$(call core_abspath,$(1)))))))
+
 # FINAL_TARGET specifies the location into which we copy end-user-shipped
 # build products (typelibs, components, chrome).
 #
 # It will usually be the well-loved $(DIST)/bin, today, but can also be an
 # XPI-contents staging directory for ambitious and right-thinking extensions.
 FINAL_TARGET = $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(DIST)/bin)
 
 ifdef XPI_NAME
@@ -313,16 +318,20 @@ endif
 endif
 
 ifndef STATIC_LIBRARY_NAME
 ifdef LIBRARY_NAME
 STATIC_LIBRARY_NAME=$(LIBRARY_NAME)
 endif
 endif
 
+ifeq (WINNT,$(OS_ARCH))
+MOZ_FAKELIBS = 1
+endif
+
 # This comes from configure
 ifdef MOZ_PROFILE_GUIDED_OPTIMIZE_DISABLE
 NO_PROFILE_GUIDED_OPTIMIZE = 1
 endif
 
 # No sense in profiling tools
 ifdef INTERNAL_TOOLS
 NO_PROFILE_GUIDED_OPTIMIZE = 1
@@ -714,17 +723,17 @@ endif
 ######################################################################
 # Now test variables that might have been set or overridden by $(MY_CONFIG).
 
 DEFINES		+= -DOSTYPE=\"$(OS_CONFIG)\"
 DEFINES		+= -DOSARCH=$(OS_ARCH)
 
 ######################################################################
 
-GARBAGE		+= $(DEPENDENCIES) $(MKDEPENDENCIES) $(MKDEPENDENCIES).bak core $(wildcard core.[0-9]*) $(wildcard *.err) $(wildcard *.pure) $(wildcard *_pure_*.o) Templates.DB
+GARBAGE		+= $(DEPENDENCIES) $(MKDEPENDENCIES) $(MKDEPENDENCIES).bak core $(wildcard core.[0-9]*) $(wildcard *.err) $(wildcard *.pure) $(wildcard *_pure_*.o) Templates.DB $(FAKE_LIBRARY)
 
 ifeq ($(OS_ARCH),Darwin)
 ifndef NSDISTMODE
 NSDISTMODE=absolute_symlink
 endif
 PWD := $(CURDIR)
 endif
 
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -116,16 +116,31 @@ EXPAND_LIBNAME = $(foreach lib,$(1),$(LI
 EXPAND_LIBNAME_PATH = $(foreach lib,$(1),$(2)/$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
 EXPAND_MOZLIBNAME = $(foreach lib,$(1),$(DIST)/lib/$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
 else
 EXPAND_LIBNAME = $(addprefix -l,$(1))
 EXPAND_LIBNAME_PATH = -L$(2) $(addprefix -l,$(1))
 EXPAND_MOZLIBNAME = $(addprefix -l,$(1))
 endif
 
+ifdef MOZ_FAKELIBS
+# If a lib.fake is present, replace it with @lib.fake, otherwise just pass
+# the library name through unchanged.
+EXPAND_FAKELIBS = $(foreach f,$(1),$(if $(wildcard $(f).fake),@$(wildcard $(f).fake),$(f)))
+
+# Also override EXPAND_LIBNAME_PATH and EXPAND_MOZLIBNAME on non-RELATIVE_PATH
+# platforms, so we can shortcut linking -lfoo if we have foo.a.fake
+ifndef _LIBNAME_RELATIVE_PATHS
+EXPAND_LIBNAME_PATH = $(if $(wildcard $(2)/$(LIB_PREFIX)$(1).$(LIB_SUFFIX).fake),@$(2)/$(LIB_PREFIX)$(1).$(LIB_SUFFIX).fake,-L$(2) $(addprefix -l,$(1)))
+EXPAND_MOZLIBNAME = $(if $(wildcard $(DIST)/lib/$(LIB_PREFIX)$(1).$(LIB_SUFFIX).fake),@$(DIST)/lib/$(LIB_PREFIX)$(1).$(LIB_SUFFIX).fake,$(addprefix -l,$(1)))
+endif
+else
+EXPAND_FAKELIBS = $1
+endif
+
 ifdef EXTRA_DSO_LIBS
 EXTRA_DSO_LIBS	:= $(call EXPAND_MOZLIBNAME,$(EXTRA_DSO_LIBS))
 endif
 
 ################################################################################
 # Testing frameworks support
 ################################################################################
 
@@ -230,16 +245,21 @@ endif # ENABLE_TESTS
 #
 # If BUILD_STATIC_LIBS or FORCE_STATIC_LIB is set, build a static library.
 # Otherwise, build a shared library.
 #
 
 ifndef LIBRARY
 ifdef STATIC_LIBRARY_NAME
 LIBRARY			:= $(LIB_PREFIX)$(STATIC_LIBRARY_NAME).$(LIB_SUFFIX)
+ifdef MOZ_FAKELIBS
+ifndef SUPPRESS_FAKELIB
+FAKE_LIBRARY = $(LIBRARY).fake
+endif # SUPPRESS_FAKELIB
+endif # MOZ_FAKELIBS
 endif # STATIC_LIBRARY_NAME
 endif # LIBRARY
 
 ifndef HOST_LIBRARY
 ifdef HOST_LIBRARY_NAME
 HOST_LIBRARY		:= $(LIB_PREFIX)$(HOST_LIBRARY_NAME).$(LIB_SUFFIX)
 endif
 endif
@@ -538,17 +558,17 @@ CPP_PROG_LINK		= 1
 endif
 
 #
 # Make sure to wrap static libs inside linker specific flags to turn on & off
 # inclusion of all symbols inside the static libs
 #
 ifndef NO_LD_ARCHIVE_FLAGS
 ifdef SHARED_LIBRARY_LIBS
-EXTRA_DSO_LDOPTS := $(MKSHLIB_FORCE_ALL) $(SHARED_LIBRARY_LIBS) $(MKSHLIB_UNFORCE_ALL) $(EXTRA_DSO_LDOPTS)
+EXTRA_DSO_LDOPTS := $(MKSHLIB_FORCE_ALL) $(call EXPAND_FAKELIBS,$(SHARED_LIBRARY_LIBS)) $(MKSHLIB_UNFORCE_ALL) $(EXTRA_DSO_LDOPTS)
 endif
 endif
 
 #
 # This will strip out symbols that the component should not be 
 # exporting from the .dynsym section.
 #
 ifdef IS_COMPONENT
@@ -865,26 +885,26 @@ libs:: $(PARALLEL_DIRS_libs)
 	+@$(call SUBMAKE,libs,$*)
 endif
 
 libs:: $(SUBMAKEFILES) $(MAKE_DIRS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS) $(JAVA_LIBRARY)
 ifndef NO_DIST_INSTALL
 ifdef LIBRARY
 ifdef EXPORT_LIBRARY # Stage libs that will be linked into a static build
 ifdef IS_COMPONENT
-	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DEPTH)/staticlib/components
+	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(FAKE_LIBRARY) $(DEPTH)/staticlib/components
 else
-	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DEPTH)/staticlib
+	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(FAKE_LIBRARY) $(DEPTH)/staticlib
 endif
 endif # EXPORT_LIBRARY
 ifdef DIST_INSTALL
 ifdef IS_COMPONENT
 	$(error Shipping static component libs makes no sense.)
 else
-	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DIST)/lib
+	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(FAKE_LIBRARY) $(DIST)/lib
 endif
 endif # DIST_INSTALL
 endif # LIBRARY
 ifdef SHARED_LIBRARY
 ifdef IS_COMPONENT
 	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)/components
 	$(ELF_DYNSTR_GC) $(FINAL_TARGET)/components/$(SHARED_LIBRARY)
 ifndef NO_COMPONENTS_MANIFEST
@@ -993,20 +1013,20 @@ alltags:
 
 #
 # PROGRAM = Foo
 # creates OBJS, links with LIBS to create Foo
 #
 $(PROGRAM): $(PROGOBJS) $(LIBS_DEPS) $(EXTRA_DEPS) $(EXE_DEF_FILE) $(RESFILE) $(GLOBAL_DEPS)
 	@rm -f $@.manifest
 ifeq (WINCE,$(OS_ARCH))
-	$(LD) -NOLOGO -OUT:$@ $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
+	$(LD) -NOLOGO -OUT:$@ $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
 else
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-	$(LD) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
+	$(LD) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
 ifdef MSMANIFEST_TOOL
 	@if test -f $@.manifest; then \
 		if test -f "$(srcdir)/$@.manifest"; then \
 			echo "Embedding manifest from $(srcdir)/$@.manifest and $@.manifest"; \
 			mt.exe -NOLOGO -MANIFEST "$(win_srcdir)/$@.manifest" $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		else \
 			echo "Embedding manifest from $@.manifest"; \
 			mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
@@ -1018,19 +1038,19 @@ ifdef MSMANIFEST_TOOL
 endif	# MSVC with manifest tool
 ifdef MOZ_PROFILE_GENERATE
 # touch it a few seconds into the future to work around FAT's
 # 2-second granularity
 	touch -t `date +%Y%m%d%H%M.%S -d "now+5seconds"` pgo.relink
 endif
 else # !WINNT || GNU_CC
 ifeq ($(CPP_PROG_LINK),1)
-	$(CCC) -o $@ $(CXXFLAGS) $(WRAP_MALLOC_CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(WRAP_MALLOC_LIB) $(EXE_DEF_FILE)
+	$(CCC) -o $@ $(CXXFLAGS) $(WRAP_MALLOC_CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS)) $(BIN_FLAGS) $(call EXPAND_FAKELIBS,$(WRAP_MALLOC_LIB)) $(EXE_DEF_FILE)
 else # ! CPP_PROG_LINK
-	$(CC) -o $@ $(CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE)
+	$(CC) -o $@ $(CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS)) $(BIN_FLAGS) $(EXE_DEF_FILE)
 endif # CPP_PROG_LINK
 endif # WINNT && !GNU_CC
 endif # WINCE
 
 ifdef ENABLE_STRIP
 	$(STRIP) $@
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
@@ -1077,31 +1097,31 @@ endif
 # in one directory, it assumes everything to compile Foo is in
 # Foo.o (from either Foo.c or Foo.cpp).
 #
 # SIMPLE_PROGRAMS = Foo Bar
 # creates Foo.o Bar.o, links with LIBS to create Foo, Bar.
 #
 $(SIMPLE_PROGRAMS): %$(BIN_SUFFIX): %.$(OBJ_SUFFIX) $(LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
 ifeq (WINCE,$(OS_ARCH))
-	$(LD) -nologo  -entry:mainACRTStartup -out:$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
+	$(LD) -nologo  -entry:mainACRTStartup -out:$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
 else
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-	$(LD) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
+	$(LD) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
 ifdef MSMANIFEST_TOOL
 	@if test -f $@.manifest; then \
 		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		rm -f $@.manifest; \
 	fi
 endif	# MSVC with manifest tool
 else
 ifeq ($(CPP_PROG_LINK),1)
-	$(CCC) $(WRAP_MALLOC_CFLAGS) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(WRAP_MALLOC_LIB) $(BIN_FLAGS)
+	$(CCC) $(WRAP_MALLOC_CFLAGS) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(WRAP_MALLOC_LIB)) $(BIN_FLAGS)
 else
-	$(CC) $(WRAP_MALLOC_CFLAGS) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(WRAP_MALLOC_LIB) $(BIN_FLAGS)
+	$(CC) $(WRAP_MALLOC_CFLAGS) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(WRAP_MALLOC_LIB)) $(BIN_FLAGS)
 endif # CPP_PROG_LINK
 endif # WINNT && !GNU_CC
 endif # WINCE
 
 ifdef ENABLE_STRIP
 	$(STRIP) $@
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
@@ -1153,43 +1173,73 @@ endif
 # that are built using other static libraries.  Confused...?
 #
 ifdef SHARED_LIBRARY_LIBS
 ifeq (,$(GNU_LD)$(filter-out OS2 WINNT WINCE, $(OS_ARCH)))
 ifneq (,$(BUILD_STATIC_LIBS)$(FORCE_STATIC_LIB))
 LOBJS	+= $(SHARED_LIBRARY_LIBS)
 endif
 else
+NONFAKE_SHARED_LIBRARY_LIBS = $(filter-out %.fake,$(call EXPAND_FAKELIBS,$(SHARED_LIBRARY_LIBS)))
+ifeq (,$(NONFAKE_SHARED_LIBRARY_LIBS))
+# All of our SHARED_LIBRARY_LIBS have fake equivalents. Score!
+# Just pass the original object files around.
+# For shared libraries, these are already included in EXTRA_DSO_LDOPTS
+# above.
+ifndef SHARED_LIBRARY
+LOBJS += $(shell cat $(addsuffix .fake,$(SHARED_LIBRARY_LIBS)))
+endif
+SKIP_SUB_LOBJS := 1
+else
 ifneq (,$(filter OSF1 BSD_OS FreeBSD NetBSD OpenBSD SunOS Darwin,$(OS_ARCH)))
 CLEANUP1	:= | egrep -v '(________64ELEL_|__.SYMDEF)'
 CLEANUP2	:= rm -f ________64ELEL_ __.SYMDEF
 else
 CLEANUP2	:= true
 endif
 SUB_LOBJS	= $(shell for lib in $(SHARED_LIBRARY_LIBS); do $(AR_LIST) $${lib} $(CLEANUP1); done;)
-endif
+endif # EXPAND_FAKELIBS
+endif # SHARED_LIBARY_LIBS
 endif
 ifdef MOZILLA_PROBE_LIBS
 PROBE_LOBJS	= $(shell for lib in $(MOZILLA_PROBE_LIBS); do $(AR_LIST) $${lib} $(CLEANUP1); done;)
 endif
 ifdef DTRACE_PROBE_OBJ
 EXTRA_DEPS += $(DTRACE_PROBE_OBJ)
 endif
 
 $(LIBRARY): $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
 	rm -f $@
+ifndef SKIP_SUB_LOBJS
 ifneq (,$(GNU_LD)$(filter-out OS2 WINNT WINCE, $(OS_ARCH)))
 ifdef SHARED_LIBRARY_LIBS
 	@rm -f $(SUB_LOBJS)
 	@for lib in $(SHARED_LIBRARY_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done
 endif
 endif
+endif # SKIP_SUB_LOBJS
 	$(AR) $(AR_FLAGS) $(OBJS) $(LOBJS) $(SUB_LOBJS)
 	$(RANLIB) $@
+ifndef MOZ_FAKELIBS
+# Don't clean these up if we're building a fake lib, because then
+# we'll reference nonexistent object files in our fake lib.
 	@rm -f foodummyfilefoo $(SUB_LOBJS)
+endif
+# Also produce a .fake file that just contains the names of the object files.
+# This can be used as a response file to the linker later instead of
+# linking the actual static library.
+ifdef MOZ_FAKELIBS
+ifndef SUPPRESS_FAKELIB
+ifeq (WINNT_,$(OS_ARCH)_$(.PYMAKE))
+	echo "$(strip $(foreach f,$(OBJS) $(SEPARATE_OBJS) $(LOBJS) $(SUB_LOBJS),$(subst \,\\,$(call core_winabspath,$(f))))) " > $@.fake
+else
+	echo "$(strip $(foreach f,$(OBJS) $(SEPARATE_OBJS) $(LOBJS) $(SUB_LOBJS),$(call core_abspath,$(f)))) " > $@.fake
+endif
+endif
+endif
 
 ifeq (,$(filter-out WINNT WINCE, $(OS_ARCH)))
 $(IMPORT_LIBRARY): $(SHARED_LIBRARY)
 endif
 
 ifeq ($(OS_ARCH),OS2)
 $(DEF_FILE): $(OBJS) $(SHARED_LIBRARY_LIBS)
 	rm -f $@
@@ -1290,26 +1340,26 @@ ifdef DTRACE_LIB_DEPENDENT
 	@for lib in $(MOZILLA_PROBE_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done
 ifndef XP_MACOSX
 	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o  $(DTRACE_PROBE_OBJ) $(PROBE_LOBJS)
 endif
 	@for lib in $(MOZILLA_PROBE_LIBS); do \
 		ofiles=`$(AR_LIST) $${lib}`; \
 		$(AR_DELETE) $${lib} $$ofiles; \
 	done
-	$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(PROBE_LOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
+	$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(PROBE_LOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(call EXPAND_FAKELIBS,$(OS_LIBS) $(EXTRA_LIBS)) $(DEF_FILE) $(SHLIB_LDENDFILE)
 	@rm -f $(PROBE_LOBJS)
 	@rm -f $(DTRACE_PROBE_OBJ)
 	@for lib in $(MOZILLA_PROBE_LIBS); do \
 		if [ -L $${lib} ]; then rm -f `readlink $${lib}`; fi; \
 	done
 	@rm -f $(MOZILLA_PROBE_LIBS)
 
 else # ! DTRACE_LIB_DEPENDENT
-	$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(DTRACE_PROBE_OBJ) $(LOBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
+	$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(DTRACE_PROBE_OBJ) $(LOBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(call EXPAND_FAKELIBS,$(OS_LIBS) $(EXTRA_LIBS)) $(DEF_FILE) $(SHLIB_LDENDFILE)
 endif # DTRACE_LIB_DEPENDENT
 
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
 ifdef MSMANIFEST_TOOL
 ifdef EMBED_MANIFEST_AT
 	@if test -f $@.manifest; then \
 		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;$(EMBED_MANIFEST_AT); \
 		rm -f $@.manifest; \
--- a/config/tests/unit-Preprocessor.py
+++ b/config/tests/unit-Preprocessor.py
@@ -443,10 +443,52 @@ octal value is equal
 #else
 octal value is not equal
 #endif
 """)
     self.pp.handleCommandLine(["-DFOO=0100"])
     self.pp.do_include(f)
     self.assertEqual(self.pp.out.getvalue(), "octal value is equal\n")
 
+  def test_value_quoted_expansion(self):
+    """
+    Quoted values on the commandline don't currently have quotes stripped.
+    Pike says this is for compat reasons.
+    """
+    f = NamedIO("value_quoted_expansion.in", """#filter substitution
+@FOO@
+""")
+    self.pp.handleCommandLine(['-DFOO="ABCD"'])
+    self.pp.do_include(f)
+    self.assertEqual(self.pp.out.getvalue(), '"ABCD"\n')
+
+  def test_octal_value_quoted_expansion(self):
+    f = NamedIO("value_quoted_expansion.in", """#filter substitution
+@FOO@
+""")
+    self.pp.handleCommandLine(['-DFOO="0100"'])
+    self.pp.do_include(f)
+    self.assertEqual(self.pp.out.getvalue(), '"0100"\n')
+
+  def test_number_value_not_equals_quoted_defines(self):
+    f = NamedIO("number_value_not_equals_quoted_defines.in", """#if FOO == 1000
+number value is equal
+#else
+number value is not equal
+#endif
+""")
+    self.pp.handleCommandLine(['-DFOO="1000"'])
+    self.pp.do_include(f)
+    self.assertEqual(self.pp.out.getvalue(), "number value is not equal\n")
+
+  def test_octal_value_not_equals_quoted_defines(self):
+    f = NamedIO("octal_value_not_equals_quoted_defines.in", """#if FOO == 0100
+octal value is equal
+#else
+octal value is not equal
+#endif
+""")
+    self.pp.handleCommandLine(['-DFOO="0100"'])
+    self.pp.do_include(f)
+    self.assertEqual(self.pp.out.getvalue(), "octal value is not equal\n")
+
 if __name__ == '__main__':
   unittest.main()
--- a/configure.in
+++ b/configure.in
@@ -6437,23 +6437,16 @@ if test -n "$MOZ_INSTALLER" -a "$OS_ARCH
     if test "$MAKENSISU_VER" == "" -o \
        ! "$MAKENSISU_MAJOR_VER" == "$REQ_NSIS_MAJOR_VER" -o \
        ! "$MAKENSISU_MINOR_VER" -ge $MIN_NSIS_MINOR_VER; then
         AC_MSG_RESULT([no])
         AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path. To build without the installer reconfigure using --disable-installer.])
     fi
     AC_MSG_RESULT([yes])
     MAKENSISU="${CYGWIN_WRAPPER} $MAKENSISU"
-
-    # The Windows build for NSIS requires the iconv command line utility to
-    # convert the charset of the locale files.
-    MOZ_PATH_PROGS(HOST_ICONV, $HOST_ICONV "iconv", "")
-    if test -z "$HOST_ICONV"; then
-        AC_MSG_ERROR([To build the installer iconv is required in your path. To build without the installer reconfigure using --disable-installer.])
-    fi
 fi
 
 AC_SUBST(MOZ_INSTALLER)
 
 AC_MSG_CHECKING([for tar archiver])
 AC_CHECK_PROGS(TAR, gnutar gtar tar, "")
 if test -z "$TAR"; then
     AC_MSG_ERROR([no tar archiver found in \$PATH])
@@ -6891,16 +6884,24 @@ if test $MOZ_PLATFORM_MAEMO; then
       PKG_CHECK_MODULES(LIBHILDONFM,hildon-fm-2, _LIB_FOUND=1, _LIB_FOUND=)
       MOZ_PLATFORM_MAEMO_LIBS="$MOZ_PLATFORM_MAEMO_LIBS $LIBHILDONFM_LIBS"
       MOZ_PLATFORM_MAEMO_CFLAGS="$MOZ_PLATFORM_MAEMO_CFLAGS $LIBHILDONFM_CFLAGS"
       if test -z "$_LIB_FOUND"; then
          AC_MSG_ERROR([Hildon FM-2 is required when building for Maemo])
       fi
 
    fi
+   if test $MOZ_PLATFORM_MAEMO = 6; then
+      PKG_CHECK_MODULES(LIBCONTENTACTION, contentaction-0.1, _LIB_FOUND=1, _LIB_FOUND=)
+      MOZ_PLATFORM_MAEMO_LIBS="$MOZ_PLATFORM_MAEMO_LIBS $LIBCONTENTACTION_LIBS"
+      MOZ_PLATFORM_MAEMO_CFLAGS="$MOZ_PLATFORM_MAEMO_CFLAGS $LIBCONTENTACTION_CFLAGS"
+      if test -z "$_LIB_FOUND"; then
+         AC_MSG_ERROR([libcontentaction is required when build for Maemo])
+      fi
+   fi
 
    if test "$MOZ_PLATFORM_MAEMO" -gt 5; then
      MOZ_THUMB2=1
    fi
 
    PKG_CHECK_MODULES(LIBLOCATION,liblocation, _LIB_FOUND=1, _LIB_FOUND=)
    MOZ_PLATFORM_MAEMO_LIBS="$MOZ_PLATFORM_MAEMO_LIBS $LIBLOCATION_LIBS"
    MOZ_PLATFORM_MAEMO_CFLAGS="$MOZ_PLATFORM_MAEMO_CFLAGS $LIBLOCATION_CFLAGS"
@@ -8382,24 +8383,19 @@ if test "$MOZ_TREE_CAIRO"; then
     AC_SUBST(FC_FONT_FEATURE)
     AC_SUBST(WIN32_FONT_FEATURE)
     AC_SUBST(WIN32_DWRITE_FONT_FEATURE)
     AC_SUBST(WIN32_D2D_SURFACE_FEATURE)
     AC_SUBST(QUARTZ_FONT_FEATURE)
     AC_SUBST(PNG_FUNCTIONS_FEATURE)
     AC_SUBST(QT_SURFACE_FEATURE)
 
-    if test "$_WIN32_MSVC"; then
-        MOZ_CAIRO_LIBS='$(DEPTH)/gfx/cairo/cairo/src/mozcairo.lib $(DEPTH)/gfx/cairo/libpixman/src/mozlibpixman.lib'
-    else
-        MOZ_CAIRO_LIBS='$(DEPTH)/gfx/cairo/cairo/src/$(LIB_PREFIX)mozcairo.$(LIB_SUFFIX) $(DEPTH)/gfx/cairo/libpixman/src/$(LIB_PREFIX)mozlibpixman.$(LIB_SUFFIX)'" $CAIRO_FT_LIBS"
-
-        if test "$MOZ_X11"; then
-            MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS $XLDFLAGS -lXrender -lfreetype -lfontconfig"
-        fi
+    MOZ_CAIRO_LIBS='$(call EXPAND_LIBNAME_PATH,mozcairo,$(DEPTH)/gfx/cairo/cairo/src) $(call EXPAND_LIBNAME_PATH,mozlibpixman,$(DEPTH)/gfx/cairo/libpixman/src)' $CAIRO_FT_LIBS
+    if test "$MOZ_X11"; then
+        MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS $XLDFLAGS -lXrender -lfreetype -lfontconfig"
     fi
 
     CAIRO_FEATURES_H=gfx/cairo/cairo/src/cairo-features.h
     mv -f $CAIRO_FEATURES_H "$CAIRO_FEATURES_H".orig 2> /dev/null
 
 else
    PKG_CHECK_MODULES(CAIRO, cairo >= $CAIRO_VERSION pixman-1 freetype2 fontconfig)
    MOZ_CAIRO_CFLAGS=$CAIRO_CFLAGS
@@ -8414,17 +8410,17 @@ fi
 AC_SUBST(MOZ_TREE_CAIRO)
 AC_SUBST(MOZ_CAIRO_CFLAGS)
 AC_SUBST(MOZ_CAIRO_LIBS)
 
 dnl ========================================================
 dnl qcms
 dnl ========================================================
 
-QCMS_LIBS='$(DEPTH)/gfx/qcms/$(LIB_PREFIX)mozqcms.$(LIB_SUFFIX)'
+QCMS_LIBS='$(call EXPAND_LIBNAME_PATH,mozqcms,$(DEPTH)/gfx/qcms)'
 AC_SUBST(QCMS_LIBS)
 
 dnl ========================================================
 dnl HarfBuzz
 dnl ========================================================
 MOZ_HARFBUZZ_LIBS='$(DEPTH)/gfx/harfbuzz/src/$(LIB_PREFIX)mozharfbuzz.$(LIB_SUFFIX)'
 AC_SUBST(MOZ_HARFBUZZ_LIBS)
 
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -60,17 +60,16 @@ nsIMutationObserver.h \
 nsINameSpaceManager.h \
 nsINode.h \
 nsINodeInfo.h \
 nsINodeList.h \
 nsIRange.h \
 nsIRangeUtils.h \
 nsIScriptElement.h \
 nsIStyleSheetLinkingElement.h \
-nsIPrivateDOMImplementation.h \
 nsIContentSerializer.h \
 nsIHTMLToTextSink.h \
 nsIXPathEvaluatorInternal.h \
 mozISanitizingSerializer.h \
 nsCaseTreatment.h \
 nsContentCID.h \
 nsCopySupport.h \
 nsContentCreatorFunctions.h \
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -106,17 +106,16 @@ class nsILineBreaker;
 class nsIWordBreaker;
 class nsIJSRuntimeService;
 class nsIEventListenerManager;
 class nsIScriptContext;
 class nsIRunnable;
 class nsIInterfaceRequestor;
 template<class E> class nsCOMArray;
 struct JSRuntime;
-class nsICaseConversion;
 class nsIUGenCategory;
 class nsIWidget;
 class nsIDragSession;
 class nsPIDOMWindow;
 class nsPIDOMEventTarget;
 class nsIPresShell;
 class nsIXPConnectJSObjectHolder;
 class nsPrefOldCallback;
@@ -153,16 +152,17 @@ class Element;
 extern const char kLoadAsData[];
 
 enum EventNameType {
   EventNameType_None = 0x0000,
   EventNameType_HTML = 0x0001,
   EventNameType_XUL = 0x0002,
   EventNameType_SVGGraphic = 0x0004, // svg graphic elements
   EventNameType_SVGSVG = 0x0008, // the svg element
+  EventNameType_SMIL = 0x0016, // smil elements
 
   EventNameType_HTMLXUL = 0x0003,
   EventNameType_All = 0xFFFF
 };
 
 struct EventNameMapping
 {
   nsIAtom* mAtom;
@@ -610,21 +610,16 @@ public:
   {
     return sLineBreaker;
   }
 
   static nsIWordBreaker* WordBreaker()
   {
     return sWordBreaker;
   }
-  
-  static nsICaseConversion* GetCaseConv()
-  {
-    return sCaseConv;
-  }
 
   static nsIUGenCategory* GetGenCat()
   {
     return sGenCat;
   }
 
   /**
    * Regster aObserver as a shutdown observer. A strong reference is held
@@ -1736,17 +1731,16 @@ private:
   static nsIStringBundleService* sStringBundleService;
   static nsIStringBundle* sStringBundles[PropertiesFile_COUNT];
 
   static nsIContentPolicy* sContentPolicyService;
   static PRBool sTriedToGetContentPolicy;
 
   static nsILineBreaker* sLineBreaker;
   static nsIWordBreaker* sWordBreaker;
-  static nsICaseConversion* sCaseConv;
   static nsIUGenCategory* sGenCat;
 
   // Holds pointers to nsISupports* that should be released at shutdown
   static nsTArray<nsISupports**>* sPtrsToPtrsToRelease;
 
   static nsIScriptRuntime* sScriptRuntimes[NS_STID_ARRAY_UBOUND];
   static PRInt32 sScriptRootCount[NS_STID_ARRAY_UBOUND];
   static PRUint32 sJSGCThingRootCount;
--- a/content/base/public/nsLineBreaker.h
+++ b/content/base/public/nsLineBreaker.h
@@ -93,17 +93,18 @@ public:
   ~nsLineBreaker();
   
   static inline PRBool IsSpace(PRUnichar u) { return NS_IsSpace(u); }
 
   static inline PRBool IsComplexASCIIChar(PRUnichar u)
   {
     return !((0x0030 <= u && u <= 0x0039) ||
              (0x0041 <= u && u <= 0x005A) ||
-             (0x0061 <= u && u <= 0x007A));
+             (0x0061 <= u && u <= 0x007A) ||
+             (0x000a == u));
   }
 
   static inline PRBool IsComplexChar(PRUnichar u)
   {
     return IsComplexASCIIChar(u) ||
            NS_NeedsPlatformNativeHandling(u) ||
            (0x1100 <= u && u <= 0x11ff) || // Hangul Jamo
            (0x2000 <= u && u <= 0x21ff) || // Punctuations and Symbols
--- a/content/base/public/nsReferencedElement.h
+++ b/content/base/public/nsReferencedElement.h
@@ -171,18 +171,18 @@ private:
       return NS_OK;
     }
     virtual void SetTo(Element* aTo) { mTo = aTo; }
     virtual void Clear()
     {
       Notification::Clear(); mFrom = nsnull; mTo = nsnull;
     }
   protected:
-    nsCOMPtr<Element> mFrom;
-    nsCOMPtr<Element> mTo;
+    nsRefPtr<Element> mFrom;
+    nsRefPtr<Element> mTo;
   };
   friend class ChangeNotification;
 
   class DocumentLoadNotification : public Notification,
                                    public nsIObserver
   {
   public:
     DocumentLoadNotification(nsReferencedElement* aTarget,
@@ -201,13 +201,13 @@ private:
     virtual void SetTo(Element* aTo) { }
 
     nsString mRef;
   };
   friend class DocumentLoadNotification;
   
   nsCOMPtr<nsIAtom>      mWatchID;
   nsCOMPtr<nsIDocument>  mWatchDocument;
-  nsCOMPtr<Element> mElement;
+  nsRefPtr<Element> mElement;
   nsRefPtr<Notification> mPendingNotification;
 };
 
 #endif /*NSREFERENCEDELEMENT_H_*/
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -141,17 +141,16 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
 #include "nsIDOMUserDataHandler.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsTPtrArray.h"
 #include "nsGUIEvent.h"
 #include "nsMutationEvent.h"
 #include "nsIMEStateManager.h"
 #include "nsContentErrors.h"
 #include "nsUnicharUtilCIID.h"
-#include "nsICaseConversion.h"
 #include "nsCompressedCharMap.h"
 #include "nsINativeKeyBindings.h"
 #include "nsIDOMNSUIEvent.h"
 #include "nsIDOMNSEvent.h"
 #include "nsIPrivateDOMEvent.h"
 #include "nsXULPopupManager.h"
 #include "nsIPermissionManager.h"
 #include "nsIScriptObjectPrincipal.h"
@@ -236,17 +235,16 @@ nsDataHashtable<nsISupportsHashKey, Even
 nsDataHashtable<nsStringHashKey, EventNameMapping>* nsContentUtils::sStringEventTable = nsnull;
 nsCOMArray<nsIAtom>* nsContentUtils::sUserDefinedEvents = nsnull;
 nsIStringBundleService *nsContentUtils::sStringBundleService;
 nsIStringBundle *nsContentUtils::sStringBundles[PropertiesFile_COUNT];
 nsIContentPolicy *nsContentUtils::sContentPolicyService;
 PRBool nsContentUtils::sTriedToGetContentPolicy = PR_FALSE;
 nsILineBreaker *nsContentUtils::sLineBreaker;
 nsIWordBreaker *nsContentUtils::sWordBreaker;
-nsICaseConversion *nsContentUtils::sCaseConv;
 nsIUGenCategory *nsContentUtils::sGenCat;
 nsTArray<nsISupports**> *nsContentUtils::sPtrsToPtrsToRelease;
 nsIScriptRuntime *nsContentUtils::sScriptRuntimes[NS_STID_ARRAY_UBOUND];
 PRInt32 nsContentUtils::sScriptRootCount[NS_STID_ARRAY_UBOUND];
 PRUint32 nsContentUtils::sJSGCThingRootCount;
 #ifdef IBMBIDI
 nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nsnull;
 #endif
@@ -398,19 +396,16 @@ nsContentUtils::Init()
     sIOService = nsnull;
   }
 
   rv = CallGetService(NS_LBRK_CONTRACTID, &sLineBreaker);
   NS_ENSURE_SUCCESS(rv, rv);
   
   rv = CallGetService(NS_WBRK_CONTRACTID, &sWordBreaker);
   NS_ENSURE_SUCCESS(rv, rv);
-  
-  rv = CallGetService(NS_UNICHARUTIL_CONTRACTID, &sCaseConv);
-  NS_ENSURE_SUCCESS(rv, rv);
 
   rv = CallGetService(NS_UNICHARCATEGORY_CONTRACTID, &sGenCat);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = CallGetService(NS_IHISTORY_CONTRACTID, &sHistory);
   if (NS_FAILED(rv)) {
     NS_RUNTIMEABORT("Cannot get the history service");
     return rv;
@@ -575,16 +570,24 @@ nsContentUtils::InitializeEventTable() {
     { nsGkAtoms::onSVGResize,                   NS_SVG_RESIZE, EventNameType_None, NS_SVG_EVENT },
     { nsGkAtoms::onSVGScroll,                   NS_SVG_SCROLL, EventNameType_None, NS_SVG_EVENT },
 
     { nsGkAtoms::onSVGZoom,                     NS_SVG_ZOOM, EventNameType_None, NS_SVGZOOM_EVENT },
 
     // This is a bit hackish, but SVG's event names are weird.
     { nsGkAtoms::onzoom,                        NS_SVG_ZOOM, EventNameType_SVGSVG, NS_EVENT_NULL },
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+    { nsGkAtoms::onbegin,                       NS_SMIL_BEGIN, EventNameType_SMIL, NS_EVENT_NULL },
+    { nsGkAtoms::onbeginEvent,                  NS_SMIL_BEGIN, EventNameType_None, NS_SMIL_TIME_EVENT },
+    { nsGkAtoms::onend,                         NS_SMIL_END, EventNameType_SMIL, NS_EVENT_NULL },
+    { nsGkAtoms::onendEvent,                    NS_SMIL_END, EventNameType_None, NS_SMIL_TIME_EVENT },
+    { nsGkAtoms::onrepeat,                      NS_SMIL_REPEAT, EventNameType_SMIL, NS_EVENT_NULL },
+    { nsGkAtoms::onrepeatEvent,                 NS_SMIL_REPEAT, EventNameType_None, NS_SMIL_TIME_EVENT },
+#endif // MOZ_SMIL
 #ifdef MOZ_MEDIA
     { nsGkAtoms::onloadstart,                   NS_LOADSTART, EventNameType_HTML, NS_EVENT_NULL },
     { nsGkAtoms::onprogress,                    NS_PROGRESS, EventNameType_HTML, NS_EVENT_NULL },
     { nsGkAtoms::onsuspend,                     NS_SUSPEND, EventNameType_HTML, NS_EVENT_NULL },
     { nsGkAtoms::onemptied,                     NS_EMPTIED, EventNameType_HTML, NS_EVENT_NULL },
     { nsGkAtoms::onstalled,                     NS_STALLED, EventNameType_HTML, NS_EVENT_NULL },
     { nsGkAtoms::onplay,                        NS_PLAY, EventNameType_HTML, NS_EVENT_NULL },
     { nsGkAtoms::onpause,                       NS_PAUSE, EventNameType_HTML, NS_EVENT_NULL },
@@ -1078,17 +1081,16 @@ nsContentUtils::Shutdown()
   sXPConnect = nsnull;
   sThreadJSContextStack = nsnull;
   NS_IF_RELEASE(sSecurityManager);
   NS_IF_RELEASE(sNameSpaceManager);
   NS_IF_RELEASE(sParserService);
   NS_IF_RELEASE(sIOService);
   NS_IF_RELEASE(sLineBreaker);
   NS_IF_RELEASE(sWordBreaker);
-  NS_IF_RELEASE(sCaseConv);
   NS_IF_RELEASE(sGenCat);
 #ifdef MOZ_XTF
   NS_IF_RELEASE(sXTFService);
 #endif
   NS_IF_RELEASE(sImgLoader);
   NS_IF_RELEASE(sImgCache);
   NS_IF_RELEASE(sHistory);
   NS_IF_RELEASE(sPrefBranch);
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -113,17 +113,16 @@
 #include "nsIRefreshURI.h"
 #include "nsIWebNavigation.h"
 #include "nsIScriptError.h"
 
 #include "nsNetUtil.h"     // for NS_MakeAbsoluteURI
 
 #include "nsIScriptSecurityManager.h"
 #include "nsIPrincipal.h"
-#include "nsIPrivateDOMImplementation.h"
 
 #include "nsIDOMWindowInternal.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMElement.h"
 #include "nsFocusManager.h"
 
 // for radio group stuff
 #include "nsIDOMHTMLInputElement.h"
@@ -1219,35 +1218,30 @@ nsDOMStyleSheetSetList::GetSets(nsTArray
 
   return NS_OK;
 }
 
 // ==================================================================
 // =
 // ==================================================================
 
-class nsDOMImplementation : public nsIDOMDOMImplementation,
-                            public nsIPrivateDOMImplementation
+class nsDOMImplementation : public nsIDOMDOMImplementation
 {
 public:
   nsDOMImplementation(nsIScriptGlobalObject* aScriptObject,
                       nsIURI* aDocumentURI,
                       nsIURI* aBaseURI,
                       nsIPrincipal* aPrincipal);
   virtual ~nsDOMImplementation();
 
   NS_DECL_ISUPPORTS
 
   // nsIDOMDOMImplementation
   NS_DECL_NSIDOMDOMIMPLEMENTATION
 
-  // nsIPrivateDOMImplementation
-  NS_IMETHOD Init(nsIURI* aDocumentURI, nsIURI* aBaseURI,
-                  nsIPrincipal* aPrincipal);
-
 protected:
   nsWeakPtr mScriptObject;
   nsCOMPtr<nsIURI> mDocumentURI;
   nsCOMPtr<nsIURI> mBaseURI;
   nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
 
@@ -1279,17 +1273,16 @@ nsDOMImplementation::~nsDOMImplementatio
 {
 }
 
 DOMCI_DATA(DOMImplementation, nsDOMImplementation)
 
 // QueryInterface implementation for nsDOMImplementation
 NS_INTERFACE_MAP_BEGIN(nsDOMImplementation)
   NS_INTERFACE_MAP_ENTRY(nsIDOMDOMImplementation)
-  NS_INTERFACE_MAP_ENTRY(nsIPrivateDOMImplementation)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDOMImplementation)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMImplementation)
 NS_INTERFACE_MAP_END
 
 
 NS_IMPL_ADDREF(nsDOMImplementation)
 NS_IMPL_RELEASE(nsDOMImplementation)
 
@@ -1366,28 +1359,16 @@ nsDOMImplementation::CreateDocument(cons
   nsCOMPtr<nsIScriptGlobalObject> scriptHandlingObject =
     do_QueryReferent(mScriptObject);
 
   return nsContentUtils::CreateDocument(aNamespaceURI, aQualifiedName, aDoctype,
                                         mDocumentURI, mBaseURI, mPrincipal,
                                         scriptHandlingObject, aReturn);
 }
 
-NS_IMETHODIMP
-nsDOMImplementation::Init(nsIURI* aDocumentURI, nsIURI* aBaseURI,
-                          nsIPrincipal* aPrincipal)
-{
-  // Note: can't require that the args be non-null, since at least one
-  // caller (XMLHttpRequest) doesn't have decent args to pass in.
-  mDocumentURI = aDocumentURI;
-  mBaseURI = aBaseURI;
-  mPrincipal = aPrincipal;
-  return NS_OK;
-}
-
 // ==================================================================
 // =
 // ==================================================================
 
   // NOTE! nsDocument::operator new() zeroes out all members, so don't
   // bother initializing members to 0.
 
 nsDocument::nsDocument(const char* aContentType)
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -2955,23 +2955,18 @@ nsGenericElement::BindToTree(nsIDocument
         }
       }
     }
   }
 
   UpdateEditableState();
 
   // Now recurse into our kids
-  PRUint32 i;
-  // Don't call GetChildCount() here since that'll make XUL generate
-  // template children, which we're not in a consistent enough state for.
-  // Additionally, there's not really a need to generate the children here.
-  for (i = 0; i < mAttrsAndChildren.ChildCount(); ++i) {
-    // The child can remove itself from the parent in BindToTree.
-    nsCOMPtr<nsIContent> child = mAttrsAndChildren.ChildAt(i);
+  for (nsIContent* child = GetFirstChild(); child;
+       child = child->GetNextSibling()) {
     rv = child->BindToTree(aDocument, this, aBindingParent,
                            aCompileEventHandlers);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   nsNodeUtils::ParentChainChanged(this);
 
   // XXXbz script execution during binding can trigger some of these
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -372,16 +372,17 @@ GK_ATOM(field, "field")
 GK_ATOM(fieldset, "fieldset")
 GK_ATOM(figcaption, "figcaption")
 GK_ATOM(figure, "figure")
 GK_ATOM(fixed, "fixed")
 GK_ATOM(fixedList, "Fixed-list")
 GK_ATOM(flags, "flags")
 GK_ATOM(flex, "flex")
 GK_ATOM(flexgroup, "flexgroup")
+GK_ATOM(floating, "floating")
 GK_ATOM(floatList, "Float-list")
 GK_ATOM(floor, "floor")
 GK_ATOM(focus, "focus")
 GK_ATOM(following, "following")
 GK_ATOM(followingSibling, "following-sibling")
 GK_ATOM(font, "font")
 GK_ATOM(fontWeight, "font-weight")
 GK_ATOM(fontpicker, "fontpicker")
@@ -1303,16 +1304,22 @@ GK_ATOM(begin, "begin")
 GK_ATOM(by, "by")
 GK_ATOM(calcMode, "calcMode")
 GK_ATOM(css, "CSS")
 GK_ATOM(dur, "dur")
 GK_ATOM(keyPoints, "keyPoints")
 GK_ATOM(keySplines, "keySplines")
 GK_ATOM(keyTimes, "keyTimes")
 GK_ATOM(mozAnimateMotionDummyAttr, "_mozAnimateMotionDummyAttr")
+GK_ATOM(onbegin, "onbegin")
+GK_ATOM(onbeginEvent, "onbeginEvent")
+GK_ATOM(onend, "onend")
+GK_ATOM(onendEvent, "onendEvent")
+GK_ATOM(onrepeat, "onrepeat")
+GK_ATOM(onrepeatEvent, "onrepeatEvent")
 GK_ATOM(repeatCount, "repeatCount")
 GK_ATOM(repeatDur, "repeatDur")
 GK_ATOM(restart, "restart")
 GK_ATOM(to, "to")
 GK_ATOM(XML, "XML")
 #endif
 
 #ifdef MOZ_MATHML
--- a/content/base/src/nsImageLoadingContent.cpp
+++ b/content/base/src/nsImageLoadingContent.cpp
@@ -17,16 +17,17 @@
  *
  * The Initial Developer of the Original Code is
  * Boris Zbarsky <bzbarsky@mit.edu>.
  * Portions created by the Initial Developer are Copyright (C) 2003
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Christian Biesinger <cbiesinger@web.de>
+ *   Bobby Holley <bobbyholley@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -98,45 +99,36 @@ static void PrintReqURL(imgIRequest* req
 }
 #endif /* DEBUG_chb */
 
 
 nsImageLoadingContent::nsImageLoadingContent()
   : mObserverList(nsnull),
     mImageBlockingStatus(nsIContentPolicy::ACCEPT),
     mLoadingEnabled(PR_TRUE),
-    mStartingLoad(PR_FALSE),
     mIsImageStateForced(PR_FALSE),
     mLoading(PR_FALSE),
     // mBroken starts out true, since an image without a URI is broken....
     mBroken(PR_TRUE),
     mUserDisabled(PR_FALSE),
     mSuppressed(PR_FALSE),
-    mBlockingOnload(PR_FALSE)
+    mBlockingOnload(PR_FALSE),
+    mStateChangerDepth(0)
 {
   if (!nsContentUtils::GetImgLoader()) {
     mLoadingEnabled = PR_FALSE;
   }
 }
 
 void
 nsImageLoadingContent::DestroyImageLoadingContent()
 {
-  // If we're blocking onload for any reason, now's a good time to stop
-  SetBlockingOnload(PR_FALSE);
-
   // Cancel our requests so they won't hold stale refs to us
-  if (mCurrentRequest) {
-    mCurrentRequest->CancelAndForgetObserver(NS_ERROR_FAILURE);
-    mCurrentRequest = nsnull;
-  }
-  if (mPendingRequest) {
-    mPendingRequest->CancelAndForgetObserver(NS_ERROR_FAILURE);
-    mPendingRequest = nsnull;
-  }
+  ClearCurrentRequest(NS_BINDING_ABORTED);
+  ClearPendingRequest(NS_BINDING_ABORTED);
 }
 
 nsImageLoadingContent::~nsImageLoadingContent()
 {
   NS_ASSERTION(!mCurrentRequest && !mPendingRequest,
                "DestroyImageLoadingContent not called");
   NS_ASSERTION(!mObserverList.mObserver && !mObserverList.mNext,
                "Observers still registered?");
@@ -256,43 +248,45 @@ nsImageLoadingContent::OnStopContainer(i
   // always fired in the decoders at the same time as OnStopDecode.
   if (aRequest == mCurrentRequest)
     SetBlockingOnload(PR_FALSE);
 
   LOOP_OVER_OBSERVERS(OnStopContainer(aRequest, aContainer));
   return NS_OK;
 }
 
+// Warning - This isn't actually fired when decode is complete. Rather, it's
+// fired when load is complete. See bug 505385, and in the mean time use
+// OnStopContainer.
 NS_IMETHODIMP
 nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
                                     nsresult aStatus,
                                     const PRUnichar* aStatusArg)
 {
   // We should definitely have a request here
   NS_ABORT_IF_FALSE(aRequest, "no request?");
 
   NS_PRECONDITION(aRequest == mCurrentRequest || aRequest == mPendingRequest,
                   "Unknown request");
   LOOP_OVER_OBSERVERS(OnStopDecode(aRequest, aStatus, aStatusArg));
 
-  if (aRequest == mPendingRequest) {
-
-    // If we were blocking for the soon-to-be-obsolete request, stop doing so
-    SetBlockingOnload(PR_FALSE);
+  // XXXbholley - When we fix bug 505385,  everything here should go in
+  // OnStopRequest.
 
-    // The new image is decoded - switch to it
-    // XXXbholley - This is technically not true pre bug 505385, but I don't
-    // think it's a big enough issue to worry about handling in the mean time
-    mCurrentRequest->Cancel(NS_ERROR_IMAGE_SRC_CHANGED);
-    mPendingRequest.swap(mCurrentRequest);
+  // Our state may change. Watch it.
+  AutoStateChanger changer(this, PR_TRUE);
+
+  // If the pending request is loaded, switch to it.
+  if (aRequest == mPendingRequest) {
+    PrepareCurrentRequest() = mPendingRequest;
     mPendingRequest = nsnull;
   }
+  NS_ABORT_IF_FALSE(aRequest == mCurrentRequest,
+                    "One way or another, we should be current by now");
 
-  // XXXbholley - When we fix bug 505385,  this should go in OnStopRequest.
-  //
   // We just loaded all the data we're going to get. If we haven't done an
   // initial paint, we want to make sure the image starts decoding for 2
   // reasons:
   //
   // 1) This image is sitting idle but might need to be decoded as soon as we
   // start painting, in which case we've wasted time.
   //
   // 2) We want to block onload until all visible images are decoded. We do this
@@ -319,36 +313,26 @@ nsImageLoadingContent::OnStopDecode(imgI
     // to be suppressed for reasons other than the initial paint delay (for
     // example - being in the bfcache), but we probably aren't loading images in
     // those situations.
     if (shell->IsPaintingSuppressed())
       doRequestDecode = PR_TRUE;
 
     // If we're requesting a decode, do it
     if (doRequestDecode)
-      aRequest->RequestDecode();
+      mCurrentRequest->RequestDecode();
   }
 
-  // XXXldb What's the difference between when OnStopDecode and OnStopRequest
-  // fire?  Should we do this work there instead?  Should they just be the
-  // same?
-
+  // Fire the appropriate DOM event.
   if (NS_SUCCEEDED(aStatus)) {
     FireEvent(NS_LITERAL_STRING("load"));
   } else {
     FireEvent(NS_LITERAL_STRING("error"));
   }
 
-  // Have to check for state changes here (for example, the new load could
-  // have resulted in a broken image).  Note that we don't want to do this
-  // async, unlike the event, because while this is waiting to happen our
-  // state could change yet again, and then we'll get confused about our
-  // state.
-  UpdateImageState(PR_TRUE);
-
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsImageLoadingContent::OnStopRequest(imgIRequest* aRequest, PRBool aLastPart)
 {
   LOOP_OVER_OBSERVERS(OnStopRequest(aRequest, aLastPart));
 
@@ -508,49 +492,46 @@ nsImageLoadingContent::GetCurrentURI(nsI
   
   return NS_EnsureSafeToReturn(mCurrentURI, aURI);
 }
 
 NS_IMETHODIMP
 nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
                                             nsIStreamListener** aListener)
 {
-  NS_PRECONDITION(aListener, "null out param");
-  
-  NS_ENSURE_ARG_POINTER(aChannel);
-
   if (!nsContentUtils::GetImgLoader()) {
     return NS_ERROR_NULL_POINTER;
   }
 
-  // XXX what should we do with content policies here, if anything?
-  // Shouldn't that be done before the start of the load?
-  // XXX what about shouldProcess?
-  
   nsCOMPtr<nsIDocument> doc = GetOurDocument();
   if (!doc) {
     // Don't bother
     return NS_OK;
   }
 
-  // Null out our mCurrentURI, in case we have no image requests right now.
-  mCurrentURI = nsnull;
-  
-  CancelImageRequests(NS_ERROR_IMAGE_SRC_CHANGED, PR_FALSE,
-                      nsIContentPolicy::ACCEPT);
+  // XXX what should we do with content policies here, if anything?
+  // Shouldn't that be done before the start of the load?
+  // XXX what about shouldProcess?
 
-  nsCOMPtr<imgIRequest> & req = mCurrentRequest ? mPendingRequest : mCurrentRequest;
+  // Our state might change. Watch it.
+  AutoStateChanger changer(this, PR_TRUE);
 
+  // Do the load.
   nsresult rv = nsContentUtils::GetImgLoader()->
-    LoadImageWithChannel(aChannel, this, doc, aListener, getter_AddRefs(req));
-
-  // Make sure our state is up to date
-  UpdateImageState(PR_TRUE);
-
-  return rv;
+    LoadImageWithChannel(aChannel, this, doc, aListener,
+                         getter_AddRefs(PrepareNextRequest()));
+  if (NS_FAILED(rv)) {
+    // If we don't have a current URI, we might as well store this URI so people
+    // know what we tried (and failed) to load.
+    if (!mCurrentRequest)
+      aChannel->GetURI(getter_AddRefs(mCurrentURI));
+    FireEvent(NS_LITERAL_STRING("error"));
+    return rv;
+  }
+  return NS_OK;;
 }
 
 NS_IMETHODIMP nsImageLoadingContent::ForceReload()
 {
   nsCOMPtr<nsIURI> currentURI;
   GetCurrentURI(getter_AddRefs(currentURI));
   if (!currentURI) {
     return NS_ERROR_NOT_AVAILABLE;
@@ -623,98 +604,72 @@ nsImageLoadingContent::LoadImage(nsIURI*
   if (!aDocument) {
     aDocument = GetOurDocument();
     if (!aDocument) {
       // No reason to bother, I think...
       return NS_OK;
     }
   }
 
-
-  nsresult rv;   // XXXbz Should failures in this method fire onerror?
-
-  // Skip the URI equality check if our current image was blocked.  If
-  // that happened, we really do want to try loading again.
+  // URI equality check.
+  //
+  // We skip the equality check if our current image was blocked, since in that
+  // case we really do want to try loading again.
   if (!aForce && NS_CP_ACCEPTED(mImageBlockingStatus)) {
     nsCOMPtr<nsIURI> currentURI;
     GetCurrentURI(getter_AddRefs(currentURI));
     PRBool equal;
     if (currentURI &&
         NS_SUCCEEDED(currentURI->Equals(aNewURI, &equal)) &&
         equal) {
       // Nothing to do here.
       return NS_OK;
     }
   }
 
-  // From this point on, our state could change before return, so make
-  // sure to notify if it does.
+  // From this point on, our image state could change. Watch it.
   AutoStateChanger changer(this, aNotify);
 
-  // Use the principal of aDocument to avoid having to QI |this| an extra time.
-  // It should be the same as the principal of this node in any case.
+  // Sanity check.
+  //
+  // We use the principal of aDocument to avoid having to QI |this| an extra
+  // time. It should always be the same as the principal of this node.
 #ifdef DEBUG
   nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
-  NS_ASSERTION(thisContent &&
-               thisContent->NodePrincipal() == aDocument->NodePrincipal(),
-               "Principal mismatch?");
+  NS_ABORT_IF_FALSE(thisContent &&
+                    thisContent->NodePrincipal() == aDocument->NodePrincipal(),
+                    "Principal mismatch?");
 #endif
-  
-  // If we'll be loading a new image, we want to cancel our existing
-  // requests; the question is what reason to pass in.  If everything
-  // is going smoothly, that reason should be
-  // NS_ERROR_IMAGE_SRC_CHANGED so that our frame (if any) will know
-  // not to show the broken image icon.  If the load is blocked by the
-  // content policy or security manager, we will want to cancel with
-  // the error code from those.
 
-  PRInt16 newImageStatus;
-  PRBool loadImage = nsContentUtils::CanLoadImage(aNewURI, this, aDocument,
-                                                  aDocument->NodePrincipal(),
-                                                  &newImageStatus);
-  NS_ASSERTION(loadImage || !NS_CP_ACCEPTED(newImageStatus),
-               "CanLoadImage lied");
-
-  nsresult cancelResult = loadImage ? NS_ERROR_IMAGE_SRC_CHANGED
-                                    : NS_ERROR_IMAGE_BLOCKED;
-
-  CancelImageRequests(cancelResult, PR_FALSE, newImageStatus);
-
-  // Remember the URL of this request, in case someone asks us for it later.
-  // But this only matters if we are affecting the current request.  Need to do
-  // this after CancelImageRequests, since that affects the value of
-  // mCurrentRequest.
-  if (!mCurrentRequest) {
-    mCurrentURI = aNewURI;
-  }
-  
-  if (!loadImage) {
-    // Don't actually load anything!  This was blocked by CanLoadImage.
+  // Are we blocked?
+  PRInt16 cpDecision = nsIContentPolicy::REJECT_REQUEST;
+  nsContentUtils::CanLoadImage(aNewURI, this, aDocument,
+                               aDocument->NodePrincipal(), &cpDecision);
+  if (!NS_CP_ACCEPTED(cpDecision)) {
     FireEvent(NS_LITERAL_STRING("error"));
+    SetBlockedRequest(aNewURI, cpDecision);
     return NS_OK;
   }
 
-  nsCOMPtr<imgIRequest> & req = mCurrentRequest ? mPendingRequest : mCurrentRequest;
-
+  // Not blocked. Do the load.
+  nsresult rv;
   rv = nsContentUtils::LoadImage(aNewURI, aDocument,
                                  aDocument->NodePrincipal(),
                                  aDocument->GetDocumentURI(),
                                  this, aLoadFlags,
-                                 getter_AddRefs(req));
+                                 getter_AddRefs(PrepareNextRequest()));
   if (NS_FAILED(rv)) {
+    // If we don't have a current URI, we might as well store this URI so people
+    // know what we tried (and failed) to load.
+    if (!mCurrentRequest)
+      mCurrentURI = aNewURI;
     FireEvent(NS_LITERAL_STRING("error"));
     return NS_OK;
   }
 
-  // If we now have a current request, we don't need to store the URI, since
-  // we can get it off the request. Release it.
-  if (mCurrentRequest) {
-    mCurrentURI = nsnull;
-  }
-
   return NS_OK;
 }
 
 nsresult
 nsImageLoadingContent::ForceImageState(PRBool aForce, PRInt32 aState)
 {
   mIsImageStateForced = aForce;
   mForcedImageState = aState;
@@ -729,22 +684,23 @@ nsImageLoadingContent::ImageState() cons
     (mUserDisabled * NS_EVENT_STATE_USERDISABLED) |
     (mSuppressed * NS_EVENT_STATE_SUPPRESSED) |
     (mLoading * NS_EVENT_STATE_LOADING);
 }
 
 void
 nsImageLoadingContent::UpdateImageState(PRBool aNotify)
 {
-  if (mStartingLoad) {
-    // Ignore this call; we'll update our state when the state changer is
-    // destroyed.  Need this to work around the fact that some libpr0n stuff is
-    // actually sync and hence we can get OnStopDecode called while we're still
-    // under LoadImage, and OnStopDecode doesn't know anything about
-    // aNotify
+  if (mStateChangerDepth > 0) {
+    // Ignore this call; we'll update our state when the outermost state
+    // changer is destroyed. Need this to work around the fact that some libpr0n
+    // stuff is actually sync and hence we can get OnStopDecode called while
+    // we're still under LoadImage, and OnStopDecode doesn't know anything about
+    // aNotify.
+    // XXX - This machinery should be removed after bug 521604.
     return;
   }
   
   nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
   if (!thisContent) {
     return;
   }
 
@@ -783,88 +739,38 @@ nsImageLoadingContent::UpdateImageState(
       }
     }
   }
 }
 
 void
 nsImageLoadingContent::CancelImageRequests(PRBool aNotify)
 {
-  // Make sure to null out mCurrentURI here, so we no longer look like an image
   AutoStateChanger changer(this, aNotify);
-  mCurrentURI = nsnull;
-  CancelImageRequests(NS_BINDING_ABORTED, PR_TRUE, nsIContentPolicy::ACCEPT);
-}
-
-void
-nsImageLoadingContent::CancelImageRequests(nsresult aReason,
-                                           PRBool   aEvenIfSizeAvailable,
-                                           PRInt16  aNewImageStatus)
-{
-  // Cancel the pending request, if any
-  if (mPendingRequest) {
-    mPendingRequest->Cancel(aReason);
-    mPendingRequest = nsnull;
-  }
-
-  // Cancel the current request if it has not progressed enough to
-  // have a size yet
-  if (mCurrentRequest) {
-    PRUint32 loadStatus = imgIRequest::STATUS_ERROR;
-    mCurrentRequest->GetImageStatus(&loadStatus);
-
-    NS_ASSERTION(NS_CP_ACCEPTED(mImageBlockingStatus),
-                 "Have current request but blocked image?");
-    
-    if (aEvenIfSizeAvailable ||
-        !(loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) {
-      // The new image is going to become the current request.  Make sure to
-      // set mImageBlockingStatus _before_ we cancel the request... if we set
-      // it after, things that are watching the mCurrentRequest will get wrong
-      // data.
-
-      // If we were blocking onload for this image, stop doing so
-      SetBlockingOnload(PR_FALSE);
-
-      // Get rid of it
-      mImageBlockingStatus = aNewImageStatus;
-      mCurrentRequest->Cancel(aReason);
-      mCurrentRequest = nsnull;
-    }
-  } else {
-    // No current request so the new image status will become the
-    // status of the current request
-    mImageBlockingStatus = aNewImageStatus;
-  }
-
-  // Note that the only way we could have avoided setting the image blocking
-  // status above is if we have a current request and have kept it as the
-  // current request.  In that case, we want to leave our old status, since the
-  // status corresponds to the current request.  Even if we plan to do a
-  // pending request load, having an mCurrentRequest means that our current
-  // status is not a REJECT_* status, and doing the load shouldn't change that.
-  // XXXbz there is an issue here if different ACCEPT statuses are used, but...
+  ClearPendingRequest(NS_BINDING_ABORTED);
+  ClearCurrentRequest(NS_BINDING_ABORTED);
 }
 
 nsresult
 nsImageLoadingContent::UseAsPrimaryRequest(imgIRequest* aRequest,
                                            PRBool aNotify)
 {
-  // Use an AutoStateChanger so that the clone call won't
-  // automatically notify from inside OnStopDecode.
-  // Also, make sure to use the CancelImageRequests which doesn't
-  // notify, so that the changer is handling the notifications.
-  NS_PRECONDITION(aRequest, "Must have a request here!");
+  // Our state will change. Watch it.
   AutoStateChanger changer(this, aNotify);
-  mCurrentURI = nsnull;
-  CancelImageRequests(NS_BINDING_ABORTED, PR_TRUE, nsIContentPolicy::ACCEPT);
+
+  // Get rid if our existing images
+  ClearPendingRequest(NS_BINDING_ABORTED);
+  ClearCurrentRequest(NS_BINDING_ABORTED);
 
-  NS_ASSERTION(!mCurrentRequest, "We should not have a current request now");
+  // Clone the request we were given.
+  nsCOMPtr<imgIRequest> newRequest;
+  nsresult rv = aRequest->Clone(this, getter_AddRefs(PrepareNextRequest()));
+  NS_ENSURE_SUCCESS(rv, rv);
 
-  return aRequest->Clone(this, getter_AddRefs(mCurrentRequest));
+  return NS_OK;
 }
 
 nsIDocument*
 nsImageLoadingContent::GetOurDocument()
 {
   nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
   NS_ENSURE_TRUE(thisContent, nsnull);
 
@@ -906,16 +812,122 @@ nsImageLoadingContent::FireEvent(const n
 
   nsRefPtr<nsPLDOMEvent> event =
     new nsLoadBlockingPLDOMEvent(thisNode, aEventType, PR_FALSE, PR_FALSE);
   event->PostDOMEvent();
   
   return NS_OK;
 }
 
+nsCOMPtr<imgIRequest>&
+nsImageLoadingContent::PrepareNextRequest()
+{
+  // If we don't have a usable current request, get rid of any half-baked
+  // request that might be sitting there and make this one current.
+  if (!HaveSize(mCurrentRequest))
+    return PrepareCurrentRequest();
+
+  // Otherwise, make it pending.
+  return PreparePendingRequest();
+}
+
+void
+nsImageLoadingContent::SetBlockedRequest(nsIURI* aURI, PRInt16 aContentDecision)
+{
+  // Sanity
+  NS_ABORT_IF_FALSE(!NS_CP_ACCEPTED(aContentDecision), "Blocked but not?");
+
+  // We do some slightly illogical stuff here to maintain consistency with
+  // old behavior that people probably depend on. Even in the case where the
+  // new image is blocked, the old one should really be canceled with the
+  // reason "image source changed". However, apparently there's some abuse
+  // over in nsImageFrame where the displaying of the "broken" icon for the
+  // next image depends on the cancel reason of the previous image. ugh.
+  ClearPendingRequest(NS_ERROR_IMAGE_BLOCKED);
+
+  // For the blocked case, we only want to cancel the existing current request
+  // if size is not available. bz says the web depends on this behavior.
+  if (!HaveSize(mCurrentRequest)) {
+
+    mImageBlockingStatus = aContentDecision;
+    ClearCurrentRequest(NS_ERROR_IMAGE_BLOCKED);
+
+    // We still want to remember what URI we were despite not having an actual
+    // request.
+    mCurrentURI = aURI;
+  }
+}
+
+nsCOMPtr<imgIRequest>&
+nsImageLoadingContent::PrepareCurrentRequest()
+{
+  // Blocked images go through SetBlockedRequest, which is a separate path. For
+  // everything else, we're unblocked.
+  mImageBlockingStatus = nsIContentPolicy::ACCEPT;
+
+  // Get rid of anything that was there previously.
+  ClearCurrentRequest(NS_ERROR_IMAGE_SRC_CHANGED);
+
+  // Return a reference.
+  return mCurrentRequest;
+}
+
+nsCOMPtr<imgIRequest>&
+nsImageLoadingContent::PreparePendingRequest()
+{
+  // Get rid of anything that was there previously.
+  ClearPendingRequest(NS_ERROR_IMAGE_SRC_CHANGED);
+
+  // Return a reference.
+  return mPendingRequest;
+}
+
+void
+nsImageLoadingContent::ClearCurrentRequest(nsresult aReason)
+{
+  if (!mCurrentRequest) {
+    // Even if we didn't have a current request, we might have been keeping
+    // a URI as a placeholder for a failed load. Clear that now.
+    mCurrentURI = nsnull;
+    return;
+  }
+  NS_ABORT_IF_FALSE(!mCurrentURI,
+                    "Shouldn't have both mCurrentRequest and mCurrentURI!");
+
+  // Clean up the request.
+  mCurrentRequest->CancelAndForgetObserver(aReason);
+  mCurrentRequest = nsnull;
+
+  // We only block onload during the decoding of "current" images. This one is
+  // going away, so we should unblock unconditionally here.
+  SetBlockingOnload(PR_FALSE);
+}
+
+void
+nsImageLoadingContent::ClearPendingRequest(nsresult aReason)
+{
+  if (!mPendingRequest)
+    return;
+  mPendingRequest->CancelAndForgetObserver(aReason);
+  mPendingRequest = nsnull;
+}
+
+bool
+nsImageLoadingContent::HaveSize(imgIRequest *aImage)
+{
+  // Handle the null case
+  if (!aImage)
+    return false;
+
+  // Query the image
+  PRUint32 status;
+  nsresult rv = aImage->GetImageStatus(&status);
+  return (NS_SUCCEEDED(rv) && (status & imgIRequest::STATUS_SIZE_AVAILABLE));
+}
+
 void
 nsImageLoadingContent::SetBlockingOnload(PRBool aBlocking)
 {
   // If we're already in the desired state, we have nothing to do
   if (mBlockingOnload == aBlocking)
     return;
 
   // Get the document
@@ -935,16 +947,16 @@ nsImageLoadingContent::SetBlockingOnload
 
 void
 nsImageLoadingContent::CreateStaticImageClone(nsImageLoadingContent* aDest) const
 {
   aDest->mCurrentRequest = nsContentUtils::GetStaticRequest(mCurrentRequest);
   aDest->mForcedImageState = mForcedImageState;
   aDest->mImageBlockingStatus = mImageBlockingStatus;
   aDest->mLoadingEnabled = mLoadingEnabled;
-  aDest->mStartingLoad = mStartingLoad;
+  aDest->mStateChangerDepth = mStateChangerDepth;
   aDest->mIsImageStateForced = mIsImageStateForced;
   aDest->mLoading = mLoading;
   aDest->mBroken = mBroken;
   aDest->mUserDisabled = mUserDisabled;
   aDest->mSuppressed = mSuppressed;
 }
 
--- a/content/base/src/nsImageLoadingContent.h
+++ b/content/base/src/nsImageLoadingContent.h
@@ -184,23 +184,21 @@ private:
    * Struct to report state changes
    */
   struct AutoStateChanger {
     AutoStateChanger(nsImageLoadingContent* aImageContent,
                      PRBool aNotify) :
       mImageContent(aImageContent),
       mNotify(aNotify)
     {
-      NS_ASSERTION(!mImageContent->mStartingLoad,
-                   "Nested AutoStateChangers somehow?");
-      mImageContent->mStartingLoad = PR_TRUE;
+      mImageContent->mStateChangerDepth++;
     }
     ~AutoStateChanger()
     {
-      mImageContent->mStartingLoad = PR_FALSE;
+      mImageContent->mStateChangerDepth--;
       mImageContent->UpdateImageState(mNotify);
     }
 
     nsImageLoadingContent* mImageContent;
     PRBool mNotify;
   };
 
   friend struct AutoStateChanger;
@@ -243,19 +241,60 @@ private:
    * Method to fire an event once we know what's going on with the image load.
    *
    * @param aEventType "load" or "error" depending on how things went
    */
   nsresult FireEvent(const nsAString& aEventType);
 protected:
   void CreateStaticImageClone(nsImageLoadingContent* aDest) const;
 
+  /**
+   * Prepare and returns a reference to the "next request". If there's already
+   * a _usable_ current request (one with SIZE_AVAILABLE), this request is
+   * "pending" until it becomes usable. Otherwise, this becomes the current
+   * request.
+   */
+   nsCOMPtr<imgIRequest>& PrepareNextRequest();
+
+  /**
+   * Called when we would normally call PrepareNextRequest(), but the request was
+   * blocked.
+   */
+  void SetBlockedRequest(nsIURI* aURI, PRInt16 aContentDecision);
+
+  /**
+   * Returns a COMPtr reference to the current/pending image requests, cleaning
+   * up and canceling anything that was there before. Note that if you just want
+   * to get rid of one of the requests, you should call
+   * Clear*Request(NS_BINDING_ABORTED) instead, since it passes a more appropriate
+   * aReason than Prepare*Request() does (NS_ERROR_IMAGE_SRC_CHANGED).
+   */
+  nsCOMPtr<imgIRequest>& PrepareCurrentRequest();
+  nsCOMPtr<imgIRequest>& PreparePendingRequest();
+
+  /**
+   * Cancels and nulls-out the "current" and "pending" requests if they exist.
+   */
+  void ClearCurrentRequest(nsresult aReason);
+  void ClearPendingRequest(nsresult aReason);
+
+  /**
+   * Static helper method to tell us if we have the size of a request. The
+   * image may be null.
+   */
+  static bool HaveSize(imgIRequest *aImage);
+
   /* MEMBERS */
   nsCOMPtr<imgIRequest> mCurrentRequest;
   nsCOMPtr<imgIRequest> mPendingRequest;
+
+  // If the image was blocked or if there was an error loading, it's nice to
+  // still keep track of what the URI was despite not having an imgIRequest.
+  // We only maintain this in those situations (in the common case, this is
+  // always null).
   nsCOMPtr<nsIURI>      mCurrentURI;
 
 private:
   /**
    * Typically we will have only one observer (our frame in the screen
    * prescontext), so we want to only make space for one and to
    * heap-allocate anything past that (saves memory and malloc churn
    * in the common case).  The storage is a linked list, we just
@@ -267,17 +306,16 @@ private:
   /**
    * When mIsImageStateForced is true, this holds the ImageState that we'll
    * return in ImageState().
    */
   PRInt32 mForcedImageState;
 
   PRInt16 mImageBlockingStatus;
   PRPackedBool mLoadingEnabled : 1;
-  PRPackedBool mStartingLoad : 1;
 
   /**
    * When true, we return mForcedImageState from ImageState().
    */
   PRPackedBool mIsImageStateForced : 1;
 
   /**
    * The state we had the last time we checked whether we needed to notify the
@@ -287,11 +325,14 @@ private:
   PRPackedBool mBroken : 1;
   PRPackedBool mUserDisabled : 1;
   PRPackedBool mSuppressed : 1;
 
   /**
    * Whether we're currently blocking document load.
    */
   PRPackedBool mBlockingOnload : 1;
+
+  /* The number of nested AutoStateChangers currently tracking our state. */
+  PRUint8 mStateChangerDepth;
 };
 
 #endif // nsImageLoadingContent_h__
--- a/content/base/src/nsSyncLoadService.cpp
+++ b/content/base/src/nsSyncLoadService.cpp
@@ -45,18 +45,16 @@
 #include "nsIChannel.h"
 #include "nsIDOMLoadListener.h"
 #include "nsIChannelEventSink.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsString.h"
 #include "nsWeakReference.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMDOMImplementation.h"
-#include "nsIPrivateDOMImplementation.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsContentUtils.h"
 #include "nsThreadUtils.h"
 #include "nsNetUtil.h"
 #include "nsAutoPtr.h"
 #include "nsLoadListenerProxy.h"
 #include "nsStreamUtils.h"
 #include "nsCrossSiteListenerProxy.h"
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -247,16 +247,17 @@ WebGLContext::SetDimensions(PRInt32 widt
     // If we already have a gl context, then we just need to resize
     // FB0.
     if (gl &&
         gl->ResizeOffscreen(gfxIntSize(width, height)))
     {
         // everything's good, we're done here
         mWidth = width;
         mHeight = height;
+        mResetLayer = PR_TRUE;
         return NS_OK;
     }
 
     // We're going to create an entirely new context.  If our
     // generation is not 0 right now (that is, if this isn't the first
     // context we're creating), we may have to dispatch a context lost
     // event.
 
@@ -314,21 +315,17 @@ WebGLContext::SetDimensions(PRInt32 widt
 
     MakeContextCurrent();
 
     // Make sure that we clear this out, otherwise
     // we'll end up displaying random memory
     gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, gl->GetOffscreenFBO());
     gl->fViewport(0, 0, mWidth, mHeight);
     gl->fClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-#ifdef USE_GLES2
-    gl->fClearDepthf(1.0f);
-#else
     gl->fClearDepth(1.0f);
-#endif
     gl->fClearStencil(0);
     gl->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::Render(gfxContext *ctx, gfxPattern::GraphicsFilter f)
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -521,21 +521,17 @@ WebGLContext::Clear(PRUint32 mask)
     gl->fClear(mask);
     Invalidate();
 
     return NS_OK;
 }
 
 GL_SAME_METHOD_4(ClearColor, ClearColor, WebGLfloat, WebGLfloat, WebGLfloat, WebGLfloat)
 
-#ifdef USE_GLES2
-GL_SAME_METHOD_1(ClearDepthf, ClearDepth, WebGLfloat)
-#else
 GL_SAME_METHOD_1(ClearDepth, ClearDepth, WebGLfloat)
-#endif
 
 GL_SAME_METHOD_1(ClearStencil, ClearStencil, WebGLint)
 
 GL_SAME_METHOD_4(ColorMask, ColorMask, WebGLboolean, WebGLboolean, WebGLboolean, WebGLboolean)
 
 NS_IMETHODIMP
 WebGLContext::CopyTexImage2D(WebGLenum target,
                              WebGLint level,
@@ -829,21 +825,17 @@ WebGLContext::DepthFunc(WebGLenum func)
 
     MakeContextCurrent();
     gl->fDepthFunc(func);
     return NS_OK;
 }
 
 GL_SAME_METHOD_1(DepthMask, DepthMask, WebGLboolean)
 
-#ifdef USE_GLES2
-GL_SAME_METHOD_2(DepthRangef, DepthRange, WebGLfloat, WebGLfloat)
-#else
 GL_SAME_METHOD_2(DepthRange, DepthRange, WebGLfloat, WebGLfloat)
-#endif
 
 NS_IMETHODIMP
 WebGLContext::DisableVertexAttribArray(WebGLuint index)
 {
     if (index > mAttribBuffers.Length())
         return ErrorInvalidValue("DisableVertexAttribArray: index out of range");
 
     MakeContextCurrent();
@@ -1337,28 +1329,28 @@ WebGLContext::GetParameter(PRUint32 pnam
             GLint i = 0;
             gl->fGetIntegerv(pname, &i);
             wrval->SetAsInt32(i);
         }
             break;
 
         case LOCAL_GL_MAX_VARYING_VECTORS:
         {
-            #ifdef USE_GLES2
+            if (gl->IsGLES2()) {
                 GLint i = 0;
                 gl->fGetIntegerv(pname, &i);
                 wrval->SetAsInt32(i);
-            #else
+            } else {
                 // since this pname is absent from desktop OpenGL, we have to implement it by hand.
                 // The formula below comes from the public_webgl list, "problematic GetParameter pnames" thread
                 GLint i = 0, j = 0;
                 gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS, &i);
                 gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS, &j);
                 wrval->SetAsInt32(PR_MIN(i,j)/4);
-            #endif
+            }
         }
             break;
 
         case LOCAL_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
             wrval->SetAsInt32(0);
             break;
         case LOCAL_GL_COMPRESSED_TEXTURE_FORMATS:
             wrval->SetAsVoid(); // the spec says we must return null
@@ -2914,22 +2906,22 @@ WebGLContext::CompileShader(nsIWebGLShad
         resources.maxVertexUniformVectors = mGLMaxVertexUniformVectors;
         resources.maxVaryingVectors = mGLMaxVaryingVectors;
         resources.maxVertexTextureImageUnits = mGLMaxVertexTextureImageUnits;
         resources.maxCombinedTextureImageUnits = mGLMaxTextureUnits;
         resources.maxTextureImageUnits = mGLMaxTextureImageUnits;
         resources.maxFragmentUniformVectors = mGLMaxFragmentUniformVectors;
         resources.maxDrawBuffers = 1;
 
-        compiler = ShConstructCompiler(lang, debugFlags);
+        compiler = ShConstructCompiler(lang, EShSpecWebGL, &resources);
 
         nsDependentCString src(shader->Source());
         const char *s = src.get();
 
-        if (!ShCompile(compiler, &s, 1, EShOptNone, &resources, debugFlags)) {
+        if (!ShCompile(compiler, &s, 1, EShOptSimple, debugFlags)) {
             shader->SetTranslationFailure(nsDependentCString(ShGetInfoLog(compiler)));
             ShDestruct(compiler);
             return NS_OK;
         }
 
         s = ShGetObjectCode(compiler);
         gl->fShaderSource(shadername, 1, &s, NULL);
         shader->SetTranslationSuccess();
--- a/content/canvas/src/WebGLContextValidate.cpp
+++ b/content/canvas/src/WebGLContextValidate.cpp
@@ -402,45 +402,52 @@ WebGLContext::InitAndValidateGL()
     mBoundCubeMapTextures.SetLength(mGLMaxTextureUnits);
 
     gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize);
     gl->fGetIntegerv(LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE, (GLint*) &mGLMaxCubeMapTextureSize);
 
     gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS, (GLint*) &mGLMaxTextureImageUnits);
     gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, (GLint*) &mGLMaxVertexTextureImageUnits);
 
-#ifdef USE_GLES2
-    gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS, (GLint*) &mGLMaxFragmentUniformVectors);
-    gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS, (GLint*) &mGLMaxVertexUniformVectors);
-    gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_VECTORS, (GLint*) &mGLMaxVaryingVectors);
+    if (gl->IsGLES2()) {
+        gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS, (GLint*) &mGLMaxFragmentUniformVectors);
+        gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS, (GLint*) &mGLMaxVertexUniformVectors);
+        gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_VECTORS, (GLint*) &mGLMaxVaryingVectors);
+    } else {
+        gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, (GLint*) &mGLMaxFragmentUniformVectors);
+        mGLMaxFragmentUniformVectors /= 4;
+        gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS, (GLint*) &mGLMaxVertexUniformVectors);
+        mGLMaxVertexUniformVectors /= 4;
+        gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_FLOATS, (GLint*) &mGLMaxVaryingVectors);
+        mGLMaxVaryingVectors /= 4;
+    }
+
+#if 0
+    // Leaving this code in here, even though it's ifdef'd out, for
+    // when we support more than 1 color attachment.
+    gl->fGetIntegerv(LOCAL_GL_MAX_COLOR_ATTACHMENTS, (GLint*) &val);
 #else
-    gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, (GLint*) &mGLMaxFragmentUniformVectors);
-    mGLMaxFragmentUniformVectors /= 4;
-    gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS, (GLint*) &mGLMaxVertexUniformVectors);
-    mGLMaxVertexUniformVectors /= 4;
-    gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_FLOATS, (GLint*) &mGLMaxVaryingVectors);
-    mGLMaxVaryingVectors /= 4;
+    // Always 1 for GLES2
+    val = 1;
 #endif
-
-    gl->fGetIntegerv(LOCAL_GL_MAX_COLOR_ATTACHMENTS, (GLint*) &val);
     mFramebufferColorAttachments.SetLength(val);
 
 #if defined(DEBUG_vladimir) && defined(USE_GLES2)
     gl->fGetIntegerv(LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT, (GLint*) &val);
     fprintf(stderr, "GL_IMPLEMENTATION_COLOR_READ_FORMAT: 0x%04x\n", val);
 
     gl->fGetIntegerv(LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE, (GLint*) &val);
     fprintf(stderr, "GL_IMPLEMENTATION_COLOR_READ_TYPE: 0x%04x\n", val);
 #endif
 
-#ifndef USE_GLES2
-    // gl_PointSize is always available in ES2 GLSL, but has to be
-    // specifically enabled on desktop GLSL.
-    gl->fEnable(LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE);
-#endif
+    if (!gl->IsGLES2()) {
+        // gl_PointSize is always available in ES2 GLSL, but has to be
+        // specifically enabled on desktop GLSL.
+        gl->fEnable(LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE);
+    }
 
 #if !defined(USE_GLES2) && defined(USE_ANGLE)
     // initialize shader translator
     static bool didTranslatorInit = false;
     if (!didTranslatorInit && mShaderValidation) {
         if (!ShInitialize()) {
             LogMessage("GLSL translator initialization failed!");
             return PR_FALSE;
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -3514,21 +3514,26 @@ nsCanvasRenderingContext2D::DrawImage(ns
 
                 ShadowFinalize(blur);
             }
         }
 
         mThebes->SetPattern(pattern);
         DirtyAllStyles();
 
-        mThebes->Clip(clip);
-
+        /* Direct2D isn't very good at clipping so use Fill() when we can */
+        if (CurrentState().globalAlpha == 1.0f && mThebes->CurrentOperator() == gfxContext::OPERATOR_OVER) {
+            mThebes->Rectangle(clip);
+            mThebes->Fill();
+        } else {
+            /* we need to use to clip instead of fill for globalAlpha */
+            mThebes->Clip(clip);
+            mThebes->Paint(CurrentState().globalAlpha);
+        }
         dirty = mThebes->UserToDevice(clip);
-
-        mThebes->Paint(CurrentState().globalAlpha);
     }
 
 #if 1
     // XXX cairo bug workaround; force a clip update on mThebes.
     // Otherwise, a pixman clip gets left around somewhere, and pixman
     // (Render) does source clipping as well -- so we end up
     // compositing with an incorrect clip.  This only seems to affect
     // fallback cases, which happen when we have CSS scaling going on.
--- a/content/events/public/nsIEventStateManager.h
+++ b/content/events/public/nsIEventStateManager.h
@@ -48,20 +48,20 @@ class nsIDOMEvent;
 class nsIFrame;
 class nsIView;
 class nsIWidget;
 class imgIContainer;
 
 /*
  * Event state manager interface.
  */
-// {C224A806-A99F-4056-85C2-3B1970F94DB2}
+// {92EDD580-062E-4471-ADEB-68329B0EC2E4}
 #define NS_IEVENTSTATEMANAGER_IID \
-{ 0xc224a806, 0xa99f, 0x4056, \
-  { 0x85, 0xc2, 0x3b, 0x19, 0x70, 0xf9, 0x4d, 0xb2 } }
+{ 0x92edd580, 0x062e, 0x4471, \
+  { 0xad, 0xeb, 0x68, 0x32, 0x9b, 0x0e, 0xc2, 0xe4 } }
 
 #define NS_EVENT_NEEDS_FRAME(event) (!NS_IS_ACTIVATION_EVENT(event))
 
 class nsIEventStateManager : public nsISupports {
 
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IEVENTSTATEMANAGER_IID)
 
@@ -207,14 +207,14 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIEventSt
 // Handler for the content has been disabled
 #define NS_EVENT_STATE_HANDLER_DISABLED \
                                      (1 << 26)
 
 #define NS_EVENT_STATE_INDETERMINATE (1 << 27) // CSS3-Selectors
 
 // Handler for the content has crashed
 #define NS_EVENT_STATE_HANDLER_CRASHED \
-                                     0x08000000
+                                     (1 << 28)
 
 // content has focus and should show a ring
-#define NS_EVENT_STATE_FOCUSRING     0x10000000
+#define NS_EVENT_STATE_FOCUSRING     (1 << 29)
 
 #endif // nsIEventStateManager_h__
--- a/content/events/public/nsIPrivateDOMEvent.h
+++ b/content/events/public/nsIPrivateDOMEvent.h
@@ -98,16 +98,20 @@ NS_NewDOMBeforeUnloadEvent(nsIDOMEvent**
 nsresult
 NS_NewDOMPageTransitionEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
 #ifdef MOZ_SVG
 nsresult
 NS_NewDOMSVGEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsEvent* aEvent);
 nsresult
 NS_NewDOMSVGZoomEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsGUIEvent* aEvent);
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+nsresult
+NS_NewDOMTimeEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsEvent* aEvent);
+#endif // MOZ_SMIL
 nsresult
 NS_NewDOMXULCommandEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsInputEvent* aEvent);
 nsresult
 NS_NewDOMCommandEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsCommandEvent* aEvent);
 nsresult
 NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
 nsresult
 NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -76,16 +76,19 @@ static const char* const sEventNames[] =
   "DOMAttrModified", "DOMCharacterDataModified",
   "DOMActivate", "DOMFocusIn", "DOMFocusOut",
   "pageshow", "pagehide", "DOMMouseScroll", "MozMousePixelScroll",
   "offline", "online", "copy", "cut", "paste",
 #ifdef MOZ_SVG
   "SVGLoad", "SVGUnload", "SVGAbort", "SVGError", "SVGResize", "SVGScroll",
   "SVGZoom",
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+  "beginEvent", "endEvent", "repeatEvent",
+#endif // MOZ_SMIL
 #ifdef MOZ_MEDIA
   "loadstart", "progress", "suspend", "emptied", "stalled", "play", "pause",
   "loadedmetadata", "loadeddata", "waiting", "playing", "canplay",
   "canplaythrough", "seeking", "seeked", "timeupdate", "ended", "ratechange",
   "durationchange", "volumechange",
 #endif // MOZ_MEDIA
   "MozAfterPaint",
   "MozSwipeGesture",
@@ -768,16 +771,25 @@ NS_METHOD nsDOMEvent::DuplicatePrivateDa
     case NS_SVGZOOM_EVENT:
     {
       newEvent = new nsGUIEvent(PR_FALSE, msg, nsnull);
       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
       newEvent->eventStructType = NS_SVGZOOM_EVENT;
       break;
     }
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+    case NS_SMIL_TIME_EVENT:
+    {
+      newEvent = new nsUIEvent(PR_FALSE, msg, 0);
+      NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
+      newEvent->eventStructType = NS_SMIL_TIME_EVENT;
+      break;
+    }
+#endif // MOZ_SMIL
     case NS_SIMPLE_GESTURE_EVENT:
     {
       nsSimpleGestureEvent* oldSimpleGestureEvent = static_cast<nsSimpleGestureEvent*>(mEvent);
       nsSimpleGestureEvent* simpleGestureEvent = 
         new nsSimpleGestureEvent(PR_FALSE, msg, nsnull, 0, 0.0);
       NS_ENSURE_TRUE(simpleGestureEvent, NS_ERROR_OUT_OF_MEMORY);
       isInputEvent = PR_TRUE;
       simpleGestureEvent->direction = oldSimpleGestureEvent->direction;
@@ -1220,16 +1232,24 @@ const char* nsDOMEvent::GetEventName(PRU
     return sEventNames[eDOMEvents_SVGError];
   case NS_SVG_RESIZE:
     return sEventNames[eDOMEvents_SVGResize];
   case NS_SVG_SCROLL:
     return sEventNames[eDOMEvents_SVGScroll];
   case NS_SVG_ZOOM:
     return sEventNames[eDOMEvents_SVGZoom];
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+  case NS_SMIL_BEGIN:
+    return sEventNames[eDOMEvents_beginEvent];
+  case NS_SMIL_END:
+    return sEventNames[eDOMEvents_endEvent];
+  case NS_SMIL_REPEAT:
+    return sEventNames[eDOMEvents_repeatEvent];
+#endif // MOZ_SMIL
 #ifdef MOZ_MEDIA
   case NS_LOADSTART:
     return sEventNames[eDOMEvents_loadstart];
   case NS_PROGRESS:
     return sEventNames[eDOMEvents_progress];
   case NS_SUSPEND:
     return sEventNames[eDOMEvents_suspend];
   case NS_EMPTIED:
--- a/content/events/src/nsDOMEvent.h
+++ b/content/events/src/nsDOMEvent.h
@@ -137,16 +137,21 @@ public:
     eDOMEvents_SVGLoad,
     eDOMEvents_SVGUnload,
     eDOMEvents_SVGAbort,
     eDOMEvents_SVGError,
     eDOMEvents_SVGResize,
     eDOMEvents_SVGScroll,
     eDOMEvents_SVGZoom,
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+    eDOMEvents_beginEvent,
+    eDOMEvents_endEvent,
+    eDOMEvents_repeatEvent,
+#endif // MOZ_SMIL
 #ifdef MOZ_MEDIA
     eDOMEvents_loadstart,
     eDOMEvents_progress,
     eDOMEvents_suspend,
     eDOMEvents_emptied,
     eDOMEvents_stalled,
     eDOMEvents_play,
     eDOMEvents_pause,
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -737,16 +737,20 @@ nsEventDispatcher::CreateEvent(nsPresCon
 #ifdef MOZ_SVG
     case NS_SVG_EVENT:
       return NS_NewDOMSVGEvent(aDOMEvent, aPresContext,
                                aEvent);
     case NS_SVGZOOM_EVENT:
       return NS_NewDOMSVGZoomEvent(aDOMEvent, aPresContext,
                                    static_cast<nsGUIEvent*>(aEvent));
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+    case NS_SMIL_TIME_EVENT:
+      return NS_NewDOMTimeEvent(aDOMEvent, aPresContext, aEvent);
+#endif // MOZ_SMIL
 
     case NS_COMMAND_EVENT:
       return NS_NewDOMCommandEvent(aDOMEvent, aPresContext,
                                    static_cast<nsCommandEvent*>(aEvent));
     case NS_SIMPLE_GESTURE_EVENT:
       return NS_NewDOMSimpleGestureEvent(aDOMEvent, aPresContext,
                                          static_cast<nsSimpleGestureEvent*>(aEvent));
     case NS_TRANSITION_EVENT:
@@ -792,16 +796,21 @@ nsEventDispatcher::CreateEvent(nsPresCon
 #ifdef MOZ_SVG
   if (aEventType.LowerCaseEqualsLiteral("svgevent") ||
       aEventType.LowerCaseEqualsLiteral("svgevents"))
     return NS_NewDOMSVGEvent(aDOMEvent, aPresContext, nsnull);
   if (aEventType.LowerCaseEqualsLiteral("svgzoomevent") ||
       aEventType.LowerCaseEqualsLiteral("svgzoomevents"))
     return NS_NewDOMSVGZoomEvent(aDOMEvent, aPresContext, nsnull);
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+  if (aEventType.LowerCaseEqualsLiteral("timeevent") ||
+      aEventType.LowerCaseEqualsLiteral("timeevents"))
+    return NS_NewDOMTimeEvent(aDOMEvent, aPresContext, nsnull);
+#endif // MOZ_SMIL
   if (aEventType.LowerCaseEqualsLiteral("xulcommandevent") ||
       aEventType.LowerCaseEqualsLiteral("xulcommandevents"))
     return NS_NewDOMXULCommandEvent(aDOMEvent, aPresContext, nsnull);
   if (aEventType.LowerCaseEqualsLiteral("commandevent") ||
       aEventType.LowerCaseEqualsLiteral("commandevents"))
     return NS_NewDOMCommandEvent(aDOMEvent, aPresContext, nsnull);
   if (aEventType.LowerCaseEqualsLiteral("datacontainerevent") ||
       aEventType.LowerCaseEqualsLiteral("datacontainerevents"))
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -978,16 +978,24 @@ nsEventListenerManager::CompileEventHand
         attrName = nsGkAtoms::onerror;
       else if (aName == nsGkAtoms::onSVGResize)
         attrName = nsGkAtoms::onresize;
       else if (aName == nsGkAtoms::onSVGScroll)
         attrName = nsGkAtoms::onscroll;
       else if (aName == nsGkAtoms::onSVGZoom)
         attrName = nsGkAtoms::onzoom;
 #endif // MOZ_SVG
+#ifdef MOZ_SMIL
+      else if (aName == nsGkAtoms::onbeginEvent)
+        attrName = nsGkAtoms::onbegin;
+      else if (aName == nsGkAtoms::onrepeatEvent)
+        attrName = nsGkAtoms::onrepeat;
+      else if (aName == nsGkAtoms::onendEvent)
+        attrName = nsGkAtoms::onend;
+#endif // MOZ_SMIL
 
       content->GetAttr(kNameSpaceID_None, attrName, handlerBody);
 
       PRUint32 lineNo = 0;
       nsCAutoString url (NS_LITERAL_CSTRING("javascript:alert('TODO: FIXME')"));
       nsIDocument* doc = nsnull;
       nsCOMPtr<nsINode> node = do_QueryInterface(aCurrentTarget);
       if (node) {
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -61,17 +61,17 @@
 #include "nsIEditorDocShell.h"
 #include "nsIFormControl.h"
 #include "nsIComboboxControlFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsIDOMNSHTMLElement.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMNSHTMLInputElement.h"
-#include "nsIDOMNSHTMLLabelElement.h"
+#include "nsIDOMHTMLLabelElement.h"
 #include "nsIDOMHTMLSelectElement.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsIDOMHTMLButtonElement.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIDOMHTMLMapElement.h"
 #include "nsIDOMHTMLBodyElement.h"
@@ -4014,17 +4014,17 @@ nsEventStateManager::GetEventTargetConte
   }
 
   return NS_OK;
 }
 
 static already_AddRefed<nsIContent>
 GetLabelTarget(nsIContent* aLabel)
 {
-  nsCOMPtr<nsIDOMNSHTMLLabelElement> label = do_QueryInterface(aLabel);
+  nsCOMPtr<nsIDOMHTMLLabelElement> label = do_QueryInterface(aLabel);
   if (!label)
     return nsnull;
 
   nsCOMPtr<nsIDOMHTMLElement> target;
   label->GetControl(getter_AddRefs(target));
   nsIContent* targetContent = nsnull;
   if (target) {
     CallQueryInterface(target, &targetContent);
--- a/content/html/content/public/nsHTMLAudioElement.h
+++ b/content/html/content/public/nsHTMLAudioElement.h
@@ -72,13 +72,14 @@ public:
   // nsIDOMHTMLAudioElement
   NS_DECL_NSIDOMHTMLAUDIOELEMENT
 
   // nsIJSNativeInitializer
   NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext,
                         JSObject* aObj, PRUint32 argc, jsval* argv);
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel);
 
   virtual nsXPCClassInfo* GetClassInfo();
 };
 
 #endif
--- a/content/html/content/public/nsHTMLMediaElement.h
+++ b/content/html/content/public/nsHTMLMediaElement.h
@@ -37,16 +37,17 @@
  * ***** END LICENSE BLOCK ***** */
 #if !defined(nsHTMLMediaElement_h__)
 #define nsHTMLMediaElement_h__
 
 #include "nsIDOMHTMLMediaElement.h"
 #include "nsGenericHTMLElement.h"
 #include "nsMediaDecoder.h"
 #include "nsIChannel.h"
+#include "nsIHttpChannel.h"
 #include "nsThreadUtils.h"
 #include "nsIDOMRange.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsILoadGroup.h"
 #include "nsIObserver.h"
 #include "ImageLayers.h"
 
 // Define to output information on decoding and painting framerate
@@ -301,16 +302,23 @@ public:
 
   /**
    * Returns PR_TRUE if the media has played or completed a seek.
    * Used by video frame to determine whether to paint the poster.
    */
   PRBool GetPlayedOrSeeked() const { return mHasPlayedOrSeeked; }
 
   nsresult CopyInnerTo(nsGenericElement* aDest) const;
+
+  /**
+   * Sets the Accept header on the HTTP channel to the required
+   * video or audio MIME types.
+   */
+  virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel) = 0;
+
 protected:
   class MediaLoadListener;
   class LoadNextSourceEvent;
   class SelectResourceEvent;
 
   /**
    * Changes mHasPlayedOrSeeked to aValue. If mHasPlayedOrSeeked changes
    * we'll force a reflow so that the video frame gets reflowed to reflect
--- a/content/html/content/public/nsHTMLVideoElement.h
+++ b/content/html/content/public/nsHTMLVideoElement.h
@@ -75,12 +75,14 @@ public:
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   // Returns the current video frame width and height.
   // If there is no video frame, returns the given default size.
   nsIntSize GetVideoSize(nsIntSize defaultSize);
 
+  virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel);
+
   virtual nsXPCClassInfo* GetClassInfo();
 };
 
 #endif
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/573322-no-quirks-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<style>
+div { background: green; border: solid blue; width: 100px; height: 100px; }
+</style>
+<table border=1 width=50%>
+<tr>
+<td><div></div>left
+</table>
+<table border=1 width=50%>
+<tr>
+<td><div></div>justify
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: -moz-right;"><div></div>right
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: -moz-center;"><div></div>center
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: -moz-center;"><div></div>middle
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: center;"><div></div>absmiddle
+</table>
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/573322-no-quirks.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<style>
+div { background: green; border: solid blue; width: 100px; height: 100px; }
+</style>
+<table border=1 width=50%>
+<tr>
+<td align=left><div></div>left
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=justify><div></div>justify
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=right><div></div>right
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=center><div></div>center
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=middle><div></div>middle
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=absmiddle><div></div>absmiddle
+</table>
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/573322-quirks-ref.html
@@ -0,0 +1,27 @@
+<style>
+div { background: green; border: solid blue; width: 100px; height: 100px; }
+</style>
+<table border=1 width=50%>
+<tr>
+<td><div></div>left
+</table>
+<table border=1 width=50%>
+<tr>
+<td><div></div>justify
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: -moz-right;"><div></div>right
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: -moz-center;"><div></div>center
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: -moz-center;"><div></div>middle
+</table>
+<table border=1 width=50%>
+<tr>
+<td style="text-align: center;"><div></div>absmiddle
+</table>
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/573322-quirks.html
@@ -0,0 +1,27 @@
+<style>
+div { background: green; border: solid blue; width: 100px; height: 100px; }
+</style>
+<table border=1 width=50%>
+<tr>
+<td align=left><div></div>left
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=justify><div></div>justify
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=right><div></div>right
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=center><div></div>center
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=middle><div></div>middle
+</table>
+<table border=1 width=50%>
+<tr>
+<td align=absmiddle><div></div>absmiddle
+</table>
--- a/content/html/content/reftests/reftest.list
+++ b/content/html/content/reftests/reftest.list
@@ -6,10 +6,12 @@
 != 468263-1c.html about:blank
 != 468263-1d.html about:blank
 == 468263-2.html 468263-2-ref.html
 == 468263-2.html 468263-2-alternate-ref.html
 == 484200-1.html 484200-1-ref.html
 == 485377.html 485377-ref.html
 == 557840.html 557840-ref.html
 == 560059-video-dimensions.html 560059-video-dimensions-ref.html
+== 573322-quirks.html 573322-quirks-ref.html
+== 573322-no-quirks.html 573322-no-quirks-ref.html
 == href-attr-change-restyles.html href-attr-change-restyles-ref.html
 == figure.html figure-ref.html
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -233,17 +233,17 @@ class nsGenericHTMLElementTearoff : publ
 
   NS_FORWARD_NSIDOMNSHTMLELEMENT(mElement->)
   NS_FORWARD_NSIDOMELEMENTCSSINLINESTYLE(mElement->)
 
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsGenericHTMLElementTearoff,
                                            nsIDOMNSHTMLElement)
 
 private:
-  nsCOMPtr<nsGenericHTMLElement> mElement;
+  nsRefPtr<nsGenericHTMLElement> mElement;
 };
 
 NS_IMPL_CYCLE_COLLECTION_1(nsGenericHTMLElementTearoff, mElement)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsGenericHTMLElementTearoff,
                                           nsIDOMNSHTMLElement)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsGenericHTMLElementTearoff,
                                            nsIDOMNSHTMLElement)
@@ -1536,49 +1536,32 @@ PRBool
 nsGenericHTMLElement::ParseTableHAlignValue(const nsAString& aString,
                                             nsAttrValue& aResult)
 {
   return aResult.ParseEnumValue(aString, kTableHAlignTable, PR_FALSE);
 }
 
 //----------------------------------------
 
-// These tables are used for TD,TH,TR, etc (but not TABLE)
+// This table is used for td, th, tr, col, thead, tbody and tfoot.
 static const nsAttrValue::EnumTable kTableCellHAlignTable[] = {
   { "left",   NS_STYLE_TEXT_ALIGN_MOZ_LEFT },
   { "right",  NS_STYLE_TEXT_ALIGN_MOZ_RIGHT },
   { "center", NS_STYLE_TEXT_ALIGN_MOZ_CENTER },
   { "char",   NS_STYLE_TEXT_ALIGN_CHAR },
   { "justify",NS_STYLE_TEXT_ALIGN_JUSTIFY },
-  { 0 }
-};
-
-static const nsAttrValue::EnumTable kCompatTableCellHAlignTable[] = {
-  { "left",   NS_STYLE_TEXT_ALIGN_MOZ_LEFT },
-  { "right",  NS_STYLE_TEXT_ALIGN_MOZ_RIGHT },
-  { "center", NS_STYLE_TEXT_ALIGN_MOZ_CENTER },
-  { "char",   NS_STYLE_TEXT_ALIGN_CHAR },
-  { "justify",NS_STYLE_TEXT_ALIGN_JUSTIFY },
-
-  // The following are non-standard but necessary for Nav4 compatibility
   { "middle", NS_STYLE_TEXT_ALIGN_MOZ_CENTER },
-  // allow center and absmiddle to map to NS_STYLE_TEXT_ALIGN_CENTER and
-  // NS_STYLE_TEXT_ALIGN_CENTER to map to center by using the following order
-  { "center", NS_STYLE_TEXT_ALIGN_CENTER },
   { "absmiddle", NS_STYLE_TEXT_ALIGN_CENTER },
   { 0 }
 };
 
 PRBool
 nsGenericHTMLElement::ParseTableCellHAlignValue(const nsAString& aString,
-                                                nsAttrValue& aResult) const
+                                                nsAttrValue& aResult)
 {
-  if (InNavQuirksMode(GetOwnerDoc())) {
-    return aResult.ParseEnumValue(aString, kCompatTableCellHAlignTable, PR_FALSE);
-  }
   return aResult.ParseEnumValue(aString, kTableCellHAlignTable, PR_FALSE);
 }
 
 //----------------------------------------
 
 PRBool
 nsGenericHTMLElement::ParseTableVAlignValue(const nsAString& aString,
                                             nsAttrValue& aResult)
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -268,18 +268,18 @@ public:
 
   /**
    * Convert a table cell halign string to value
    *
    * @param aString the string to parse
    * @param aResult the resulting HTMLValue
    * @return whether the value was parsed
    */
-  PRBool ParseTableCellHAlignValue(const nsAString& aString,
-                                   nsAttrValue& aResult) const;
+  static PRBool ParseTableCellHAlignValue(const nsAString& aString,
+                                          nsAttrValue& aResult);
 
   /**
    * Convert a table valign string to value (left/right/center/char/justify/
    * abscenter/absmiddle/middle)
    *
    * @param aString the string to parse
    * @param aResult the resulting HTMLValue
    * @return whether the value was parsed
--- a/content/html/content/src/nsHTMLAnchorElement.cpp
+++ b/content/html/content/src/nsHTMLAnchorElement.cpp
@@ -45,34 +45,31 @@
 #include "nsGenericHTMLElement.h"
 #include "nsILink.h"
 #include "nsGkAtoms.h"
 #include "nsIPresShell.h"
 #include "nsIDocument.h"
 #include "nsPresContext.h"
 #include "nsIEventStateManager.h"
 
-// For GetText().
-#include "nsIContentIterator.h"
-#include "nsIDOMText.h"
-
 #include "nsHTMLDNSPrefetch.h"
 
 #include "Link.h"
 using namespace mozilla::dom;
 
-nsresult NS_NewPreContentIterator(nsIContentIterator** aInstancePtrResult);
-
 class nsHTMLAnchorElement : public nsGenericHTMLElement,
                             public nsIDOMHTMLAnchorElement,
                             public nsIDOMNSHTMLAnchorElement2,
                             public nsILink,
                             public Link
 {
 public:
+  using nsGenericElement::GetText;
+  using nsGenericElement::SetText;
+
   nsHTMLAnchorElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLAnchorElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
@@ -364,46 +361,24 @@ IMPL_URI_PART(Search)
 IMPL_URI_PART(Port)
 IMPL_URI_PART(Hash)
 
 #undef IMPL_URI_PART
 
 NS_IMETHODIMP    
 nsHTMLAnchorElement::GetText(nsAString& aText)
 {
-  aText.Truncate();
-
-  // Since this is a Netscape 4 proprietary attribute, we have to implement
-  // the same behavior. Basically it is returning the last text node of
-  // of the anchor. Returns an empty string if there is no text node.
-  // The nsIContentIterator does exactly what we want, if we start the 
-  // iteration from the end.
-  nsCOMPtr<nsIContentIterator> iter;
-  nsresult rv = NS_NewPreContentIterator(getter_AddRefs(iter));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Initialize the content iterator with the children of the anchor
-  iter->Init(this);
+  nsContentUtils::GetNodeTextContent(this, PR_TRUE, aText);
+  return NS_OK;
+}
 
-  // Last() positions the iterator to the last child of the anchor,
-  // starting at the deepest level of children, just like NS4 does.
-  iter->Last();
-
-  while (!iter->IsDone()) {
-    nsCOMPtr<nsIDOMText> textNode(do_QueryInterface(iter->GetCurrentNode()));
-    if(textNode) {
-      // The current node is a text node. Get its value and break the loop.
-      textNode->GetData(aText);
-      break;
-    }
-
-    iter->Prev();
-  }
-
-  return NS_OK;
+NS_IMETHODIMP    
+nsHTMLAnchorElement::SetText(const nsAString& aText)
+{
+  return nsContentUtils::SetNodeTextContent(this, aText, PR_FALSE);
 }
 
 NS_IMETHODIMP
 nsHTMLAnchorElement::ToString(nsAString& aSource)
 {
   return GetHref(aSource);
 }
 
--- a/content/html/content/src/nsHTMLAreaElement.cpp
+++ b/content/html/content/src/nsHTMLAreaElement.cpp
@@ -31,34 +31,32 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #include "nsIDOMHTMLAreaElement.h"
-#include "nsIDOMNSHTMLAreaElement2.h"
 #include "nsIDOMEventTarget.h"
 #include "nsGenericHTMLElement.h"
 #include "nsILink.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsIEventStateManager.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 #include "nsReadableUtils.h"
 #include "nsIDocument.h"
 
 #include "Link.h"
 using namespace mozilla::dom;
 
 class nsHTMLAreaElement : public nsGenericHTMLElement,
                           public nsIDOMHTMLAreaElement,
-                          public nsIDOMNSHTMLAreaElement2,
                           public nsILink,
                           public Link
 {
 public:
   nsHTMLAreaElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLAreaElement();
 
   // nsISupports
@@ -71,22 +69,16 @@ public:
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLAreaElement
   NS_DECL_NSIDOMHTMLAREAELEMENT
 
-  // nsIDOMNSHTMLAreaElement
-  NS_DECL_NSIDOMNSHTMLAREAELEMENT
-
-  // nsIDOMNSHTMLAreaElement2
-  NS_DECL_NSIDOMNSHTMLAREAELEMENT2
-
   // nsILink
   NS_IMETHOD LinkAdded() { return NS_OK; }
   NS_IMETHOD LinkRemoved() { return NS_OK; }
 
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
   virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
   virtual PRBool IsLink(nsIURI** aURI) const;
   virtual void GetLinkTarget(nsAString& aTarget);
@@ -131,20 +123,18 @@ nsHTMLAreaElement::~nsHTMLAreaElement()
 
 NS_IMPL_ADDREF_INHERITED(nsHTMLAreaElement, nsGenericElement) 
 NS_IMPL_RELEASE_INHERITED(nsHTMLAreaElement, nsGenericElement) 
 
 DOMCI_NODE_DATA(HTMLAreaElement, nsHTMLAreaElement)
 
 // QueryInterface implementation for nsHTMLAreaElement
 NS_INTERFACE_TABLE_HEAD(nsHTMLAreaElement)
-  NS_HTML_CONTENT_INTERFACE_TABLE5(nsHTMLAreaElement,
+  NS_HTML_CONTENT_INTERFACE_TABLE3(nsHTMLAreaElement,
                                    nsIDOMHTMLAreaElement,
-                                   nsIDOMNSHTMLAreaElement,
-                                   nsIDOMNSHTMLAreaElement2,
                                    nsILink,
                                    Link)
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLAreaElement,
                                                nsGenericHTMLElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLAreaElement)
 
 
 NS_IMPL_ELEMENT_CLONE(nsHTMLAreaElement)
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/nsHTMLAudioElement.cpp
@@ -141,8 +141,32 @@ nsHTMLAudioElement::Initialize(nsISuppor
   if (NS_FAILED(rv))
     return rv;
 
   // We have been specified with a src URL. Begin a load.
   QueueSelectResourceTask();
 
   return NS_OK;
 }
+
+  
+nsresult nsHTMLAudioElement::SetAcceptHeader(nsIHttpChannel* aChannel)
+{
+    nsCAutoString value(
+#ifdef MOZ_WEBM
+      "audio/webm,"
+#endif
+#ifdef MOZ_OGG
+      "audio/ogg,"
+#endif
+#ifdef MOZ_WAVE
+      "audio/wav,"
+#endif
+      "audio/*;q=0.9,"
+#ifdef MOZ_OGG
+      "application/ogg;q=0.7,"
+#endif
+      "video/*;q=0.6,*/*;q=0.5");
+
+    return aChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
+                                      value,
+                                      PR_FALSE);
+}
--- a/content/html/content/src/nsHTMLButtonElement.cpp
+++ b/content/html/content/src/nsHTMLButtonElement.cpp
@@ -30,17 +30,16 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #include "nsIDOMHTMLButtonElement.h"
-#include "nsIDOMNSHTMLButtonElement.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMEventTarget.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsIPresShell.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsIFormControl.h"
@@ -72,18 +71,17 @@ static const nsAttrValue::EnumTable kBut
   { "submit", NS_FORM_BUTTON_SUBMIT },
   { 0 }
 };
 
 // Default type is 'submit'.
 static const nsAttrValue::EnumTable* kButtonDefaultType = &kButtonTypeTable[2];
 
 class nsHTMLButtonElement : public nsGenericHTMLFormElement,
-                            public nsIDOMHTMLButtonElement,
-                            public nsIDOMNSHTMLButtonElement
+                            public nsIDOMHTMLButtonElement
 {
 public:
   nsHTMLButtonElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLButtonElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
@@ -94,26 +92,16 @@ public:
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLButtonElement
   NS_DECL_NSIDOMHTMLBUTTONELEMENT
 
-  // nsIDOMNSHTMLButtonElement
-  // Can't just use the macro, since it shares GetType with
-  // nsIDOMHTMLButtonElement
-  NS_IMETHOD Blur();
-  NS_IMETHOD Focus();
-  NS_IMETHOD Click();
-  NS_IMETHOD SetType(const nsAString& aType);
-  NS_IMETHOD GetAutofocus(PRBool* aAutofocus);
-  NS_IMETHOD SetAutofocus(PRBool aAutofocus);
-
   // overriden nsIFormControl methods
   NS_IMETHOD_(PRUint32) GetType() const { return mType; }
   NS_IMETHOD Reset();
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
                                nsIContent* aSubmitElement);
   NS_IMETHOD SaveState();
   PRBool RestoreState(nsPresState* aState);
 
@@ -182,19 +170,18 @@ nsHTMLButtonElement::~nsHTMLButtonElemen
 NS_IMPL_ADDREF_INHERITED(nsHTMLButtonElement, nsGenericElement)
 NS_IMPL_RELEASE_INHERITED(nsHTMLButtonElement, nsGenericElement)
 
 
 DOMCI_NODE_DATA(HTMLButtonElement, nsHTMLButtonElement)
 
 // QueryInterface implementation for nsHTMLButtonElement
 NS_INTERFACE_TABLE_HEAD(nsHTMLButtonElement)
-  NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLButtonElement,
-                                   nsIDOMHTMLButtonElement,
-                                   nsIDOMNSHTMLButtonElement)
+  NS_HTML_CONTENT_INTERFACE_TABLE1(nsHTMLButtonElement,
+                                   nsIDOMHTMLButtonElement)
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLButtonElement,
                                                nsGenericHTMLFormElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLButtonElement)
 
 // nsIDOMHTMLButtonElement
 
 
 NS_IMPL_ELEMENT_CLONE(nsHTMLButtonElement)
--- a/content/html/content/src/nsHTMLLabelElement.cpp
+++ b/content/html/content/src/nsHTMLLabelElement.cpp
@@ -31,17 +31,16 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #include "nsCOMPtr.h"
 #include "nsIDOMHTMLLabelElement.h"
-#include "nsIDOMNSHTMLLabelElement.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMEventTarget.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsIFormControl.h"
 #include "nsIForm.h"
@@ -49,18 +48,17 @@
 #include "nsIDocument.h"
 #include "nsGUIEvent.h"
 #include "nsIEventStateManager.h"
 #include "nsEventDispatcher.h"
 #include "nsPIDOMWindow.h"
 #include "nsFocusManager.h"
 
 class nsHTMLLabelElement : public nsGenericHTMLFormElement,
-                           public nsIDOMHTMLLabelElement,
-                           public nsIDOMNSHTMLLabelElement
+                           public nsIDOMHTMLLabelElement
 {
 public:
   nsHTMLLabelElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLLabelElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
@@ -71,19 +69,16 @@ public:
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLLabelElement
   NS_DECL_NSIDOMHTMLLABELELEMENT
 
-  // nsIDOMNSHTMLLabelElement
-  NS_DECL_NSIDOMNSHTMLLABELELEMENT
-
   // nsIFormControl
   NS_IMETHOD_(PRUint32) GetType() const { return NS_FORM_LABEL; }
   NS_IMETHOD Reset();
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
                                nsIContent* aSubmitElement);
 
   NS_IMETHOD Focus();
 
@@ -141,19 +136,18 @@ nsHTMLLabelElement::~nsHTMLLabelElement(
 NS_IMPL_ADDREF_INHERITED(nsHTMLLabelElement, nsGenericElement) 
 NS_IMPL_RELEASE_INHERITED(nsHTMLLabelElement, nsGenericElement) 
 
 
 DOMCI_NODE_DATA(HTMLLabelElement, nsHTMLLabelElement)
 
 // QueryInterface implementation for nsHTMLLabelElement
 NS_INTERFACE_TABLE_HEAD(nsHTMLLabelElement)
-  NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLLabelElement,
-                                   nsIDOMHTMLLabelElement,
-                                   nsIDOMNSHTMLLabelElement)
+  NS_HTML_CONTENT_INTERFACE_TABLE1(nsHTMLLabelElement,
+                                   nsIDOMHTMLLabelElement)
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLLabelElement,
                                                nsGenericHTMLFormElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLLabelElement)
 
 
 // nsIDOMHTMLLabelElement
 
 
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -734,16 +734,19 @@ nsresult nsHTMLMediaElement::LoadResourc
   nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(mChannel);
   if (hc) {
     // Use a byte range request from the start of the resource.
     // This enables us to detect if the stream supports byte range
     // requests, and therefore seeking, early.
     hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"),
                          NS_LITERAL_CSTRING("bytes=0-"),
                          PR_FALSE);
+
+    // Send Accept header for video and audio types only (Bug 489071)
+    SetAcceptHeader(hc);
   }
 
   rv = mChannel->AsyncOpen(listener, nsnull);
   if (NS_FAILED(rv)) {
     // OnStartRequest is guaranteed to be called if the open succeeds.  If
     // the open failed, the listener's OnStartRequest will never be called,
     // so we need to break the element->channel->listener->element reference
     // cycle here.  The channel holds the only reference to the listener,
--- a/content/html/content/src/nsHTMLOptionElement.cpp
+++ b/content/html/content/src/nsHTMLOptionElement.cpp
@@ -33,17 +33,16 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "nsIDOMNSHTMLOptionElement.h"
 #include "nsHTMLOptionElement.h"
 #include "nsIDOMHTMLOptGroupElement.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMEventTarget.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsIFormControl.h"
 #include "nsIForm.h"
@@ -112,19 +111,18 @@ nsHTMLOptionElement::~nsHTMLOptionElemen
 NS_IMPL_ADDREF_INHERITED(nsHTMLOptionElement, nsGenericElement)
 NS_IMPL_RELEASE_INHERITED(nsHTMLOptionElement, nsGenericElement)
 
 
 DOMCI_NODE_DATA(HTMLOptionElement, nsHTMLOptionElement)
 
 // QueryInterface implementation for nsHTMLOptionElement
 NS_INTERFACE_TABLE_HEAD(nsHTMLOptionElement)
-  NS_HTML_CONTENT_INTERFACE_TABLE3(nsHTMLOptionElement,
+  NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLOptionElement,
                                    nsIDOMHTMLOptionElement,
-                                   nsIDOMNSHTMLOptionElement,
                                    nsIJSNativeInitializer)
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLOptionElement,
                                                nsGenericHTMLElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLOptionElement)
 
 
 NS_IMPL_ELEMENT_CLONE(nsHTMLOptionElement)
 
--- a/content/html/content/src/nsHTMLOptionElement.h
+++ b/content/html/content/src/nsHTMLOptionElement.h
@@ -38,22 +38,20 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsHTMLOptionElement_h__
 #define nsHTMLOptionElement_h__
 
 #include "nsGenericHTMLElement.h"
 #include "nsIDOMHTMLOptionElement.h"
-#include "nsIDOMNSHTMLOptionElement.h"
 #include "nsIJSNativeInitializer.h"
 
 class nsHTMLOptionElement : public nsGenericHTMLElement,
                             public nsIDOMHTMLOptionElement,
-                            public nsIDOMNSHTMLOptionElement,
                             public nsIJSNativeInitializer
 {
 public:
   nsHTMLOptionElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLOptionElement();
 
   /** Typesafe, non-refcounting cast from nsIContent.  Cheaper than QI. **/
   static nsHTMLOptionElement* FromContent(nsIContent *aContent)
@@ -73,19 +71,16 @@ public:
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLOptionElement
   NS_DECL_NSIDOMHTMLOPTIONELEMENT
 
-  // nsIDOMNSHTMLOptionElement
-  NS_IMETHOD SetText(const nsAString & aText); 
-
   // nsIJSNativeInitializer
   NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext,
                         JSObject *aObj, PRUint32 argc, jsval *argv);
 
   virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
                                               PRInt32 aModType) const;
 
   virtual nsresult BeforeSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
--- a/content/html/content/src/nsHTMLScriptElement.cpp
+++ b/content/html/content/src/nsHTMLScriptElement.cpp
@@ -31,17 +31,16 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #include "nsIDOMHTMLScriptElement.h"
-#include "nsIDOMNSHTMLScriptElement.h"
 #include "nsIDOMEventTarget.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsIDocument.h"
 #include "nsScriptElement.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
@@ -300,17 +299,16 @@ nsHTMLScriptEventHandler::Invoke(nsISupp
   nsCOMPtr<nsIVariant> ret;
   return scriptContext->CallEventHandler(aTargetObject, scope, funcObject,
                                          argarray, getter_AddRefs(ret));
 }
 
 
 class nsHTMLScriptElement : public nsGenericHTMLElement,
                             public nsIDOMHTMLScriptElement,
-                            public nsIDOMNSHTMLScriptElement,
                             public nsScriptElement
 {
 public:
   nsHTMLScriptElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                       PRUint32 aFromParser);
   virtual ~nsHTMLScriptElement();
 
   // nsISupports
@@ -321,17 +319,16 @@ public:
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   NS_DECL_NSIDOMHTMLSCRIPTELEMENT
-  NS_DECL_NSIDOMNSHTMLSCRIPTELEMENT
 
   // nsIScriptElement
   virtual void GetScriptType(nsAString& type);
   virtual void GetScriptText(nsAString& text);
   virtual void GetScriptCharset(nsAString& charset);
   virtual void FreezeUriAsyncDefer();
 
   // nsIContent
@@ -378,21 +375,20 @@ nsHTMLScriptElement::~nsHTMLScriptElemen
 
 NS_IMPL_ADDREF_INHERITED(nsHTMLScriptElement, nsGenericElement)
 NS_IMPL_RELEASE_INHERITED(nsHTMLScriptElement, nsGenericElement)
 
 DOMCI_NODE_DATA(HTMLScriptElement, nsHTMLScriptElement)
 
 // QueryInterface implementation for nsHTMLScriptElement
 NS_INTERFACE_TABLE_HEAD(nsHTMLScriptElement)
-  NS_HTML_CONTENT_INTERFACE_TABLE5(nsHTMLScriptElement,
+  NS_HTML_CONTENT_INTERFACE_TABLE4(nsHTMLScriptElement,
                                    nsIDOMHTMLScriptElement,
                                    nsIScriptLoaderObserver,
                                    nsIScriptElement,
-                                   nsIDOMNSHTMLScriptElement,
                                    nsIMutationObserver)
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLScriptElement,
                                                nsGenericHTMLElement)
   if (mScriptEventHandler && aIID.Equals(NS_GET_IID(nsIScriptEventHandler)))
     foundInterface = static_cast<nsIScriptEventHandler*>
                                 (mScriptEventHandler);
   else
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(HTMLScriptElement)
--- a/content/html/content/src/nsHTMLSelectElement.cpp
+++ b/content/html/content/src/nsHTMLSelectElement.cpp
@@ -176,19 +176,18 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_ADDREF_INHERITED(nsHTMLSelectElement, nsGenericElement)
 NS_IMPL_RELEASE_INHERITED(nsHTMLSelectElement, nsGenericElement)
 
 
 DOMCI_NODE_DATA(HTMLSelectElement, nsHTMLSelectElement)
 
 // QueryInterface implementation for nsHTMLSelectElement
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLSelectElement)
-  NS_HTML_CONTENT_INTERFACE_TABLE3(nsHTMLSelectElement,
+  NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLSelectElement,
                                    nsIDOMHTMLSelectElement,
-                                   nsIDOMNSHTMLSelectElement,
                                    nsISelectElement)
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLSelectElement,
                                                nsGenericHTMLFormElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLSelectElement)
 
 
 // nsIDOMHTMLSelectElement
 
@@ -792,18 +791,18 @@ nsHTMLSelectElement::SetSelectedIndex(PR
   return rv;
 }
 
 NS_IMETHODIMP
 nsHTMLSelectElement::GetOptionIndex(nsIDOMHTMLOptionElement* aOption,
                                     PRInt32 aStartIndex, PRBool aForward,
                                     PRInt32* aIndex)
 {
-  nsCOMPtr<Element> option = do_QueryInterface(aOption);
-  return mOptions->GetOptionIndex(option, aStartIndex, aForward, aIndex);
+  nsCOMPtr<nsINode> option = do_QueryInterface(aOption);
+  return mOptions->GetOptionIndex(option->AsElement(), aStartIndex, aForward, aIndex);
 }
 
 PRBool
 nsHTMLSelectElement::IsOptionSelectedByIndex(PRInt32 aIndex)
 {
   nsIDOMHTMLOptionElement *option = mOptions->ItemAsOption(aIndex);
   PRBool isSelected = PR_FALSE;
   if (option) {
--- a/content/html/content/src/nsHTMLSelectElement.h
+++ b/content/html/content/src/nsHTMLSelectElement.h
@@ -40,17 +40,16 @@
 #ifndef nsHTMLSelectElement_h___
 #define nsHTMLSelectElement_h___
 
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsGenericHTMLElement.h"
 #include "nsISelectElement.h"
 #include "nsIDOMHTMLSelectElement.h"
-#include "nsIDOMNSHTMLSelectElement.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMHTMLOptionElement.h"
 #include "nsIDOMHTMLOptionsCollection.h"
 #include "nsIDOMNSHTMLOptionCollectn.h"
 #include "nsISelectControlFrame.h"
 #include "nsContentUtils.h"
 #include "nsIHTMLCollection.h"
 
@@ -232,17 +231,16 @@ private:
 };
 
 
 /**
  * Implementation of &lt;select&gt;
  */
 class nsHTMLSelectElement : public nsGenericHTMLFormElement,
                             public nsIDOMHTMLSelectElement,
-                            public nsIDOMNSHTMLSelectElement,
                             public nsISelectElement
 {
 public:
   nsHTMLSelectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                       PRUint32 aFromParser = 0);
   virtual ~nsHTMLSelectElement();
 
   // nsISupports
@@ -255,19 +253,16 @@ public:
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLSelectElement
   NS_DECL_NSIDOMHTMLSELECTELEMENT
 
-  // nsIDOMNSHTMLSelectElement
-  NS_DECL_NSIDOMNSHTMLSELECTELEMENT
-
   // nsIContent
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
 
   virtual PRBool IsHTMLFocusable(PRBool aWithMouse, PRBool *aIsFocusable, PRInt32 *aTabIndex);
   virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
                                  PRBool aNotify);
   virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
 
--- a/content/html/content/src/nsHTMLVideoElement.cpp
+++ b/content/html/content/src/nsHTMLVideoElement.cpp
@@ -155,9 +155,29 @@ nsHTMLVideoElement::IsAttributeMapped(co
 }
 
 nsMapRuleToAttributesFunc
 nsHTMLVideoElement::GetAttributeMappingFunction() const
 {
   return &MapAttributesIntoRule;
 }
 
+nsresult nsHTMLVideoElement::SetAcceptHeader(nsIHttpChannel* aChannel)
+{
+    nsCAutoString value(
+#ifdef MOZ_WEBM
+        "video/webm,"
+#endif
+#ifdef MOZ_OGG
+        "video/ogg,"
+#endif
+        "video/*;q=0.9,"
+#ifdef MOZ_OGG
+        "application/ogg;q=0.7,"
+#endif
+        "audio/*;q=0.6,*/*;q=0.5");
+
+    return aChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
+                                      value,
+                                      PR_FALSE);
+}
+
 NS_IMPL_URI_ATTR(nsHTMLVideoElement, Poster, poster)
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -139,16 +139,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug448166.html \
 		test_bug460568.html \
 		test_bug347174.html \
 		test_bug347174_write.html \
 		test_bug347174_xsl.html \
 		test_bug347174_xslp.html \
 		347174transformable.xml \
 		347174transform.xsl \
+		test_a_text.html \
 		test_anchor_href_cache_invalidation.html \
 		test_bug481335.xhtml \
 		test_bug500885.html \
 		test_bug514856.html \
 		bug514856_iframe.html \
 		test_bug518122.html \
 		test_bug519987.html \
 		test_bug579079.html \
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_a_text.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for a.text</title>
+  <script src="/MochiKit/packed.js"></script>
+  <script src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+  <link rel="help" href="http://www.whatwg.org/html/#dom-a-text"/>
+</head>
+<body>
+<div id="content">
+<a href="a">a b c</a>
+<a href="b">a <!--b--> c</a>
+<a href="c">a <b>b</b> c</a>
+</div>
+<pre id="test">
+<script>
+var d = document.getElementById("content")
+                .appendChild(document.createElement("a"));
+d.href = "d";
+d.appendChild(document.createTextNode("a "));
+d.appendChild(document.createTextNode("b "));
+d.appendChild(document.createTextNode("c "));
+var expected = ["a b c", "a  c", "a b c", "a b c "];
+var list = document.getElementById("content").getElementsByTagName("a");
+for (var i = 0, il = list.length; i < il; ++i) {
+  is(list[i].text, list[i].textContent);
+  is(list[i].text, expected[i]);
+
+  list[i].text = "x";
+  is(list[i].text, "x");
+  is(list[i].textContent, "x");
+  is(list[i].firstChild.data, "x");
+  is(list[i].childNodes.length, 1);
+
+  list[i].textContent = "y";
+  is(list[i].text, "y");
+  is(list[i].textContent, "y");
+  is(list[i].firstChild.data, "y");
+  is(list[i].childNodes.length, 1);
+}
+</script>
+</pre>
+</body>
+</html>
--- a/content/html/content/test/test_bug389797.html
+++ b/content/html/content/test/test_bug389797.html
@@ -112,17 +112,17 @@ objectIfaces2.push("nsIImageLoadingConte
    html
  */
 
 HTML_TAG("a", "Anchor", [ "nsIDOMNSHTMLAnchorElement2" ]);
 HTML_TAG("abbr", ""); // HTMLElement
 HTML_TAG("acronym", ""); // HTMLElement
 HTML_TAG("address", ""); // HTMLElement
 HTML_TAG("applet", "Applet", [], objectIfaces);
-HTML_TAG("area", "Area", [ "nsIDOMNSHTMLAreaElement2" ]);
+HTML_TAG("area", "Area");
 HTML_TAG("article", ""); // HTMLElement
 HTML_TAG("aside", ""); // HTMLElement
 HTML_TAG("b", ""); // HTMLElement
 HTML_TAG("base", "Base");
 HTML_TAG("bdo", ""); // HTMLElement
 HTML_TAG("bgsound", "Span");
 HTML_TAG("big", ""); // HTMLElement
 HTML_TAG("blink", ""); // HTMLElement
--- a/content/media/nsMediaStream.cpp
+++ b/content/media/nsMediaStream.cpp
@@ -463,16 +463,24 @@ void nsMediaChannelStream::SetupChannelH
   // This enables us to detect if the stream supports byte range
   // requests, and therefore seeking, early.
   nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(mChannel);
   if (hc) {
     nsCAutoString rangeString("bytes=");
     rangeString.AppendInt(mOffset);
     rangeString.Append("-");
     hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"), rangeString, PR_FALSE);
+
+    // Send Accept header for video and audio types only (Bug 489071)
+    NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
+    nsHTMLMediaElement* element = mDecoder->GetMediaElement();
+    if (!element) {
+      return;
+    }
+    element->SetAcceptHeader(hc);
   } else {
     NS_ASSERTION(mOffset == 0, "Don't know how to seek on this channel type");
   }
 }
 
 nsresult nsMediaChannelStream::Close()
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
--- a/content/media/nsMediaStream.h
+++ b/content/media/nsMediaStream.h
@@ -388,16 +388,17 @@ protected:
                            nsIInputStream* aStream,
                            PRUint32 aCount);
   nsresult OnChannelRedirect(nsIChannel* aOld, nsIChannel* aNew, PRUint32 aFlags);
 
   // Opens the channel, using an HTTP byte range request to start at mOffset
   // if possible. Main thread only.
   nsresult OpenChannel(nsIStreamListener** aStreamListener);
   nsresult RecreateChannel();
+  // Add headers to HTTP request. Main thread only.
   void SetupChannelHeaders();
   // Closes the channel. Main thread only.
   void CloseChannel();
 
   void DoNotifyDataReceived();
 
   static NS_METHOD CopySegmentToCache(nsIInputStream *aInStream,
                                       void *aClosure,
--- a/content/smil/Makefile.in
+++ b/content/smil/Makefile.in
@@ -49,16 +49,17 @@ LIBXUL_LIBRARY	= 1
 
 # nsSMILKeySpline is used by CSS transitions -- need to build it regardless
 # of whether SMIL is enabled.
 CPPSRCS		= nsSMILKeySpline.cpp
 EXPORTS		= nsSMILKeySpline.h
 
 ifdef MOZ_SMIL
 CPPSRCS		+= \
+	nsDOMTimeEvent.cpp \
 	nsSMILAnimationController.cpp \
 	nsSMILAnimationFunction.cpp \
 	nsSMILCompositor.cpp \
 	nsSMILCSSProperty.cpp \
 	nsSMILCSSValueType.cpp \
 	nsSMILFloatType.cpp \
 	nsSMILInstanceTime.cpp \
 	nsSMILInterval.cpp \
@@ -100,14 +101,15 @@ EXPORTS		+= \
 	  nsSMILMilestone.h \
 	  nsSMILTimeContainer.h \
 	  nsSMILTypes.h \
 	  $(NULL)
 
 INCLUDES += 	\
 		-I$(srcdir)/../base/src \
 		-I$(srcdir)/../../layout/style \
+		-I$(srcdir)/../events/src \
 		$(NULL)
 endif # MOZ_SMIL
 
 include $(topsrcdir)/config/rules.mk
 
 DEFINES += -D_IMPL_NS_LAYOUT
new file mode 100644
--- /dev/null
+++ b/content/smil/nsDOMTimeEvent.cpp
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SMIL Module.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsDOMTimeEvent.h"
+#include "nsGUIEvent.h"
+#include "nsPresContext.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIDOMAbstractView.h"
+
+nsDOMTimeEvent::nsDOMTimeEvent(nsPresContext* aPresContext, nsEvent* aEvent)
+  : nsDOMEvent(aPresContext, aEvent ? aEvent : new nsUIEvent(PR_FALSE, 0, 0)),
+    mDetail(0)
+{
+  if (aEvent) {
+    mEventIsInternal = PR_FALSE;
+  } else {
+    mEventIsInternal = PR_TRUE;
+    mEvent->eventStructType = NS_SMIL_TIME_EVENT;
+  }
+
+  if (mEvent->eventStructType == NS_SMIL_TIME_EVENT) {
+    nsUIEvent* event = static_cast<nsUIEvent*>(mEvent);
+    mDetail = event->detail;
+  }
+
+  mEvent->flags |= NS_EVENT_FLAG_CANT_BUBBLE |
+                   NS_EVENT_FLAG_CANT_CANCEL;
+
+  if (mPresContext) {
+    nsCOMPtr<nsISupports> container = mPresContext->GetContainer();
+    if (container) {
+      nsCOMPtr<nsIDOMWindowInternal> window = do_GetInterface(container);
+      if (window) {
+        mView = do_QueryInterface(window);
+      }
+    }
+  }
+}
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMTimeEvent)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMTimeEvent, nsDOMEvent)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mView)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMTimeEvent, nsDOMEvent)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mView)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_ADDREF_INHERITED(nsDOMTimeEvent, nsDOMEvent)
+NS_IMPL_RELEASE_INHERITED(nsDOMTimeEvent, nsDOMEvent)
+
+DOMCI_DATA(TimeEvent, nsDOMTimeEvent)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMTimeEvent)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMTimeEvent)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TimeEvent)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
+
+NS_IMETHODIMP
+nsDOMTimeEvent::GetView(nsIDOMAbstractView** aView)
+{
+  *aView = mView;
+  NS_IF_ADDREF(*aView);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMTimeEvent::GetDetail(PRInt32* aDetail)
+{
+  *aDetail = mDetail;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMTimeEvent::InitTimeEvent(const nsAString& aTypeArg,
+                              nsIDOMAbstractView* aViewArg,
+                              PRInt32 aDetailArg)
+{
+  nsresult rv = nsDOMEvent::InitEvent(aTypeArg, PR_FALSE /*doesn't bubble*/,
+                                                PR_FALSE /*can't cancel*/);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  mDetail = aDetailArg;
+  mView = aViewArg;
+
+  return NS_OK;
+}
+
+nsresult NS_NewDOMTimeEvent(nsIDOMEvent** aInstancePtrResult,
+                            nsPresContext* aPresContext,
+                            nsEvent* aEvent)
+{
+  nsDOMTimeEvent* it = new nsDOMTimeEvent(aPresContext, aEvent);
+  return CallQueryInterface(it, aInstancePtrResult);
+}
new file mode 100644
--- /dev/null
+++ b/content/smil/nsDOMTimeEvent.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SMIL Module.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef NS_DOMTIMEEVENT_H_
+#define NS_DOMTIMEEVENT_H_
+
+#include "nsIDOMTimeEvent.h"
+#include "nsDOMEvent.h"
+
+class nsDOMTimeEvent : public nsDOMEvent,
+                       public nsIDOMTimeEvent
+{
+public:
+  nsDOMTimeEvent(nsPresContext* aPresContext, nsEvent* aEvent);
+                     
+  // nsISupports interface:
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMTimeEvent, nsDOMEvent)
+
+  // nsIDOMTimeEvent interface:
+  NS_DECL_NSIDOMTIMEEVENT
+
+  // Forward to base class
+  NS_FORWARD_TO_NSDOMEVENT
+
+private:
+  nsCOMPtr<nsIDOMAbstractView> mView;
+  PRInt32                      mDetail;
+};
+
+#endif // NS_DOMTIMEEVENT_H_
--- a/content/smil/nsSMILTimedElement.cpp
+++ b/content/smil/nsSMILTimedElement.cpp
@@ -38,25 +38,29 @@
 #include "nsSMILTimedElement.h"
 #include "nsSMILAnimationFunction.h"
 #include "nsSMILTimeValue.h"
 #include "nsSMILTimeValueSpec.h"
 #include "nsSMILInstanceTime.h"
 #include "nsSMILParserUtils.h"
 #include "nsSMILTimeContainer.h"
 #include "nsGkAtoms.h"
+#include "nsGUIEvent.h"
+#include "nsEventDispatcher.h"
 #include "nsReadableUtils.h"
 #include "nsMathUtils.h"
+#include "nsThreadUtils.h"
+#include "nsIPresShell.h"
 #include "prdtoa.h"
 #include "plstr.h"
 #include "prtime.h"
 #include "nsString.h"
 
 //----------------------------------------------------------------------
-// Helper classes -- InstanceTimeComparator
+// Helper class: InstanceTimeComparator
 
 // Upon inserting an instance time into one of our instance time lists we assign
 // it a serial number. This allows us to sort the instance times in such a way
 // that where we have several equal instance times, the ones added later will
 // sort later. This means that when we call UpdateCurrentInterval during the
 // waiting state we won't unnecessarily change the begin instance.
 //
 // The serial number also means that every instance time has an unambiguous
@@ -86,16 +90,53 @@ nsSMILTimedElement::InstanceTimeComparat
   NS_ABORT_IF_FALSE(aElem1->Serial() && aElem2->Serial(),
       "Instance times have not been assigned serial numbers");
 
   PRInt8 cmp = aElem1->Time().CompareTo(aElem2->Time());
   return cmp == 0 ? aElem1->Serial() < aElem2->Serial() : cmp < 0;
 }
 
 //----------------------------------------------------------------------
+// Helper class: AsyncTimeEventRunner
+
+namespace
+{
+  class AsyncTimeEventRunner : public nsRunnable
+  {
+  protected:
+    nsRefPtr<nsIContent> mTarget;
+    PRUint32             mMsg;
+    PRInt32              mDetail;
+
+  public:
+    AsyncTimeEventRunner(nsIContent* aTarget, PRUint32 aMsg, PRInt32 aDetail)
+      : mTarget(aTarget), mMsg(aMsg), mDetail(aDetail)
+    {
+    }
+
+    NS_IMETHOD Run()
+    {
+      nsUIEvent event(PR_TRUE, mMsg, mDetail);
+      event.eventStructType = NS_SMIL_TIME_EVENT;
+
+      nsPresContext* context = nsnull;
+      nsIDocument* doc = mTarget->GetCurrentDoc();
+      if (doc) {
+        nsCOMPtr<nsIPresShell> shell = doc->GetShell();
+        if (shell) {
+          context = shell->GetPresContext();
+        }
+      }
+
+      return nsEventDispatcher::Dispatch(mTarget, context, &event);
+    }
+  };
+}
+
+//----------------------------------------------------------------------
 // Templated helper functions
 
 // Selectively remove elements from an array of type
 // nsTArray<nsRefPtr<nsSMILInstanceTime> > with O(n) performance.
 template <class TestFunctor>
 void
 nsSMILTimedElement::RemoveInstanceTimes(InstanceTimeList& aArray,
                                         TestFunctor& aTest)
@@ -145,16 +186,17 @@ nsSMILTimedElement::nsSMILTimedElement()
   mAnimationElement(nsnull),
   mFillMode(FILL_REMOVE),
   mRestartMode(RESTART_ALWAYS),
   mBeginSpecSet(PR_FALSE),
   mEndHasEventConditions(PR_FALSE),
   mInstanceSerialIndex(0),
   mClient(nsnull),
   mCurrentInterval(nsnull),
+  mCurrentRepeatIteration(0),
   mPrevRegisteredMilestone(sMaxMilestone),
   mElementState(STATE_STARTUP),
   mSeekState(SEEK_NOT_SEEKING)
 {
   mSimpleDur.SetIndefinite();
   mMin.SetMillis(0L);
   mMax.SetIndefinite();
   mTimeDependents.Init();
@@ -501,30 +543,31 @@ nsSMILTimedElement::DoSampleAt(nsSMILTim
       }
       break;
 
     case STATE_WAITING:
       {
         if (mCurrentInterval->Begin()->Time() <= sampleTime) {
           mElementState = STATE_ACTIVE;
           mCurrentInterval->FixBegin();
-          if (HasPlayed()) {
-            Reset(); // Apply restart behaviour
-          }
           if (mClient) {
             mClient->Activate(mCurrentInterval->Begin()->Time().GetMillis());
           }
+          if (mSeekState == SEEK_NOT_SEEKING) {
+            FireTimeEventAsync(NS_SMIL_BEGIN, 0);
+          }
           if (HasPlayed()) {
+            Reset(); // Apply restart behaviour
             // The call to Reset() may mean that the end point of our current
             // interval should be changed and so we should update the interval
             // now. However, calling UpdateCurrentInterval could result in the
             // interval getting deleted (perhaps through some web of syncbase
             // dependencies) therefore we make updating the interval the last
-            // thing we do. There is no guarantee that mCurrentInterval.IsSet()
-            // is true after this.
+            // thing we do. There is no guarantee that mCurrentInterval is set
+            // after this.
             UpdateCurrentInterval();
           }
           stateChanged = PR_TRUE;
         }
       }
       break;
 
     case STATE_ACTIVE:
@@ -536,31 +579,48 @@ nsSMILTimedElement::DoSampleAt(nsSMILTim
           mElementState =
             NS_SUCCEEDED(GetNextInterval(mCurrentInterval, nsnull, newInterval))
             ? STATE_WAITING
             : STATE_POSTACTIVE;
           if (mClient) {
             mClient->Inactivate(mFillMode == FILL_FREEZE);
           }
           mCurrentInterval->FixEnd();
+          if (mSeekState == SEEK_NOT_SEEKING) {
+            FireTimeEventAsync(NS_SMIL_END, 0);
+          }
+          mCurrentRepeatIteration = 0;
           mOldIntervals.AppendElement(mCurrentInterval.forget());
           // We must update mOldIntervals before calling SampleFillValue
           SampleFillValue();
           if (mElementState == STATE_WAITING) {
             mCurrentInterval = new nsSMILInterval(newInterval);
             NotifyNewInterval();
           }
           FilterHistory();
           stateChanged = PR_TRUE;
         } else {
           nsSMILTime beginTime = mCurrentInterval->Begin()->Time().GetMillis();
           NS_ASSERTION(aContainerTime >= beginTime,
                        "Sample time should not precede current interval");
           nsSMILTime activeTime = aContainerTime - beginTime;
           SampleSimpleTime(activeTime);
+          // We register our repeat times as milestones (except when we're
+          // seeking) so we should get a sample at exactly the time we repeat.
+          // (And even when we are seeking we want to update
+          // mCurrentRepeatIteration so we do that first before testing the seek
+          // state.)
+          PRUint32 prevRepeatIteration = mCurrentRepeatIteration;
+          if (ActiveTimeToSimpleTime(activeTime, mCurrentRepeatIteration)==0 &&
+              mCurrentRepeatIteration != prevRepeatIteration &&
+              mCurrentRepeatIteration &&
+              mSeekState == SEEK_NOT_SEEKING) {
+            FireTimeEventAsync(NS_SMIL_REPEAT,
+                          static_cast<PRInt32>(mCurrentRepeatIteration));
+          }
         }
       }
       break;
 
     case STATE_POSTACTIVE:
       break;
     }
 
@@ -602,16 +662,17 @@ nsSMILTimedElement::Rewind()
 
   mSeekState = mElementState == STATE_ACTIVE ?
                SEEK_BACKWARD_FROM_ACTIVE :
                SEEK_BACKWARD_FROM_INACTIVE;
 
   // Set the STARTUP state first so that if we get any callbacks we won't waste
   // time recalculating the current interval
   mElementState = STATE_STARTUP;
+  mCurrentRepeatIteration = 0;
 
   // Clear the intervals and instance times except those instance times we can't
   // regenerate (DOM calls etc.)
   RewindTiming();
 
   UnsetBeginSpec();
   UnsetEndSpec();
 
@@ -1233,23 +1294,16 @@ nsSMILTimedElement::Reset()
 
   RemoveReset resetEnd(nsnull);
   RemoveInstanceTimes(mEndInstances, resetEnd);
 }
 
 void
 nsSMILTimedElement::DoPostSeek()
 {
-  // XXX When implementing TimeEvents we'll need to compare mElementState with
-  // mSeekState and dispatch events as follows:
-  //     ACTIVE->INACTIVE: End event
-  //     INACTIVE->ACTIVE: Begin event
-  //     ACTIVE->ACTIVE: Nothing (even if they're different intervals)
-  //     INACTIVE->INACTIVE: Nothing (even if we've skipped intervals)
-
   // Finish backwards seek
   if (mSeekState == SEEK_BACKWARD_FROM_INACTIVE ||
       mSeekState == SEEK_BACKWARD_FROM_ACTIVE) {
     // Previously some dynamic instance times may have been marked to be
     // preserved because they were endpoints of an historic interval (which may
     // or may not have been filtered). Now that we've finished a seek we should
     // clear that flag for those instance times whose intervals are no longer
     // historic.
@@ -1261,16 +1315,44 @@ nsSMILTimedElement::DoPostSeek()
     // SMIL seems to require this. SMIL 3.0, 'Hyperlinks and timing':
     //   Resolved end times associated with events, Repeat-values,
     //   Accesskey-values or added via DOM method calls are cleared when seeking
     //   to time earlier than the resolved end time.
     Reset();
     UpdateCurrentInterval();
   }
 
+  // XXX
+  // Note that SMIL gives the very cryptic description:
+  //   The associated time for the event is the document time before the seek.
+  //   This action does not resolve any times in the instance times list for end
+  //   times.
+  //
+  // The second sentence was added as a clarification in a SMIL 2.0 erratum.
+  // Presumably the intention is that we fire the event as implemented below but
+  // don't act on it. This makes sense at least for dependencies within the same
+  // time container. So we'll probably need to set a flag here to ensure we
+  // don't actually act on it when we implement event-based timing.
+  switch (mSeekState)
+  {
+  case SEEK_FORWARD_FROM_ACTIVE:
+  case SEEK_BACKWARD_FROM_ACTIVE:
+    if (mElementState != STATE_ACTIVE) {
+      FireTimeEventAsync(NS_SMIL_END, 0);
+    }
+    break;
+
+  case SEEK_FORWARD_FROM_INACTIVE:
+  case SEEK_BACKWARD_FROM_INACTIVE:
+    if (mElementState == STATE_ACTIVE) {
+      FireTimeEventAsync(NS_SMIL_BEGIN, 0);
+    }
+    break;
+  }
+
   mSeekState = SEEK_NOT_SEEKING;
 }
 
 void
 nsSMILTimedElement::UnpreserveInstanceTimes(InstanceTimeList& aList)
 {
   const nsSMILInterval* prevInterval = GetPreviousInterval();
   const nsSMILInstanceTime* cutoff = mCurrentInterval ?
@@ -1856,20 +1938,16 @@ nsSMILTimedElement::RegisterMilestone()
   mPrevRegisteredMilestone = nextMilestone;
 }
 
 PRBool
 nsSMILTimedElement::GetNextMilestone(nsSMILMilestone& aNextMilestone) const
 {
   // Return the next key moment in our lifetime.
   //
-  // XXX Once we implement TimeEvents and event based timing we might need to
-  // include repeat times too, particularly if it's important to get them in
-  // order.
-  //
   // XXX It may be possible in future to optimise this so that we only register
   // for milestones if:
   // a) We have time dependents, or
   // b) We are dependent on events or syncbase relationships, or
   // c) There are registered listeners for our events
   //
   // Then for the simple case where everything uses offset values we could
   // ignore milestones altogether.
@@ -1891,32 +1969,37 @@ nsSMILTimedElement::GetNextMilestone(nsS
     NS_ABORT_IF_FALSE(mCurrentInterval,
         "In waiting state but the current interval has not been set");
     aNextMilestone.mIsEnd = PR_FALSE;
     aNextMilestone.mTime = mCurrentInterval->Begin()->Time().GetMillis();
     return PR_TRUE;
 
   case STATE_ACTIVE:
     {
-      // XXX When we implement TimeEvents, we may need to consider what comes
-      // next: the interval end or an interval repeat.
+      // Work out what comes next: the interval end or the next repeat iteration
+      nsSMILTimeValue nextRepeat;
+      if (mSeekState == SEEK_NOT_SEEKING && mSimpleDur.IsResolved()) {
+        nextRepeat.SetMillis(mCurrentInterval->Begin()->Time().GetMillis() +
+            (mCurrentRepeatIteration + 1) * mSimpleDur.GetMillis());
+      }
+      nsSMILTimeValue nextMilestone =
+        NS_MIN(mCurrentInterval->End()->Time(), nextRepeat);
 
-      // Check for an early end
-      nsSMILInstanceTime* earlyEnd =
-        CheckForEarlyEnd(mCurrentInterval->End()->Time());
+      // Check for an early end before that time
+      nsSMILInstanceTime* earlyEnd = CheckForEarlyEnd(nextMilestone);
       if (earlyEnd) {
         aNextMilestone.mIsEnd = PR_TRUE;
         aNextMilestone.mTime = earlyEnd->Time().GetMillis();
         return PR_TRUE;
       }
 
-      // Otherwise it's just the next interval end
-      if (mCurrentInterval->End()->Time().IsResolved()) {
-        aNextMilestone.mIsEnd = PR_TRUE;
-        aNextMilestone.mTime = mCurrentInterval->End()->Time().GetMillis();
+      // Apply the previously calculated milestone
+      if (nextMilestone.IsResolved()) {
+        aNextMilestone.mIsEnd = nextMilestone != nextRepeat;
+        aNextMilestone.mTime = nextMilestone.GetMillis();
         return PR_TRUE;
       }
 
       return PR_FALSE;
     }
 
   case STATE_POSTACTIVE:
     return PR_FALSE;
@@ -1953,16 +2036,27 @@ nsSMILTimedElement::NotifyChangedInterva
   nsSMILTimeContainer* container = GetTimeContainer();
   if (container) {
     container->SyncPauseTime();
   }
 
   mCurrentInterval->NotifyChanged(container);
 }
 
+void
+nsSMILTimedElement::FireTimeEventAsync(PRUint32 aMsg, PRInt32 aDetail)
+{
+  if (!mAnimationElement)
+    return;
+
+  nsCOMPtr<nsIRunnable> event =
+    new AsyncTimeEventRunner(&mAnimationElement->Content(), aMsg, aDetail);
+  NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
+}
+
 const nsSMILInstanceTime*
 nsSMILTimedElement::GetEffectiveBeginInstance() const
 {
   switch (mElementState)
   {
   case STATE_STARTUP:
     return nsnull;
 
--- a/content/smil/nsSMILTimedElement.h
+++ b/content/smil/nsSMILTimedElement.h
@@ -477,16 +477,17 @@ protected:
   void              SampleFillValue();
   void              AddInstanceTimeFromCurrentTime(nsSMILTime aCurrentTime,
                         double aOffsetSeconds, PRBool aIsBegin);
   void              RegisterMilestone();
   PRBool            GetNextMilestone(nsSMILMilestone& aNextMilestone) const;
 
   void              NotifyNewInterval();
   void              NotifyChangedInterval();
+  void              FireTimeEventAsync(PRUint32 aMsg, PRInt32 aDetail);
   const nsSMILInstanceTime* GetEffectiveBeginInstance() const;
   const nsSMILInterval* GetPreviousInterval() const;
   PRBool            HasPlayed() const { return !mOldIntervals.IsEmpty(); }
 
   // Hashtable callback methods
   PR_STATIC_CALLBACK(PLDHashOperator) NotifyNewIntervalCallback(
       TimeValueSpecPtrKey* aKey, void* aData);
 
@@ -534,16 +535,17 @@ protected:
 
   InstanceTimeList                mBeginInstances;
   InstanceTimeList                mEndInstances;
   PRUint32                        mInstanceSerialIndex;
 
   nsSMILAnimationFunction*        mClient;
   nsAutoPtr<nsSMILInterval>       mCurrentInterval;
   IntervalList                    mOldIntervals;
+  PRUint32                        mCurrentRepeatIteration;
   nsSMILMilestone                 mPrevRegisteredMilestone;
   static const nsSMILMilestone    sMaxMilestone;
   static const PRUint8            sMaxNumIntervals;
   static const PRUint8            sMaxNumInstanceTimes;
 
   // Set of dependent time value specs to be notified when establishing a new
   // current interval. Change notifications and delete notifications are handled
   // by the interval.
--- a/content/smil/test/Makefile.in
+++ b/content/smil/test/Makefile.in
@@ -77,16 +77,17 @@ include $(topsrcdir)/config/rules.mk
 	  test_smilGetSimpleDuration.xhtml \
 	  test_smilKeySplines.xhtml \
 	  test_smilKeyTimesPacedMode.xhtml \
 	  test_smilSetCurrentTime.xhtml \
 	  test_smilSync.xhtml \
 	  test_smilSyncbaseTarget.xhtml \
 	  test_smilSyncTransform.xhtml \
 	  test_smilTextZoom.xhtml \
+	  test_smilTimeEvents.xhtml \
 	  test_smilTiming.xhtml \
 	  test_smilTimingZeroIntervals.xhtml \
 	  test_smilUpdatedInterval.xhtml \
 	  test_smilXHR.xhtml \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/content/smil/test/test_smilTimeEvents.xhtml
@@ -0,0 +1,292 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=572270
+-->
+<head>
+  <title>Test TimeEvents dispatching</title>
+  <script type="text/javascript" src="/MochiKit/packed.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank"
+  href="https://bugzilla.mozilla.org/show_bug.cgi?id=572270">Mozilla Bug
+  572270</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="100px" height="100px">
+  <g font-size="10px">
+    <circle cx="0" cy="0" r="15" fill="blue" id="circle"
+      onbegin="parentHandler(evt)" onrepeat="parentHandler(evt)"
+      onend="parentHandler(evt)">
+      <animate attributeName="cy" from="0" to="100" dur="60s" begin="2s"
+        id="anim" repeatCount="2"
+        onbegin="handleOnBegin(evt)" onrepeat="handleOnRepeat(evt)"
+        onend="handleOnEnd(evt)"/>
+    </circle>
+  </g>
+</svg>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+<![CDATA[
+/** Test SMIL TimeEvents dispatching **/
+
+/* Global Variables */
+const gTimeoutDur = 5000; // Time until we give up waiting for events in ms
+var gSvg    = document.getElementById("svg");
+var gAnim   = document.getElementById('anim');
+var gCircle = document.getElementById('circle');
+var gExpectedEvents = new Array();
+var gTimeoutID;
+var gTestStages =
+  [ testPlaybackBegin,
+    testPlaybackRepeat,
+    testPlaybackEnd,
+    testForwardsSeekToMid,
+    testForwardsSeekToNextInterval,
+    testForwardsSeekPastEnd,
+    testBackwardsSeekToMid,
+    testBackwardsSeekToStart,
+    testCreateEvent,
+    testRegistration
+    ];
+
+SimpleTest.waitForExplicitFinish();
+
+function continueTest()
+{
+  if (gTestStages.length == 0) {
+    SimpleTest.finish();
+    return;
+  }
+  gTestStages.shift()();
+}
+
+function testPlaybackBegin()
+{
+  // Test events are dispatched through normal playback
+  gSvg.pauseAnimations();
+  gSvg.setCurrentTime(1.99);
+  gExpectedEvents.push("beginEvent", "beginEvent"); // Two registered handlers
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function testPlaybackRepeat()
+{
+  gSvg.pauseAnimations();
+  gSvg.setCurrentTime(61.99);
+  gExpectedEvents.push(["repeatEvent", 1], ["repeatEvent", 1]);
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function testPlaybackEnd()
+{
+  gSvg.pauseAnimations();
+  gSvg.setCurrentTime(121.99);
+  gExpectedEvents.push("endEvent", "endEvent");
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function testForwardsSeekToMid()
+{
+  gSvg.pauseAnimations();
+  // Set animation parameters to something that repeats a lot
+  gSvg.setCurrentTime(0);
+  gAnim.setAttribute('begin', '2s; 102s');
+  gAnim.setAttribute('dur', '15s');
+  gAnim.setAttribute('repeatCount', '6');
+  gSvg.setCurrentTime(46.99);
+  gExpectedEvents.push("beginEvent", "beginEvent",
+                       ["repeatEvent", 3], ["repeatEvent", 3]);
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function testForwardsSeekToNextInterval()
+{
+  // Skip to next interval -- we shouldn't get any additional begin or end
+  // events in between
+  gSvg.pauseAnimations();
+  gSvg.setCurrentTime(131.99);
+  gExpectedEvents.push(["repeatEvent", 2], ["repeatEvent", 2]);
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function testForwardsSeekPastEnd()
+{
+  gSvg.pauseAnimations();
+  gSvg.setCurrentTime(200);
+  gExpectedEvents.push("endEvent", "endEvent");
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function testBackwardsSeekToMid()
+{
+  gSvg.pauseAnimations();
+  gSvg.setCurrentTime(31.99);
+  gExpectedEvents.push("beginEvent", "beginEvent",
+                       ["repeatEvent", 2], ["repeatEvent", 2]);
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function testBackwardsSeekToStart()
+{
+  gSvg.pauseAnimations();
+  gExpectedEvents.push("endEvent", "endEvent");
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.setCurrentTime(0);
+}
+
+function testCreateEvent()
+{
+  var evt;
+  try {
+    evt = document.createEvent("TimeEvents");
+  } catch (e) {
+    ok(false, "Failed to create TimeEvent via script: " + e);
+    return;
+  }
+  evt.initTimeEvent("repeatEvent", null, 3);
+  is(evt.type, "repeatEvent", "Unexpected type for user-generated event");
+  is(evt.detail, 3, "Unexpected detail for user-generated event");
+  is(evt.target, null, "Unexpected event target");
+  is(evt.currentTarget, null, "Unexpected event current target");
+  is(evt.eventPhase, evt.AT_TARGET);
+  is(evt.bubbles, false, "Event should not bubble");
+  is(evt.cancelable, false, "Event should not be cancelable");
+  is(evt.view, null, "Event view should be null");
+
+  // Prior to dispatch we should be able to change the event type
+  evt.initTimeEvent("beginEvent", document.defaultView, 0);
+  is(evt.type, "beginEvent", "Failed to update event type before dispatch");
+  is(evt.detail, 0, "Failed to update event detail before dispatch");
+  is(evt.view, document.defaultView, "Event view should be set");
+
+  // But not directly as it's readonly
+  try {
+    evt.type = "endEvent";
+  } catch(e) { }
+  is(evt.type, "beginEvent", "Event type should be readonly");
+
+  // Likewise the detail field should be readonly
+  try {
+    evt.detail = "8";
+  } catch(e) { }
+  is(evt.detail, 0, "Event detail should be readonly");
+
+  // Dispatch
+  gExpectedEvents.push("beginEvent", "beginEvent");
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gAnim.dispatchEvent(evt);
+}
+
+function testRegistration()
+{
+  gSvg.pauseAnimations();
+  // Reset animation to something simple
+  gSvg.setCurrentTime(0);
+  gAnim.setAttribute('begin', '2s');
+  gAnim.setAttribute('dur', '50s');
+
+  // Remove attribute handler
+  gAnim.removeAttribute('onbegin');
+
+  // Add bogus handlers
+  gAnim.setAttribute('onbeginElement', 'handleOnBegin(evt)');
+  gAnim.addEventListener("begin", handleOnBegin, false);
+  gAnim.addEventListener("onbegin", handleOnBegin, false);
+
+  // We should now have just one legitimate listener: the one registered to
+  // handle 'beginElement'
+  gSvg.setCurrentTime(1.99);
+  gExpectedEvents.push("beginEvent");
+  gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
+  gSvg.unpauseAnimations();
+}
+
+function handleOnBegin(evt)
+{
+  is(evt.type, "beginEvent", "Expected begin event but got " + evt.type);
+  checkExpectedEvent(evt);
+}
+
+function handleOnRepeat(evt)
+{
+  is(evt.type, "repeatEvent", "Expected repeat event but got " + evt.type);
+  checkExpectedEvent(evt);
+}
+
+function handleOnEnd(evt)
+{
+  is(evt.type, "endEvent", "Expected end event but got " + evt.type);
+  checkExpectedEvent(evt);
+}
+
+function sanityCheckEvent(evt)
+{
+  is(evt.target, gAnim, "Unexpected event target");
+  is(evt.currentTarget, gAnim, "Unexpected event current target");
+  is(evt.eventPhase, evt.AT_TARGET);
+  is(evt.bubbles, false, "Event should not bubble");
+  is(evt.cancelable, false, "Event should not be cancelable");
+  // Currently we set event timestamps to 0 which DOM 2 allows. This isn't
+  // correct since SMIL uses this field to avoid synchronisation slew but first
+  // we need to fix bug 323039 and bug 77992 which involve storing timestamps as
+  // 64-bit integers and deciding whether those timestamps should be related to
+  // the epoch or system start.
+  is(evt.timeStamp, 0, "Event timeStamp should be 0");
+  ok(evt.view !== null, "Event view not set");
+}
+
+function checkExpectedEvent(evt)
+{
+  sanityCheckEvent(evt);
+  ok(gExpectedEvents.length > 0, "Unexpected event: " + evt.type);
+  if (gExpectedEvents.length == 0) return;
+
+  var expected = gExpectedEvents.shift();
+  if (typeof expected == 'string') {
+    is(evt.type, expected, "Unexpected event type");
+    is(evt.detail, 0, "Unexpected event detail (repeat iteration)");
+  } else {
+    is(evt.type, expected[0], "Unexpected event type");
+    is(evt.detail, expected[1], "Unexpected event detail (repeat iteration)");
+  }
+  if (gExpectedEvents.length == 0) {
+    clearTimeout(gTimeoutID);
+    continueTest();
+  }
+}
+
+function timeoutFail()
+{
+  ok(false, "Timed out waiting for events: " + gExpectedEvents.join(', '));
+  SimpleTest.finish(); // No point continuing
+}
+
+function parentHandler(evt)
+{
+  ok(false, "Handler on parent got called but event shouldn't bubble.");
+}
+
+window.addEventListener("load", continueTest, false);
+
+// Register event handlers *in addition* to the handlers already added via the
+// "onbegin", "onend", "onrepeat" attributes on the <animate> and <circle>
+// elements. This is to test that both types of registration work.
+gAnim.addEventListener("beginEvent", handleOnBegin, false);
+gAnim.addEventListener("repeatEvent", handleOnRepeat, false);
+gAnim.addEventListener("endEvent", handleOnEnd, false);
+gCircle.addEventListener("beginEvent", parentHandler, false);
+]]>
+</script>
+</pre>
+</body>
+</html>
--- a/content/svg/content/src/nsSVGAnimationElement.cpp
+++ b/content/svg/content/src/nsSVGAnimationElement.cpp
@@ -471,16 +471,22 @@ nsSVGAnimationElement::EndElementAt(floa
   if (NS_FAILED(rv))
     return rv;
 
   AnimationNeedsResample();
  
   return NS_OK;
 }
 
+PRBool
+nsSVGAnimationElement::IsEventName(nsIAtom* aName)
+{
+  return nsContentUtils::IsEventAttributeName(aName, EventNameType_SMIL);
+}
+
 void
 nsSVGAnimationElement::UpdateHrefTarget(nsIContent* aNodeForContext,
                                         const nsAString& aHrefStr)
 {
   nsCOMPtr<nsIURI> targetURI;
   nsCOMPtr<nsIURI> baseURI = GetBaseURI();
   nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI),
                                             aHrefStr, GetOwnerDoc(), baseURI);
--- a/content/svg/content/src/nsSVGAnimationElement.h
+++ b/content/svg/content/src/nsSVGAnimationElement.h
@@ -93,16 +93,19 @@ public:
   virtual PRBool HasAnimAttr(nsIAtom* aAttName) const;
   virtual mozilla::dom::Element* GetTargetElementContent();
   virtual nsIAtom* GetTargetAttributeName() const;
   virtual nsSMILTargetAttrType GetTargetAttributeType() const;
   virtual nsSMILTimedElement& TimedElement();
   virtual nsSMILTimeContainer* GetTimeContainer();
 
 protected:
+  // nsSVGElement overrides
+  PRBool IsEventName(nsIAtom* aName);
+
   void UpdateHrefTarget(nsIContent* aNodeForContext,
                         const nsAString& aHrefStr);
 
   class TargetReference : public nsReferencedElement {
   public:
     TargetReference(nsSVGAnimationElement* aAnimationElement) :
       mAnimationElement(aAnimationElement) {}
   protected:
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1359,16 +1359,24 @@ nsIAtom* nsSVGElement::GetEventNameForAt
   if (aAttr == nsGkAtoms::onerror)
     return nsGkAtoms::onSVGError;
   if (aAttr == nsGkAtoms::onresize)
     return nsGkAtoms::onSVGResize;
   if (aAttr == nsGkAtoms::onscroll)
     return nsGkAtoms::onSVGScroll;
   if (aAttr == nsGkAtoms::onzoom)
     return nsGkAtoms::onSVGZoom;
+#ifdef MOZ_SMIL
+  if (aAttr == nsGkAtoms::onbegin)
+    return nsGkAtoms::onbeginEvent;
+  if (aAttr == nsGkAtoms::onrepeat)
+    return nsGkAtoms::onrepeatEvent;
+  if (aAttr == nsGkAtoms::onend)
+    return nsGkAtoms::onendEvent;
+#endif // MOZ_SMIL
 
   return aAttr;
 }
 
 nsSVGSVGElement *
 nsSVGElement::GetCtx()
 {
   nsCOMPtr<nsIDOMSVGSVGElement> svg;
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -2434,17 +2434,17 @@ nsXULDocument::PrepareToWalk()
     }
 
     // Now check the chrome registry for any additional overlays.
     rv = AddChromeOverlays();
     if (NS_FAILED(rv)) return rv;
 
     // Do one-time initialization if we're preparing to walk the
     // master document's prototype.
-    nsCOMPtr<Element> root;
+    nsRefPtr<Element> root;
 
     if (mState == eState_Master) {
         // Add the root element
         rv = CreateElementFromPrototype(proto, getter_AddRefs(root));
         if (NS_FAILED(rv)) return rv;
 
         rv = AppendChildTo(root, PR_FALSE);
         if (NS_FAILED(rv)) return rv;
@@ -2925,17 +2925,17 @@ nsXULDocument::ResumeWalk()
                          "no element on context stack");
 
             switch (childproto->mType) {
             case nsXULPrototypeNode::eType_Element: {
                 // An 'element', which may contain more content.
                 nsXULPrototypeElement* protoele =
                     static_cast<nsXULPrototypeElement*>(childproto);
 
-                nsCOMPtr<Element> child;
+                nsRefPtr<Element> child;
 
                 if (!processingOverlayHookupNodes) {
                     rv = CreateElementFromPrototype(protoele,
                                                     getter_AddRefs(child));
                     if (NS_FAILED(rv)) return rv;
 
                     // ...and append it to the content model.
                     rv = element->AppendChildTo(child, PR_FALSE);
@@ -3675,17 +3675,17 @@ nsXULDocument::CreateElementFromPrototyp
         nsCAutoString tagstrC;
         tagstrC.AssignWithConversion(tagstr);
         PR_LOG(gXULLog, PR_LOG_NOTICE,
                ("xul: creating <%s> from prototype",
                 tagstrC.get()));
     }
 #endif
 
-    nsCOMPtr<Element> result;
+    nsRefPtr<Element> result;
 
     if (aPrototype->mNodeInfo->NamespaceEquals(kNameSpaceID_XUL)) {
         // If it's a XUL element, it'll be lightweight until somebody
         // monkeys with it.
         rv = nsXULElement::Create(aPrototype, this, PR_TRUE, getter_AddRefs(result));
         if (NS_FAILED(rv)) return rv;
     }
     else {
@@ -3723,17 +3723,17 @@ nsXULDocument::CreateElementFromPrototyp
 }
 
 nsresult
 nsXULDocument::CreateOverlayElement(nsXULPrototypeElement* aPrototype,
                                     Element** aResult)
 {
     nsresult rv;
 
-    nsCOMPtr<Element> element;
+    nsRefPtr<Element> element;
     rv = CreateElementFromPrototype(aPrototype, getter_AddRefs(element));
     if (NS_FAILED(rv)) return rv;
 
     OverlayForwardReference* fwdref =
         new OverlayForwardReference(this, element);
     if (! fwdref)
         return NS_ERROR_OUT_OF_MEMORY;
 
--- a/content/xul/document/src/nsXULDocument.h
+++ b/content/xul/document/src/nsXULDocument.h
@@ -487,17 +487,17 @@ protected:
 
     /**
      * Used to resolve broadcaster references
      */
     class BroadcasterHookup : public nsForwardReference
     {
     protected:
         nsXULDocument* mDocument;              // [WEAK]
-        nsCOMPtr<mozilla::dom::Element> mObservesElement; // [OWNER]
+        nsRefPtr<mozilla::dom::Element> mObservesElement; // [OWNER]
         PRBool mResolved;
 
     public:
         BroadcasterHookup(nsXULDocument* aDocument,
                           mozilla::dom::Element* aObservesElement)
             : mDocument(aDocument),
               mObservesElement(aObservesElement),
               mResolved(PR_FALSE)
--- a/content/xul/templates/src/Makefile.in
+++ b/content/xul/templates/src/Makefile.in
@@ -77,12 +77,13 @@ CPPSRCS		= \
 		$(NULL)
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES	= -I$(srcdir)/../../../base/src \
-		   -I$(srcdir)/../../content/src \
-		   $(NULL)
+		  -I$(srcdir)/../../content/src \
+		  -I$(srcdir)/../../../../layout/xul/base/src/tree/src \
+		  $(NULL)
 
 DEFINES += -D_IMPL_NS_LAYOUT
--- a/content/xul/templates/src/nsXULContentUtils.cpp
+++ b/content/xul/templates/src/nsXULContentUtils.cpp
@@ -85,16 +85,17 @@
 #include "nsIDateTimeFormat.h"
 #include "nsDateTimeFormatCID.h"
 #include "nsIScriptableDateFormat.h"
 #include "nsICollation.h"
 #include "nsCollationCID.h"
 #include "nsILocale.h"
 #include "nsILocaleService.h"
 #include "nsIConsoleService.h"
+#include "nsEscape.h"
 
 static NS_DEFINE_CID(kRDFServiceCID,        NS_RDFSERVICE_CID);
 
 //------------------------------------------------------------------------
 
 nsIRDFService* nsXULContentUtils::gRDF;
 nsIDateTimeFormat* nsXULContentUtils::gFormat;
 nsICollation *nsXULContentUtils::gCollation;
@@ -330,16 +331,30 @@ nsXULContentUtils::MakeElementURI(nsIDoc
     nsIURI *docURL = aDocument->GetDocumentURI();
     NS_ENSURE_TRUE(docURL, NS_ERROR_UNEXPECTED);
 
     nsCOMPtr<nsIURI> docURIClone;
     nsresult rv = docURL->Clone(getter_AddRefs(docURIClone));
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIURL> mutableURL(do_QueryInterface(docURIClone));
+    if (!mutableURL) {
+        nsCString uri;
+        rv = docURL->GetSpec(aURI);
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        nsCAutoString ref;
+        NS_EscapeURL(NS_ConvertUTF16toUTF8(aElementID), esc_FilePath | esc_AlwaysCopy, ref);
+
+        aURI.Append('#');
+        aURI.Append(ref);
+
+        return NS_OK;
+    }
+
     NS_ENSURE_TRUE(mutableURL, NS_ERROR_NOT_AVAILABLE);
 
     rv = mutableURL->SetRef(NS_ConvertUTF16toUTF8(aElementID));
     NS_ENSURE_SUCCESS(rv, rv);
 
     return mutableURL->GetSpec(aURI);
 }
 
@@ -376,16 +391,29 @@ nsXULContentUtils::MakeElementID(nsIDocu
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIURL> url = do_QueryInterface(uri);
     if (url) {
         nsCAutoString ref;
         url->GetRef(ref);
         CopyUTF8toUTF16(ref, aElementID);
     } else {
+        const char* start = aURI.BeginReading();
+        const char* end = aURI.EndReading();
+        const char* chr = end;
+
+        while (--chr >= start) {
+            if (*chr == '#') {
+                nsDependentCSubstring ref = Substring(chr + 1, end);
+                nsCAutoString unescaped;
+                CopyUTF8toUTF16(NS_UnescapeURL(ref, esc_FilePath, unescaped), aElementID);
+                return NS_OK;
+            }
+        }
+
         aElementID.Truncate();
     }
 
     return NS_OK;
 }
 
 nsresult
 nsXULContentUtils::GetResource(PRInt32 aNameSpaceID, nsIAtom* aAttribute, nsIRDFResource** aResult)
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -59,17 +59,16 @@
 #include "nsCOMPtr.h"
 #include "nsCRT.h"
 #include "nsFixedSizeAllocator.h"
 #include "nsIContent.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMXMLDocument.h"
-#include "nsIPrivateDOMImplementation.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDocument.h"
 #include "nsBindingManager.h"
 #include "nsIDOMNodeList.h"
 #include "nsINameSpaceManager.h"
 #include "nsIObserverService.h"
 #include "nsIRDFCompositeDataSource.h"
 #include "nsIRDFInferDataSource.h"
--- a/content/xul/templates/src/nsXULTreeBuilder.cpp
+++ b/content/xul/templates/src/nsXULTreeBuilder.cpp
@@ -60,16 +60,17 @@
 #include "nsXULContentUtils.h"
 #include "nsXULTemplateBuilder.h"
 #include "nsIXULSortService.h"
 #include "nsTArray.h"
 #include "nsUnicharUtils.h"
 #include "nsINameSpaceManager.h"
 #include "nsIDOMClassInfo.h"
 #include "nsWhitespaceTokenizer.h"
+#include "nsTreeContentView.h"
 
 // For security check
 #include "nsIDocument.h"
 
 /**
  * A XUL template builder that serves as an tree view, allowing
  * (pretty much) arbitrary RDF to be presented in an tree.
  */
@@ -462,16 +463,19 @@ nsXULTreeBuilder::GetSelection(nsITreeSe
 {
     NS_IF_ADDREF(*aSelection = mSelection.get());
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeBuilder::SetSelection(nsITreeSelection* aSelection)
 {
+    NS_ENSURE_TRUE(!aSelection ||
+                   nsTreeContentView::CanTrustTreeSelection(aSelection),
+                   NS_ERROR_DOM_SECURITY_ERR);
     mSelection = aSelection;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeBuilder::GetRowProperties(PRInt32 aIndex, nsISupportsArray* aProperties)
 {
     NS_ENSURE_ARG_POINTER(aProperties);
--- a/docshell/base/IHistory.h
+++ b/docshell/base/IHistory.h
@@ -47,17 +47,17 @@ class nsString;
 
 namespace mozilla {
 
     namespace dom {
         class Link;
     }
 
 #define IHISTORY_IID \
-  {0x6f736049, 0x6370, 0x4376, {0xb7, 0x17, 0xfa, 0xfc, 0x0b, 0x4f, 0xd0, 0xf1}}
+  {0x6f733924, 0x6321, 0x4384, {0x01, 0xee, 0x8e, 0x7d, 0xfb, 0xde, 0xe7, 0xa8}}
 
 class IHistory : public nsISupports
 {
 public:
     NS_DECLARE_STATIC_IID_ACCESSOR(IHISTORY_IID)
 
     /**
      * Registers the Link for notifications about the visited-ness of aURI.
@@ -66,17 +66,17 @@ public:
      * SetLinkState called on themselves.  This function is guaranteed to run to
      * completion before aLink is notified.  After the node is notified, it will
      * be unregistered.
      *
      * @note SetLinkState must not call RegisterVisitedCallback or
      *       UnregisterVisitedCallback.
      *
      * @pre aURI must not be null.
-     * @pre aLink must not be null.
+     * @pre aLink may be null only in the MOZ_IPC parent process.
      *
      * @param aURI
      *        The URI to check.
      * @param aLink
      *        The link to update whenever the history status changes.  The
      *        implementation will only hold onto a raw pointer, so if this
      *        object should be destroyed, be sure to call
      *        UnregisterVistedCallback first.
--- a/docshell/test/navigation/NavigationUtils.js
+++ b/docshell/test/navigation/NavigationUtils.js
@@ -172,17 +172,17 @@ function xpcGetFramesByName(name) {
       results.push(win);
   });
 
   return results;
 }
 
 function xpcCleanupWindows() {
   xpcEnumerateContentWindows(function(win) {
-    if (win.location.protocol == "data:")
+    if (win.location && win.location.protocol == "data:")
       win.close();
   });
 }
 
 function xpcWaitForFinishedFrames(callback, numFrames) {
   var finishedFrameCount = 0;
   function frameFinished() {
     finishedFrameCount++;
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -149,17 +149,16 @@
 
 // Oh, did I mention that I hate Microsoft for doing this to me?
 #ifdef XP_WIN
 #undef GetClassName
 #endif
 
 // HTMLOptionsCollection includes
 #include "nsIDOMHTMLOptionElement.h"
-#include "nsIDOMNSHTMLOptionElement.h"
 #include "nsIDOMHTMLOptionsCollection.h"
 #include "nsIDOMNSHTMLOptionCollectn.h"
 
 // ContentList includes
 #include "nsContentList.h"
 #include "nsGenericElement.h"
 
 // Event related includes
@@ -249,22 +248,20 @@
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMNSHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMNSHTMLElement.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMNSHTMLAnchorElement2.h"
 #include "nsIDOMHTMLAppletElement.h"
 #include "nsIDOMHTMLAreaElement.h"
-#include "nsIDOMNSHTMLAreaElement2.h"
 #include "nsIDOMHTMLBRElement.h"
 #include "nsIDOMHTMLBaseElement.h"
 #include "nsIDOMHTMLBodyElement.h"
 #include "nsIDOMHTMLButtonElement.h"
-#include "nsIDOMNSHTMLButtonElement.h"
 #include "nsIDOMHTMLCanvasElement.h"
 #include "nsIDOMHTMLDListElement.h"
 #include "nsIDOMHTMLDirectoryElement.h"
 #include "nsIDOMHTMLDivElement.h"
 #include "nsIDOMHTMLEmbedElement.h"
 #include "nsIDOMHTMLFieldSetElement.h"
 #include "nsIDOMHTMLFontElement.h"
 #include "nsIDOMNSHTMLFormElement.h"
@@ -279,34 +276,31 @@
 #include "nsIDOMHTMLIFrameElement.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIDOMNSHTMLImageElement.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMNSHTMLInputElement.h"
 #include "nsIDOMHTMLIsIndexElement.h"
 #include "nsIDOMHTMLLIElement.h"
 #include "nsIDOMHTMLLabelElement.h"
-#include "nsIDOMNSHTMLLabelElement.h"
 #include "nsIDOMHTMLLegendElement.h"
 #include "nsIDOMHTMLLinkElement.h"
 #include "nsIDOMHTMLMapElement.h"
 #include "nsIDOMHTMLMenuElement.h"
 #include "nsIDOMHTMLMetaElement.h"
 #include "nsIDOMHTMLModElement.h"
 #include "nsIDOMHTMLOListElement.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMHTMLOptGroupElement.h"
 #include "nsIDOMHTMLOutputElement.h"
 #include "nsIDOMHTMLParagraphElement.h"
 #include "nsIDOMHTMLParamElement.h"
 #include "nsIDOMHTMLPreElement.h"
 #include "nsIDOMHTMLQuoteElement.h"
 #include "nsIDOMHTMLScriptElement.h"
-#include "nsIDOMNSHTMLScriptElement.h"
-#include "nsIDOMNSHTMLSelectElement.h"
 #include "nsIDOMHTMLStyleElement.h"
 #include "nsIDOMHTMLTableCaptionElem.h"
 #include "nsIDOMHTMLTableCellElement.h"
 #include "nsIDOMHTMLTableColElement.h"
 #include "nsIDOMHTMLTableElement.h"
 #include "nsIDOMHTMLTableRowElement.h"
 #include "nsIDOMHTMLTableSectionElem.h"
 #include "nsIDOMHTMLTextAreaElement.h"
@@ -378,16 +372,17 @@
 #ifdef MOZ_SMIL
 #include "nsIDOMSVGAnimateElement.h"
 #include "nsIDOMSVGAnimateTransformElement.h"
 #include "nsIDOMSVGAnimateMotionElement.h"
 #include "nsIDOMSVGMpathElement.h"
 #include "nsIDOMSVGSetElement.h"
 #include "nsIDOMSVGAnimationElement.h"
 #include "nsIDOMElementTimeControl.h"
+#include "nsIDOMTimeEvent.h"
 #endif // MOZ_SMIL
 #include "nsIDOMSVGAnimTransformList.h"
 #include "nsIDOMSVGCircleElement.h"
 #include "nsIDOMSVGClipPathElement.h"
 #include "nsIDOMSVGDefsElement.h"
 #include "nsIDOMSVGDescElement.h"
 #include "nsIDOMSVGDocument.h"
 #include "nsIDOMSVGElement.h"
@@ -1004,16 +999,18 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(SVGAnimateTransformElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGAnimateMotionElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGMpathElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGSetElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(TimeEvent, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
 #endif // MOZ_SMIL
   NS_DEFINE_CLASSINFO_DATA(SVGCircleElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGClipPathElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGDefsElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGDescElement, nsElementSH,
@@ -2437,18 +2434,16 @@ nsDOMClassInfo::Init()
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLAppletElement, nsIDOMHTMLAppletElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLAppletElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLAreaElement, nsIDOMHTMLAreaElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLAreaElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSHTMLAreaElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSHTMLAreaElement2)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLBRElement, nsIDOMHTMLBRElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLBRElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
@@ -2459,17 +2454,16 @@ nsDOMClassInfo::Init()
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLBodyElement, nsIDOMHTMLBodyElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLBodyElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLButtonElement, nsIDOMHTMLButtonElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLButtonElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSHTMLButtonElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLDListElement, nsIDOMHTMLDListElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLDListElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
@@ -2577,17 +2571,16 @@ nsDOMClassInfo::Init()
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLLIElement, nsIDOMHTMLLIElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLLIElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLLabelElement, nsIDOMHTMLLabelElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLLabelElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSHTMLLabelElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLLegendElement, nsIDOMHTMLLegendElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLLegendElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
@@ -2626,19 +2619,16 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLOptGroupElement, nsIDOMHTMLOptGroupElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLOptGroupElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLOptionElement, nsIDOMHTMLOptionElement)
-    // Order is significant.  nsIDOMNSHTMLOptionElement.text shdaows
-    // nsIDOMHTMLOptionElement.text, which is readonly.
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSHTMLOptionElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLOptionElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLOutputElement, nsIDOMHTMLOutputElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLOutputElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
@@ -2660,23 +2650,21 @@ nsDOMClassInfo::Init()
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLQuoteElement, nsIDOMHTMLQuoteElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLQuoteElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLScriptElement, nsIDOMHTMLScriptElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLScriptElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSHTMLScriptElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLSelectElement, nsIDOMHTMLSelectElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLSelectElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSHTMLSelectElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(HTMLSpacerElement, nsIDOMHTMLElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
@@ -3050,16 +3038,20 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGMpathElement, nsIDOMSVGMpathElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(TimeEvent, nsIDOMTimeEvent)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMTimeEvent)
+    DOM_CLASSINFO_EVENT_MAP_ENTRIES
+  DOM_CLASSINFO_MAP_END
 #endif // MOZ_SMIL
 
   DOM_CLASSINFO_MAP_BEGIN(SVGCircleElement, nsIDOMSVGCircleElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGCircleElement)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGClipPathElement, nsIDOMSVGClipPathElement)
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -235,16 +235,17 @@ DOMCI_CLASS(SVGDocument)
 DOMCI_CLASS(SVGAElement)
 DOMCI_CLASS(SVGAltGlyphElement)
 #ifdef MOZ_SMIL
 DOMCI_CLASS(SVGAnimateElement)
 DOMCI_CLASS(SVGAnimateTransformElement)
 DOMCI_CLASS(SVGAnimateMotionElement)
 DOMCI_CLASS(SVGMpathElement)
 DOMCI_CLASS(SVGSetElement)
+DOMCI_CLASS(TimeEvent)
 #endif // MOZ_SMIL
 DOMCI_CLASS(SVGCircleElement)
 DOMCI_CLASS(SVGClipPathElement)
 DOMCI_CLASS(SVGDefsElement)
 DOMCI_CLASS(SVGDescElement)
 DOMCI_CLASS(SVGEllipseElement)
 DOMCI_CLASS(SVGFEBlendElement)
 DOMCI_CLASS(SVGFEColorMatrixElement)
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -1069,16 +1069,28 @@ nsDOMWindowUtils::SendQueryContentEvent(
                                         nsIQueryContentEventResult **aResult)
 {
   *aResult = nsnull;
 
   if (!IsUniversalXPConnectCapable()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
+  NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE);
+
+  nsIDocShell *docShell = mWindow->GetDocShell();
+  NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
+
+  nsCOMPtr<nsIPresShell> presShell;
+  docShell->GetPresShell(getter_AddRefs(presShell));
+  NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
+
+  nsPresContext* presContext = presShell->GetPresContext();
+  NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
+
   // get the widget to send the event to
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
     return NS_ERROR_FAILURE;
   }
 
   if (aType != NS_QUERY_SELECTED_TEXT &&
       aType != NS_QUERY_TEXT_CONTENT &&
@@ -1092,17 +1104,17 @@ nsDOMWindowUtils::SendQueryContentEvent(
   nsCOMPtr<nsIWidget> targetWidget = widget;
   nsIntPoint pt(aX, aY);
 
   if (aType == QUERY_CHARACTER_AT_POINT) {
     // Looking for the widget at the point.
     nsQueryContentEvent dummyEvent(PR_TRUE, NS_QUERY_CONTENT_STATE, widget);
     InitEvent(dummyEvent, &pt);
     nsIFrame* popupFrame =
-      nsLayoutUtils::GetPopupFrameForEventCoordinates(&dummyEvent);
+      nsLayoutUtils::GetPopupFrameForEventCoordinates(presContext->GetRootPresContext(), &dummyEvent);
 
     nsIntRect widgetBounds;
     nsresult rv = widget->GetClientBounds(widgetBounds);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // There is no popup frame at the point and the point isn't in our widget,
     // we cannot process this request.
     NS_ENSURE_TRUE(popupFrame || widgetBounds.Contains(pt),
--- a/dom/indexedDB/test/test_writer_starvation.html
+++ b/dom/indexedDB/test/test_writer_starvation.html
@@ -91,16 +91,17 @@
       }
 
       is(callbackCount, readerCount, "All requests accounted for");
       ok(callbackCount > finalCallbackCount, "More readers after writer");
 
       finishTest();
       yield;
     }
+    SimpleTest.requestLongerTimeout(5); // see bug 580875
   </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/interfaces/html/Makefile.in
+++ b/dom/interfaces/html/Makefile.in
@@ -113,27 +113,20 @@ SDK_XPIDLSRCS =					\
 	nsIDOMHTMLAudioElement.idl		\
 	nsIDOMHTMLVoidCallback.idl		\
 	$(NULL)
 
 XPIDLSRCS = 					\
 	nsIDOMHTMLCanvasElement.idl		\
 	nsIDOMNSHTMLAnchorElement.idl		\
 	nsIDOMNSHTMLAnchorElement2.idl		\
-	nsIDOMNSHTMLAreaElement.idl		\
-	nsIDOMNSHTMLAreaElement2.idl		\
-	nsIDOMNSHTMLButtonElement.idl		\
 	nsIDOMNSHTMLDocument.idl		\
 	nsIDOMNSHTMLElement.idl			\
 	nsIDOMNSHTMLFormElement.idl		\
 	nsIDOMNSHTMLFrameElement.idl		\
 	nsIDOMNSHTMLHRElement.idl		\
 	nsIDOMNSHTMLImageElement.idl		\
 	nsIDOMNSHTMLInputElement.idl		\
-	nsIDOMNSHTMLLabelElement.idl		\
 	nsIDOMNSHTMLOptionCollectn.idl		\
-	nsIDOMNSHTMLOptionElement.idl		\
-	nsIDOMNSHTMLSelectElement.idl		\
 	nsIDOMNSHTMLTextAreaElement.idl		\
-	nsIDOMNSHTMLScriptElement.idl		\
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/dom/interfaces/html/nsIDOMHTMLAreaElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLAreaElement.idl
@@ -42,20 +42,35 @@
 /**
  * The nsIDOMHTMLAreaElement interface is the interface to a [X]HTML
  * area element.
  *
  * For more information on this interface please see
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  */
 
-[scriptable, uuid(a6cf90b0-15b3-11d2-932e-00805f8add32)]
+[scriptable, uuid(fca7d30d-c834-470d-9bb2-25eddfedd86b)]
 interface nsIDOMHTMLAreaElement : nsIDOMHTMLElement
 {
-           attribute DOMString        accessKey;
            attribute DOMString        alt;
            attribute DOMString        coords;
+           attribute DOMString        shape;
            attribute DOMString        href;
+           attribute DOMString        target;
+
+           attribute DOMString        ping;
+
+           // URL decomposition IDL attributes
+           attribute DOMString        protocol;
+           attribute DOMString        host;
+           attribute DOMString        hostname;  
+           attribute DOMString        port;
+           attribute DOMString        pathname;
+           attribute DOMString        search;
+           attribute DOMString        hash;
+           
+
+           attribute DOMString        accessKey;
+           attribute long             tabIndex;
            attribute boolean          noHref;
-           attribute DOMString        shape;
-           attribute long             tabIndex;
-           attribute DOMString        target;
+           DOMString                 toString();
+
 };
--- a/dom/interfaces/html/nsIDOMHTMLButtonElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLButtonElement.idl
@@ -42,22 +42,27 @@
 /**
  * The nsIDOMHTMLButtonElement interface is the interface to a [X]HTML
  * button element.
  *
  * For more information on this interface please see
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  */
 
-[scriptable, uuid(a6cf9095-15b3-11d2-932e-00805f8add32)]
+[scriptable, uuid(dfed25e8-07e8-41a9-8f9e-9fbf59c539ea)]
 interface nsIDOMHTMLButtonElement : nsIDOMHTMLElement
 {
+           attribute boolean               autofocus;
+           attribute boolean               disabled;
   readonly attribute nsIDOMHTMLFormElement form;
+
+           attribute DOMString             name;
+           attribute DOMString             type;
+           attribute DOMString             value;
+
+           
            attribute DOMString             accessKey;
-           attribute boolean               disabled;
-           attribute DOMString             name;
            attribute long                  tabIndex;
-  // The scriptable version of type is writable and lives on
-  // nsIDOMNSHTMLButtonElement (have to do it this way because this
-  // interface is frozen and we don't want to break binary compat).
-  [noscript] readonly attribute DOMString  type;
-           attribute DOMString             value;
+  void                      blur();
+  void                      focus();
+  void                      click();
 };
+
--- a/dom/interfaces/html/nsIDOMHTMLLabelElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLLabelElement.idl
@@ -42,15 +42,17 @@
 /**
  * The nsIDOMHTMLLabelElement interface is the interface to a [X]HTML
  * label element.
  *
  * For more information on this interface please see
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  */
 
-[scriptable, uuid(a6cf9096-15b3-11d2-932e-00805f8add32)]
+[scriptable, uuid(8a207452-e725-4a9e-beb6-9e0c0a65012c)]
 interface nsIDOMHTMLLabelElement : nsIDOMHTMLElement
 {
   readonly attribute nsIDOMHTMLFormElement form;
+           attribute DOMString             htmlFor;
+  readonly attribute nsIDOMHTMLElement     control;
+
            attribute DOMString             accessKey;
-           attribute DOMString             htmlFor;
 };
--- a/dom/interfaces/html/nsIDOMHTMLOptionElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLOptionElement.idl
@@ -42,22 +42,21 @@
 /**
  * The nsIDOMHTMLOptionElement interface is the interface to a [X]HTML
  * option element.
  *
  * For more information on this interface please see
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  */
 
-[scriptable, uuid(a6cf9092-15b3-11d2-932e-00805f8add32)]
+[scriptable, uuid(611d00f5-1eb8-4571-b995-2a2019d2d11c)]
 interface nsIDOMHTMLOptionElement : nsIDOMHTMLElement
 {
+           attribute boolean               disabled;
   readonly attribute nsIDOMHTMLFormElement form;
-  // Modified in DOM Level 2:
+           attribute DOMString             label;
            attribute boolean               defaultSelected;
-  readonly attribute DOMString             text;
-  // Modified in DOM Level 2:
-  readonly attribute long                  index;
-           attribute boolean               disabled;
-           attribute DOMString             label;
            attribute boolean               selected;
            attribute DOMString             value;
+
+           attribute DOMString             text;
+  readonly attribute long                  index;
 };
--- a/dom/interfaces/html/nsIDOMHTMLScriptElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLScriptElement.idl
@@ -42,19 +42,21 @@
 /**
  * The nsIDOMHTMLScriptElement interface is the interface to a [X]HTML
  * script element.
  *
  * For more information on this interface please see
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  */
 
-[scriptable, uuid(a6cf90b1-15b3-11d2-932e-00805f8add32)]
+[scriptable, uuid(4af8568c-375c-42fd-a82f-b25a7c03fc3e)]
 interface nsIDOMHTMLScriptElement : nsIDOMHTMLElement
 {
+           attribute DOMString        src;
+           attribute boolean          async;
+           attribute boolean          defer;
+           attribute DOMString        type;
+           attribute DOMString        charset;
            attribute DOMString        text;
+
            attribute DOMString        htmlFor;
            attribute DOMString        event;
-           attribute DOMString        charset;
-           attribute boolean          defer;
-           attribute DOMString        src;
-           attribute DOMString        type;
 };
--- a/dom/interfaces/html/nsIDOMHTMLSelectElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLSelectElement.idl
@@ -43,33 +43,36 @@
 /**
  * The nsIDOMHTMLSelectElement interface is the interface to a [X]HTML
  * select element.
  *
  * For more information on this interface please see
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  */
 
-[scriptable, uuid(a6cf9090-15b3-11d2-932e-00805f8add32)]
+[scriptable, uuid(110a4b15-e0a2-48d7-8e59-d8d94ef510ad)]
 interface nsIDOMHTMLSelectElement : nsIDOMHTMLElement
 {
-  readonly attribute DOMString             type;
+           attribute boolean                     autofocus;
+           attribute boolean                     disabled;
+  readonly attribute nsIDOMHTMLFormElement       form;
+           attribute boolean                     multiple;
+           attribute DOMString                   name;
+           attribute long                        size;
+
+  readonly attribute DOMString                   type;
+
+  readonly attribute nsIDOMHTMLOptionsCollection options;
+           attribute unsigned long               length;
+  nsIDOMNode                item(in unsigned long index);
+  nsIDOMNode                namedItem(in DOMString name);
+  void                      add(in nsIDOMHTMLElement element, 
+                                in nsIDOMHTMLElement before)
+                                                     raises(DOMException);   
+  void                      remove(in long index);
+
            attribute long                  selectedIndex;
            attribute DOMString             value;
-  // Modified in DOM Level 2:
-           attribute unsigned long         length;
-                                             // raises(DOMException) on setting
 
-  readonly attribute nsIDOMHTMLFormElement form;
-  // Modified in DOM Level 2:
-  readonly attribute nsIDOMHTMLOptionsCollection options;
-           attribute boolean               disabled;
-           attribute boolean               multiple;
-           attribute DOMString             name;
-           attribute long                  size;
            attribute long                  tabIndex;
-  void                      add(in nsIDOMHTMLElement element, 
-                                in nsIDOMHTMLElement before)
-                                                     raises(DOMException);
-  void                      remove(in long index);
   void                      blur();
   void                      focus();
 };
--- a/dom/interfaces/html/nsIDOMNSHTMLAnchorElement.idl
+++ b/dom/interfaces/html/nsIDOMNSHTMLAnchorElement.idl
@@ -34,22 +34,27 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "domstubs.idl"
 
-[scriptable, uuid(a6cf911c-15b3-11d2-932e-00805f8add32)]
+[scriptable, uuid(24c39afa-44f7-4cd4-9e63-0504a581a081)]
 interface nsIDOMNSHTMLAnchorElement : nsISupports
 {
            attribute DOMString        protocol;
            attribute DOMString        host;
            attribute DOMString        hostname;
            attribute DOMString        pathname;
            attribute DOMString        search;
            attribute DOMString        port;
            attribute DOMString        hash;
-  readonly attribute DOMString        text;
+
+  /**
+   * An alias for the textContent attribute.
+   */
+  [Null(Stringify)]
+           attribute DOMString        text;
 
   DOMString                 toString();
 };
deleted file mode 100644
--- a/dom/interfaces/html/nsIDOMNSHTMLAreaElement.idl
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Vidur Apparao <vidur@netscape.com> (original author)
- *   Johnny Stenback <jst@netscape.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "domstubs.idl"
-
-[scriptable, uuid(3dce9071-f3b9-4280-a6ee-776cdfe3dd9e)]
-interface nsIDOMNSHTMLAreaElement : nsISupports
-{
-  attribute DOMString        protocol;
-  attribute DOMString        host;
-  attribute DOMString        hostname;  
-  attribute DOMString        pathname;
-  attribute DOMString        search;
-  attribute DOMString        port;
-  attribute DOMString        hash;
-
-  DOMString                 toString();
-};
deleted file mode 100644
--- a/dom/interfaces/html/nsIDOMNSHTMLAreaElement2.idl
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is Google Inc.
- * Portions created by the Initial Developer are Copyright (C) 2006
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  Darin Fisher <darin@meer.net>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsIDOMNSHTMLAreaElement.idl"
-
-[scriptable, uuid(1859b16a-7c16-4ab7-bdb9-52792ba16cc1)]
-interface nsIDOMNSHTMLAreaElement2 : nsIDOMNSHTMLAreaElement
-{
-  attribute DOMString ping;
-};
deleted file mode 100644
--- a/dom/interfaces/html/nsIDOMNSHTMLButtonElement.idl
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Vidur Apparao <vidur@netscape.com> (original author)
- *   Johnny Stenback <jst@netscape.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "domstubs.idl"
-
-[scriptable, uuid(41494073-ac06-4fbe-9d5e-f79c2586385b)]
-interface nsIDOMNSHTMLButtonElement : nsISupports
-{
-  attribute boolean         autofocus;
-  void                      blur();
-  void                      focus();
-  void                      click();
-  attribute DOMString       type;
-};
deleted file mode 100644
--- a/dom/interfaces/html/nsIDOMNSHTMLLabelElement.idl
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Mounir Lamouri <mounir.lamouri@mozilla.com> (original author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "domstubs.idl"
-
-interface nsIDOMHTMLElement;
-
-[scriptable, uuid(93e8a513-6cef-44c3-875e-1bce83c3b1f0)]
-interface nsIDOMNSHTMLLabelElement : nsISupports
-{
-  readonly attribute nsIDOMHTMLElement     control;
-};
deleted file mode 100644
--- a/dom/interfaces/html/nsIDOMNSHTMLOptionElement.idl
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2003
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Johnny Stenback <jst@netscape.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsIDOMHTMLElement.idl"
-
-[scriptable, uuid(e2dfc89c-7ae0-4651-8aee-7f5edc2aa626)]
-interface nsIDOMNSHTMLOptionElement : nsISupports
-{
-  // Settable version of the text attribute.
-           attribute DOMString             text;
-};
deleted file mode 100644
--- a/dom/interfaces/html/nsIDOMNSHTMLScriptElement.idl
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "domstubs.idl"
-
-[scriptable, uuid(5b2065d7-7888-4529-8a29-e58390a40bd2)]
-interface nsIDOMNSHTMLScriptElement : nsISupports
-{
-	attribute boolean async;
-};
deleted file mode 100644
--- a/dom/interfaces/html/nsIDOMNSHTMLSelectElement.idl
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Vidur Apparao <vidur@netscape.com> (original author)
- *   Johnny Stenback <jst@netscape.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "domstubs.idl"
-
-[scriptable, uuid(3212788d-fa20-44c4-b945-bd70bdc23ddf)]
-interface nsIDOMNSHTMLSelectElement : nsISupports
-{
-  attribute boolean         autofocus;
-  nsIDOMNode                item(in unsigned long index);
-  nsIDOMNode                namedItem(in DOMString name);
-};
--- a/dom/interfaces/smil/Makefile.in
+++ b/dom/interfaces/smil/Makefile.in
@@ -43,11 +43,12 @@ VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= dom
 XPIDL_MODULE	= dom_smil
 
 XPIDLSRCS	= \
 		nsIDOMElementTimeControl.idl \
+		nsIDOMTimeEvent.idl \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/smil/nsIDOMTimeEvent.idl
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SMIL Module.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIDOMEvent.idl"
+
+/**
+ * The SMIL TimeEvent interface.
+ *
+ * For more information please refer to:
+ * http://www.w3.org/TR/SMIL/smil-timing.html#Events-TimeEvent
+ * http://www.w3.org/TR/SVG/animate.html#InterfaceTimeEvent
+ */
+
+[scriptable, uuid(0d309c26-ddbb-44cb-9af1-3008972349e3)]
+interface nsIDOMTimeEvent : nsIDOMEvent
+{
+  readonly attribute long detail;
+  readonly attribute nsIDOMAbstractView view;
+  
+  void initTimeEvent(in DOMString typeArg,
+                     in nsIDOMAbstractView viewArg,
+                     in long detailArg);
+};
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -49,24 +49,29 @@
 #include "nsTObserverArray.h"
 #include "nsIObserver.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsServiceManagerUtils.h"
 #include "nsXULAppAPI.h"
 #include "nsWeakReference.h"
 
+#include "History.h"
+#include "nsDocShellCID.h"
+#include "nsNetUtil.h"
+
 #include "base/message_loop.h"
 #include "base/task.h"
 
 #include "nsChromeRegistryContent.h"
 #include "mozilla/chrome/RegistryMessageUtils.h"
 
 using namespace mozilla::ipc;
 using namespace mozilla::net;
+using namespace mozilla::places;
 
 namespace mozilla {
 namespace dom {
 
 class PrefObserver
 {
 public:
     /**
@@ -94,17 +99,17 @@ public:
 
     /**
      * Return true if this observer can no longer receive
      * notifications.
      */
     bool IsDead() const
     {
         nsCOMPtr<nsIObserver> observer = GetObserver();
-        return !!observer;
+        return !observer;
     }
 
     /**
      * Return true iff a request to remove observers matching
      * <aObserver, aDomain, aPrefRoot> entails removal of this.
      */
     bool ShouldRemoveFrom(nsIObserver* aObserver,
                           const nsCString& aPrefRoot,
@@ -338,10 +343,18 @@ ContentChild::RecvNotifyRemotePrefObserv
             mPrefObservers.RemoveElementAt(i);
             continue;
         }
         ++i;
     }
     return true;
 }
 
+bool
+ContentChild::RecvNotifyVisited(const IPC::URI& aURI)
+{
+    nsCOMPtr<nsIURI> newURI = aURI;
+    History::GetService()->NotifyVisited(newURI);
+    return true;
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -83,16 +83,18 @@ public:
     virtual bool DeallocPNecko(PNeckoChild*);
 
     virtual bool RecvRegisterChrome(const nsTArray<ChromePackage>& packages,
                                     const nsTArray<ResourceMapping>& resources,
                                     const nsTArray<OverrideMapping>& overrides);
 
     virtual bool RecvSetOffline(const PRBool& offline);
 
+    virtual bool RecvNotifyVisited(const IPC::URI& aURI);
+
     /**
      * Notify |aObserver| of changes to |aPrefRoot|.|aDomain|.  If
      * |aHoldWeak|, only a weak reference to |aObserver| is held.
      */
     nsresult AddRemotePrefObserver(const nsCString& aDomain, 
                                    const nsCString& aPrefRoot, 
                                    nsIObserver* aObserver, PRBool aHoldWeak);
     nsresult RemoveRemotePrefObserver(const nsCString& aDomain, 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -35,31 +35,33 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "ContentParent.h"
 
 #include "TabParent.h"
+#include "History.h"
 #include "mozilla/ipc/TestShellParent.h"
 #include "mozilla/net/NeckoParent.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefBranch2.h"
 #include "nsIPrefLocalizedString.h"
 #include "nsIObserverService.h"
-
+#include "nsContentUtils.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "nsChromeRegistryChrome.h"
 
 using namespace mozilla::ipc;
 using namespace mozilla::net;
+using namespace mozilla::places;
 using mozilla::MonitorAutoEnter;
 
 namespace mozilla {
 namespace dom {
 
 #define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
 
 ContentParent* ContentParent::gSingleton;
@@ -425,16 +427,49 @@ ContentParent::RequestRunToCompletion()
         printf("Running to completion...\n");
 #endif
         mRunToCompletionDepth = 1;
         mShouldCallUnblockChild = true;
     }
     return !!mRunToCompletionDepth;
 }
 
+bool
+ContentParent::RecvStartVisitedQuery(const IPC::URI& aURI)
+{
+    nsCOMPtr<nsIURI> newURI = aURI;
+    IHistory *history = nsContentUtils::GetHistory(); 
+    history->RegisterVisitedCallback(newURI, nsnull);
+    return true;
+}
+
+
+bool
+ContentParent::RecvVisitURI(const IPC::URI& uri,
+                                   const IPC::URI& referrer,
+                                   const PRUint32& flags)
+{
+    nsCOMPtr<nsIURI> ourURI = uri;
+    nsCOMPtr<nsIURI> ourReferrer = referrer;
+    IHistory *history = nsContentUtils::GetHistory(); 
+    history->VisitURI(ourURI, ourReferrer, flags);
+    return true;
+}
+
+
+bool
+ContentParent::RecvSetURITitle(const IPC::URI& uri,
+                                      const nsString& title)
+{
+    nsCOMPtr<nsIURI> ourURI = uri;
+    IHistory *history = nsContentUtils::GetHistory(); 
+    history->SetURITitle(ourURI, title);
+    return true;
+}
+
 /* void onDispatchedEvent (in nsIThreadInternal thread); */
 NS_IMETHODIMP
 ContentParent::OnDispatchedEvent(nsIThreadInternal *thread)
 {
     if (mOldObserver)
         return mOldObserver->OnDispatchedEvent(thread);
 
     return NS_OK;
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -42,16 +42,17 @@
 #include "base/waitable_event_watcher.h"
 
 #include "mozilla/dom/PContentParent.h"
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 
 #include "nsIObserver.h"
 #include "nsIThreadInternal.h"
 #include "mozilla/Monitor.h"
+#include "nsNetUtil.h"
 #include "nsIPrefService.h"
 #include "nsIPermissionManager.h"
 
 namespace mozilla {
 
 namespace ipc {
 class TestShellParent;
 }
@@ -140,16 +141,25 @@ private:
     virtual bool RecvTestPermission(const IPC::URI&  aUri,
                                     const nsCString& aType,
                                     const PRBool&    aExact,
                                     PRUint32*        retValue);
 
     void EnsurePrefService();
     void EnsurePermissionService();
 
+    virtual bool RecvStartVisitedQuery(const IPC::URI& uri);
+
+    virtual bool RecvVisitURI(const IPC::URI& uri,
+                              const IPC::URI& referrer,
+                              const PRUint32& flags);
+
+    virtual bool RecvSetURITitle(const IPC::URI& uri,
+                                 const nsString& title);
+
     mozilla::Monitor mMonitor;
 
     GeckoChildProcessHost* mSubprocess;
 
     int mRunToCompletionDepth;
     bool mShouldCallUnblockChild;
     nsCOMPtr<nsIThreadObserver> mOldObserver;
 
--- a/dom/ipc/Makefile.in
+++ b/dom/ipc/Makefile.in
@@ -74,15 +74,16 @@ CPPSRCS = \
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES += \
 		-I$(srcdir)/../../content/base/src \
 		-I$(srcdir)/../../content/events/src \
+		-I$(srcdir)/../../toolkit/components/places/src \
 		-I$(srcdir)/../src/geolocation \
 		-I$(topsrcdir)/chrome/src \
 		$(NULL)
 
 CXXFLAGS += $(TK_CFLAGS)
 
 DEFINES += -DBIN_SUFFIX='"$(BIN_SUFFIX)"'
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -63,23 +63,29 @@ child:
 
     PTestShell();
 
     RegisterChrome(ChromePackage[] packages, ResourceMapping[] resources,
                    OverrideMapping[] overrides);
 
     async SetOffline(PRBool offline);
 
+    async NotifyVisited(URI uri);
+
     NotifyRemotePrefObserver(nsCString aDomain);
 
 parent:
     PNecko();
 
     // Services remoting
 
+    async StartVisitedQuery(URI uri);
+    async VisitURI(URI uri, URI referrer, PRUint32 flags);
+    async SetURITitle(URI uri, nsString title);
+
     // PrefService messages
     sync GetPrefType(nsCString prefName) returns (PRInt32 retValue, nsresult rv);
     sync GetBoolPref(nsCString prefName) returns (PRBool retValue, nsresult rv);
     sync GetIntPref(nsCString prefName)  returns (PRInt32 retValue, nsresult rv);
     sync GetCharPref(nsCString prefName) returns (nsCString retValue, nsresult rv);
     sync GetPrefLocalizedString(nsCString prefName) returns (nsString retValue, nsresult rv);
     sync PrefHasUserValue(nsCString prefName) returns (PRBool retValue, nsresult rv);
     sync PrefIsLocked(nsCString prefName) returns (PRBool retValue, nsresult rv);
--- a/dom/plugins/Makefile.in
+++ b/dom/plugins/Makefile.in
@@ -125,16 +125,22 @@ CPPSRCS = \
   PluginStreamChild.cpp \
   PluginStreamParent.cpp \
   $(NULL)
 
 ifeq (WINNT,$(OS_ARCH))
 CPPSRCS += COMMessageFilter.cpp
 endif
 
+ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
+CMMSRCS   += \
+    PluginUtilsOSX.mm \
+    $(NULL)
+endif
+
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/modules/plugin/base/public/ \
   -I$(topsrcdir)/modules/plugin/base/src/ \
   $(NULL)
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 endif
--- a/dom/plugins/PluginInstanceChild.cpp
+++ b/dom/plugins/PluginInstanceChild.cpp
@@ -107,16 +107,17 @@ PluginInstanceChild::PluginInstanceChild
     , mWinlessThrottleOldWndProc(0)
     , mWinlessHiddenMsgHWND(0)
 #endif // OS_WIN
     , mAsyncCallMutex("PluginInstanceChild::mAsyncCallMutex")
 #if defined(OS_MACOSX)  
     , mShColorSpace(nsnull)
     , mShContext(nsnull)
     , mDrawingModel(NPDrawingModelCoreGraphics)
+    , mCurrentEvent(nsnull)
 #endif
 {
     memset(&mWindow, 0, sizeof(mWindow));
     mData.ndata = (void*) this;
     mData.pdata = nsnull;
 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
     mWindow.ws_info = &mWsInfo;
     memset(&mWsInfo, 0, sizeof(mWsInfo));
@@ -537,16 +538,22 @@ PluginInstanceChild::AnswerNPP_HandleEve
     if (GraphicsExpose == event.event.type)
         PLUGIN_LOG_DEBUG(("  received drawable 0x%lx\n",
                           event.event.xgraphicsexpose.drawable));
 #endif
 
 #ifdef XP_MACOSX
     // Mac OS X does not define an NPEvent structure. It defines more specific types.
     NPCocoaEvent evcopy = event.event;
+
+    // Make sure we reset mCurrentEvent in case of an exception
+    AutoRestore<const NPCocoaEvent*> savePreviousEvent(mCurrentEvent);
+
+    // Track the current event for NPN_PopUpContextMenu.
+    mCurrentEvent = &event.event;
 #else
     // Make a copy since we may modify values.
     NPEvent evcopy = event.event;
 #endif
 
 #ifdef OS_WIN
     // FIXME/bug 567645: temporarily drop the "dummy event" on the floor
     if (WM_NULL == evcopy.event)
--- a/dom/plugins/PluginInstanceChild.h
+++ b/dom/plugins/PluginInstanceChild.h
@@ -355,19 +355,27 @@ private:
       PRUint32        doublePassEvent;
       PRUint16        doublePass;
       HDC             hdc;
       HBITMAP         bmp;
     } mAlphaExtract;
 #endif // defined(OS_WIN)
 #if defined(OS_MACOSX)
 private:
-    CGColorSpaceRef mShColorSpace;
-    CGContextRef    mShContext;
-    int16_t         mDrawingModel;
-    nsCARenderer    mCARenderer;
+    CGColorSpaceRef       mShColorSpace;
+    CGContextRef          mShContext;
+    int16_t               mDrawingModel;
+    nsCARenderer          mCARenderer;
+
+public:
+    const NPCocoaEvent* getCurrentEvent() {
+        return mCurrentEvent;
+    }
+
+private:
+    const NPCocoaEvent   *mCurrentEvent;
 #endif
 };
 
 } // namespace plugins
 } // namespace mozilla
 
 #endif // ifndef dom_plugins_PluginInstanceChild_h
--- a/dom/plugins/PluginModuleChild.cpp
+++ b/dom/plugins/PluginModuleChild.cpp
@@ -64,16 +64,20 @@
 #include "PluginIdentifierChild.h"
 
 #include "nsNPAPIPlugin.h"
 
 #ifdef XP_WIN
 #include "COMMessageFilter.h"
 #endif
 
+#ifdef OS_MACOSX
+#include "PluginUtilsOSX.h"
+#endif
+
 using namespace mozilla::plugins;
 
 #if defined(XP_WIN)
 const PRUnichar * kFlashFullscreenClass = L"ShockwaveFlashFullScreen";
 #endif
 
 namespace {
 PluginModuleChild* gInstance = nsnull;
@@ -1510,23 +1514,77 @@ uint32_t NP_CALLBACK
 void NP_CALLBACK
 _unscheduletimer(NPP npp, uint32_t timerID)
 {
     PLUGIN_LOG_DEBUG_FUNCTION;
     AssertPluginThread();
     InstCast(npp)->UnscheduleTimer(timerID);
 }
 
+
+#ifdef OS_MACOSX
+static void ProcessBrowserEvents(void* pluginModule) {
+    PluginModuleChild* pmc = static_cast<PluginModuleChild*>(pluginModule);
+
+    if (!pmc)
+        return;
+
+    pmc->CallProcessSomeEvents();
+}
+#endif
+
 NPError NP_CALLBACK
 _popupcontextmenu(NPP instance, NPMenu* menu)
 {
     PLUGIN_LOG_DEBUG_FUNCTION;
     AssertPluginThread();
-    NS_WARNING("Not yet implemented!");
+
+#ifdef OS_MACOSX
+    double pluginX, pluginY; 
+    double screenX, screenY;
+
+    const NPCocoaEvent* currentEvent = InstCast(instance)->getCurrentEvent();
+    if (!currentEvent) {
+        return NPERR_GENERIC_ERROR;
+    }
+
+    // Ensure that the events has an x/y value.
+    if (currentEvent->type != NPCocoaEventMouseDown    &&
+        currentEvent->type != NPCocoaEventMouseUp      &&
+        currentEvent->type != NPCocoaEventMouseMoved   &&
+        currentEvent->type != NPCocoaEventMouseEntered &&
+        currentEvent->type != NPCocoaEventMouseExited  &&
+        currentEvent->type != NPCocoaEventMouseDragged) {
+        return NPERR_GENERIC_ERROR;
+    }
+
+    pluginX = currentEvent->data.mouse.pluginX;
+    pluginY = currentEvent->data.mouse.pluginY;
+
+    if ((pluginX < 0.0) || (pluginY < 0.0))
+        return NPERR_GENERIC_ERROR;
+
+    NPBool success = _convertpoint(instance, 
+                                  pluginX,  pluginY, NPCoordinateSpacePlugin, 
+                                 &screenX, &screenY, NPCoordinateSpaceScreen);
+
+    if (success) {
+        return mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(menu,
+                                    screenX, screenY,
+                                    PluginModuleChild::current(),
+                                    ProcessBrowserEvents);
+    } else {
+        NS_WARNING("Convertpoint failed, could not created contextmenu.");
+        return NPERR_GENERIC_ERROR;
+    }
+
+#else
+    NS_WARNING("Not supported on this platform!");
     return NPERR_GENERIC_ERROR;
+#endif
 }
 
 NPBool NP_CALLBACK
 _convertpoint(NPP instance, 
               double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
               double *destX, double *destY, NPCoordinateSpace destSpace)
 {
     PLUGIN_LOG_DEBUG_FUNCTION;
@@ -1606,25 +1664,27 @@ PluginModuleChild::AllocPPluginIdentifie
     // string or int because we do all this identifier construction
     // asynchronously. Check to see if we've already wrapped here, and then set
     // canonical actor of the new one to the actor already in our hash.
     PluginIdentifierChild* newActor;
     PluginIdentifierChild* existingActor;
 
     if (aString.IsVoid()) {
         newActor = new PluginIdentifierChildInt(aInt);
-        if (mIntIdentifiers.Get(aInt, &existingActor)) {
+        if (mIntIdentifiers.Get(aInt, &existingActor))
             newActor->SetCanonicalIdentifier(existingActor);
-        }
+        else
+            mIntIdentifiers.Put(aInt, newActor);
     }
     else {
         newActor = new PluginIdentifierChildString(aString);
-        if (mStringIdentifiers.Get(aString, &existingActor)) {
+        if (mStringIdentifiers.Get(aString, &existingActor))
             newActor->SetCanonicalIdentifier(existingActor);
-        }
+        else
+            mStringIdentifiers.Put(aString, newActor);
     }
     return newActor;
 }
 
 bool
 PluginModuleChild::DeallocPPluginIdentifier(PPluginIdentifierChild* aActor)
 {
     delete aActor;
@@ -2020,8 +2080,15 @@ PluginModuleChild::ResetEventHooks()
     if (mNestedEventHook)
         UnhookWindowsHookEx(mNestedEventHook);
     mNestedEventHook = NULL;
     if (mGlobalCallWndProcHook)
         UnhookWindowsHookEx(mGlobalCallWndProcHook);
     mGlobalCallWndProcHook = NULL;
 }
 #endif
+
+#ifdef OS_MACOSX
+void
+PluginModuleChild::ProcessNativeEvents() {
+    CallProcessSomeEvents();    
+}
+#endif
--- a/dom/plugins/PluginModuleChild.h
+++ b/dom/plugins/PluginModuleChild.h
@@ -188,16 +188,20 @@ public:
     static void NP_CALLBACK NPN_GetStringIdentifiers(const NPUTF8** aNames,
                                                      int32_t aNameCount,
                                                      NPIdentifier* aIdentifiers);
     static NPIdentifier NP_CALLBACK NPN_GetIntIdentifier(int32_t aIntId);
     static bool NP_CALLBACK NPN_IdentifierIsString(NPIdentifier aIdentifier);
     static NPUTF8* NP_CALLBACK NPN_UTF8FromIdentifier(NPIdentifier aIdentifier);
     static int32_t NP_CALLBACK NPN_IntFromIdentifier(NPIdentifier aIdentifier);
 
+#ifdef OS_MACOSX
+    void ProcessNativeEvents();
+#endif
+
 private:
     bool InitGraphics();
 #if defined(MOZ_WIDGET_GTK2)
     static gboolean DetectNestedEventLoop(gpointer data);
     static gboolean ProcessBrowserEvents(gpointer data);
 
     NS_OVERRIDE
     virtual void EnteredCxxStack();
--- a/dom/plugins/PluginModuleParent.cpp
+++ b/dom/plugins/PluginModuleParent.cpp
@@ -33,16 +33,18 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifdef MOZ_WIDGET_GTK2
 #include <glib.h>
+#elif XP_MACOSX
+#include "PluginUtilsOSX.h"
 #endif
 #ifdef MOZ_WIDGET_QT
 #include <QtCore/QCoreApplication>
 #include <QtCore/QEventLoop>
 #endif
 
 #include "base/process_util.h"
 
@@ -766,16 +768,24 @@ PluginModuleParent::AnswerProcessSomeEve
     PLUGIN_LOG_DEBUG(("Spinning mini nested loop ..."));
     QCoreApplication::processEvents(QEventLoop::AllEvents, kMaxtimeToProcessEvents);
 
     PLUGIN_LOG_DEBUG(("... quitting mini nested loop"));
 
     return true;
 }
 
+#elif defined(XP_MACOSX)
+bool
+PluginModuleParent::AnswerProcessSomeEvents()
+{
+    mozilla::plugins::PluginUtilsOSX::InvokeNativeEventLoop();
+    return true;
+}
+
 #elif !defined(MOZ_WIDGET_GTK2)
 bool
 PluginModuleParent::AnswerProcessSomeEvents()
 {
     NS_RUNTIMEABORT("unreached");
     return false;
 }
 
new file mode 100644
--- /dev/null
+++ b/dom/plugins/PluginUtilsOSX.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+// vim:set ts=2 sts=2 sw=2 et cin:
+/* ***** BEGIN LICENSE BLOCK *****
+  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+  *
+  * The contents of this file are subject to the Mozilla Public License Version
+  * 1.1 (the "License"); you may not use this file except in compliance with
+  * the License. You may obtain a copy of the License at
+  * http://www.mozilla.org/MPL/
+  *
+  * Software distributed under the License is distributed on an "AS IS" basis,
+  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+  * for the specific language governing rights and limitations under the
+  * License.
+  *
+  * The Original Code is Mozilla.org code.
+  *
+  * The Initial Developer of the Original Code is
+  *   Mozilla Corporation.
+  * Portions created by the Initial Developer are Copyright (C) 2010
+  * the Initial Developer. All Rights Reserved.
+  *
+  * Contributor(s):
+  *   Benoit Girard <b56girard@gmail.com>
+  *
+  * Alternatively, the contents of this file may be used under the terms of
+  * either of the GNU General Public License Version 2 or later (the "GPL"),
+  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+  * in which case the provisions of the GPL or the LGPL are applicable instead
+  * of those above. If you wish to allow use of your version of this file only
+  * under the terms of either the GPL or the LGPL, and not to allow others to
+  * use your version of this file under the terms of the MPL, indicate your
+  * decision by deleting the provisions above and replace them with the notice
+  * and other provisions required by the GPL or the LGPL. If you do not delete
+  * the provisions above, a recipient may use your version of this file under
+  * the terms of any one of the MPL, the GPL or the LGPL.
+  *
+  * ***** END LICENSE BLOCK ***** */
+
+#include "npapi.h"
+
+namespace mozilla {
+namespace plugins {
+namespace PluginUtilsOSX {
+
+// Need to call back into the browser's to process event.
+typedef void (*RemoteProcessEvents) (void*);
+
+NPError ShowCocoaContextMenu(void* aMenu, int aX, int aY, void* pluginModule, RemoteProcessEvents remoteEvent);
+
+void InvokeNativeEventLoop();
+
+} // namespace PluginUtilsOSX
+} // namespace plugins
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/plugins/PluginUtilsOSX.mm
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+// vim:set ts=2 sts=2 sw=2 et cin:
+/* ***** BEGIN LICENSE BLOCK *****
+  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+  *
+  * The contents of this file are subject to the Mozilla Public License Version
+  * 1.1 (the "License"); you may not use this file except in compliance with
+  * the License. You may obtain a copy of the License at
+  * http://www.mozilla.org/MPL/
+  *
+  * Software distributed under the License is distributed on an "AS IS" basis,
+  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+  * for the specific language governing rights and limitations under the
+  * License.
+  *
+  * The Original Code is Mozilla.org code.
+  *
+  * The Initial Developer of the Original Code is
+  *   Mozilla Corporation.
+  * Portions created by the Initial Developer are Copyright (C) 2010
+  * the Initial Developer. All Rights Reserved.
+  *
+  * Contributor(s):
+  *   Benoit Girard <b56girard@gmail.com>
+  *
+  * Alternatively, the contents of this file may be used under the terms of
+  * either of the GNU General Public License Version 2 or later (the "GPL"),
+  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+  * in which case the provisions of the GPL or the LGPL are applicable instead
+  * of those above. If you wish to allow use of your version of this file only
+  * under the terms of either the GPL or the LGPL, and not to allow others to
+  * use your version of this file under the terms of the MPL, indicate your
+  * decision by deleting the provisions above and replace them with the notice
+  * and other provisions required by the GPL or the LGPL. If you do not delete
+  * the provisions above, a recipient may use your version of this file under
+  * the terms of any one of the MPL, the GPL or the LGPL.
+  *
+  * ***** END LICENSE BLOCK ***** */
+
+#import <AppKit/AppKit.h>
+#include "PluginUtilsOSX.h"
+
+// Remove definitions for try/catch interfering with ObjCException macros.
+#include "nsObjCExceptions.h"
+
+using namespace mozilla::plugins::PluginUtilsOSX;
+
+@interface EventProcessor : NSObject {
+  RemoteProcessEvents   aRemoteEvents;
+  void                 *aPluginModule;
+}
+- (void)setRemoteEvents:(RemoteProcessEvents) remoteEvents pluginModule:(void*) pluginModule;
+- (void)onTick;
+@end
+
+@implementation EventProcessor
+- (void) onTick
+{
+    aRemoteEvents(aPluginModule);
+}
+
+- (void)setRemoteEvents:(RemoteProcessEvents) remoteEvents pluginModule:(void*) pluginModule
+{
+    aRemoteEvents = remoteEvents;
+    aPluginModule = pluginModule;
+}
+@end
+
+#define EVENT_PROCESS_DELAY 0.05 // 50 ms
+
+NPError mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(void* aMenu, int aX, int aY, void* pluginModule, RemoteProcessEvents remoteEvent) 
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
+  // Leave out this code until we can fix painting. See bug 568513.
+  /*
+  // Create a timer to process browser events while waiting
+  // on the menu. This prevents the browser from hanging
+  // during the lifetime of the menu.
+  EventProcessor* eventProcessor = [[EventProcessor alloc] init];
+  [eventProcessor setRemoteEvents:remoteEvent pluginModule:pluginModule];
+  NSTimer *eventTimer = [NSTimer timerWithTimeInterval:EVENT_PROCESS_DELAY
+                             target:eventProcessor selector:@selector(onTick) 
+                             userInfo:nil repeats:TRUE];
+  // Use NSEventTrackingRunLoopMode otherwise the timer will
+  // not fire during the right click menu.
+  [[NSRunLoop currentRunLoop] addTimer:eventTimer 
+                              forMode:NSEventTrackingRunLoopMode];
+  */
+
+  NSMenu* nsmenu = reinterpret_cast<NSMenu*>(aMenu);
+  NSPoint screen_point = ::NSMakePoint(aX, aY);
+
+  [nsmenu popUpMenuPositioningItem:nil atLocation:screen_point inView:nil];
+
+  //[eventTimer invalidate];
+  //[eventProcessor release];
+
+  return NPERR_NO_ERROR;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
+}
+
+void mozilla::plugins::PluginUtilsOSX::InvokeNativeEventLoop()
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+  ::CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.0, true);
+  NS_OBJC_END_TRY_ABORT_BLOCK;
+}
--- a/editor/composer/src/crashtests/crashtests.list
+++ b/editor/composer/src/crashtests/crashtests.list
@@ -1,5 +1,5 @@
 load 351236-1.html
 load 407062-1.html
-skip-if(MOZ_WIDGET_TOOLKIT=="windows") load 428844-1.html # bug 471185
+skip-if(winWidget) load 428844-1.html # bug 471185
 load 461049-1.html
-asserts(0-1) asserts-if(MOZ_WIDGET_TOOLKIT=="windows",0-2) load removing-editable-xslt.html # bug 500847
+asserts(0-1) asserts-if(winWidget,0-2) load removing-editable-xslt.html # bug 500847
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp
@@ -1279,17 +1279,17 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromTr
   PRUint32 len = 0;
   if ( NS_SUCCEEDED(transferable->GetAnyTransferData(getter_Copies(bestFlavor), getter_AddRefs(genericDataObj), &len)) )
   {
     nsAutoTxnsConserveSelection dontSpazMySelection(this);
     nsAutoString flavor;
     flavor.AssignWithConversion(bestFlavor);
     nsAutoString stuffToPaste;
 #ifdef DEBUG_clipboard
-    printf("Got flavor [%s]\n", bestFlavor);
+    printf("Got flavor [%s]\n", bestFlavor.get());
 #endif
     if (0 == nsCRT::strcmp(bestFlavor, kNativeHTMLMime))
     {
       // note cf_html uses utf8, hence use length = len, not len/2 as in flavors below
       nsCOMPtr<nsISupportsCString> textDataObj(do_QueryInterface(genericDataObj));
       if (textDataObj && len > 0)
       {
         nsCAutoString cfhtml;
--- a/editor/txmgr/src/nsTransactionItem.cpp
+++ b/editor/txmgr/src/nsTransactionItem.cpp
@@ -218,17 +218,20 @@ nsTransactionItem::UndoTransaction(nsTra
 {
   nsresult result = UndoChildren(aTxMgr);
 
   if (NS_FAILED(result)) {
     RecoverFromUndoError(aTxMgr);
     return result;
   }
 
-  NS_ENSURE_TRUE(mTransaction, NS_OK);
+  // FIXME: bug 583493
+  // NS_ENSURE_TRUE(mTransaction, NS_OK);
+  if (!mTransaction)
+    return NS_OK;
 
   result = mTransaction->UndoTransaction();
 
   if (NS_FAILED(result)) {
     RecoverFromUndoError(aTxMgr);
     return result;
   }
 
--- a/embedding/android/GeckoApp.java
+++ b/embedding/android/GeckoApp.java
@@ -223,26 +223,43 @@ abstract public class GeckoApp
     {
         Log.i("GeckoApp", "low memory");
         // XXX TODO
         super.onLowMemory();
     }
 
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         switch (keyCode) {
+            case KeyEvent.KEYCODE_BACK:
+                if (event.getRepeatCount() == 0) {
+                    event.startTracking();
+                    return true;
+                } else {
+                    return false;
+                }
             case KeyEvent.KEYCODE_VOLUME_UP:
             case KeyEvent.KEYCODE_VOLUME_DOWN:
+            case KeyEvent.KEYCODE_SEARCH:
                 return false;
             default:
-                GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
-                return true;
+                break;
         }
+        GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
+        return true;
     }
 
     public boolean onKeyUp(int keyCode, KeyEvent event) {
+        switch(keyCode) {
+            case KeyEvent.KEYCODE_BACK:
+                if (!event.isTracking() || event.isCanceled())
+                    return false;
+                break;
+            default:
+                break;
+        }
         GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
         return true;
     }
 
     public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
         GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
         return true;
     }
--- a/embedding/components/printingui/src/Makefile.in
+++ b/embedding/components/printingui/src/Makefile.in
@@ -58,9 +58,9 @@ ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 PLATFORM_DIR = mac
 endif
 
 DIRS = $(PLATFORM_DIR)
 
 include $(topsrcdir)/config/rules.mk
 
 libs::
-	$(INSTALL) $(PLATFORM_DIR)/$(LIB_PREFIX)printingui_s.$(LIB_SUFFIX) .
+	$(INSTALL) $(PLATFORM_DIR)/$(LIB_PREFIX)printingui_s.$(LIB_SUFFIX) $(wildcard $(PLATFORM_DIR)/$(LIB_PREFIX)printingui_s.$(LIB_SUFFIX).fake) .
--- a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
@@ -1507,20 +1507,22 @@ PRUint32 nsWindowWatcher::CalculateChrom
   /* OK.
      Normal browser windows, in spite of a stated pattern of turning off
      all chrome not mentioned explicitly, will want the new OS chrome (window
      borders, titlebars, closebox) on, unless explicitly turned off.
      Dialogs, on the other hand, take the absence of any explicit settings
      to mean "OS' choice." */
 
   // default titlebar and closebox to "on," if not mentioned at all
-  if (!PL_strcasestr(aFeatures, "titlebar"))
-    chromeFlags |= nsIWebBrowserChrome::CHROME_TITLEBAR;
-  if (!PL_strcasestr(aFeatures, "close"))
-    chromeFlags |= nsIWebBrowserChrome::CHROME_WINDOW_CLOSE;
+  if (!(chromeFlags & nsIWebBrowserChrome::CHROME_WINDOW_POPUP)) {
+    if (!PL_strcasestr(aFeatures, "titlebar"))
+      chromeFlags |= nsIWebBrowserChrome::CHROME_TITLEBAR;
+    if (!PL_strcasestr(aFeatures, "close"))
+      chromeFlags |= nsIWebBrowserChrome::CHROME_WINDOW_CLOSE;
+  }
 
   if (aDialog && !presenceFlag)
     chromeFlags = nsIWebBrowserChrome::CHROME_DEFAULT;
 
   /* Finally, once all the above normal chrome has been divined, deal
      with the features that are more operating hints than appearance
      instructions. (Note modality implies dependence.) */
 
--- a/embedding/tests/winEmbed/WebBrowserChrome.cpp
+++ b/embedding/tests/winEmbed/WebBrowserChrome.cpp
@@ -35,17 +35,16 @@
 // OS headers
 #include <stdio.h>
 
 // Frozen APIs
 
 #include "nsStringAPI.h"
 #include "nsIComponentManager.h"
 #include "nsIDOMWindow.h"
-#include "nsIGenericFactory.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIRequest.h"
 #include "nsIURI.h"
 #include "nsIWebProgress.h"
 #include "nsCWebBrowser.h"
 #include "nsIProfileChangeStatus.h"
 
 // Glue APIs (not frozen, but safe to use because they are statically linked)
--- a/embedding/tests/winEmbed/winEmbed.cpp
+++ b/embedding/tests/winEmbed/winEmbed.cpp
@@ -40,17 +40,17 @@
 // Win32 header files
 #include <windows.h>
 #include <commctrl.h>
 #include <commdlg.h>
 
 // Mozilla Frozen APIs
 #include "nsXULAppAPI.h"
 
-XRE_InitEmbeddingType XRE_InitEmbedding;
+XRE_InitEmbedding2Type XRE_InitEmbedding2;
 XRE_TermEmbeddingType XRE_TermEmbedding;
 
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsProfileDirServiceProvider.h"
 #include "nsStringAPI.h"
 #include "nsXPCOMGlue.h"
 
@@ -197,19 +197,19 @@ int main(int argc, char *argv[])
 
     HINSTANCE xulModule = LoadLibraryEx(xulPath, NULL, 0);
     if (!xulModule)
         return 4;
 
     char temp[_MAX_PATH];
     GetModuleFileName(xulModule, temp, sizeof(temp));
 
-    XRE_InitEmbedding =
-        (XRE_InitEmbeddingType) GetProcAddress(xulModule, "XRE_InitEmbedding");
-    if (!XRE_InitEmbedding) {
+    XRE_InitEmbedding2 =
+        (XRE_InitEmbedding2Type) GetProcAddress(xulModule, "XRE_InitEmbedding2");
+    if (!XRE_InitEmbedding2) {
         fprintf(stderr, "Error: %i\n", GetLastError());
         return 5;
     }
 
     XRE_TermEmbedding =
         (XRE_TermEmbeddingType) GetProcAddress(xulModule, "XRE_TermEmbedding");
     if (!XRE_TermEmbedding) {
         fprintf(stderr, "Error: %i\n", GetLastError());
@@ -233,17 +233,17 @@ int main(int argc, char *argv[])
         *lastslash = '\0';
 
         nsCOMPtr<nsILocalFile> appdir;
         rv = NS_NewNativeLocalFile(nsCString(self), PR_FALSE,
                                    getter_AddRefs(appdir));
         if (NS_FAILED(rv))
             return 8;
 
-        rv = XRE_InitEmbedding(xuldir, appdir, nsnull, nsnull, 0);