Merge m-c to s-c.
authorRichard Newman <rnewman@mozilla.com>
Wed, 12 Sep 2012 12:22:12 -0700
changeset 111075 e0896a31061deb6cae38a9b07f26219029de5cdd
parent 111074 2a728027d8f65e8e7ff279b25347e3dba7dc3cac (current diff)
parent 106943 d260fcec71cecee4a021ffc8bba5caef6f9b4d63 (diff)
child 111076 ce8eea3e3ca6636f09f12d633393663f41df4b58
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
milestone18.0a1
Merge m-c to s-c.
netwerk/wifi/nsWifiScannerUnix.cpp
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -198,16 +198,17 @@
 @BINPATH@/components/dom_stylesheets.xpt
 @BINPATH@/components/dom_threads.xpt
 @BINPATH@/components/dom_traversal.xpt
 @BINPATH@/components/dom_views.xpt
 @BINPATH@/components/dom_xbl.xpt
 @BINPATH@/components/dom_xpath.xpt
 @BINPATH@/components/dom_xul.xpt
 @BINPATH@/components/dom_loadsave.xpt
+@BINPATH@/components/dom_time.xpt
 @BINPATH@/components/downloads.xpt
 @BINPATH@/components/editor.xpt
 @BINPATH@/components/embed_base.xpt
 @BINPATH@/components/extensions.xpt
 @BINPATH@/components/exthandler.xpt
 @BINPATH@/components/exthelper.xpt
 @BINPATH@/components/fastfind.xpt
 @BINPATH@/components/feeds.xpt
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -845,16 +845,20 @@ pref("browser.zoom.full", true);
 pref("browser.zoom.siteSpecific", true);
 
 // Whether or not to update background tabs to the current zoom level.
 pref("browser.zoom.updateBackgroundTabs", true);
 
 // The breakpad report server to link to in about:crashes
 pref("breakpad.reportURL", "http://crash-stats.mozilla.com/report/index/");
 
+// Override submission of plugin hang reports to a different processing server
+pref("toolkit.crashreporter.pluginHangSubmitURL",
+     "https://hang-reports.mozilla.org/submit");
+
 // base URL for web-based support pages
 pref("app.support.baseURL", "http://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/");
 
 // Name of alternate about: page for certificate errors (when undefined, defaults to about:neterror)
 pref("security.alternate_certificate_error_page", "certerror");
 
 // Whether to start the private browsing mode at application startup
 pref("browser.privatebrowsing.autostart", false);
--- a/build/autoconf/compiler-opts.m4
+++ b/build/autoconf/compiler-opts.m4
@@ -36,16 +36,18 @@ case "$target" in
 *-darwin*)
     # GCC on darwin is based on gcc 4.2 and we don't support it anymore.
     MOZ_PATH_PROGS(CC, $CC clang)
     MOZ_PATH_PROGS(CXX, $CXX clang++)
     IS_GCC=$($CC -v 2>&1 | grep gcc)
     if test -n "$IS_GCC"
     then
       echo gcc is known to be broken on OS X, please use clang.
+      echo see http://developer.mozilla.org/en-US/docs/Developer_Guide/Build_Instructions/Mac_OS_X_Prerequisites
+      echo for more information.
       exit 1
     fi
     ;;
 esac
 fi
 ])
 
 dnl ============================================================================
--- a/build/mobile/robocop/AndroidManifest.xml.in
+++ b/build/mobile/robocop/AndroidManifest.xml.in
@@ -3,17 +3,17 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="org.mozilla.roboexample.test"
     android:versionCode="1"
     android:versionName="1.0" >
 
     <uses-sdk android:minSdkVersion="8" />
 
     <instrumentation
-        android:name="android.test.InstrumentationTestRunner"
+        android:name="@ANDROID_PACKAGE_NAME@.FennecInstrumentationTestRunner"
         android:targetPackage="@ANDROID_PACKAGE_NAME@" />
 
     <application
         android:label="@string/app_name" >
         <uses-library android:name="android.test.runner" />
     </application>
 
 </manifest>
new file mode 100644
--- /dev/null
+++ b/build/mobile/robocop/FennecInstrumentationTestRunner.java.in
@@ -0,0 +1,25 @@
+#filter substitution
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package @ANDROID_PACKAGE_NAME@;
+
+import android.os.Bundle;
+import android.test.InstrumentationTestRunner;
+
+public class FennecInstrumentationTestRunner extends InstrumentationTestRunner {
+    private static Bundle sArguments;
+
+    @Override
+    public void onCreate(Bundle arguments) {
+        super.onCreate(arguments);
+        sArguments = arguments;
+    }
+
+    // unfortunately we have to make this static because test classes that don't extend
+    // from ActivityInstrumentationTestCase2 can't get a reference to this class.
+    public static Bundle getArguments() {
+        return sArguments;
+    }
+}
--- a/build/mobile/robocop/FennecNativeDriver.java.in
+++ b/build/mobile/robocop/FennecNativeDriver.java.in
@@ -36,16 +36,17 @@ import com.jayway.android.robotium.solo.
 
 public class FennecNativeDriver implements Driver {
     private static final int FRAME_TIME_THRESHOLD = 25;     // allow 25ms per frame (40fps)
 
     // Map of IDs to element names.
     private HashMap mLocators = null;
     private Activity mActivity;
     private Solo mSolo;
+    private String mRootPath;
 
     private static String mLogFile = null;
     private static LogLevel mLogLevel = LogLevel.INFO;
 
     // Objects for reflexive access of fennec classes.
     private ClassLoader mClassLoader;
     private Class mApiClass;
     private Class mEventListenerClass;
@@ -71,22 +72,23 @@ public class FennecNativeDriver implemen
         public boolean isEnabled(LogLevel configuredLevel) {
             return mValue >= configuredLevel.getValue();
         }
         private int getValue() {
             return mValue;
         }
     }
 
-    public FennecNativeDriver(Activity activity, Solo robocop) {
+    public FennecNativeDriver(Activity activity, Solo robocop, String rootPath) {
         mActivity = activity;
         mSolo = robocop;
+        mRootPath = rootPath;
 
         // Set up table of fennec_ids.
-        mLocators = convertTextToTable(getFile("/mnt/sdcard/fennec_ids.txt"));
+        mLocators = convertTextToTable(getFile(mRootPath + "/fennec_ids.txt"));
 
         // Set up reflexive access of java classes and methods.
         try {
             mClassLoader = activity.getClassLoader();
 
             mApiClass = mClassLoader.loadClass("org.mozilla.gecko.RobocopAPI");
             mEventListenerClass = mClassLoader.loadClass("org.mozilla.gecko.util.GeckoEventListener");
             mPanningPerfClass = mClassLoader.loadClass("org.mozilla.gecko.gfx.PanningPerfAPI");
@@ -261,17 +263,17 @@ public class FennecNativeDriver implemen
             return null;
         }
 
         // now we need to (1) flip the image, because GL likes to do things up-side-down,
         // and (2) rearrange the bits from AGBR-8888 to ARGB-8888.
         int w = view.getWidth();
         int h = view.getHeight();
         pixelBuffer.position(0);
-        String mapFile = "/mnt/sdcard/pixels.map";
+        String mapFile = mRootPath + "/pixels.map";
 
         FileOutputStream fos = null;
         BufferedOutputStream bos = null;
         DataOutputStream dos = null;
         try {
             fos = new FileOutputStream(mapFile);
             bos = new BufferedOutputStream(fos);
             dos = new DataOutputStream(bos);
--- a/build/mobile/robocop/Makefile.in
+++ b/build/mobile/robocop/Makefile.in
@@ -17,16 +17,17 @@ ROBOTIUM_PATH = $(srcdir)/robotium-solo-
 JAVAFILES = \
   R.java \
 
 _JAVA_HARNESS = \
   Actions.java \
   Assert.java \
   Driver.java \
   Element.java \
+  FennecInstrumentationTestRunner.java \
   FennecNativeActions.java \
   FennecMochitestAssert.java \
   FennecTalosAssert.java \
   FennecNativeDriver.java \
   FennecNativeElement.java \
   RoboCopException.java \
   PaintedSurface.java \
   $(NULL)
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -598,16 +598,25 @@ public:
    * Just like the style sheet API, but for "catalog" sheets,
    * extra sheets inserted at the UA level.
    */
   virtual int32_t GetNumberOfCatalogStyleSheets() const = 0;
   virtual nsIStyleSheet* GetCatalogStyleSheetAt(int32_t aIndex) const = 0;
   virtual void AddCatalogStyleSheet(nsIStyleSheet* aSheet) = 0;
   virtual void EnsureCatalogStyleSheet(const char *aStyleSheetURI) = 0;
 
+  enum additionalSheetType {
+    eAgentSheet,
+    eUserSheet,
+    SheetTypeCount
+  };
+
+  virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI) = 0;
+  virtual void RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* sheetURI) = 0;
+
   /**
    * Get this document's CSSLoader.  This is guaranteed to not return null.
    */
   mozilla::css::Loader* CSSLoader() const {
     return mCSSLoader;
   }
 
   /**
--- a/content/base/src/WebSocket.h
+++ b/content/base/src/WebSocket.h
@@ -128,20 +128,20 @@ public: // WebIDL interface:
                                                  const nsAString& aUrl,
                                                  const Sequence<nsString>& aProtocols,
                                                  ErrorResult& rv);
 
   // webIDL: readonly attribute DOMString url
   void GetUrl(nsAString& aResult);
 
   // webIDL: readonly attribute unsigned short readyState;
-  uint16_t GetReadyState() { return (uint16_t)mReadyState; }
+  uint16_t ReadyState() const { return mReadyState; }
 
   // webIDL: readonly attribute unsigned long bufferedAmount;
-  uint32_t GetBufferedAmount() { return (uint32_t) mOutgoingBufferedAmount; }
+  uint32_t BufferedAmount() const { return mOutgoingBufferedAmount; }
 
   // webIDL: attribute Function? onopen;
   IMPL_EVENT_HANDLER(open)
 
   // webIDL: attribute Function? onerror;
   IMPL_EVENT_HANDLER(error)
 
   // webIDL: attribute Function? onclose;
@@ -157,18 +157,18 @@ public: // WebIDL interface:
   void Close(const Optional<uint16_t>& aCode,
              const Optional<nsAString>& aReason,
              ErrorResult& aRv);
 
   // webIDL: attribute Function? onmessage;
   IMPL_EVENT_HANDLER(message)
 
   // webIDL: attribute DOMString binaryType;
-  BinaryType GetBinaryType() { return mBinaryType; }
-  void SetBinaryType(BinaryType aData) { mBinaryType = aData; }
+  dom::BinaryType BinaryType() const { return mBinaryType; }
+  void SetBinaryType(dom::BinaryType aData) { mBinaryType = aData; }
 
   // webIDL: void send(DOMString|Blob|ArrayBufferView data);
   void Send(const nsAString& aData,
             ErrorResult& aRv);
   void Send(nsIDOMBlob* aData,
             ErrorResult& aRv);
   void Send(ArrayBuffer& aData,
             ErrorResult& aRv);
@@ -274,17 +274,17 @@ protected: //data
   nsCString mEstablishedExtensions;
 
   uint16_t mReadyState;
 
   nsCOMPtr<nsIPrincipal> mPrincipal;
 
   uint32_t mOutgoingBufferedAmount;
 
-  BinaryType mBinaryType;
+  dom::BinaryType mBinaryType;
 
   // Web Socket owner information:
   // - the script file name, UTF8 encoded.
   // - source code line number where the Web Socket object was constructed.
   // - the ID of the inner window where the script lives. Note that this may not
   //   be the same as the Web Socket owner window.
   // These attributes are used for error reporting.
   nsCString mScriptFile;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -321,17 +321,17 @@ nsIdentifierMapEntry::AddIdElement(Eleme
   }
 
   // We seem to have multiple content nodes for the same id, or XUL is messing
   // with us.  Search for the right place to insert the content.
   int32_t start = 0;
   int32_t end = mIdContentList.Count();
   do {
     NS_ASSERTION(start < end, "Bogus start/end");
-    
+
     int32_t cur = (start + end) / 2;
     NS_ASSERTION(cur >= start && cur < end, "What happened here?");
 
     Element* curElement = static_cast<Element*>(mIdContentList[cur]);
     if (curElement == aElement) {
       // Already in the list, so already in the right spot.  Get out of here.
       // XXXbz this only happens because XUL does all sorts of random
       // UpdateIdTableEntry calls.  Hate, hate, hate!
@@ -583,34 +583,34 @@ nsDOMStyleSheetList::StyleSheetRemoved(n
   }
 }
 
 // nsOnloadBlocker implementation
 NS_IMPL_ISUPPORTS1(nsOnloadBlocker, nsIRequest)
 
 NS_IMETHODIMP
 nsOnloadBlocker::GetName(nsACString &aResult)
-{ 
+{
   aResult.AssignLiteral("about:document-onload-blocker");
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsOnloadBlocker::IsPending(bool *_retval)
 {
   *_retval = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsOnloadBlocker::GetStatus(nsresult *status)
 {
   *status = NS_OK;
   return NS_OK;
-} 
+}
 
 NS_IMETHODIMP
 nsOnloadBlocker::Cancel(nsresult status)
 {
   return NS_OK;
 }
 NS_IMETHODIMP
 nsOnloadBlocker::Suspend(void)
@@ -668,24 +668,24 @@ nsExternalResourceMap::RequestResource(n
   // something interesting with aRequestingPrincipal even for the hashtable
   // gets.
   NS_PRECONDITION(aURI, "Must have a URI");
   NS_PRECONDITION(aRequestingNode, "Must have a node");
   *aPendingLoad = nullptr;
   if (mHaveShutDown) {
     return nullptr;
   }
-  
+
   // First, make sure we strip the ref from aURI.
   nsCOMPtr<nsIURI> clone;
   nsresult rv = aURI->CloneIgnoringRef(getter_AddRefs(clone));
   if (NS_FAILED(rv) || !clone) {
     return nullptr;
   }
-  
+
   ExternalResource* resource;
   mMap.Get(clone, &resource);
   if (resource) {
     return resource->mDocument;
   }
 
   nsRefPtr<PendingLoad> load;
   mPendingLoads.Get(clone, getter_AddRefs(load));
@@ -736,17 +736,17 @@ nsExternalResourceMap::EnumerateResource
   mMap.EnumerateRead(ExternalResourceEnumerator, &args);
 }
 
 static PLDHashOperator
 ExternalResourceTraverser(nsIURI* aKey,
                           nsExternalResourceMap::ExternalResource* aData,
                           void* aClosure)
 {
-  nsCycleCollectionTraversalCallback *cb = 
+  nsCycleCollectionTraversalCallback *cb =
     static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
 
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb,
                                      "mExternalResourceMap.mMap entry"
                                      "->mDocument");
   cb->NoteXPCOMChild(aData->mDocument);
 
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb,
@@ -847,23 +847,23 @@ nsresult
 nsExternalResourceMap::AddExternalResource(nsIURI* aURI,
                                            nsIContentViewer* aViewer,
                                            nsILoadGroup* aLoadGroup,
                                            nsIDocument* aDisplayDocument)
 {
   NS_PRECONDITION(aURI, "Unexpected call");
   NS_PRECONDITION((aViewer && aLoadGroup) || (!aViewer && !aLoadGroup),
                   "Must have both or neither");
-  
+
   nsRefPtr<PendingLoad> load;
   mPendingLoads.Get(aURI, getter_AddRefs(load));
   mPendingLoads.Remove(aURI);
 
   nsresult rv = NS_OK;
-  
+
   nsCOMPtr<nsIDocument> doc;
   if (aViewer) {
     doc = aViewer->GetDocument();
     NS_ASSERTION(doc, "Must have a document");
 
     nsCOMPtr<nsIXULDocument> xulDoc = do_QueryInterface(doc);
     if (xulDoc) {
       // We don't handle XUL stuff here yet.
@@ -874,17 +874,17 @@ nsExternalResourceMap::AddExternalResour
       // Make sure that hiding our viewer will tear down its presentation.
       aViewer->SetSticky(false);
 
       rv = aViewer->Init(nullptr, nsIntRect(0, 0, 0, 0));
       if (NS_SUCCEEDED(rv)) {
         rv = aViewer->Open(nullptr, nullptr);
       }
     }
-    
+
     if (NS_FAILED(rv)) {
       doc = nullptr;
       aViewer = nullptr;
       aLoadGroup = nullptr;
     }
   }
 
   ExternalResource* newResource = new ExternalResource();
@@ -929,42 +929,42 @@ nsExternalResourceMap::PendingLoad::OnSt
                                          mDisplayDocument);
   if (NS_FAILED(rv)) {
     return rv;
   }
   if (NS_FAILED(rv2)) {
     mTargetListener = nullptr;
     return rv2;
   }
-  
+
   return mTargetListener->OnStartRequest(aRequest, aContext);
 }
 
 nsresult
 nsExternalResourceMap::PendingLoad::SetupViewer(nsIRequest* aRequest,
                                                 nsIContentViewer** aViewer,
                                                 nsILoadGroup** aLoadGroup)
 {
   NS_PRECONDITION(!mTargetListener, "Unexpected call to OnStartRequest");
   *aViewer = nullptr;
   *aLoadGroup = nullptr;
-  
+
   nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
   NS_ENSURE_TRUE(chan, NS_ERROR_UNEXPECTED);
 
   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aRequest));
   if (httpChannel) {
     bool requestSucceeded;
     if (NS_FAILED(httpChannel->GetRequestSucceeded(&requestSucceeded)) ||
         !requestSucceeded) {
       // Bail out on this load, since it looks like we have an HTTP error page
       return NS_BINDING_ABORTED;
     }
   }
- 
+
   nsAutoCString type;
   chan->GetContentType(type);
 
   nsCOMPtr<nsILoadGroup> loadGroup;
   chan->GetLoadGroup(getter_AddRefs(loadGroup));
 
   // Give this document its own loadgroup
   nsCOMPtr<nsILoadGroup> newLoadGroup =
@@ -1059,17 +1059,17 @@ nsExternalResourceMap::PendingLoad::Star
   // Time to start a load.  First, the security checks.
 
   nsIPrincipal* requestingPrincipal = aRequestingNode->NodePrincipal();
 
   nsresult rv = nsContentUtils::GetSecurityManager()->
     CheckLoadURIWithPrincipal(requestingPrincipal, aURI,
                               nsIScriptSecurityManager::STANDARD);
   NS_ENSURE_SUCCESS(rv, rv);
-  
+
   // Allow data URIs and other URI's that inherit their principal by passing
   // true as the 3rd argument of CheckMayLoad, since we want
   // to allow external resources from data URIs regardless of the difference
   // in URI scheme.
   rv = requestingPrincipal->CheckMayLoad(aURI, true, true);
   NS_ENSURE_SUCCESS(rv, rv);
 
   int16_t shouldLoad = nsIContentPolicy::ACCEPT;
@@ -1147,17 +1147,17 @@ nsExternalResourceMap::LoadgroupCallback
 
   *aSink = nullptr;
 
   TRY_SHIM(nsILoadContext);
   TRY_SHIM(nsIProgressEventSink);
   TRY_SHIM(nsIChannelEventSink);
   TRY_SHIM(nsISecurityEventSink);
   TRY_SHIM(nsIApplicationCacheContainer);
-    
+
   return NS_NOINTERFACE;
 }
 
 #undef TRY_SHIM
 #undef IID_IS
 
 nsExternalResourceMap::ExternalResource::~ExternalResource()
 {
@@ -1186,17 +1186,17 @@ public:
   void Disconnect()
   {
     mDocument = nullptr;
   }
 
 protected:
   // Rebuild our list of style sets
   nsresult GetSets(nsTArray<nsString>& aStyleSets);
-  
+
   nsIDocument* mDocument;  // Our document; weak ref.  It'll let us know if it
                            // dies.
 };
 
 NS_IMPL_ADDREF(nsDOMStyleSheetSetList)
 NS_IMPL_RELEASE(nsDOMStyleSheetSetList)
 NS_INTERFACE_TABLE_HEAD(nsDOMStyleSheetSetList)
   NS_OFFSET_AND_INTERFACE_TABLE_BEGIN(nsDOMStyleSheetSetList)
@@ -1213,58 +1213,58 @@ nsDOMStyleSheetSetList::nsDOMStyleSheetS
 }
 
 NS_IMETHODIMP
 nsDOMStyleSheetSetList::Item(uint32_t aIndex, nsAString& aResult)
 {
   nsTArray<nsString> styleSets;
   nsresult rv = GetSets(styleSets);
   NS_ENSURE_SUCCESS(rv, rv);
-  
+
   if (aIndex >= styleSets.Length()) {
     SetDOMStringToNull(aResult);
   } else {
     aResult = styleSets[aIndex];
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMStyleSheetSetList::GetLength(uint32_t *aLength)
 {
   nsTArray<nsString> styleSets;
   nsresult rv = GetSets(styleSets);
   NS_ENSURE_SUCCESS(rv, rv);
-  
+
   *aLength = styleSets.Length();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMStyleSheetSetList::Contains(const nsAString& aString, bool *aResult)
 {
   nsTArray<nsString> styleSets;
   nsresult rv = GetSets(styleSets);
   NS_ENSURE_SUCCESS(rv, rv);
-  
+
   *aResult = styleSets.Contains(aString);
 
   return NS_OK;
 }
 
 nsresult
 nsDOMStyleSheetSetList::GetSets(nsTArray<nsString>& aStyleSets)
 {
   if (!mDocument) {
     return NS_OK; // Spec says "no exceptions", and we have no style sets if we
                   // have no document, for sure
   }
-  
+
   int32_t count = mDocument->GetNumberOfStyleSheets();
   nsAutoString title;
   nsAutoString temp;
   for (int32_t index = 0; index < count; index++) {
     nsIStyleSheet* sheet = mDocument->GetStyleSheetAt(index);
     NS_ASSERTION(sheet, "Null sheet in sheet list!");
     sheet->GetTitle(title);
     if (!title.IsEmpty() && !aStyleSets.Contains(title) &&
@@ -1387,23 +1387,23 @@ nsDOMImplementation::CreateDocument(cons
   }
   else if (DOMStringIsNull(aQualifiedName) &&
            !DOMStringIsNull(aNamespaceURI)) {
     return NS_ERROR_DOM_NAMESPACE_ERR;
   }
 
   nsCOMPtr<nsIScriptGlobalObject> scriptHandlingObject =
     do_QueryReferent(mScriptObject);
-  
+
   NS_ENSURE_STATE(!mScriptObject || scriptHandlingObject);
 
   nsCOMPtr<nsIDOMDocument> document;
 
   rv = nsContentUtils::CreateDocument(aNamespaceURI, aQualifiedName, aDoctype,
-                                      mDocumentURI, mBaseURI, 
+                                      mDocumentURI, mBaseURI,
                                       mOwner->NodePrincipal(),
                                       scriptHandlingObject,
                                         DocumentFlavorLegacyGuess,
                                       getter_AddRefs(document));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
   doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
@@ -1429,17 +1429,17 @@ nsDOMImplementation::CreateHTMLDocument(
                                       NullString()); // aInternalSubset
   NS_ENSURE_SUCCESS(rv, rv);
 
 
   nsCOMPtr<nsIScriptGlobalObject> scriptHandlingObject =
     do_QueryReferent(mScriptObject);
 
   NS_ENSURE_STATE(!mScriptObject || scriptHandlingObject);
-                                                       
+
   nsCOMPtr<nsIDOMDocument> document;
   rv = nsContentUtils::CreateDocument(EmptyString(), EmptyString(),
                                       doctype, mDocumentURI, mBaseURI,
                                       mOwner->NodePrincipal(),
                                       scriptHandlingObject,
                                       DocumentFlavorLegacyGuess,
                                       getter_AddRefs(document));
   NS_ENSURE_SUCCESS(rv, rv);
@@ -1516,16 +1516,19 @@ nsIDocument::nsIDocument()
 // NOTE! nsDocument::operator new() zeroes out all members, so don't
 // bother initializing members to 0.
 
 nsDocument::nsDocument(const char* aContentType)
   : nsIDocument()
   , mAnimatingImages(true)
   , mVisibilityState(eHidden)
 {
+  MOZ_STATIC_ASSERT(NS_ARRAY_LENGTH(mAdditionalSheets) == SheetTypeCount,
+    "mAdditionalSheets array count is not correct");
+
   SetContentTypeInternal(nsDependentCString(aContentType));
 
 #ifdef PR_LOGGING
   if (!gDocumentLeakPRLog)
     gDocumentLeakPRLog = PR_NewLogModule("DocumentLeak");
 
   if (gDocumentLeakPRLog)
     PR_LOG(gDocumentLeakPRLog, PR_LOG_DEBUG,
@@ -1701,17 +1704,17 @@ NS_INTERFACE_TABLE_HEAD(nsDocument)
 
     return mXPathEvaluatorTearoff->QueryInterface(aIID, aInstancePtr);
   }
   else
 NS_INTERFACE_MAP_END
 
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDocument)
-NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsDocument, 
+NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsDocument,
                                               nsNodeUtils::LastRelease(this))
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsDocument)
   if (nsGenericElement::CanSkip(tmp, aRemovingAllowed)) {
     nsEventListenerManager* elm = tmp->GetListenerManager(false);
     if (elm) {
       elm->UnmarkGrayJSListeners();
     }
@@ -1727,32 +1730,32 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_B
   return nsGenericElement::CanSkipThis(tmp);
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
 
 static PLDHashOperator
 SubDocTraverser(PLDHashTable *table, PLDHashEntryHdr *hdr, uint32_t number,
                 void *arg)
 {
   SubDocMapEntry *entry = static_cast<SubDocMapEntry*>(hdr);
-  nsCycleCollectionTraversalCallback *cb = 
+  nsCycleCollectionTraversalCallback *cb =
     static_cast<nsCycleCollectionTraversalCallback*>(arg);
 
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mSubDocuments entry->mKey");
   cb->NoteXPCOMChild(entry->mKey);
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mSubDocuments entry->mSubDocument");
   cb->NoteXPCOMChild(entry->mSubDocument);
 
   return PL_DHASH_NEXT;
 }
 
 static PLDHashOperator
 RadioGroupsTraverser(const nsAString& aKey, nsRadioGroupStruct* aData,
                      void* aClosure)
 {
-  nsCycleCollectionTraversalCallback *cb = 
+  nsCycleCollectionTraversalCallback *cb =
     static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
 
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb,
                                    "mRadioGroups entry->mSelectedRadioButton");
   cb->NoteXPCOMChild(aData->mSelectedRadioButton);
 
   uint32_t i, count = aData->mRadioButtons.Count();
   for (i = 0; i < count; ++i) {
@@ -1762,19 +1765,19 @@ RadioGroupsTraverser(const nsAString& aK
   }
 
   return PL_DHASH_NEXT;
 }
 
 static PLDHashOperator
 BoxObjectTraverser(nsIContent* key, nsPIBoxObject* boxObject, void* userArg)
 {
-  nsCycleCollectionTraversalCallback *cb = 
+  nsCycleCollectionTraversalCallback *cb =
     static_cast<nsCycleCollectionTraversalCallback*>(userArg);
- 
+
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mBoxObjectTable entry");
   cb->NoteXPCOMChild(boxObject);
 
   return PL_DHASH_NEXT;
 }
 
 static PLDHashOperator
 IdentifierMapEntryTraverse(nsIdentifierMapEntry *aEntry, void *aArg)
@@ -1908,17 +1911,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   // Clear out our external resources
   tmp->mExternalResourceMap.Shutdown();
 
   nsAutoScriptBlocker scriptBlocker;
 
   nsINode::Unlink(tmp);
 
   // Unlink the mChildren nsAttrAndChildArray.
-  for (int32_t indx = int32_t(tmp->mChildren.ChildCount()) - 1; 
+  for (int32_t indx = int32_t(tmp->mChildren.ChildCount()) - 1;
        indx >= 0; --indx) {
     tmp->mChildren.ChildAt(indx)->UnbindFromTree();
     tmp->mChildren.RemoveChildAt(indx);
   }
   tmp->mFirstChild = nullptr;
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mXPathEvaluatorTearoff)
   tmp->mCachedRootElement = nullptr; // Avoid a dangling pointer
@@ -2058,17 +2061,17 @@ nsDocument::AddXMLEventsContent(nsIConte
 
 void
 nsDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup)
 {
   nsCOMPtr<nsIURI> uri;
   nsCOMPtr<nsIPrincipal> principal;
   if (aChannel) {
     // Note: this code is duplicated in nsXULDocument::StartDocumentLoad and
-    // nsScriptSecurityManager::GetChannelPrincipal.    
+    // nsScriptSecurityManager::GetChannelPrincipal.
     // Note: this should match nsDocShell::OnLoadingSite
     NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
 
     nsIScriptSecurityManager *securityManager =
       nsContentUtils::GetSecurityManager();
     if (securityManager) {
       securityManager->GetChannelPrincipal(aChannel,
                                            getter_AddRefs(principal));
@@ -2119,17 +2122,17 @@ nsDocument::ResetToURI(nsIURI *aURI, nsI
   // Destroy link map now so we don't waste time removing
   // links one by one
   DestroyElementMaps();
 
   bool oldVal = mInUnlinkOrDeletion;
   mInUnlinkOrDeletion = true;
   uint32_t count = mChildren.ChildCount();
   { // Scope for update
-    MOZ_AUTO_DOC_UPDATE(this, UPDATE_CONTENT_MODEL, true);    
+    MOZ_AUTO_DOC_UPDATE(this, UPDATE_CONTENT_MODEL, true);
     for (int32_t i = int32_t(count) - 1; i >= 0; i--) {
       nsCOMPtr<nsIContent> content = mChildren.ChildAt(i);
 
       nsIContent* previousSibling = content->GetPreviousSibling();
 
       if (nsINode::GetFirstChild() == content) {
         mFirstChild = content->GetNextSibling();
       }
@@ -2138,17 +2141,17 @@ nsDocument::ResetToURI(nsIURI *aURI, nsI
       content->UnbindFromTree();
     }
   }
   mInUnlinkOrDeletion = oldVal;
   mCachedRootElement = nullptr;
 
   // Reset our stylesheets
   ResetStylesheetsToURI(aURI);
-  
+
   // Release the listener manager
   if (mListenerManager) {
     mListenerManager->Disconnect();
     mListenerManager = nullptr;
   }
 
   // Release the stylesheets list.
   mDOMStyleSheets = nullptr;
@@ -2217,54 +2220,52 @@ nsDocument::ResetToURI(nsIURI *aURI, nsI
 
   // Refresh the principal on the compartment.
   nsPIDOMWindow* win = GetInnerWindow();
   if (win) {
     win->RefreshCompartmentPrincipal();
   }
 }
 
+void
+nsDocument::RemoveStyleSheetsFromStyleSets(nsCOMArray<nsIStyleSheet>& aSheets, nsStyleSet::sheetType aType)
+{
+  // The stylesheets should forget us
+  int32_t indx = aSheets.Count();
+  while (--indx >= 0) {
+    nsIStyleSheet* sheet = aSheets[indx];
+    sheet->SetOwningDocument(nullptr);
+
+    if (sheet->IsApplicable()) {
+      nsCOMPtr<nsIPresShell> shell = GetShell();
+      if (shell) {
+        shell->StyleSet()->RemoveStyleSheet(aType, sheet);
+      }
+    }
+
+    // XXX Tell observers?
+  }
+
+}
+
 nsresult
 nsDocument::ResetStylesheetsToURI(nsIURI* aURI)
 {
   NS_PRECONDITION(aURI, "Null URI passed to ResetStylesheetsToURI");
 
   mozAutoDocUpdate upd(this, UPDATE_STYLE, true);
-  
-  // The stylesheets should forget us
-  int32_t indx = mStyleSheets.Count();
-  while (--indx >= 0) {
-    nsIStyleSheet* sheet = mStyleSheets[indx];
-    sheet->SetOwningDocument(nullptr);
-
-    if (sheet->IsApplicable()) {
-      RemoveStyleSheetFromStyleSets(sheet);
-    }
-
-    // XXX Tell observers?
-  }
-
-  indx = mCatalogSheets.Count();
-  while (--indx >= 0) {
-    nsIStyleSheet* sheet = mCatalogSheets[indx];
-    sheet->SetOwningDocument(nullptr);
-
-    if (sheet->IsApplicable()) {
-      nsCOMPtr<nsIPresShell> shell = GetShell();
-      if (shell) {
-        shell->StyleSet()->RemoveStyleSheet(nsStyleSet::eAgentSheet, sheet);
-      }
-    }
-
-    // XXX Tell observers?
-  }
-
+  RemoveStyleSheetsFromStyleSets(mStyleSheets, nsStyleSet::eDocSheet);
+  RemoveStyleSheetsFromStyleSets(mCatalogSheets, nsStyleSet::eAgentSheet);
+  RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eAgentSheet], nsStyleSet::eAgentSheet);
+  RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eUserSheet], nsStyleSet::eUserSheet);
 
   // Release all the sheets
   mStyleSheets.Clear();
+  mAdditionalSheets[eAgentSheet].Clear();
+  mAdditionalSheets[eUserSheet].Clear();
   // NOTE:  We don't release the catalog sheets.  It doesn't really matter
   // now, but it could in the future -- in which case not releasing them
   // is probably the right thing to do.
 
   // Now reset our inline style and attribute sheets.
   if (mAttrStyleSheet) {
     // Remove this sheet from all style sets
     nsCOMPtr<nsIPresShell> shell = GetShell();
@@ -2275,17 +2276,17 @@ nsDocument::ResetStylesheetsToURI(nsIURI
     mAttrStyleSheet->Reset(aURI);
   } else {
     mAttrStyleSheet = new nsHTMLStyleSheet(aURI, this);
   }
 
   // Don't use AddStyleSheet, since it'll put the sheet into style
   // sets in the document level, which is not desirable here.
   mAttrStyleSheet->SetOwningDocument(this);
-  
+
   if (mStyleAttrStyleSheet) {
     // Remove this sheet from all style sets
     nsCOMPtr<nsIPresShell> shell = GetShell();
     if (shell) {
       shell->StyleSet()->
         RemoveStyleSheet(nsStyleSet::eStyleAttrSheet, mStyleAttrStyleSheet);
     }
     mStyleAttrStyleSheet->Reset(aURI);
@@ -2315,17 +2316,17 @@ nsDocument::FillStyleSet(nsStyleSet* aSt
   NS_PRECONDITION(aStyleSet->SheetCount(nsStyleSet::ePresHintSheet) == 0,
                   "Style set already has a preshint sheet?");
   NS_PRECONDITION(aStyleSet->SheetCount(nsStyleSet::eDocSheet) == 0,
                   "Style set already has document sheets?");
   NS_PRECONDITION(aStyleSet->SheetCount(nsStyleSet::eStyleAttrSheet) == 0,
                   "Style set already has style attr sheets?");
   NS_PRECONDITION(mStyleAttrStyleSheet, "No style attr stylesheet?");
   NS_PRECONDITION(mAttrStyleSheet, "No attr stylesheet?");
-  
+
   aStyleSet->AppendStyleSheet(nsStyleSet::ePresHintSheet, mAttrStyleSheet);
 
   aStyleSet->AppendStyleSheet(nsStyleSet::eStyleAttrSheet,
                               mStyleAttrStyleSheet);
 
   int32_t i;
   for (i = mStyleSheets.Count() - 1; i >= 0; --i) {
     nsIStyleSheet* sheet = mStyleSheets[i];
@@ -2335,16 +2336,26 @@ nsDocument::FillStyleSet(nsStyleSet* aSt
   }
 
   for (i = mCatalogSheets.Count() - 1; i >= 0; --i) {
     nsIStyleSheet* sheet = mCatalogSheets[i];
     if (sheet->IsApplicable()) {
       aStyleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, sheet);
     }
   }
+
+  for (int32_t i = mAdditionalSheets[eAgentSheet].Count() - 1; i >= 0; --i) {
+    nsIStyleSheet* sheet = mAdditionalSheets[eAgentSheet][i];
+    aStyleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, sheet);
+  }
+
+  for (int32_t i = mAdditionalSheets[eUserSheet].Count() - 1; i >= 0; --i) {
+    nsIStyleSheet* sheet = mAdditionalSheets[eUserSheet][i];
+    aStyleSet->AppendStyleSheet(nsStyleSet::eUserSheet, sheet);
+  }
 }
 
 nsresult
 nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
                               nsILoadGroup* aLoadGroup,
                               nsISupports* aContainer,
                               nsIStreamListener **aDocListener,
                               bool aReset, nsIContentSink* aSink)
@@ -2436,40 +2447,40 @@ nsDocument::InitCSP()
       return NS_OK;
     }
 
     if (cspHeaderValue.IsEmpty() && cspROHeaderValue.IsEmpty()) {
       // no CSP header present, stop processing
       return NS_OK;
     }
 
-#ifdef PR_LOGGING 
+#ifdef PR_LOGGING
     PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("CSP header specified for document %p", this));
 #endif
 
     nsresult rv;
     nsCOMPtr<nsIContentSecurityPolicy> mCSP;
     mCSP = do_CreateInstance("@mozilla.org/contentsecuritypolicy;1", &rv);
 
     if (NS_FAILED(rv)) {
-#ifdef PR_LOGGING 
+#ifdef PR_LOGGING
       PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("Failed to create CSP object: %x", rv));
 #endif
       return rv;
     }
 
     // Store the request context for violation reports
     nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
     mCSP->ScanRequestData(httpChannel);
 
     // Start parsing the policy
     nsCOMPtr<nsIURI> chanURI;
     mChannel->GetURI(getter_AddRefs(chanURI));
 
-#ifdef PR_LOGGING 
+#ifdef PR_LOGGING
     PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("CSP Loaded"));
 #endif
 
     // ReportOnly mode is enabled *only* if there are no regular-strength CSP
     // headers present.  If there are, then we ignore the ReportOnly mode and
     // toss a warning into the error console, proceeding with enforcing the
     // regular-strength CSP.
     if (cspHeaderValue.IsEmpty()) {
@@ -2486,17 +2497,17 @@ nsDocument::InitCSP()
         {
           PR_LOG(gCspPRLog, PR_LOG_DEBUG,
                   ("CSP (report only) refined with policy: \"%s\"",
                     NS_ConvertUTF16toUTF8(policy).get()));
         }
 #endif
       }
     } else {
-      //XXX(sstamm): maybe we should post a warning when both read only and regular 
+      //XXX(sstamm): maybe we should post a warning when both read only and regular
       // CSP headers are present.
 
       // Need to tokenize the header value since multiple headers could be
       // concatenated into one comma-separated list of policies.
       // See RFC2616 section 4.2 (last paragraph)
       nsCharSeparatedTokenizer tokenizer(cspHeaderValue, ',');
       while (tokenizer.hasMoreTokens()) {
         const nsSubstring& policy = tokenizer.nextToken();
@@ -2517,42 +2528,42 @@ nsDocument::InitCSP()
         bool safeAncestry = false;
 
         // PermitsAncestry sends violation reports when necessary
         rv = mCSP->PermitsAncestry(docShell, &safeAncestry);
         NS_ENSURE_SUCCESS(rv, rv);
 
         if (!safeAncestry) {
 #ifdef PR_LOGGING
-            PR_LOG(gCspPRLog, PR_LOG_DEBUG, 
+            PR_LOG(gCspPRLog, PR_LOG_DEBUG,
                    ("CSP doesn't like frame's ancestry, not loading."));
 #endif
             // stop!  ERROR page!
             mChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION);
         }
     }
 
     //Copy into principal
     nsIPrincipal* principal = GetPrincipal();
 
     if (principal) {
         principal->SetCsp(mCSP);
 #ifdef PR_LOGGING
-        PR_LOG(gCspPRLog, PR_LOG_DEBUG, 
+        PR_LOG(gCspPRLog, PR_LOG_DEBUG,
                 ("Inserted CSP into principal %p", principal));
     }
     else {
-      PR_LOG(gCspPRLog, PR_LOG_DEBUG, 
+      PR_LOG(gCspPRLog, PR_LOG_DEBUG,
               ("Couldn't copy CSP into absent principal %p", principal));
 #endif
     }
   }
 #ifdef PR_LOGGING
   else { //CSP was not enabled!
-    PR_LOG(gCspPRLog, PR_LOG_DEBUG, 
+    PR_LOG(gCspPRLog, PR_LOG_DEBUG,
            ("CSP is disabled, skipping CSP init for document %p", this));
   }
 #endif
   return NS_OK;
 }
 
 void
 nsDocument::StopDocumentLoad()
@@ -2723,17 +2734,17 @@ nsDocument::SetContentType(const nsAStri
 nsresult
 nsDocument::GetAllowPlugins(bool * aAllowPlugins)
 {
   // First, we ask our docshell if it allows plugins.
   nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
 
   if (docShell) {
     docShell->GetAllowPlugins(aAllowPlugins);
-      
+
     // If the docshell allows plugins, we check whether
     // we are sandboxed and plugins should not be allowed.
     if (*aAllowPlugins)
       *aAllowPlugins = !(mSandboxFlags & SANDBOXED_PLUGINS);
   }
 
   return NS_OK;
 }
@@ -2823,17 +2834,17 @@ nsDocument::GetActiveElement(nsIDOMEleme
 
 NS_IMETHODIMP
 nsDocument::GetCurrentScript(nsIDOMElement **aElement)
 {
   nsIScriptElement* script = mScriptLoader->GetCurrentScript();
   if (script) {
     return CallQueryInterface(script, aElement);
   }
-  
+
   *aElement = nullptr;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocument::ElementFromPoint(float aX, float aY, nsIDOMElement** aReturn)
 {
@@ -2888,17 +2899,17 @@ nsresult
 nsDocument::NodesFromRectHelper(float aX, float aY,
                                 float aTopSize, float aRightSize,
                                 float aBottomSize, float aLeftSize,
                                 bool aIgnoreRootScrollFrame,
                                 bool aFlushLayout,
                                 nsIDOMNodeList** aReturn)
 {
   NS_ENSURE_ARG_POINTER(aReturn);
-  
+
   nsSimpleContentList* elements = new nsSimpleContentList(this);
   NS_ADDREF(elements);
   *aReturn = elements;
 
   // Following the same behavior of elementFromPoint,
   // we don't return anything if either coord is negative
   if (!aIgnoreRootScrollFrame && (aX < 0 || aY < 0))
     return NS_OK;
@@ -2968,17 +2979,17 @@ nsDocument::ReleaseCapture()
 }
 
 nsresult
 nsDocument::SetBaseURI(nsIURI* aURI)
 {
   if (!aURI && !mDocumentBaseURI) {
     return NS_OK;
   }
-  
+
   // Don't do anything if the URI wasn't actually changed.
   if (aURI && mDocumentBaseURI) {
     bool equalBases = false;
     mDocumentBaseURI->Equals(aURI, &equalBases);
     if (equalBases) {
       return NS_OK;
     }
   }
@@ -3182,17 +3193,17 @@ nsDocument::doCreateShell(nsPresContext*
 {
   *aInstancePtrResult = nullptr;
 
   NS_ASSERTION(!mPresShell, "We have a presshell already!");
 
   NS_ENSURE_FALSE(GetBFCacheEntry(), NS_ERROR_FAILURE);
 
   FillStyleSet(aStyleSet);
-  
+
   nsCOMPtr<nsIPresShell> shell;
   nsresult rv = NS_NewPresShell(getter_AddRefs(shell));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   rv = shell->Init(this, aContext, aViewManager, aStyleSet, aCompatMode);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -3425,17 +3436,17 @@ nsDocument::GetRootElementInternal() con
   uint32_t i;
   for (i = mChildren.ChildCount(); i > 0; --i) {
     nsIContent* child = mChildren.ChildAt(i - 1);
     if (child->IsElement()) {
       const_cast<nsDocument*>(this)->mCachedRootElement = child->AsElement();
       return child->AsElement();
     }
   }
-  
+
   const_cast<nsDocument*>(this)->mCachedRootElement = nullptr;
   return nullptr;
 }
 
 nsIContent *
 nsDocument::GetChildAt(uint32_t aIndex) const
 {
   return mChildren.GetSafeChildAt(aIndex);
@@ -3453,17 +3464,17 @@ nsDocument::GetChildCount() const
   return mChildren.ChildCount();
 }
 
 nsIContent * const *
 nsDocument::GetChildArray(uint32_t* aChildCount) const
 {
   return mChildren.GetChildArray(aChildCount);
 }
-  
+
 
 nsresult
 nsDocument::InsertChildAt(nsIContent* aKid, uint32_t aIndex,
                           bool aNotify)
 {
   if (aKid->IsElement() && GetRootElement()) {
     NS_ERROR("Inserting element child when we already have one");
     return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
@@ -3511,16 +3522,24 @@ nsDocument::GetStyleSheetAt(int32_t aInd
 {
   NS_ENSURE_TRUE(0 <= aIndex && aIndex < mStyleSheets.Count(), nullptr);
   return mStyleSheets[aIndex];
 }
 
 int32_t
 nsDocument::GetIndexOfStyleSheet(nsIStyleSheet* aSheet) const
 {
+  if (mAdditionalSheets[eUserSheet].IndexOf(aSheet) >= 0 ||
+      mAdditionalSheets[eAgentSheet].IndexOf(aSheet) >= 0 ) {
+    // Returning INT32_MAX to make sure that additional sheets are
+    // in the style set of the PresShell will be always after the
+    // document sheets (even if document sheets are added dynamically).
+    return INT32_MAX;
+  }
+
   return mStyleSheets.IndexOf(aSheet);
 }
 
 void
 nsDocument::AddStyleSheetToStyleSets(nsIStyleSheet* aSheet)
 {
   nsCOMPtr<nsIPresShell> shell = GetShell();
   if (shell) {
@@ -3673,17 +3692,17 @@ nsDocument::AddCatalogStyleSheet(nsIStyl
 
   if (aSheet->IsApplicable()) {
     // This is like |AddStyleSheetToStyleSets|, but for an agent sheet.
     nsCOMPtr<nsIPresShell> shell = GetShell();
     if (shell) {
       shell->StyleSet()->AppendStyleSheet(nsStyleSet::eAgentSheet, aSheet);
     }
   }
-                                                                                
+
   NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetAdded, (this, aSheet, false));
 }
 
 void
 nsDocument::EnsureCatalogStyleSheet(const char *aStyleSheetURI)
 {
   mozilla::css::Loader* cssLoader = CSSLoader();
   if (cssLoader->GetEnabled()) {
@@ -3708,16 +3727,99 @@ nsDocument::EnsureCatalogStyleSheet(cons
         BeginUpdate(UPDATE_STYLE);
         AddCatalogStyleSheet(sheet);
         EndUpdate(UPDATE_STYLE);
       }
     }
   }
 }
 
+static int32_t
+FindSheet(const nsCOMArray<nsIStyleSheet>& aSheets, nsIURI* aSheetURI)
+{
+  for (int32_t i = aSheets.Count() - 1; i >= 0; i-- ) {
+    bool bEqual;
+    nsIURI* uri = aSheets[i]->GetSheetURI();
+
+    if (uri && NS_SUCCEEDED(uri->Equals(aSheetURI, &bEqual)) && bEqual)
+      return i;
+  }
+
+  return -1;
+}
+
+nsresult
+nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI)
+{
+  NS_PRECONDITION(aSheetURI, "null arg");
+
+  // Checking if we have loaded this one already.
+  if (FindSheet(mAdditionalSheets[aType], aSheetURI) >= 0)
+    return NS_ERROR_INVALID_ARG;
+
+  // Loading the sheet sync.
+  nsRefPtr<mozilla::css::Loader> loader = new mozilla::css::Loader();
+
+  nsRefPtr<nsCSSStyleSheet> sheet;
+  nsresult rv = loader->LoadSheetSync(aSheetURI, aType == eAgentSheet,
+    true, getter_AddRefs(sheet));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  mAdditionalSheets[aType].AppendObject(sheet);
+  sheet->SetOwningDocument(this);
+  MOZ_ASSERT(sheet->IsApplicable());
+
+  BeginUpdate(UPDATE_STYLE);
+  nsCOMPtr<nsIPresShell> shell = GetShell();
+  if (shell) {
+    nsStyleSet::sheetType type = aType == eAgentSheet ? nsStyleSet::eAgentSheet :
+                                                        nsStyleSet::eUserSheet;
+    shell->StyleSet()->AppendStyleSheet(type, sheet);
+  }
+
+  // Passing false, so documet.styleSheets.length will not be affected by
+  // these additional sheets.
+  NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetAdded, (this, sheet, false));
+  EndUpdate(UPDATE_STYLE);
+
+  return NS_OK;
+}
+
+void
+nsDocument::RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI)
+{
+  MOZ_ASSERT(aSheetURI);
+
+  nsCOMArray<nsIStyleSheet>& sheets = mAdditionalSheets[aType];
+
+  int32_t i = FindSheet(mAdditionalSheets[aType], aSheetURI);
+  if (i >= 0) {
+    nsCOMPtr<nsIStyleSheet> sheetRef = sheets[i];
+    sheets.RemoveObjectAt(i);
+
+    BeginUpdate(UPDATE_STYLE);
+    if (!mIsGoingAway) {
+      MOZ_ASSERT(sheetRef->IsApplicable());
+      nsCOMPtr<nsIPresShell> shell = GetShell();
+      if (shell) {
+        nsStyleSet::sheetType type = aType == eAgentSheet ? nsStyleSet::eAgentSheet :
+                                                            nsStyleSet::eUserSheet;
+        shell->StyleSet()->RemoveStyleSheet(type, sheetRef);
+      }
+    }
+
+    // Passing false, so documet.styleSheets.length will not be affected by
+    // these additional sheets.
+    NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetRemoved, (this, sheetRef, false));
+    EndUpdate(UPDATE_STYLE);
+
+    sheetRef->SetOwningDocument(nullptr);
+  }
+}
+
 nsIScriptGlobalObject*
 nsDocument::GetScriptGlobalObject() const
 {
    // If we're going away, we've already released the reference to our
    // ScriptGlobalObject.  We can, however, try to obtain it for the
    // caller through our docshell.
 
    // We actually need to start returning the docshell's script global
@@ -3985,17 +4087,17 @@ nsDocument::MaybeEndOutermostXBLUpdate()
 
 void
 nsDocument::BeginUpdate(nsUpdateType aUpdateType)
 {
   if (mUpdateNestLevel == 0 && !mInXBLUpdate) {
     mInXBLUpdate = true;
     BindingManager()->BeginOutermostUpdate();
   }
-  
+
   ++mUpdateNestLevel;
   nsContentUtils::AddScriptBlocker();
   NS_DOCUMENT_NOTIFY_OBSERVERS(BeginUpdate, (this, aUpdateType));
 }
 
 void
 nsDocument::EndUpdate(nsUpdateType aUpdateType)
 {
@@ -4049,17 +4151,17 @@ nsDocument::GetElementById(const nsAStri
 const nsSmallVoidArray*
 nsDocument::GetAllElementsForId(const nsAString& aElementId) const
 {
   if (aElementId.IsEmpty()) {
     return nullptr;
   }
 
   nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aElementId);
-  return entry ? entry->GetIdElements() : nullptr;  
+  return entry ? entry->GetIdElements() : nullptr;
 }
 
 NS_IMETHODIMP
 nsDocument::GetElementById(const nsAString& aId, nsIDOMElement** aReturn)
 {
   Element *content = GetElementById(aId);
   if (content) {
     return CallQueryInterface(content, aReturn);
@@ -4136,24 +4238,24 @@ nsDocument::LookupImageElement(const nsA
 }
 
 void
 nsDocument::DispatchContentLoadedEvents()
 {
   NS_TIME_FUNCTION;
   // If you add early returns from this method, make sure you're
   // calling UnblockOnload properly.
-  
+
   // Unpin references to preloaded images
   mPreloadingImages.Clear();
 
   if (mTiming) {
     mTiming->NotifyDOMContentLoadedStart(nsIDocument::GetDocumentURI());
   }
-    
+
   // Fire a DOM event notifying listeners that this document has been
   // loaded (excluding images and other loads initiated by this
   // document).
   nsContentUtils::DispatchTrustedEvent(this, static_cast<nsIDocument*>(this),
                                        NS_LITERAL_STRING("DOMContentLoaded"),
                                        true, true);
 
   if (mTiming) {
@@ -4210,17 +4312,17 @@ nsDocument::DispatchContentLoadedEvents(
 
             if (context) {
               nsEventDispatcher::Dispatch(parent, context, innerEvent, event,
                                           &status);
             }
           }
         }
       }
-      
+
       parent = parent->GetParentDocument();
     } while (parent);
   }
 
   // If the document has a manifest attribute, fire a MozApplicationManifest
   // event.
   Element* root = GetRootElement();
   if (root && root->HasAttr(kNameSpaceID_None, nsGkAtoms::manifest)) {
@@ -4237,19 +4339,19 @@ nsDocument::EndLoad()
 {
   // Drop the ref to our parser, if any, but keep hold of the sink so that we
   // can flush it from FlushPendingNotifications as needed.  We might have to
   // do that to get a StartLayout() to happen.
   if (mParser) {
     mWeakSink = do_GetWeakReference(mParser->GetContentSink());
     mParser = nullptr;
   }
-  
+
   NS_DOCUMENT_NOTIFY_OBSERVERS(EndLoad, (this));
-  
+
   if (!mSynchronousDOMContentLoaded) {
     nsRefPtr<nsIRunnable> ev =
       NS_NewRunnableMethod(this, &nsDocument::DispatchContentLoadedEvents);
     NS_DispatchToCurrentThread(ev);
   } else {
     DispatchContentLoadedEvents();
   }
 }
@@ -4666,33 +4768,33 @@ nsDocument::GetStyleSheets(nsIDOMStyleSh
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocument::GetSelectedStyleSheetSet(nsAString& aSheetSet)
 {
   aSheetSet.Truncate();
-  
+
   // Look through our sheets, find the selected set title
   int32_t count = GetNumberOfStyleSheets();
   nsAutoString title;
   for (int32_t index = 0; index < count; index++) {
     nsIStyleSheet* sheet = GetStyleSheetAt(index);
     NS_ASSERTION(sheet, "Null sheet in sheet list!");
 
     nsCOMPtr<nsIDOMStyleSheet> domSheet = do_QueryInterface(sheet);
     NS_ASSERTION(domSheet, "Sheet must QI to nsIDOMStyleSheet");
     bool disabled;
     domSheet->GetDisabled(&disabled);
     if (disabled) {
       // Disabled sheets don't affect the currently selected set
       continue;
     }
-    
+
     sheet->GetTitle(title);
 
     if (aSheetSet.IsEmpty()) {
       aSheetSet = title;
     } else if (!title.IsEmpty() && !aSheetSet.Equals(title)) {
       // Sheets from multiple sets enabled; return null string, per spec.
       SetDOMStringToNull(aSheetSet);
       break;
@@ -4839,17 +4941,17 @@ nsDocument::ImportNode(nsIDOMNode* aImpo
     }
   }
 }
 
 NS_IMETHODIMP
 nsDocument::AddBinding(nsIDOMElement* aContent, const nsAString& aURI)
 {
   NS_ENSURE_ARG(aContent);
-  
+
   nsresult rv = nsContentUtils::CheckSameOrigin(this, aContent);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(aContent));
 
   nsCOMPtr<nsIURI> uri;
@@ -4866,17 +4968,17 @@ nsDocument::AddBinding(nsIDOMElement* aC
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (!subject) {
     // Fall back to our principal.  Or should we fall back to the null
     // principal?  The latter would just mean no binding loads....
     subject = NodePrincipal();
   }
-  
+
   return BindingManager()->AddLayeredBinding(content, uri, subject);
 }
 
 NS_IMETHODIMP
 nsDocument::RemoveBinding(nsIDOMElement* aContent, const nsAString& aURI)
 {
   NS_ENSURE_ARG(aContent);
 
@@ -4912,17 +5014,17 @@ nsDocument::LoadBindingDocument(const ns
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (!subject) {
     // Fall back to our principal.  Or should we fall back to the null
     // principal?  The latter would just mean no binding loads....
     subject = NodePrincipal();
   }
-  
+
   BindingManager()->LoadBindingDocument(this, uri, subject);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocument::GetBindingParent(nsIDOMNode* aNode, nsIDOMElement** aResult)
 {
@@ -5532,17 +5634,17 @@ nsDocument::GetAnimationController()
   if (mAnimationController)
     return mAnimationController;
   // Refuse to create an Animation Controller if SMIL is disabled, and also
   // for data documents.
   if (!NS_SMILEnabled() || mLoadedAsData || mLoadedAsInteractiveData)
     return nullptr;
 
   mAnimationController = new nsSMILAnimationController(this);
-  
+
   // If there's a presContext then check the animation mode and pause if
   // necessary.
   nsIPresShell *shell = GetShell();
   if (mAnimationController && shell) {
     nsPresContext *context = shell->GetPresContext();
     if (context &&
         context->ImageAnimationMode() == imgIContainer::kDontAnimMode) {
       mAnimationController->Pause(nsSMILTimeContainer::PAUSE_USERPREF);
@@ -5794,17 +5896,17 @@ nsDocument::AppendChild(nsIDOMNode* aNew
 }
 
 NS_IMETHODIMP
 nsDocument::CloneNode(bool aDeep, uint8_t aOptionalArgc, nsIDOMNode** aReturn)
 {
   if (!aOptionalArgc) {
     aDeep = true;
   }
-  
+
   return nsNodeUtils::CloneNodeImpl(this, aDeep, !mCreatingStaticClone, aReturn);
 }
 
 NS_IMETHODIMP
 nsDocument::Normalize()
 {
   return nsIDocument::Normalize();
 }
@@ -6520,19 +6622,19 @@ nsDocument::GetCurrentRadioButton(const 
 }
 
 NS_IMETHODIMP
 nsDocument::GetNextRadioButton(const nsAString& aName,
                                const bool aPrevious,
                                nsIDOMHTMLInputElement*  aFocusedRadio,
                                nsIDOMHTMLInputElement** aRadioOut)
 {
-  // XXX Can we combine the HTML radio button method impls of 
+  // XXX Can we combine the HTML radio button method impls of
   //     nsDocument and nsHTMLFormControl?
-  // XXX Why is HTML radio button stuff in nsDocument, as 
+  // XXX Why is HTML radio button stuff in nsDocument, as
   //     opposed to nsHTMLDocument?
   *aRadioOut = nullptr;
 
   nsRadioGroupStruct* radioGroup = GetOrCreateRadioGroup(aName);
 
   // Return the radio button relative to the focused radio button.
   // If no radio is focused, get the radio relative to the selected one.
   nsCOMPtr<nsIDOMHTMLInputElement> currentRadio;
@@ -6692,17 +6794,17 @@ nsDocument::RetrieveRelevantHeaders(nsIC
       "x-content-security-policy",
       "x-content-security-policy-report-only",
       "x-frame-options",
       // add more http headers if you need
       // XXXbz don't add content-location support without reading bug
       // 238654 and its dependencies/dups first.
       0
     };
-    
+
     nsAutoCString headerVal;
     const char *const *name = headers;
     while (*name) {
       rv =
         httpChannel->GetResponseHeader(nsDependentCString(*name), headerVal);
       if (NS_SUCCEEDED(rv) && !headerVal.IsEmpty()) {
         nsCOMPtr<nsIAtom> key = do_GetAtom(*name);
         SetHeaderData(key, NS_ConvertASCIItoUTF16(headerVal));
@@ -6773,17 +6875,17 @@ nsDocument::CreateElem(const nsAString& 
   // which would cause an error if we just used true here.
   bool nsAware = aPrefix != nullptr || aNamespaceID != GetDefaultNamespaceID();
   NS_ASSERTION(NS_SUCCEEDED(nsContentUtils::CheckQName(qName, nsAware)),
                "Don't pass invalid prefixes to nsDocument::CreateElem, "
                "check caller.");
 #endif
 
   *aResult = nullptr;
-  
+
   nsCOMPtr<nsINodeInfo> nodeInfo;
   mNodeInfoManager->GetNodeInfo(aName, aPrefix, aNamespaceID,
                                 nsIDOMNode::ELEMENT_NODE,
                                 getter_AddRefs(nodeInfo));
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   return NS_NewElement(aResult, nodeInfo.forget(), NOT_FROM_PARSER);
 }
@@ -7030,17 +7132,17 @@ nsDocument::Destroy()
 
 void
 nsDocument::RemovedFromDocShell()
 {
   if (mRemovedFromDocShell)
     return;
 
   mRemovedFromDocShell = true;
-  EnumerateFreezableElements(NotifyActivityChanged, nullptr); 
+  EnumerateFreezableElements(NotifyActivityChanged, nullptr);
 
   uint32_t i, count = mChildren.ChildCount();
   for (i = 0; i < count; ++i) {
     mChildren.ChildAt(i)->SaveSubtreeState();
   }
 }
 
 already_AddRefed<nsILayoutHistoryState>
@@ -7098,17 +7200,17 @@ nsDocument::AsyncBlockOnload()
 
 void
 nsDocument::BlockOnload()
 {
   if (mDisplayDocument) {
     mDisplayDocument->BlockOnload();
     return;
   }
-  
+
   // If mScriptGlobalObject is null, we shouldn't be messing with the loadgroup
   // -- it's not ours.
   if (mOnloadBlockCount == 0 && mScriptGlobalObject) {
     if (!nsContentUtils::IsSafeToRunScript()) {
       // Because AddRequest may lead to OnStateChange calls in chrome,
       // block onload only when there are no script blockers.
       ++mAsyncOnloadBlockCount;
       if (mAsyncOnloadBlockCount == 1) {
@@ -7125,17 +7227,17 @@ nsDocument::BlockOnload()
       }
       return;
     }
     nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
     if (loadGroup) {
       loadGroup->AddRequest(mOnloadBlocker, nullptr);
     }
   }
-  ++mOnloadBlockCount;      
+  ++mOnloadBlockCount;
 }
 
 void
 nsDocument::UnblockOnload(bool aFireSync)
 {
   if (mDisplayDocument) {
     mDisplayDocument->UnblockOnload(aFireSync);
     return;
@@ -7163,17 +7265,17 @@ nsDocument::UnblockOnload(bool aFireSync
 
 class nsUnblockOnloadEvent : public nsRunnable {
 public:
   nsUnblockOnloadEvent(nsDocument *doc) : mDoc(doc) {}
   NS_IMETHOD Run() {
     mDoc->DoUnblockOnload();
     return NS_OK;
   }
-private:  
+private:
   nsRefPtr<nsDocument> mDoc;
 };
 
 void
 nsDocument::PostUnblockOnloadEvent()
 {
   nsCOMPtr<nsIRunnable> evt = new nsUnblockOnloadEvent(this);
   nsresult rv = NS_DispatchToCurrentThread(evt);
@@ -7188,17 +7290,17 @@ nsDocument::PostUnblockOnloadEvent()
 void
 nsDocument::DoUnblockOnload()
 {
   NS_PRECONDITION(!mDisplayDocument,
                   "Shouldn't get here for resource document");
   NS_PRECONDITION(mOnloadBlockCount != 0,
                   "Shouldn't have a count of zero here, since we stabilized in "
                   "PostUnblockOnloadEvent");
-  
+
   --mOnloadBlockCount;
 
   if (mOnloadBlockCount != 0) {
     // We blocked again after the last unblock.  Nothing to do here.  We'll
     // post a new event when we unblock again.
     return;
   }
 
@@ -7292,17 +7394,17 @@ nsDocument::OnPageShow(bool aPersisted,
   }
 
   // See nsIDocument
   if (!aDispatchStartTarget) {
     // Set mIsShowing before firing events, in case those event handlers
     // move us around.
     mIsShowing = true;
   }
- 
+
   if (mAnimationController) {
     mAnimationController->OnPageShow();
   }
 
   if (aPersisted) {
     SetImagesNeedAnimating(true);
   }
 
@@ -7349,32 +7451,32 @@ nsDocument::OnPageHide(bool aPersisted,
     // Set mIsShowing before firing events, in case those event handlers
     // move us around.
     mIsShowing = false;
   }
 
   if (mAnimationController) {
     mAnimationController->OnPageHide();
   }
-  
+
   if (aPersisted) {
     SetImagesNeedAnimating(false);
   }
 
   // Now send out a PageHide event.
   nsCOMPtr<nsIDOMEventTarget> target = aDispatchStartTarget;
   if (!target) {
     target = do_QueryInterface(GetWindow());
   }
   DispatchPageTransition(target, NS_LITERAL_STRING("pagehide"), aPersisted);
 
   mVisible = false;
 
   UpdateVisibilityState();
-  
+
   EnumerateExternalResources(NotifyPageHide, &aPersisted);
   EnumerateFreezableElements(NotifyActivityChanged, nullptr);
 
   if (IsFullScreenDoc()) {
     // A full-screen doc has been hidden. We need to ensure we exit
     // full-screen, i.e. remove full-screen state from all full-screen
     // documents, and exit the top-level window from full-screen mode.
     // By the time a doc is hidden, it has been removed from the doc tree,
@@ -7601,17 +7703,17 @@ nsDocument::SetReadyStateInternal(ReadyS
     }
   }
   // At the time of loading start, we don't have timing object, record time.
   if (READYSTATE_LOADING == rs) {
     mLoadingTimeStamp = mozilla::TimeStamp::Now();
   }
 
   nsRefPtr<nsAsyncDOMEvent> plevent =
-    new nsAsyncDOMEvent(this, NS_LITERAL_STRING("readystatechange"), false, false); 
+    new nsAsyncDOMEvent(this, NS_LITERAL_STRING("readystatechange"), false, false);
   if (plevent) {
     plevent->RunDOMEventWhenSafe();
   }
 }
 
 nsIDocument::ReadyState
 nsDocument::GetReadyStateEnum()
 {
@@ -7625,17 +7727,17 @@ nsDocument::GetReadyState(nsAString& aRe
   case READYSTATE_LOADING :
     aReadyState.Assign(NS_LITERAL_STRING("loading"));
     break;
   case READYSTATE_INTERACTIVE :
     aReadyState.Assign(NS_LITERAL_STRING("interactive"));
     break;
   case READYSTATE_COMPLETE :
     aReadyState.Assign(NS_LITERAL_STRING("complete"));
-    break;  
+    break;
   default:
     aReadyState.Assign(NS_LITERAL_STRING("uninitialized"));
   }
   return NS_OK;
 }
 
 static bool
 SuppressEventHandlingInDocument(nsIDocument* aDocument, void* aData)
@@ -7993,33 +8095,33 @@ nsIDocument::RegisterPendingLinkUpdate(L
   mHasLinksToUpdate = true;
 }
 
 void
 nsIDocument::UnregisterPendingLinkUpdate(Link* aLink)
 {
   if (!mHasLinksToUpdate)
     return;
-    
+
   mLinksToUpdate.RemoveEntry(aLink);
 }
-  
+
 static PLDHashOperator
 EnumeratePendingLinkUpdates(nsPtrHashKey<Link>* aEntry, void* aData)
 {
   aEntry->GetKey()->GetElement()->UpdateLinkState(aEntry->GetKey()->LinkState());
   return PL_DHASH_NEXT;
 }
 
 void
-nsIDocument::FlushPendingLinkUpdates() 
+nsIDocument::FlushPendingLinkUpdates()
 {
   if (!mHasLinksToUpdate)
     return;
-    
+
   nsAutoScriptBlocker scriptBlocker;
   mLinksToUpdate.EnumerateEntries(EnumeratePendingLinkUpdates, nullptr);
   mLinksToUpdate.Clear();
   mHasLinksToUpdate = false;
 }
 
 already_AddRefed<nsIDocument>
 nsIDocument::CreateStaticClone(nsISupports* aCloneContainer)
@@ -8127,17 +8229,17 @@ nsDocument::GetStateObject(nsIVariant** 
   nsCOMPtr<nsIVariant> stateObj;
   if (!mStateObjectCached && mStateObjectContainer) {
     JSContext *cx = nsContentUtils::GetContextFromDocument(this);
     mStateObjectContainer->
       DeserializeToVariant(cx, getter_AddRefs(mStateObjectCached));
   }
 
   NS_IF_ADDREF(*aState = mStateObjectCached);
-  
+
   return NS_OK;
 }
 
 nsDOMNavigationTiming*
 nsDocument::GetNavigationTiming() const
 {
   return mTiming;
 }
@@ -9854,17 +9956,17 @@ nsDocument::DocSizeOfExcludingThis(nsWin
       break;
     }
 
     *p += nodeSize;
   }
 
   aWindowSizes->mStyleSheets +=
     mStyleSheets.SizeOfExcludingThis(SizeOfStyleSheetsElementIncludingThis,
-                                     aWindowSizes->mMallocSizeOf); 
+                                     aWindowSizes->mMallocSizeOf);
   aWindowSizes->mDOMOther +=
     mAttrStyleSheet ?
     mAttrStyleSheet->DOMSizeOfIncludingThis(aWindowSizes->mMallocSizeOf) :
     0;
 
   aWindowSizes->mDOMOther +=
     mStyledLinks.SizeOfExcludingThis(NULL, aWindowSizes->mMallocSizeOf);
 
@@ -9895,17 +9997,17 @@ nsAutoSyncOperation::nsAutoSyncOperation
   mMicroTaskLevel = nsContentUtils::MicroTaskLevel();
   nsContentUtils::SetMicroTaskLevel(0);
   if (aDoc) {
     nsPIDOMWindow* win = aDoc->GetWindow();
     if (win) {
       nsCOMPtr<nsIDOMWindow> topWindow;
       win->GetTop(getter_AddRefs(topWindow));
       nsCOMPtr<nsPIDOMWindow> top = do_QueryInterface(topWindow);
-      if (top) {                               
+      if (top) {
         nsCOMPtr<nsIDocument> doc = do_QueryInterface(top->GetExtantDocument());
         MarkDocumentTreeToBeInSyncOperation(doc, &mDocuments);
       }
     }
   }
 }
 
 nsAutoSyncOperation::~nsAutoSyncOperation()
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -594,16 +594,19 @@ public:
   virtual void SetStyleSheetApplicableState(nsIStyleSheet* aSheet,
                                             bool aApplicable);
 
   virtual int32_t GetNumberOfCatalogStyleSheets() const;
   virtual nsIStyleSheet* GetCatalogStyleSheetAt(int32_t aIndex) const;
   virtual void AddCatalogStyleSheet(nsIStyleSheet* aSheet);
   virtual void EnsureCatalogStyleSheet(const char *aStyleSheetURI);
 
+  virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI);
+  virtual void RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* sheetURI);
+
   virtual nsIChannel* GetChannel() const {
     return mChannel;
   }
 
   /**
    * Get this document's inline style sheet.  May return null if there
    * isn't one
    */
@@ -1065,16 +1068,18 @@ protected:
   // nothing if there is no such element.
   void GetTitleFromElement(uint32_t aNodeType, nsAString& aTitle);
 
   nsresult doCreateShell(nsPresContext* aContext,
                          nsIViewManager* aViewManager, nsStyleSet* aStyleSet,
                          nsCompatibility aCompatMode,
                          nsIPresShell** aInstancePtrResult);
 
+  void RemoveStyleSheetsFromStyleSets(nsCOMArray<nsIStyleSheet>& aSheets, 
+                                      nsStyleSet::sheetType aType);
   nsresult ResetStylesheetsToURI(nsIURI* aURI);
   void FillStyleSet(nsStyleSet* aStyleSet);
 
   // Return whether all the presshells for this document are safe to flush
   bool IsSafeToFlush() const;
   
   void DispatchPageTransition(nsIDOMEventTarget* aDispatchTarget,
                               const nsAString& aType,
@@ -1114,16 +1119,17 @@ protected:
 
   // Weak reference to our sink for in case we no longer have a parser.  This
   // will allow us to flush out any pending stuff from the sink even if
   // EndLoad() has already happened.
   nsWeakPtr mWeakSink;
 
   nsCOMArray<nsIStyleSheet> mStyleSheets;
   nsCOMArray<nsIStyleSheet> mCatalogSheets;
+  nsCOMArray<nsIStyleSheet> mAdditionalSheets[2];
 
   // Array of observers
   nsTObserverArray<nsIDocumentObserver*> mObservers;
 
   // If document is created for example using
   // document.implementation.createDocument(...), mScriptObject points to
   // the script global object of the original document.
   nsWeakPtr mScriptObject;
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -717,16 +717,17 @@ GK_ATOM(onmouseout, "onmouseout")
 GK_ATOM(onmouseover, "onmouseover")
 GK_ATOM(onMozMouseHittest, "onMozMouseHittest")
 GK_ATOM(onmouseup, "onmouseup")
 GK_ATOM(onMozAfterPaint, "onMozAfterPaint")
 GK_ATOM(onmozfullscreenchange, "onmozfullscreenchange")
 GK_ATOM(onmozfullscreenerror, "onmozfullscreenerror")
 GK_ATOM(onmozpointerlockchange, "onmozpointerlockchange")
 GK_ATOM(onmozpointerlockerror, "onmozpointerlockerror")
+GK_ATOM(onmoztimechange, "onmoztimechange")
 GK_ATOM(onMozMousePixelScroll, "onMozMousePixelScroll")
 GK_ATOM(onMozScrolledAreaChanged, "onMozScrolledAreaChanged")
 GK_ATOM(onnoupdate, "onnoupdate")
 GK_ATOM(onobsolete, "onobsolete")
 GK_ATOM(ononline, "ononline")
 GK_ATOM(onoffline, "onoffline")
 GK_ATOM(onopen, "onopen")
 GK_ATOM(onoverflow, "onoverflow")
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -953,17 +953,17 @@ nsXMLHttpRequest::StaticAssertions()
   ASSERT_ENUM_EQUAL(Moz_blob, MOZ_BLOB);
 #undef ASSERT_ENUM_EQUAL
 }
 #endif
 
 /* attribute AString responseType; */
 NS_IMETHODIMP nsXMLHttpRequest::SetResponseType(const nsAString& aResponseType)
 {
-  nsXMLHttpRequest::ResponseType responseType;
+  nsXMLHttpRequest::ResponseTypeEnum responseType;
   if (aResponseType.IsEmpty()) {
     responseType = XML_HTTP_RESPONSE_TYPE_DEFAULT;
   } else if (aResponseType.EqualsLiteral("arraybuffer")) {
     responseType = XML_HTTP_RESPONSE_TYPE_ARRAYBUFFER;
   } else if (aResponseType.EqualsLiteral("blob")) {
     responseType = XML_HTTP_RESPONSE_TYPE_BLOB;
   } else if (aResponseType.EqualsLiteral("document")) {
     responseType = XML_HTTP_RESPONSE_TYPE_DOCUMENT;
@@ -985,21 +985,21 @@ NS_IMETHODIMP nsXMLHttpRequest::SetRespo
   SetResponseType(responseType, rv);
   return rv.ErrorCode();
 }
 
 void
 nsXMLHttpRequest::SetResponseType(XMLHttpRequestResponseType aType,
                                   ErrorResult& aRv)
 {
-  SetResponseType(ResponseType(aType), aRv);
+  SetResponseType(ResponseTypeEnum(aType), aRv);
 }
 
 void
-nsXMLHttpRequest::SetResponseType(nsXMLHttpRequest::ResponseType aResponseType,
+nsXMLHttpRequest::SetResponseType(nsXMLHttpRequest::ResponseTypeEnum aResponseType,
                                   ErrorResult& aRv)
 {
   // If the state is not OPENED or HEADERS_RECEIVED raise an
   // INVALID_STATE_ERR exception and terminate these steps.
   if (!(mState & (XML_HTTP_REQUEST_OPENED | XML_HTTP_REQUEST_SENT |
                   XML_HTTP_REQUEST_HEADERS_RECEIVED))) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
@@ -1151,22 +1151,22 @@ nsXMLHttpRequest::GetResponse(JSContext*
 
   return JSVAL_NULL;
 }
 
 /* readonly attribute unsigned long status; */
 NS_IMETHODIMP
 nsXMLHttpRequest::GetStatus(uint32_t *aStatus)
 {
-  *aStatus = GetStatus();
+  *aStatus = Status();
   return NS_OK;
 }
 
 uint32_t
-nsXMLHttpRequest::GetStatus()
+nsXMLHttpRequest::Status()
 {
   if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {
     // Make sure we don't leak status information from denied cross-site
     // requests.
     if (mChannel) {
       nsresult status;
       mChannel->GetStatus(&status);
       if (NS_FAILED(status)) {
@@ -3171,17 +3171,17 @@ nsXMLHttpRequest::SetRequestHeader(const
   }
   return rv;
 }
 
 /* attribute unsigned long timeout; */
 NS_IMETHODIMP
 nsXMLHttpRequest::GetTimeout(uint32_t *aTimeout)
 {
-  *aTimeout = GetTimeout();
+  *aTimeout = Timeout();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXMLHttpRequest::SetTimeout(uint32_t aTimeout)
 {
   ErrorResult rv;
   SetTimeout(aTimeout, rv);
@@ -3235,22 +3235,22 @@ nsXMLHttpRequest::StartTimeoutTimer()
     nsITimer::TYPE_ONE_SHOT
   );
 }
 
 /* readonly attribute unsigned short readyState; */
 NS_IMETHODIMP
 nsXMLHttpRequest::GetReadyState(uint16_t *aState)
 {
-  *aState = GetReadyState();
+  *aState = ReadyState();
   return NS_OK;
 }
 
 uint16_t
-nsXMLHttpRequest::GetReadyState()
+nsXMLHttpRequest::ReadyState()
 {
   // Translate some of our internal states for external consumers
   if (mState & XML_HTTP_REQUEST_UNSENT) {
     return UNSENT;
   }
   if (mState & (XML_HTTP_REQUEST_OPENED | XML_HTTP_REQUEST_SENT)) {
     return OPENED;
   }
@@ -3271,22 +3271,22 @@ nsXMLHttpRequest::SlowOverrideMimeType(c
   OverrideMimeType(aMimeType);
   return NS_OK;
 }
 
 /* attribute boolean multipart; */
 NS_IMETHODIMP
 nsXMLHttpRequest::GetMultipart(bool *_retval)
 {
-  *_retval = GetMultipart();
+  *_retval = Multipart();
   return NS_OK;
 }
 
 bool
-nsXMLHttpRequest::GetMultipart()
+nsXMLHttpRequest::Multipart()
 {
   return !!(mState & XML_HTTP_REQUEST_MULTIPART);
 }
 
 NS_IMETHODIMP
 nsXMLHttpRequest::SetMultipart(bool aMultipart)
 {
   nsresult rv = NS_OK;
@@ -3309,22 +3309,22 @@ nsXMLHttpRequest::SetMultipart(bool aMul
     mState &= ~XML_HTTP_REQUEST_MULTIPART;
   }
 }
 
 /* attribute boolean mozBackgroundRequest; */
 NS_IMETHODIMP
 nsXMLHttpRequest::GetMozBackgroundRequest(bool *_retval)
 {
-  *_retval = GetMozBackgroundRequest();
+  *_retval = MozBackgroundRequest();
   return NS_OK;
 }
 
 bool
-nsXMLHttpRequest::GetMozBackgroundRequest()
+nsXMLHttpRequest::MozBackgroundRequest()
 {
   return !!(mState & XML_HTTP_REQUEST_BACKGROUND);
 }
 
 NS_IMETHODIMP
 nsXMLHttpRequest::SetMozBackgroundRequest(bool aMozBackgroundRequest)
 {
   nsresult rv = NS_OK;
@@ -3358,22 +3358,22 @@ nsXMLHttpRequest::SetMozBackgroundReques
     mState &= ~XML_HTTP_REQUEST_BACKGROUND;
   }
 }
 
 /* attribute boolean withCredentials; */
 NS_IMETHODIMP
 nsXMLHttpRequest::GetWithCredentials(bool *_retval)
 {
-  *_retval = GetWithCredentials();
+  *_retval = WithCredentials();
   return NS_OK;
 }
 
 bool
-nsXMLHttpRequest::GetWithCredentials()
+nsXMLHttpRequest::WithCredentials()
 {
   return !!(mState & XML_HTTP_REQUEST_AC_WITH_CREDENTIALS);
 }
 
 NS_IMETHODIMP
 nsXMLHttpRequest::SetWithCredentials(bool aWithCredentials)
 {
   nsresult rv = NS_OK;
@@ -3771,55 +3771,55 @@ nsXMLHttpRequest::GetInterface(JSContext
   NS_ENSURE_FALSE(aRv.Failed(), JSVAL_NULL);
 
   JSObject* global = JS_GetGlobalForObject(aCx, GetWrapper());
   aRv = nsContentUtils::WrapNative(aCx, global, result, iid, &v);
   return aRv.Failed() ? JSVAL_NULL : v;
 }
 
 nsXMLHttpRequestUpload*
-nsXMLHttpRequest::GetUpload()
+nsXMLHttpRequest::Upload()
 {
   if (!mUpload) {
     mUpload = new nsXMLHttpRequestUpload(this);
   }
   return mUpload;
 }
 
 NS_IMETHODIMP
 nsXMLHttpRequest::GetUpload(nsIXMLHttpRequestUpload** aUpload)
 {
-  nsRefPtr<nsXMLHttpRequestUpload> upload = GetUpload();
+  nsRefPtr<nsXMLHttpRequestUpload> upload = Upload();
   upload.forget(aUpload);
   return NS_OK;
 }
 
 bool
-nsXMLHttpRequest::GetMozAnon()
+nsXMLHttpRequest::MozAnon()
 {
   return mIsAnon;
 }
 
 NS_IMETHODIMP
 nsXMLHttpRequest::GetMozAnon(bool* aAnon)
 {
-  *aAnon = GetMozAnon();
+  *aAnon = MozAnon();
   return NS_OK;
 }
 
 bool
-nsXMLHttpRequest::GetMozSystem()
+nsXMLHttpRequest::MozSystem()
 {
   return IsSystemXHR();
 }
 
 NS_IMETHODIMP
 nsXMLHttpRequest::GetMozSystem(bool* aSystem)
 {
-  *aSystem = GetMozSystem();
+  *aSystem = MozSystem();
   return NS_OK;
 }
 
 void
 nsXMLHttpRequest::HandleTimeoutCallback()
 {
   if (mState & XML_HTTP_REQUEST_DONE) {
     NS_NOTREACHED("nsXMLHttpRequest::HandleTimeoutCallback with completed request");
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -36,16 +36,22 @@
 #include "nsIScriptObjectPrincipal.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/TypedArray.h"
 #include "mozilla/dom/XMLHttpRequestBinding.h"
 #include "mozilla/dom/XMLHttpRequestUploadBinding.h"
 
+#ifdef Status
+/* Xlib headers insist on this for some reason... Nuke it because
+   it'll override our member name */
+#undef Status
+#endif
+
 class nsILoadGroup;
 class AsyncVerifyRedirectCallbackForwarder;
 class nsIUnicodeDecoder;
 class nsIDOMFormData;
 
 #define IMPL_EVENT_HANDLER(_lowercase)                                  \
   inline JSObject* GetOn##_lowercase(JSContext* aCx)                    \
   {                                                                     \
@@ -231,41 +237,41 @@ public:
 #ifdef DEBUG
   void StaticAssertions();
 #endif
 
   // event handler
   IMPL_EVENT_HANDLER(readystatechange)
 
   // states
-  uint16_t GetReadyState();
+  uint16_t ReadyState();
 
   // request
   void Open(const nsAString& aMethod, const nsAString& aUrl, bool aAsync,
             const mozilla::dom::Optional<nsAString>& aUser,
             const mozilla::dom::Optional<nsAString>& aPassword,
             ErrorResult& aRv)
   {
     aRv = Open(NS_ConvertUTF16toUTF8(aMethod), NS_ConvertUTF16toUTF8(aUrl),
                aAsync, aUser, aPassword);
   }
   void SetRequestHeader(const nsAString& aHeader, const nsAString& aValue,
                         ErrorResult& aRv)
   {
     aRv = SetRequestHeader(NS_ConvertUTF16toUTF8(aHeader),
                            NS_ConvertUTF16toUTF8(aValue));
   }
-  uint32_t GetTimeout()
+  uint32_t Timeout()
   {
     return mTimeoutMilliseconds;
   }
   void SetTimeout(uint32_t aTimeout, ErrorResult& aRv);
-  bool GetWithCredentials();
+  bool WithCredentials();
   void SetWithCredentials(bool aWithCredentials, nsresult& aRv);
-  nsXMLHttpRequestUpload* GetUpload();
+  nsXMLHttpRequestUpload* Upload();
 
 private:
   class RequestBody
   {
   public:
     RequestBody() : mType(Uninitialized)
     {
     }
@@ -382,17 +388,17 @@ public:
     NS_ASSERTION(aStream, "Null should go to string version");
     aRv = Send(RequestBody(aStream));
   }
   void SendAsBinary(const nsAString& aBody, ErrorResult& aRv);
 
   void Abort();
 
   // response
-  uint32_t GetStatus();
+  uint32_t Status();
   void GetStatusText(nsString& aStatusText);
   void GetResponseHeader(const nsACString& aHeader, nsACString& aResult,
                          ErrorResult& aRv);
   void GetResponseHeader(const nsAString& aHeader, nsString& aResult,
                          ErrorResult& aRv)
   {
     nsCString result;
     GetResponseHeader(NS_ConvertUTF16toUTF8(aHeader), result, aRv);
@@ -408,32 +414,32 @@ public:
     }
   }
   void GetAllResponseHeaders(nsString& aResponseHeaders);
   void OverrideMimeType(const nsAString& aMimeType)
   {
     // XXX Should we do some validation here?
     mOverrideMimeType = aMimeType;
   }
-  XMLHttpRequestResponseType GetResponseType()
+  XMLHttpRequestResponseType ResponseType()
   {
     return XMLHttpRequestResponseType(mResponseType);
   }
   void SetResponseType(XMLHttpRequestResponseType aType, ErrorResult& aRv);
   JS::Value GetResponse(JSContext* aCx, ErrorResult& aRv);
   void GetResponseText(nsString& aResponseText, ErrorResult& aRv);
   nsIDocument* GetResponseXML(ErrorResult& aRv);
 
-  bool GetMozBackgroundRequest();
+  bool MozBackgroundRequest();
   void SetMozBackgroundRequest(bool aMozBackgroundRequest, nsresult& aRv);
-  bool GetMultipart();
+  bool Multipart();
   void SetMultipart(bool aMultipart, nsresult& aRv);
 
-  bool GetMozAnon();
-  bool GetMozSystem();
+  bool MozAnon();
+  bool MozSystem();
 
   nsIChannel* GetChannel()
   {
     return mChannel;
   }
 
   // We need a GetInterface callable from JS for chrome JS
   JS::Value GetInterface(JSContext* aCx, nsIJSIID* aIID, ErrorResult& aRv);
@@ -569,31 +575,31 @@ protected:
   // In cases where we've only received half a surrogate, the decoder itself
   // carries the state to remember this. Next time we receive more data we
   // simply feed the new data into the decoder which will handle the second
   // part of the surrogate.
   nsCOMPtr<nsIUnicodeDecoder> mDecoder;
 
   nsCString mResponseCharset;
 
-  enum ResponseType {
+  enum ResponseTypeEnum {
     XML_HTTP_RESPONSE_TYPE_DEFAULT,
     XML_HTTP_RESPONSE_TYPE_ARRAYBUFFER,
     XML_HTTP_RESPONSE_TYPE_BLOB,
     XML_HTTP_RESPONSE_TYPE_DOCUMENT,
     XML_HTTP_RESPONSE_TYPE_JSON,
     XML_HTTP_RESPONSE_TYPE_TEXT,
     XML_HTTP_RESPONSE_TYPE_CHUNKED_TEXT,
     XML_HTTP_RESPONSE_TYPE_CHUNKED_ARRAYBUFFER,
     XML_HTTP_RESPONSE_TYPE_MOZ_BLOB
   };
 
-  void SetResponseType(nsXMLHttpRequest::ResponseType aType, ErrorResult& aRv);
+  void SetResponseType(nsXMLHttpRequest::ResponseTypeEnum aType, ErrorResult& aRv);
 
-  ResponseType mResponseType;
+  ResponseTypeEnum mResponseType;
 
   // It is either a cached blob-response from the last call to GetResponse,
   // but is also explicitly set in OnStopRequest.
   nsCOMPtr<nsIDOMBlob> mResponseBlob;
   // Non-null only when we are able to get a os-file representation of the
   // response, i.e. when loading from a file, or when the http-stream
   // caches into a file or is reading from a cached file.
   nsRefPtr<nsDOMFile> mDOMFile;
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -1524,25 +1524,25 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLExt
 NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLExtension)
 
 DOMCI_DATA(WebGLExtension, WebGLExtension)
 
 /* readonly attribute WebGLsizei drawingBufferWidth; */
 NS_IMETHODIMP
 WebGLContext::GetDrawingBufferWidth(WebGLsizei *aWidth)
 {
-    *aWidth = GetDrawingBufferWidth();
+    *aWidth = DrawingBufferWidth();
     return NS_OK;
 }
 
 /* readonly attribute WebGLsizei drawingBufferHeight; */
 NS_IMETHODIMP
 WebGLContext::GetDrawingBufferHeight(WebGLsizei *aHeight)
 {
-    *aHeight = GetDrawingBufferHeight();
+    *aHeight = DrawingBufferHeight();
     return NS_OK;
 }
 
 /* [noscript] attribute WebGLint location; */
 NS_IMETHODIMP
 WebGLUniformLocation::GetLocation(WebGLint *aLocation)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -600,22 +600,22 @@ public:
             mContextLossTimerRunning = false;
         }
     }
 
     // WebIDL WebGLRenderingContext API
     nsHTMLCanvasElement* GetCanvas() const {
         return mCanvasElement;
     }
-    WebGLsizei GetDrawingBufferWidth() const {
+    WebGLsizei DrawingBufferWidth() const {
         if (!IsContextStable())
             return 0;
         return mWidth;
     }
-    WebGLsizei GetDrawingBufferHeight() const {
+    WebGLsizei DrawingBufferHeight() const {
         if (!IsContextStable())
             return 0;
         return mHeight;
     }
         
     JSObject *GetContextAttributes(ErrorResult &rv);
     bool IsContextLost() const { return !IsContextStable(); }
     void GetSupportedExtensions(dom::Nullable< nsTArray<nsString> > &retval);
@@ -1120,16 +1120,25 @@ protected:
     int32_t mGLMaxTextureSize;
     int32_t mGLMaxCubeMapTextureSize;
     int32_t mGLMaxTextureImageUnits;
     int32_t mGLMaxVertexTextureImageUnits;
     int32_t mGLMaxVaryingVectors;
     int32_t mGLMaxFragmentUniformVectors;
     int32_t mGLMaxVertexUniformVectors;
 
+    // Cache the max number of elements that can be read from bound VBOs
+    // (result of ValidateBuffers).
+    int32_t mMinInUseAttribArrayLength;
+
+    inline void InvalidateCachedMinInUseAttribArrayLength()
+    {
+        mMinInUseAttribArrayLength = -1;
+    }
+
     // Represents current status, or state, of the context. That is, is it lost
     // or stable and what part of the context lost process are we currently at.
     // This is used to support the WebGL spec's asyncronous nature in handling
     // context loss.
     enum ContextStatus {
         // The context is stable; there either are none or we don't know of any.
         ContextStable,
         // The context has been lost, but we have not yet sent an event to the
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -476,16 +476,17 @@ WebGLContext::BufferData(WebGLenum targe
     BufferData(target, WebGLsizeiptr(size), usage);
     return NS_OK;
 }
 
 void
 WebGLContext::BufferData(WebGLenum target, WebGLsizeiptr size,
                          WebGLenum usage)
 {
+    InvalidateCachedMinInUseAttribArrayLength();
     if (!IsContextStable())
         return;
 
     WebGLBuffer *boundBuffer = NULL;
 
     if (target == LOCAL_GL_ARRAY_BUFFER) {
         boundBuffer = mBoundArrayBuffer;
     } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
@@ -515,16 +516,17 @@ WebGLContext::BufferData(WebGLenum targe
     boundBuffer->InvalidateCachedMaxElements();
     if (!boundBuffer->ZeroDataIfElementArray())
         return ErrorOutOfMemory("bufferData: out of memory");
 }
 
 void
 WebGLContext::BufferData(WebGLenum target, ArrayBuffer *data, WebGLenum usage)
 {
+    InvalidateCachedMinInUseAttribArrayLength();
     if (!IsContextStable())
         return;
 
     if (!data) {
         // see http://www.khronos.org/bugzilla/show_bug.cgi?id=386
         return ErrorInvalidValue("bufferData: null object passed");
     }
 
@@ -557,16 +559,17 @@ WebGLContext::BufferData(WebGLenum targe
     boundBuffer->InvalidateCachedMaxElements();
     if (!boundBuffer->CopyDataIfElementArray(data->Data()))
         return ErrorOutOfMemory("bufferData: out of memory");
 }
 
 void
 WebGLContext::BufferData(WebGLenum target, ArrayBufferView& data, WebGLenum usage)
 {
+    InvalidateCachedMinInUseAttribArrayLength();
     if (!IsContextStable())
         return;
 
     WebGLBuffer *boundBuffer = NULL;
 
     if (target == LOCAL_GL_ARRAY_BUFFER) {
         boundBuffer = mBoundArrayBuffer;
     } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
@@ -1489,16 +1492,17 @@ WebGLContext::MozDisableVertexAttribArra
 {
     DisableVertexAttribArray(index);
     return NS_OK;
 }
 
 void
 WebGLContext::DisableVertexAttribArray(WebGLuint index)
 {
+    InvalidateCachedMinInUseAttribArrayLength();
     if (!IsContextStable())
         return;
 
     if (!ValidateAttribIndex(index, "disableVertexAttribArray"))
         return;
 
     MakeContextCurrent();
 
@@ -1971,16 +1975,17 @@ WebGLContext::MozEnableVertexAttribArray
 {
     EnableVertexAttribArray(index);
     return NS_OK;
 }
 
 void
 WebGLContext::EnableVertexAttribArray(WebGLuint index)
 {
+    InvalidateCachedMinInUseAttribArrayLength();
     if (!IsContextStable())
         return;
 
     if (!ValidateAttribIndex(index, "enableVertexAttribArray"))
         return;
 
     MakeContextCurrent();
 
@@ -3696,16 +3701,17 @@ WebGLContext::LinkProgram(nsIWebGLProgra
     ErrorResult rv;
     LinkProgram(static_cast<WebGLProgram*>(pobj), rv);
     return rv.ErrorCode();
 }
 
 void
 WebGLContext::LinkProgram(WebGLProgram *program, ErrorResult& rv)
 {
+    InvalidateCachedMinInUseAttribArrayLength();
     if (!IsContextStable())
         return;
 
     if (!ValidateObject("linkProgram", program))
         return;
 
     GLuint progname = program->GLName();
 
@@ -4823,16 +4829,17 @@ WebGLContext::UseProgram(nsIWebGLProgram
 {
     UseProgram(static_cast<WebGLProgram*>(pobj));
     return NS_OK;
 }
 
 void
 WebGLContext::UseProgram(WebGLProgram *prog)
 {
+    InvalidateCachedMinInUseAttribArrayLength();
     if (!IsContextStable())
         return;
 
     if (!ValidateObjectAllowNull("useProgram", prog))
         return;
 
     WebGLuint progname = prog ? prog->GLName() : 0;;
     MakeContextCurrent();
@@ -5490,16 +5497,17 @@ WebGLContext::MozVertexAttribPointer(Web
     return NS_OK;
 }
 
 void
 WebGLContext::VertexAttribPointer(WebGLuint index, WebGLint size, WebGLenum type,
                                   WebGLboolean normalized, WebGLsizei stride,
                                   WebGLintptr byteOffset)
 {
+    InvalidateCachedMinInUseAttribArrayLength();
     if (!IsContextStable())
         return;
 
     if (mBoundArrayBuffer == nullptr)
         return ErrorInvalidOperation("vertexAttribPointer: must have valid GL_ARRAY_BUFFER binding");
 
     WebGLsizei requiredAlignment = 1;
     switch (type) {
--- a/content/canvas/src/WebGLContextValidate.cpp
+++ b/content/canvas/src/WebGLContextValidate.cpp
@@ -78,16 +78,21 @@ WebGLContext::ValidateBuffers(int32_t *m
     MakeContextCurrent();
     gl->fGetIntegerv(LOCAL_GL_CURRENT_PROGRAM, &currentProgram);
     NS_ASSERTION(GLuint(currentProgram) == mCurrentProgram->GLName(),
                  "WebGL: current program doesn't agree with GL state");
     if (GLuint(currentProgram) != mCurrentProgram->GLName())
         return false;
 #endif
 
+    if (mMinInUseAttribArrayLength != -1) {
+        *maxAllowedCount = mMinInUseAttribArrayLength;
+        return true;
+    }
+
     *maxAllowedCount = -1;
 
     uint32_t attribs = mAttribBuffers.Length();
     for (uint32_t i = 0; i < attribs; ++i) {
         const WebGLVertexAttribData& vd = mAttribBuffers[i];
 
         // If the attrib array isn't enabled, there's nothing to check;
         // it's a static value.
@@ -127,17 +132,17 @@ WebGLContext::ValidateBuffers(int32_t *m
             ErrorInvalidOperation("%s: integer overflow occured while checking vertex attrib %d", info, i);
             return false;
           }
 
           if (*maxAllowedCount == -1 || *maxAllowedCount > checked_maxAllowedCount.value())
               *maxAllowedCount = checked_maxAllowedCount.value();
         }
     }
-
+    mMinInUseAttribArrayLength = *maxAllowedCount;
     return true;
 }
 
 bool WebGLContext::ValidateCapabilityEnum(WebGLenum cap, const char *info)
 {
     switch (cap) {
         case LOCAL_GL_BLEND:
         case LOCAL_GL_CULL_FACE:
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -1449,17 +1449,17 @@ nsCanvasRenderingContext2DAzure::SetGlob
 {
   SetGlobalAlpha((double)aGlobalAlpha);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetGlobalAlpha(float *aGlobalAlpha)
 {
-  *aGlobalAlpha = GetGlobalAlpha();
+  *aGlobalAlpha = GlobalAlpha();
   return NS_OK;
 }
 
 void
 nsCanvasRenderingContext2DAzure::SetStyleFromJSValue(JSContext* cx,
                                                      JS::Value& value,
                                                      Style whichStyle)
 {
@@ -1896,45 +1896,45 @@ nsCanvasRenderingContext2DAzure::SetShad
 {
   SetShadowOffsetX((double)x);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetShadowOffsetX(float *x)
 {
-  *x = static_cast<float>(GetShadowOffsetX());
+  *x = static_cast<float>(ShadowOffsetX());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetShadowOffsetY(float y)
 {
   SetShadowOffsetY((double)y);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetShadowOffsetY(float *y)
 {
-  *y = static_cast<float>(GetShadowOffsetY());
+  *y = static_cast<float>(ShadowOffsetY());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetShadowBlur(float blur)
 {
   SetShadowBlur((double)blur);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetShadowBlur(float *blur)
 {
-  *blur = GetShadowBlur();
+  *blur = ShadowBlur();
   return NS_OK;
 }
 
 void
 nsCanvasRenderingContext2DAzure::SetShadowColor(const nsAString& shadowColor)
 {
   nscolor color;
   if (!ParseColor(shadowColor, &color)) {
@@ -3404,17 +3404,17 @@ nsCanvasRenderingContext2DAzure::SetLine
 {
   SetLineWidth((double)width);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetLineWidth(float *width)
 {
-  *width = GetLineWidth();
+  *width = LineWidth();
   return NS_OK;
 }
 
 void
 nsCanvasRenderingContext2DAzure::SetLineCap(const nsAString& capstyle)
 {
   CapStyle cap;
 
@@ -3523,17 +3523,17 @@ nsCanvasRenderingContext2DAzure::SetMite
 {
   SetMiterLimit((double)miter);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetMiterLimit(float *miter)
 {
-  *miter = GetMiterLimit();
+  *miter = MiterLimit();
   return NS_OK;
 }
 
 void
 nsCanvasRenderingContext2DAzure::SetMozDash(JSContext* cx,
                                             const JS::Value& mozDash,
                                             ErrorResult& error)
 {
@@ -3583,17 +3583,17 @@ nsCanvasRenderingContext2DAzure::SetMozD
     state.dashOffset = offset;
   }
   return NS_OK;
 }
  
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetMozDashOffset(float* offset)
 {
-  *offset = GetMozDashOffset();
+  *offset = MozDashOffset();
   return NS_OK;
 }
 
 bool
 nsCanvasRenderingContext2DAzure::IsPointInPath(double x, double y)
 {
   if (!FloatValidate(x,y)) {
     return false;
@@ -4601,17 +4601,17 @@ nsCanvasRenderingContext2DAzure::CreateI
 {
   /* Should never be called; handled entirely in new bindings */
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetMozImageSmoothingEnabled(bool *retVal)
 {
-  *retVal = GetImageSmoothingEnabled();
+  *retVal = ImageSmoothingEnabled();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetMozImageSmoothingEnabled(bool val)
 {
   SetImageSmoothingEnabled(val);
   return NS_OK;
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.h
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.h
@@ -151,17 +151,17 @@ public:
   void Scale(double x, double y, mozilla::ErrorResult& error);
   void Rotate(double angle, mozilla::ErrorResult& error);
   void Translate(double x, double y, mozilla::ErrorResult& error);
   void Transform(double m11, double m12, double m21, double m22, double dx,
                  double dy, mozilla::ErrorResult& error);
   void SetTransform(double m11, double m12, double m21, double m22, double dx,
                     double dy, mozilla::ErrorResult& error);
 
-  double GetGlobalAlpha()
+  double GlobalAlpha()
   {
     return CurrentState().globalAlpha;
   }
 
   void SetGlobalAlpha(double globalAlpha)
   {
     if (mozilla::CanvasUtils::FloatValidate(globalAlpha) &&
         globalAlpha >= 0.0 && globalAlpha <= 1.0) {
@@ -191,41 +191,41 @@ public:
                          mozilla::ErrorResult& aError);
   already_AddRefed<nsIDOMCanvasGradient>
     CreateRadialGradient(double x0, double y0, double r0, double x1, double y1,
                          double r1, mozilla::ErrorResult& aError);
   already_AddRefed<nsIDOMCanvasPattern>
     CreatePattern(const HTMLImageOrCanvasOrVideoElement& element,
                   const nsAString& repeat, mozilla::ErrorResult& error);
 
-  double GetShadowOffsetX()
+  double ShadowOffsetX()
   {
     return CurrentState().shadowOffset.x;
   }
 
   void SetShadowOffsetX(double shadowOffsetX)
   {
     if (mozilla::CanvasUtils::FloatValidate(shadowOffsetX)) {
       CurrentState().shadowOffset.x = shadowOffsetX;
     }
   }
 
-  double GetShadowOffsetY()
+  double ShadowOffsetY()
   {
     return CurrentState().shadowOffset.y;
   }
 
   void SetShadowOffsetY(double shadowOffsetY)
   {
     if (mozilla::CanvasUtils::FloatValidate(shadowOffsetY)) {
       CurrentState().shadowOffset.y = shadowOffsetY;
     }
   }
 
-  double GetShadowBlur()
+  double ShadowBlur()
   {
     return CurrentState().shadowBlur;
   }
 
   void SetShadowBlur(double shadowBlur)
   {
     if (mozilla::CanvasUtils::FloatValidate(shadowBlur) && shadowBlur >= 0.0) {
       CurrentState().shadowBlur = shadowBlur;
@@ -296,33 +296,33 @@ public:
                  mozilla::ErrorResult& error);
   void PutImageData(JSContext* cx, mozilla::dom::ImageData* imageData,
                     double dx, double dy, mozilla::ErrorResult& error);
   void PutImageData(JSContext* cx, mozilla::dom::ImageData* imageData,
                     double dx, double dy, double dirtyX, double dirtyY,
                     double dirtyWidth, double dirtyHeight,
                     mozilla::ErrorResult& error);
 
-  double GetLineWidth()
+  double LineWidth()
   {
     return CurrentState().lineWidth;
   }
 
   void SetLineWidth(double width)
   {
     if (mozilla::CanvasUtils::FloatValidate(width) && width > 0.0) {
       CurrentState().lineWidth = width;
     }
   }
   void GetLineCap(nsAString& linecap);
   void SetLineCap(const nsAString& linecap);
   void GetLineJoin(nsAString& linejoin, mozilla::ErrorResult& error);
   void SetLineJoin(const nsAString& linejoin);
 
-  double GetMiterLimit()
+  double MiterLimit()
   {
     return CurrentState().miterLimit;
   }
 
   void SetMiterLimit(double miter)
   {
     if (mozilla::CanvasUtils::FloatValidate(miter) && miter > 0.0) {
       CurrentState().miterLimit = miter;
@@ -418,17 +418,17 @@ public:
   void SetMozCurrentTransformInverse(JSContext* cx, JSObject& currentTransform, 
                                      mozilla::ErrorResult& error);
   void GetFillRule(nsAString& fillRule);
   void SetFillRule(const nsAString& fillRule);
   JS::Value GetMozDash(JSContext* cx, mozilla::ErrorResult& error);
   void SetMozDash(JSContext* cx, const JS::Value& mozDash,
                   mozilla::ErrorResult& error);
 
-  double GetMozDashOffset()
+  double MozDashOffset()
   {
     return CurrentState().dashOffset;
   }
 
   void SetMozDashOffset(double mozDashOffset, mozilla::ErrorResult& error);
 
   void GetMozTextStyle(nsAString& mozTextStyle)
   {
@@ -436,17 +436,17 @@ public:
   }
 
   void SetMozTextStyle(const nsAString& mozTextStyle,
                        mozilla::ErrorResult& error)
   {
     SetFont(mozTextStyle, error);
   }
 
-  bool GetImageSmoothingEnabled()
+  bool ImageSmoothingEnabled()
   {
     return CurrentState().imageSmoothingEnabled;
   }
 
   void SetImageSmoothingEnabled(bool imageSmoothingEnabled)
   {
     if (imageSmoothingEnabled != CurrentState().imageSmoothingEnabled) {
       CurrentState().imageSmoothingEnabled = imageSmoothingEnabled;
--- a/content/events/public/nsEventNameList.h
+++ b/content/events/public/nsEventNameList.h
@@ -458,16 +458,20 @@ WINDOW_ONLY_EVENT(deviceproximity,
 WINDOW_ONLY_EVENT(userproximity,
                   NS_USER_PROXIMITY,
                   EventNameType_None,
                   NS_EVENT)
 WINDOW_ONLY_EVENT(devicelight,
                   NS_DEVICE_LIGHT,
                   EventNameType_None,
                   NS_EVENT)
+WINDOW_ONLY_EVENT(moztimechange,
+                  NS_MOZ_TIME_CHANGE_EVENT,
+                  EventNameType_None,
+                  NS_EVENT)
 
 TOUCH_EVENT(touchstart,
             NS_TOUCH_START,
             EventNameType_All,
             NS_TOUCH_EVENT)
 TOUCH_EVENT(touchend,
             NS_TOUCH_END,
             EventNameType_All,
--- a/content/events/src/nsDOMEventTargetHelper.h
+++ b/content/events/src/nsDOMEventTargetHelper.h
@@ -105,17 +105,17 @@ public:
       }
     }
     return NS_OK;
   }
 
   void BindToOwner(nsPIDOMWindow* aOwner);
   void BindToOwner(nsDOMEventTargetHelper* aOther);
   virtual void DisconnectFromOwner();                   
-  nsPIDOMWindow* GetOwner() { return mOwner; }
+  nsPIDOMWindow* GetOwner() const { return mOwner; }
   bool HasOrHasHadOwner() { return mHasOrHasHadOwner; }
 protected:
   nsRefPtr<nsEventListenerManager> mListenerManager;
 private:
   // These may be null (native callers or xpcshell).
   nsPIDOMWindow*             mOwner; // Inner window.
   bool                       mHasOrHasHadOwner;
 };
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -49,16 +49,17 @@
 #include "nsDOMScriptObjectHolder.h"
 #include "nsDataHashtable.h"
 #include "nsCOMArray.h"
 #include "nsEventListenerService.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsJSEnvironment.h"
 #include "xpcpublic.h"
 #include "nsSandboxFlags.h"
+#include "TimeChangeObserver.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::hal;
 
 #define EVENT_TYPE_EQUALS( ls, type, userType ) \
   (ls->mEventType == type && \
   (ls->mEventType != NS_USER_DEFINED_EVENT || ls->mTypeAtom == userType))
 
@@ -271,16 +272,18 @@ nsEventListenerManager::AddEventListener
   } else if (aTypeAtom == nsGkAtoms::ondeviceorientation) {
     EnableDevice(NS_DEVICE_ORIENTATION);
   } else if (aTypeAtom == nsGkAtoms::ondeviceproximity || aTypeAtom == nsGkAtoms::onuserproximity) {
     EnableDevice(NS_DEVICE_PROXIMITY);
   } else if (aTypeAtom == nsGkAtoms::ondevicelight) {
     EnableDevice(NS_DEVICE_LIGHT);
   } else if (aTypeAtom == nsGkAtoms::ondevicemotion) {
     EnableDevice(NS_DEVICE_MOTION);
+  } else if (aTypeAtom == nsGkAtoms::onmoztimechange) {
+    EnableTimeChangeNotifications();
   } else if ((aType >= NS_MOZTOUCH_DOWN && aType <= NS_MOZTOUCH_UP) ||
              (aTypeAtom == nsGkAtoms::ontouchstart ||
               aTypeAtom == nsGkAtoms::ontouchend ||
               aTypeAtom == nsGkAtoms::ontouchmove ||
               aTypeAtom == nsGkAtoms::ontouchenter ||
               aTypeAtom == nsGkAtoms::ontouchleave ||
               aTypeAtom == nsGkAtoms::ontouchcancel)) {
     mMayHaveTouchEventListener = true;
@@ -396,39 +399,42 @@ nsEventListenerManager::RemoveEventListe
   }
 
   nsListenerStruct* ls;
   aFlags &= ~NS_PRIV_EVENT_UNTRUSTED_PERMITTED;
 
   uint32_t count = mListeners.Length();
   uint32_t typeCount = 0;
   bool deviceType = IsDeviceType(aType);
+  bool timeChangeEvent = (aType == NS_MOZ_TIME_CHANGE_EVENT);
 
   for (uint32_t i = 0; i < count; ++i) {
     ls = &mListeners.ElementAt(i);
     if (EVENT_TYPE_EQUALS(ls, aType, aUserType)) {
       ++typeCount;
       if (ls->mListener == aListener &&
           (ls->mFlags & ~NS_PRIV_EVENT_UNTRUSTED_PERMITTED) == aFlags) {
         nsRefPtr<nsEventListenerManager> kungFuDeathGrip = this;
         mListeners.RemoveElementAt(i);
         --count;
         mNoListenerForEvent = NS_EVENT_TYPE_NULL;
         mNoListenerForEventAtom = nullptr;
 
-        if (!deviceType) {
+        if (!deviceType && !timeChangeEvent) {
           return;
         }
         --typeCount;
       }
     }
   }
 
   if (deviceType && typeCount == 0) {
     DisableDevice(aType);
+  } else if (timeChangeEvent && typeCount == 0) {
+    DisableTimeChangeNotifications();
   }
 }
 
 static inline bool
 ListenerCanHandle(nsListenerStruct* aLs, nsEvent* aEvent)
 {
   // This is slightly different from EVENT_TYPE_EQUALS in that it returns
   // true even when aEvent->message == NS_USER_DEFINED_EVENT and
@@ -1160,8 +1166,32 @@ nsEventListenerManager::UnmarkGrayJSList
     if (jsl) {
       xpc_UnmarkGrayObject(jsl->GetHandler());
       xpc_UnmarkGrayObject(jsl->GetEventScope());
     } else if (ls.mListenerType == eWrappedJSListener) {
       xpc_TryUnmarkWrappedGrayObject(ls.mListener);
     }
   }
 }
+
+void
+nsEventListenerManager::EnableTimeChangeNotifications()
+{
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(mTarget);
+  if (!window) {
+    return;
+  }
+
+  NS_ASSERTION(window->IsInnerWindow(), "Target should not be an outer window");
+  window->EnableTimeChangeNotifications();
+}
+
+void
+nsEventListenerManager::DisableTimeChangeNotifications()
+{
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(mTarget);
+  if (!window) {
+    return;
+  }
+
+  NS_ASSERTION(window->IsInnerWindow(), "Target should not be an outer window");
+  window->DisableTimeChangeNotifications();
+}
--- a/content/events/src/nsEventListenerManager.h
+++ b/content/events/src/nsEventListenerManager.h
@@ -264,16 +264,19 @@ protected:
                                    JSObject *aHandler,
                                    bool aPermitUntrustedEvents,
                                    nsListenerStruct **aListenerStruct);
 
   bool IsDeviceType(uint32_t aType);
   void EnableDevice(uint32_t aType);
   void DisableDevice(uint32_t aType);
 
+  void EnableTimeChangeNotifications();
+  void DisableTimeChangeNotifications();
+
 public:
   /**
    * Set the "inline" event listener for aEventName to |v|.  This
    * might actually remove the event listener, depending on the value
    * of |v|.  Note that on entry to this function cx and aScope might
    * not be in the same compartment, though cx and v are guaranteed to
    * be in the same compartment.  If aExpectScriptContext is false,
    * not finding an nsIScriptContext does not cause failure.
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -1571,16 +1571,52 @@ nsEventStateManager::IsRemoteTarget(nsIC
     if (isBrowser) {
       return !!TabParent::GetFrom(target);
     }
   }
 
   return false;
 }
 
+/*static*/ void
+nsEventStateManager::MapEventCoordinatesForChildProcess(nsFrameLoader* aFrameLoader,
+                                                        nsEvent* aEvent)
+{
+  // The "toplevel widget" in child processes is always at position
+  // 0,0.  Map the event coordinates to match that.
+  nsIFrame* targetFrame = aFrameLoader->GetPrimaryFrameOfOwningContent();
+  if (!targetFrame) {
+    return;
+  }
+  nsPresContext* presContext = targetFrame->PresContext();
+
+  if (aEvent->eventStructType != NS_TOUCH_EVENT) {
+    nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent,
+                                                              targetFrame);
+    aEvent->refPoint = pt.ToNearestPixels(presContext->AppUnitsPerDevPixel());
+  } else {
+    aEvent->refPoint = nsIntPoint();
+    // Find out how far we're offset from the nearest widget.
+    nsPoint offset =
+      nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, targetFrame);
+    nsIntPoint intOffset =
+      offset.ToNearestPixels(presContext->AppUnitsPerDevPixel());
+    nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
+    // Then offset all the touch points by that distance, to put them
+    // in the space where top-left is 0,0.
+    const nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
+    for (uint32_t i = 0; i < touches.Length(); ++i) {
+      nsIDOMTouch* touch = touches[i];
+      if (touch) {
+        touch->mRefPoint += intOffset;
+      }
+    }
+  }
+}
+
 bool
 CrossProcessSafeEvent(const nsEvent& aEvent)
 {
   switch (aEvent.eventStructType) {
   case NS_KEY_EVENT:
   case NS_WHEEL_EVENT:
     return true;
   case NS_MOUSE_EVENT:
@@ -1684,42 +1720,17 @@ nsEventStateManager::HandleCrossProcessE
     }
 
     uint32_t eventMode;
     frameLoader->GetEventMode(&eventMode);
     if (eventMode == nsIFrameLoader::EVENT_MODE_DONT_FORWARD_TO_CHILD) {
       continue;
     }
 
-    // The "toplevel widget" in content processes is always at position
-    // 0,0.  Map the event coordinates to match that.
-    if (aEvent->eventStructType != NS_TOUCH_EVENT) {
-      nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent,
-                                                                aTargetFrame);
-      aEvent->refPoint =
-        pt.ToNearestPixels(mPresContext->AppUnitsPerDevPixel());
-    } else {
-      nsIFrame* targetFrame = frameLoader->GetPrimaryFrameOfOwningContent();
-      aEvent->refPoint = nsIntPoint();
-      // Find out how far we're offset from the nearest widget.
-      nsPoint offset =
-        nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, targetFrame);
-      nsIntPoint intOffset =
-        offset.ToNearestPixels(mPresContext->AppUnitsPerDevPixel());
-      nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
-      // Then offset all the touch points by that distance, to put them
-      // in the space where top-left is 0,0.
-      const nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
-      for (uint32_t i = 0; i < touches.Length(); ++i) {
-        nsIDOMTouch* touch = touches[i];
-        if (touch) {
-          touch->mRefPoint += intOffset;
-        }
-      }
-    }
+    MapEventCoordinatesForChildProcess(frameLoader, aEvent);
 
     dispatched |= DispatchCrossProcessEvent(aEvent, frameLoader, aStatus);
   }
   return dispatched;
 }
 
 //
 // CreateClickHoldTimer
--- a/content/events/src/nsEventStateManager.h
+++ b/content/events/src/nsEventStateManager.h
@@ -199,16 +199,19 @@ public:
   static void SetActiveManager(nsEventStateManager* aNewESM,
                                nsIContent* aContent);
 
   // Sets the full-screen event state on aElement to aIsFullScreen.
   static void SetFullScreenState(mozilla::dom::Element* aElement, bool aIsFullScreen);
 
   static bool IsRemoteTarget(nsIContent* aTarget);
 
+  static void MapEventCoordinatesForChildProcess(nsFrameLoader* aFrameLoader,
+                                                 nsEvent* aEvent);
+
   // Holds the point in screen coords that a mouse event was dispatched to,
   // before we went into pointer lock mode. This is constantly updated while
   // the pointer is not locked, but we don't update it while the pointer is
   // locked. This is used by nsDOMEvent::GetScreenCoords() to make mouse
   // events' screen coord appear frozen at the last mouse position while
   // the pointer is locked.
   static nsIntPoint sLastScreenPoint;
 
--- a/content/media/raw/nsRawStructs.h
+++ b/content/media/raw/nsRawStructs.h
@@ -52,9 +52,9 @@ struct nsRawVideoHeader {
   PRUint24 frameHeight;
   PRUint24 aspectNumerator;
   PRUint24 aspectDenominator;
 
   uint32_t framerateNumerator;
   uint32_t framerateDenominator;
 };
 
-#endif // nsRawStructs_h_
\ No newline at end of file
+#endif // nsRawStructs_h_
--- a/content/smil/nsSMILSetAnimationFunction.cpp
+++ b/content/smil/nsSMILSetAnimationFunction.cpp
@@ -83,17 +83,17 @@ nsSMILSetAnimationFunction::GetAttr(nsIA
   return nsSMILAnimationFunction::GetAttr(aAttName);
 }
 
 bool
 nsSMILSetAnimationFunction::GetAttr(nsIAtom* aAttName,
                                     nsAString& aResult) const
 {
   if (IsDisallowedAttribute(aAttName))
-    return nullptr;
+    return false;
 
   return nsSMILAnimationFunction::GetAttr(aAttName, aResult);
 }
 
 bool
 nsSMILSetAnimationFunction::WillReplace() const
 {
   return true;
--- a/content/xml/document/src/nsXMLDocument.cpp
+++ b/content/xml/document/src/nsXMLDocument.cpp
@@ -257,17 +257,17 @@ nsXMLDocument::Reset(nsIChannel* aChanne
 
 void
 nsXMLDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
                           nsIPrincipal* aPrincipal)
 {
   if (mChannelIsPending) {
     StopDocumentLoad();
     mChannel->Cancel(NS_BINDING_ABORTED);
-    mChannelIsPending = nullptr;
+    mChannelIsPending = false;
   }
 
   nsDocument::ResetToURI(aURI, aLoadGroup, aPrincipal);
 }
 
 NS_IMETHODIMP
 nsXMLDocument::GetAsync(bool *aAsync)
 {
--- a/dom/Makefile.in
+++ b/dom/Makefile.in
@@ -53,16 +53,17 @@ PARALLEL_DIRS += \
   file \
   media \
   messages \
   power \
   settings \
   sms \
   mms \
   src \
+  time \
   locales \
   network \
   permission \
   plugins/base \
   plugins/ipc \
   indexedDB \
   system \
   ipc \
--- a/dom/activities/interfaces/Makefile.in
+++ b/dom/activities/interfaces/Makefile.in
@@ -20,9 +20,10 @@ XPIDLSRCS = nsIDOMActivity.idl \
             nsIActivityUIGlue.idl \
             $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 XPIDL_FLAGS += \
   -I$(topsrcdir)/dom/base \
   -I$(topsrcdir)/dom/interfaces/base \
+  -I$(topsrcdir)/dom/interfaces/events \
   $(NULL)
--- a/dom/apps/src/Makefile.in
+++ b/dom/apps/src/Makefile.in
@@ -7,18 +7,21 @@ topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 EXTRA_COMPONENTS = \
   AppsService.js \
   AppsService.manifest \
+  Webapps.manifest \
+  $(NULL)
+
+EXTRA_PP_COMPONENTS = \
   Webapps.js \
-  Webapps.manifest \
   $(NULL)
 
 EXTRA_PP_JS_MODULES += \
   Webapps.jsm \
   AppsServiceChild.jsm \
   AppsUtils.jsm \
   $(NULL)
 
--- a/dom/apps/src/Webapps.js
+++ b/dom/apps/src/Webapps.js
@@ -28,17 +28,29 @@ function convertAppsArray(aApps, aWindow
 
 function WebappsRegistry() {
 }
 
 WebappsRegistry.prototype = {
   __proto__: DOMRequestIpcHelper.prototype,
   __exposedProps__: {
                       install: 'r',
+#ifdef MOZ_PHOENIX
+# Firefox Desktop: installPackage not implemented
+#elifdef ANDROID
+#ifndef MOZ_WIDGET_GONK
+# Firefox Android (Fennec): installPackage not implemented
+#else
+# B2G Gonk: installPackage implemented
                       installPackage: 'r',
+#endif
+#else
+# B2G Desktop and others: installPackage implementation status varies
+                      installPackage: 'r',
+#endif
                       getSelf: 'r',
                       getInstalled: 'r',
                       mgmt: 'r'
                      },
 
   /** from https://developer.mozilla.org/en/OpenWebApps/The_Manifest
    * only the name property is mandatory
    */
@@ -162,16 +174,28 @@ WebappsRegistry.prototype = {
   getInstalled: function() {
     let request = this.createRequest();
     cpmm.sendAsyncMessage("Webapps:GetInstalled", { origin: this._getOrigin(this._window.location.href),
                                                     oid: this._id,
                                                     requestID: this.getRequestId(request) });
     return request;
   },
 
+  get mgmt() {
+    if (!this._mgmt)
+      this._mgmt = new WebappsApplicationMgmt(this._window);
+    return this._mgmt;
+  },
+
+  uninit: function() {
+    this._mgmt = null;
+  },
+
+  // mozIDOMApplicationRegistry2 implementation
+
   installPackage: function(aPackageURL, aParams) {
     let request = this.createRequest();
     let requestID = this.getRequestId(request);
 
     let receipts = (aParams && aParams.receipts &&
                     Array.isArray(aParams.receipts)) ? aParams.receipts : [];
     let categories = (aParams && aParams.categories &&
                       Array.isArray(aParams.categories)) ? aParams.categories : [];
@@ -180,43 +204,61 @@ WebappsRegistry.prototype = {
                                                       categories: categories,
                                                       requestID: requestID,
                                                       oid: this._id,
                                                       from: this._window.location.href,
                                                       installOrigin: this._getOrigin(this._window.location.href) });
     return request;
   },
 
-  get mgmt() {
-    if (!this._mgmt)
-      this._mgmt = new WebappsApplicationMgmt(this._window);
-    return this._mgmt;
-  },
-
-  uninit: function() {
-    this._mgmt = null;
-  },
-
   // nsIDOMGlobalPropertyInitializer implementation
   init: function(aWindow) {
     this.initHelper(aWindow, ["Webapps:Install:Return:OK", "Webapps:Install:Return:KO",
                               "Webapps:GetInstalled:Return:OK",
                               "Webapps:GetSelf:Return:OK", "Webapps:GetSelf:Return:KO"]);
 
     let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
     this._id = util.outerWindowID;
   },
 
   classID: Components.ID("{fff440b3-fae2-45c1-bf03-3b5a2e432270}"),
 
-  QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationRegistry, Ci.nsIDOMGlobalPropertyInitializer]),
+  QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationRegistry,
+#ifdef MOZ_PHOENIX
+# Firefox Desktop: installPackage not implemented
+#elifdef ANDROID
+#ifndef MOZ_WIDGET_GONK
+# Firefox Android (Fennec): installPackage not implemented
+#else
+# B2G Gonk: installPackage implemented
+                                         Ci.mozIDOMApplicationRegistry2,
+#endif
+#else
+# B2G Desktop and others: installPackage implementation status varies
+                                         Ci.mozIDOMApplicationRegistry2,
+#endif
+                                         Ci.nsIDOMGlobalPropertyInitializer]),
 
   classInfo: XPCOMUtils.generateCI({classID: Components.ID("{fff440b3-fae2-45c1-bf03-3b5a2e432270}"),
                                     contractID: "@mozilla.org/webapps;1",
-                                    interfaces: [Ci.mozIDOMApplicationRegistry],
+                                    interfaces: [Ci.mozIDOMApplicationRegistry,
+#ifdef MOZ_PHOENIX
+# Firefox Desktop: installPackage not implemented
+#elifdef ANDROID
+#ifndef MOZ_WIDGET_GONK
+# Firefox Android (Fennec): installPackage not implemented
+#else
+# B2G Gonk: installPackage implemented
+                                                 Ci.mozIDOMApplicationRegistry2,
+#endif
+#else
+# B2G Desktop and others: installPackage implementation status varies
+                                                 Ci.mozIDOMApplicationRegistry2,
+#endif
+                                                 ],
                                     flags: Ci.nsIClassInfo.DOM_OBJECT,
                                     classDescription: "Webapps Registry"})
 }
 
 /**
   * mozIDOMApplication object
   */
 
--- a/dom/base/Makefile.in
+++ b/dom/base/Makefile.in
@@ -131,10 +131,11 @@ LOCAL_INCLUDES += \
 		$(NULL)
 
 ifdef MOZ_X11
 CXXFLAGS += $(TK_CFLAGS)
 LDFLAGS += $(TK_LIBS)
 endif
 
 XPIDL_FLAGS += \
+  -I$(topsrcdir)/dom/interfaces/base \
   -I$(topsrcdir)/dom/interfaces/events \
   $(NULL)
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -38,16 +38,17 @@
 #include "Connection.h"
 #ifdef MOZ_B2G_RIL
 #include "MobileConnection.h"
 #endif
 #include "nsIIdleObserver.h"
 #include "nsIPermissionManager.h"
 #include "nsNetUtil.h"
 #include "nsIHttpChannel.h"
+#include "TimeManager.h"
 
 #ifdef MOZ_MEDIA_NAVIGATOR
 #include "MediaManager.h"
 #endif
 #ifdef MOZ_B2G_RIL
 #include "TelephonyFactory.h"
 #endif
 #ifdef MOZ_B2G_BT
@@ -121,16 +122,17 @@ NS_INTERFACE_MAP_BEGIN(Navigator)
 #ifdef MOZ_B2G_RIL
   NS_INTERFACE_MAP_ENTRY(nsIMozNavigatorMobileConnection)
 #endif
 #ifdef MOZ_B2G_BT
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorBluetooth)
 #endif
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorCamera)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorSystemMessages)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMMozNavigatorTime)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Navigator)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(Navigator)
 NS_IMPL_RELEASE(Navigator)
 
 void
 Navigator::Invalidate()
@@ -205,16 +207,19 @@ Navigator::Invalidate()
 #endif
 
   uint32_t len = mDeviceStorageStores.Length();
   for (uint32_t i = 0; i < len; ++i) {
     mDeviceStorageStores[i]->Shutdown();
   }
   mDeviceStorageStores.Clear();
 
+  if (mTimeManager) {
+    mTimeManager = nullptr;
+  }
 }
 
 nsPIDOMWindow *
 Navigator::GetWindow()
 {
   nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
 
   return win;
@@ -1310,16 +1315,48 @@ Navigator::MozSetMessageHandler(const ns
 
   return mMessagesManager->MozSetMessageHandler(aType, aCallback);
 #else
   return NS_ERROR_NOT_IMPLEMENTED;
 #endif
 }
 
 //*****************************************************************************
+//    Navigator::nsIDOMNavigatorTime
+//*****************************************************************************
+NS_IMETHODIMP
+Navigator::GetMozTime(nsIDOMMozTimeManager** aTime)
+{
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
+  NS_ENSURE_TRUE(window, NS_OK);
+
+  nsCOMPtr<nsIDocument> document = do_QueryInterface(window->GetExtantDocument());
+  NS_ENSURE_TRUE(document, NS_OK);
+  nsCOMPtr<nsIPrincipal> principal = document->NodePrincipal();
+  nsCOMPtr<nsIPermissionManager> permMgr =
+    do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
+  NS_ENSURE_TRUE(permMgr, NS_OK);
+  
+  uint32_t permission = nsIPermissionManager::DENY_ACTION;
+  permMgr->TestPermissionFromPrincipal(principal, "time", &permission);
+
+  if (permission != nsIPermissionManager::ALLOW_ACTION) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+
+  if (!mTimeManager) {
+    *aTime = nullptr;
+    mTimeManager = new time::TimeManager();
+  }
+
+  NS_ADDREF(*aTime = mTimeManager);
+  return NS_OK;
+}
+
+//*****************************************************************************
 //    nsNavigator::nsIDOMNavigatorCamera
 //*****************************************************************************
 
 NS_IMETHODIMP
 Navigator::GetMozCameras(nsIDOMCameraManager** aCameraManager)
 {
   if (!mCameraManager) {
     nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -14,16 +14,17 @@
 #include "nsIDOMClientInformation.h"
 #include "nsINavigatorBattery.h"
 #include "nsIDOMNavigatorSms.h"
 #include "nsIDOMNavigatorNetwork.h"
 #ifdef MOZ_B2G_RIL
 #include "nsINavigatorMobileConnection.h"
 #endif
 #include "nsAutoPtr.h"
+#include "nsIDOMNavigatorTime.h"
 #include "nsWeakReference.h"
 #include "DeviceStorage.h"
 
 class nsPluginArray;
 class nsMimeTypeArray;
 class nsGeolocation;
 class nsDesktopNotificationCenter;
 class nsPIDOMWindow;
@@ -69,16 +70,20 @@ class Connection;
 class MobileConnection;
 #endif
 } // namespace Connection;
 
 namespace power {
 class PowerManager;
 } // namespace power
 
+namespace time {
+class TimeManager;
+} // namespace time
+
 class Navigator : public nsIDOMNavigator
                 , public nsIDOMClientInformation
                 , public nsIDOMNavigatorDeviceStorage
                 , public nsIDOMNavigatorGeolocation
                 , public nsIDOMNavigatorDesktopNotification
                 , public nsINavigatorBattery
                 , public nsIDOMMozNavigatorSms
 #ifdef MOZ_MEDIA_NAVIGATOR
@@ -91,16 +96,17 @@ class Navigator : public nsIDOMNavigator
 #ifdef MOZ_B2G_RIL
                 , public nsIMozNavigatorMobileConnection
 #endif
 #ifdef MOZ_B2G_BT
                 , public nsIDOMNavigatorBluetooth
 #endif
                 , public nsIDOMNavigatorCamera
                 , public nsIDOMNavigatorSystemMessages
+                , public nsIDOMMozNavigatorTime
 {
 public:
   Navigator(nsPIDOMWindow *aInnerWindow);
   virtual ~Navigator();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMNAVIGATOR
   NS_DECL_NSIDOMCLIENTINFORMATION
@@ -119,16 +125,17 @@ public:
 #ifdef MOZ_B2G_RIL
   NS_DECL_NSIMOZNAVIGATORMOBILECONNECTION
 #endif
 
 #ifdef MOZ_B2G_BT
   NS_DECL_NSIDOMNAVIGATORBLUETOOTH
 #endif
   NS_DECL_NSIDOMNAVIGATORSYSTEMMESSAGES
+  NS_DECL_NSIDOMMOZNAVIGATORTIME
 
   static void Init();
 
   void Invalidate();
   nsPIDOMWindow *GetWindow();
 
   void RefreshMIMEArray();
 
@@ -171,16 +178,17 @@ private:
   nsRefPtr<network::MobileConnection> mMobileConnection;
 #endif
 #ifdef MOZ_B2G_BT
   nsCOMPtr<nsIDOMBluetoothManager> mBluetooth;
 #endif
   nsRefPtr<nsDOMCameraManager> mCameraManager;
   nsCOMPtr<nsIDOMNavigatorSystemMessages> mMessagesManager;
   nsTArray<nsRefPtr<nsDOMDeviceStorage> > mDeviceStorageStores;
+  nsRefPtr<time::TimeManager> mTimeManager;
   nsWeakPtr mWindow;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 nsresult NS_GetNavigatorUserAgent(nsAString& aUserAgent);
 nsresult NS_GetNavigatorPlatform(nsAString& aPlatform);
--- a/dom/base/ScreenOrientation.h
+++ b/dom/base/ScreenOrientation.h
@@ -8,39 +8,22 @@
 #include "ipc/IPCMessageUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 // Make sure that any change here is also made in
 // * mobile/android/base/GeckoScreenOrientationListener.java
 // * embedding/android/GeckoScreenOrientationListener.java
-enum ScreenOrientation {
-  eScreenOrientation_None               = 0,
-  eScreenOrientation_PortraitPrimary    = 1,  // 00000001
-  eScreenOrientation_PortraitSecondary  = 2,  // 00000010
-  eScreenOrientation_Portrait           = 3,  // 00000011
-  eScreenOrientation_LandscapePrimary   = 4,  // 00000100
-  eScreenOrientation_LandscapeSecondary = 8,  // 00001000
-  eScreenOrientation_Landscape          = 12, // 00001100
-  eScreenOrientation_EndGuard
-};
+typedef uint32_t ScreenOrientation;
+
+static const ScreenOrientation eScreenOrientation_None               = 0;
+static const ScreenOrientation eScreenOrientation_PortraitPrimary    = 1;  // 00000001
+static const ScreenOrientation eScreenOrientation_PortraitSecondary  = 2;  // 00000010
+static const ScreenOrientation eScreenOrientation_Portrait           = 3;  // 00000011
+static const ScreenOrientation eScreenOrientation_LandscapePrimary   = 4;  // 00000100
+static const ScreenOrientation eScreenOrientation_LandscapeSecondary = 8;  // 00001000
+static const ScreenOrientation eScreenOrientation_Landscape          = 12; // 00001100
 
 } // namespace dom
 } // namespace mozilla
 
-namespace IPC {
-
-/**
- * Screen orientation serializer.
- * Note that technically, 5, 6, 7, 9, 10 and 11 are illegal values but will
- * not make the serializer to fail. We might want to write our own serializer.
- */
-template <>
-struct ParamTraits<mozilla::dom::ScreenOrientation>
-  : public EnumSerializer<mozilla::dom::ScreenOrientation,
-                          mozilla::dom::eScreenOrientation_None,
-                          mozilla::dom::eScreenOrientation_EndGuard>
-{};
-
-} // namespace IPC
-
 #endif // mozilla_dom_ScreenOrientation_h
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -521,16 +521,17 @@ using mozilla::dom::indexedDB::IDBWrappe
 #include "BluetoothAdapter.h"
 #include "BluetoothDevice.h"
 #include "BluetoothPropertyEvent.h"
 #endif
 
 #include "nsIDOMNavigatorSystemMessages.h"
 
 #include "mozilla/dom/Activity.h"
+#include "TimeManager.h"
 
 #include "DOMCameraManager.h"
 #include "DOMCameraControl.h"
 #include "DOMCameraCapabilities.h"
 
 #include "DOMError.h"
 #include "DOMRequest.h"
 #include "nsIOpenWindowEventDetail.h"
@@ -1712,16 +1713,19 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA_WITH_NAME(DOMFileHandle, FileHandle, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(FileRequest, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(LockedFile, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MozActivity, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
+
+  NS_DEFINE_CLASSINFO_DATA(MozTimeManager, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
 };
 
 // Objects that should be constructable through |new Name();|
 struct nsContractIDMapData
 {
   int32_t mDOMClassInfoID;
   const char *mContractID;
 };
@@ -2078,21 +2082,18 @@ WrapNativeParent(JSContext *cx, JSObject
 static inline nsresult
 SetParentToWindow(nsGlobalWindow *win, JSObject **parent)
 {
   MOZ_ASSERT(win);
   MOZ_ASSERT(win->IsInnerWindow());
   *parent = win->FastGetGlobalJSObject();
 
   if (MOZ_UNLIKELY(!*parent)) {
-    // The only known case where this can happen is when the inner window has
-    // been torn down. See bug 691178 comment 11. Should be a fatal MOZ_ASSERT,
-    // but we've found a way to hit it too often in mochitests. See bugs 777875
-    // 778424, 781078.
-    NS_ASSERTION(win->IsClosedOrClosing(), "win should be closed or closing");
+    // The inner window has been torn down. The scope is dying, so don't create
+    // any new wrappers.
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 // static
 
 nsISupports *
@@ -2492,16 +2493,17 @@ nsDOMClassInfo::Init()
 #ifdef MOZ_B2G_RIL
     DOM_CLASSINFO_MAP_ENTRY(nsIMozNavigatorMobileConnection)
 #endif
 #ifdef MOZ_B2G_BT
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorBluetooth)
 #endif
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorCamera)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorSystemMessages)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozNavigatorTime)
 
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Plugin, nsIDOMPlugin)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMPlugin)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(PluginArray, nsIDOMPluginArray)
@@ -4551,16 +4553,20 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MozActivity, nsIDOMMozActivity)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozActivity)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMRequest)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(MozTimeManager, nsIDOMMozTimeManager)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozTimeManager)
+  DOM_CLASSINFO_MAP_END
+
 #ifdef DEBUG
   {
     uint32_t i = ArrayLength(sClassInfoData);
 
     if (i != eDOMClassInfoIDCount) {
       NS_ERROR("The number of items in sClassInfoData doesn't match the "
                "number of nsIDOMClassInfo ID's, this is bad! Fix it!");
 
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -536,8 +536,10 @@ DOMCI_CLASS(DOMError)
 DOMCI_CLASS(DOMRequest)
 DOMCI_CLASS(OpenWindowEventDetail)
 
 DOMCI_CLASS(DOMFileHandle)
 DOMCI_CLASS(FileRequest)
 DOMCI_CLASS(LockedFile)
 
 DOMCI_CLASS(MozActivity)
+
+DOMCI_CLASS(MozTimeManager)
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2878,8 +2878,68 @@ nsDOMWindowUtils::SelectAtPoint(float aX
 
   nsresult rv =
     static_cast<nsFrame*>(targetFrame)->
       SelectByTypeAtPoint(GetPresContext(), relPoint, amount, amount,
                           nsFrame::SELECT_ACCUMULATE);
   *_retval = !NS_FAILED(rv);
   return NS_OK;
 }
+
+NS_IMETHODIMP
+nsDOMWindowUtils::LoadSheet(nsIURI *aSheetURI, PRUint32 aSheetType)
+{
+  if (!IsUniversalXPConnectCapable()) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+
+  NS_ENSURE_ARG_POINTER(aSheetURI);
+  NS_ENSURE_ARG(aSheetType == AGENT_SHEET || aSheetType == USER_SHEET);
+
+  nsCOMPtr<nsIDOMWindow> window = do_QueryReferent(mWindow);
+  NS_ENSURE_TRUE(window, NS_ERROR_INVALID_ARG);
+  
+  nsCOMPtr<nsIDOMDocument> ddoc;
+  nsresult rv = window->GetDocument(getter_AddRefs(ddoc));
+  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_TRUE(ddoc, NS_ERROR_FAILURE);
+
+  nsCOMPtr<nsIDocument> doc = do_QueryInterface(ddoc);
+  NS_ENSURE_TRUE(doc, NS_ERROR_INVALID_ARG);
+
+  nsIDocument::additionalSheetType type = 
+    aSheetType == AGENT_SHEET ? nsIDocument::eAgentSheet :
+                                nsIDocument::eUserSheet;
+
+  rv = doc->LoadAdditionalStyleSheet(type, aSheetURI);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMWindowUtils::RemoveSheet(nsIURI *aSheetURI, PRUint32 aSheetType)
+{
+  if (!IsUniversalXPConnectCapable()) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+
+  NS_ENSURE_ARG_POINTER(aSheetURI);
+  NS_ENSURE_ARG(aSheetType == AGENT_SHEET || aSheetType == USER_SHEET);
+
+  nsCOMPtr<nsIDOMWindow> window = do_QueryReferent(mWindow);
+  NS_ENSURE_TRUE(window, NS_ERROR_INVALID_ARG);
+
+  nsCOMPtr<nsIDOMDocument> ddoc;
+  nsresult rv = window->GetDocument(getter_AddRefs(ddoc));
+  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_TRUE(ddoc, NS_ERROR_FAILURE);
+
+  nsCOMPtr<nsIDocument> doc = do_QueryInterface(ddoc);
+  NS_ENSURE_TRUE(doc, NS_ERROR_INVALID_ARG);
+
+  nsIDocument::additionalSheetType type = 
+    aSheetType == AGENT_SHEET ? nsIDocument::eAgentSheet :
+                                nsIDocument::eUserSheet;
+
+  doc->RemoveAdditionalStyleSheet(type, aSheetURI);
+  return NS_OK;
+}
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -218,16 +218,17 @@
 
 #include "mozilla/Telemetry.h"
 #include "nsLocation.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsIAppsService.h"
 #include "prrng.h"
 #include "nsSandboxFlags.h"
+#include "TimeChangeObserver.h"
 
 #ifdef ANDROID
 #include <android/log.h>
 #endif
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gDOMLeakPRLog;
 #endif
@@ -1047,16 +1048,17 @@ nsGlobalWindow::CleanUp(bool aIgnoreModa
 
   CleanupCachedXBLHandlers(this);
 
   if (mIdleTimer) {
     mIdleTimer->Cancel();
     mIdleTimer = nullptr;
   }
 
+  DisableTimeChangeNotifications();
 #ifdef DEBUG
   nsCycleCollector_DEBUG_shouldBeFreed(static_cast<nsIScriptGlobalObject*>(this));
 #endif
 }
 
 void
 nsGlobalWindow::ClearControllers()
 {
@@ -10644,16 +10646,28 @@ nsGlobalWindow::GetURL(nsIDOMMozURLPrope
     mURLProperty = new nsDOMMozURLProperty(this);
   }
 
   NS_ADDREF(*aURL = mURLProperty);
 
   return NS_OK;
 }
 
+void
+nsGlobalWindow::EnableTimeChangeNotifications()
+{
+  nsSystemTimeChangeObserver::AddWindowListener(this);
+}
+
+void
+nsGlobalWindow::DisableTimeChangeNotifications()
+{
+  nsSystemTimeChangeObserver::RemoveWindowListener(this);
+}
+
 // static
 bool
 nsGlobalWindow::HasIndexedDBSupport()
 {
   return Preferences::GetBool("indexedDB.feature.enabled", true);
 }
 
 // static
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -529,16 +529,19 @@ public:
   virtual void SetReadyForFocus();
   virtual void PageHidden();
   virtual nsresult DispatchAsyncHashchange(nsIURI *aOldURI, nsIURI *aNewURI);
   virtual nsresult DispatchSyncPopState();
 
   virtual void EnableDeviceSensor(uint32_t aType);
   virtual void DisableDeviceSensor(uint32_t aType);
 
+  virtual void EnableTimeChangeNotifications();
+  virtual void DisableTimeChangeNotifications();
+
   virtual nsresult SetArguments(nsIArray *aArguments, nsIPrincipal *aOrigin);
 
   static bool DOMWindowDumpEnabled();
 
   void MaybeForgiveSpamCount();
   bool IsClosedOrClosing() {
     return (mIsClosed ||
             mInClose ||
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -566,16 +566,19 @@ public:
    */
   virtual void EnableDeviceSensor(uint32_t aType) = 0;
 
   /**
    * Tell this window that it should remove itself from sensor change notifications.
    */
   virtual void DisableDeviceSensor(uint32_t aType) = 0;
 
+  virtual void EnableTimeChangeNotifications() = 0;
+  virtual void DisableTimeChangeNotifications() = 0;
+
   /**
    * Set a arguments for this window. This will be set on the window
    * right away (if there's an existing document) and it will also be
    * installed on the window when the next document is loaded. Each
    * language impl is responsible for converting to an array of args
    * as appropriate for that language.
    */
   virtual nsresult SetArguments(nsIArray *aArguments, nsIPrincipal *aOrigin) = 0;
--- a/dom/base/nsPerformance.cpp
+++ b/dom/base/nsPerformance.cpp
@@ -40,91 +40,91 @@ nsPerformanceTiming::nsPerformanceTiming
   SetIsDOMBinding();
 }
 
 nsPerformanceTiming::~nsPerformanceTiming()
 {
 }
 
 DOMTimeMilliSec
-nsPerformanceTiming::GetDomainLookupStart() const
+nsPerformanceTiming::DomainLookupStart() const
 {
   if (!mChannel) {
-    return GetFetchStart();
+    return FetchStart();
   }
   mozilla::TimeStamp stamp;
   mChannel->GetDomainLookupStart(&stamp);
   return GetDOMTiming()->TimeStampToDOMOrFetchStart(stamp);
 }
 
 DOMTimeMilliSec
-nsPerformanceTiming::GetDomainLookupEnd() const
+nsPerformanceTiming::DomainLookupEnd() const
 {
   if (!mChannel) {
-    return GetFetchStart();
+    return FetchStart();
   }
   mozilla::TimeStamp stamp;
   mChannel->GetDomainLookupEnd(&stamp);
   return GetDOMTiming()->TimeStampToDOMOrFetchStart(stamp);
 }
 
 DOMTimeMilliSec
-nsPerformanceTiming::GetConnectStart() const
+nsPerformanceTiming::ConnectStart() const
 {
   if (!mChannel) {
-    return GetFetchStart();
+    return FetchStart();
   }
   mozilla::TimeStamp stamp;
   mChannel->GetConnectStart(&stamp);
   return GetDOMTiming()->TimeStampToDOMOrFetchStart(stamp);
 }
 
 DOMTimeMilliSec
-nsPerformanceTiming::GetConnectEnd() const
+nsPerformanceTiming::ConnectEnd() const
 {
   if (!mChannel) {
-    return GetFetchStart();
+    return FetchStart();
   }
   mozilla::TimeStamp stamp;
   mChannel->GetConnectEnd(&stamp);
   return GetDOMTiming()->TimeStampToDOMOrFetchStart(stamp);
 }
 
 DOMTimeMilliSec
-nsPerformanceTiming::GetRequestStart() const
+nsPerformanceTiming::RequestStart() const
 {
   if (!mChannel) {
-    return GetFetchStart();
+    return FetchStart();
   }
   mozilla::TimeStamp stamp;
   mChannel->GetRequestStart(&stamp);
   return GetDOMTiming()->TimeStampToDOMOrFetchStart(stamp);
 }
 
 DOMTimeMilliSec
-nsPerformanceTiming::GetResponseStart() const
+nsPerformanceTiming::ResponseStart() const
 {
   if (!mChannel) {
-    return GetFetchStart();
+    return FetchStart();
   }
   mozilla::TimeStamp stamp;
   mChannel->GetResponseStart(&stamp);
   mozilla::TimeStamp cacheStamp;
   mChannel->GetCacheReadStart(&cacheStamp);
   if (stamp.IsNull() || (!cacheStamp.IsNull() && cacheStamp < stamp)) {
     stamp = cacheStamp;
   }
   return GetDOMTiming()->TimeStampToDOMOrFetchStart(stamp);
 }
 
 DOMTimeMilliSec
-nsPerformanceTiming::GetResponseEnd() const
+nsPerformanceTiming::ResponseEnd() const
 {
   if (!mChannel) {
-    return GetFetchStart();
+    return FetchStart();
   }
   mozilla::TimeStamp stamp;
   mChannel->GetResponseEnd(&stamp);
   mozilla::TimeStamp cacheStamp;
   mChannel->GetCacheReadEnd(&cacheStamp);
   if (stamp.IsNull() || (!cacheStamp.IsNull() && cacheStamp < stamp)) {
     stamp = cacheStamp;
   }
@@ -199,26 +199,26 @@ nsPerformance::~nsPerformance()
 // QueryInterface implementation for nsPerformance
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPerformance)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 
 nsPerformanceTiming*
-nsPerformance::GetTiming()
+nsPerformance::Timing()
 {
   if (!mTiming) {
     mTiming = new nsPerformanceTiming(this, mChannel);
   }
   return mTiming;
 }
 
 nsPerformanceNavigation*
-nsPerformance::GetNavigation()
+nsPerformance::Navigation()
 {
   if (!mNavigation) {
     mNavigation = new nsPerformanceNavigation(this);
   }
   return mNavigation;
 }
 
 DOMHighResTimeStamp
--- a/dom/base/nsPerformance.h
+++ b/dom/base/nsPerformance.h
@@ -34,60 +34,60 @@ public:
   nsPerformance* GetParentObject() const
   {
     return mPerformance;
   }
 
   JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap);
 
   // PerformanceNavigation WebIDL methods
-  DOMTimeMilliSec GetNavigationStart() const {
+  DOMTimeMilliSec NavigationStart() const {
     return GetDOMTiming()->GetNavigationStart();
   }
-  DOMTimeMilliSec GetUnloadEventStart() {
+  DOMTimeMilliSec UnloadEventStart() {
     return GetDOMTiming()->GetUnloadEventStart();
   }
-  DOMTimeMilliSec GetUnloadEventEnd() {
+  DOMTimeMilliSec UnloadEventEnd() {
     return GetDOMTiming()->GetUnloadEventEnd();
   }
-  DOMTimeMilliSec GetRedirectStart() {
+  DOMTimeMilliSec RedirectStart() {
     return GetDOMTiming()->GetRedirectStart();
   }
-  DOMTimeMilliSec GetRedirectEnd() {
+  DOMTimeMilliSec RedirectEnd() {
     return GetDOMTiming()->GetRedirectEnd();
   }
-  DOMTimeMilliSec GetFetchStart() const {
+  DOMTimeMilliSec FetchStart() const {
     return GetDOMTiming()->GetFetchStart();
   }
-  DOMTimeMilliSec GetDomainLookupStart() const;
-  DOMTimeMilliSec GetDomainLookupEnd() const;
-  DOMTimeMilliSec GetConnectStart() const;
-  DOMTimeMilliSec GetConnectEnd() const;
-  DOMTimeMilliSec GetRequestStart() const;
-  DOMTimeMilliSec GetResponseStart() const;
-  DOMTimeMilliSec GetResponseEnd() const;
-  DOMTimeMilliSec GetDomLoading() const {
+  DOMTimeMilliSec DomainLookupStart() const;
+  DOMTimeMilliSec DomainLookupEnd() const;
+  DOMTimeMilliSec ConnectStart() const;
+  DOMTimeMilliSec ConnectEnd() const;
+  DOMTimeMilliSec RequestStart() const;
+  DOMTimeMilliSec ResponseStart() const;
+  DOMTimeMilliSec ResponseEnd() const;
+  DOMTimeMilliSec DomLoading() const {
     return GetDOMTiming()->GetDomLoading();
   }
-  DOMTimeMilliSec GetDomInteractive() const {
+  DOMTimeMilliSec DomInteractive() const {
     return GetDOMTiming()->GetDomInteractive();
   }
-  DOMTimeMilliSec GetDomContentLoadedEventStart() const {
+  DOMTimeMilliSec DomContentLoadedEventStart() const {
     return GetDOMTiming()->GetDomContentLoadedEventStart();
   }
-  DOMTimeMilliSec GetDomContentLoadedEventEnd() const {
+  DOMTimeMilliSec DomContentLoadedEventEnd() const {
     return GetDOMTiming()->GetDomContentLoadedEventEnd();
   }
-  DOMTimeMilliSec GetDomComplete() const {
+  DOMTimeMilliSec DomComplete() const {
     return GetDOMTiming()->GetDomComplete();
   }
-  DOMTimeMilliSec GetLoadEventStart() const {
+  DOMTimeMilliSec LoadEventStart() const {
     return GetDOMTiming()->GetLoadEventStart();
   }
-  DOMTimeMilliSec GetLoadEventEnd() const {
+  DOMTimeMilliSec LoadEventEnd() const {
     return GetDOMTiming()->GetLoadEventEnd();
   }
 
 private:
   ~nsPerformanceTiming();
   nsRefPtr<nsPerformance> mPerformance;
   nsCOMPtr<nsITimedChannel> mChannel;
 };
@@ -106,20 +106,20 @@ public:
   nsPerformance* GetParentObject() const
   {
     return mPerformance;
   }
 
   JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap);
 
   // PerformanceNavigation WebIDL methods
-  uint16_t GetType() const {
+  uint16_t Type() const {
     return GetDOMTiming()->GetType();
   }
-  uint16_t GetRedirectCount() const {
+  uint16_t RedirectCount() const {
     return GetDOMTiming()->GetRedirectCount();
   }
 
 private:
   ~nsPerformanceNavigation();
   nsRefPtr<nsPerformance> mPerformance;
 };
 
@@ -149,18 +149,18 @@ public:
   {
     return mWindow.get();
   }
 
   JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap);
 
   // Performance WebIDL methods
   DOMHighResTimeStamp Now();
-  nsPerformanceTiming* GetTiming();
-  nsPerformanceNavigation* GetNavigation();
+  nsPerformanceTiming* Timing();
+  nsPerformanceNavigation* Navigation();
 
 private:
   ~nsPerformance();
 
   nsCOMPtr<nsIDOMWindow> mWindow;
   nsRefPtr<nsDOMNavigationTiming> mDOMTiming;
   nsCOMPtr<nsITimedChannel> mChannel;
   nsRefPtr<nsPerformanceTiming> mTiming;
--- a/dom/base/nsScreen.cpp
+++ b/dom/base/nsScreen.cpp
@@ -8,16 +8,17 @@
 #include "nsIDocShell.h"
 #include "nsPresContext.h"
 #include "nsCOMPtr.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsLayoutUtils.h"
 #include "nsDOMEvent.h"
 #include "nsGlobalWindow.h"
+#include "nsJSUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 namespace {
 
 bool
 IsChromeType(nsIDocShell *aDocShell)
@@ -67,17 +68,17 @@ void
 nsScreen::Reset()
 {
   hal::UnlockScreenOrientation();
 
   if (mEventListener) {
     nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner());
     if (target) {
       target->RemoveSystemEventListener(NS_LITERAL_STRING("mozfullscreenchange"),
-                                        mEventListener, true);
+                                        mEventListener, /* usecapture */ true);
     }
 
     mEventListener = nullptr;
   }
 }
 
 nsScreen::~nsScreen()
 {
@@ -271,17 +272,16 @@ nsScreen::GetAvailRect(nsRect& aRect)
 
 void
 nsScreen::Notify(const hal::ScreenConfiguration& aConfiguration)
 {
   ScreenOrientation previousOrientation = mOrientation;
   mOrientation = aConfiguration.orientation();
 
   NS_ASSERTION(mOrientation != eScreenOrientation_None &&
-               mOrientation != eScreenOrientation_EndGuard &&
                mOrientation != eScreenOrientation_Portrait &&
                mOrientation != eScreenOrientation_Landscape,
                "Invalid orientation value passed to notify method!");
 
   if (mOrientation != previousOrientation) {
     // TODO: use an helper method, see bug 720768.
     nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nullptr, nullptr);
     nsresult rv = event->InitEvent(NS_LITERAL_STRING("mozorientationchange"), false, false);
@@ -302,17 +302,16 @@ nsScreen::Notify(const hal::ScreenConfig
   }
 }
 
 NS_IMETHODIMP
 nsScreen::GetMozOrientation(nsAString& aOrientation)
 {
   switch (mOrientation) {
     case eScreenOrientation_None:
-    case eScreenOrientation_EndGuard:
     case eScreenOrientation_Portrait:
     case eScreenOrientation_Landscape:
       NS_ASSERTION(false, "Shouldn't be used when getting value!");
       return NS_ERROR_FAILURE;
     case eScreenOrientation_PortraitPrimary:
       aOrientation.AssignLiteral("portrait-primary");
       break;
     case eScreenOrientation_PortraitSecondary:
@@ -324,93 +323,143 @@ nsScreen::GetMozOrientation(nsAString& a
     case eScreenOrientation_LandscapeSecondary:
       aOrientation.AssignLiteral("landscape-secondary");
       break;
   }
 
   return NS_OK;
 }
 
+nsScreen::LockPermission
+nsScreen::GetLockOrientationPermission() const
+{
+  nsCOMPtr<nsPIDOMWindow> owner = GetOwner();
+  if (!owner) {
+    return LOCK_DENIED;
+  }
+
+  // Chrome can always lock the screen orientation.
+  if (IsChromeType(owner->GetDocShell())) {
+    return LOCK_ALLOWED;
+  }
+
+  nsCOMPtr<nsIDOMDocument> domDoc;
+  owner->GetDocument(getter_AddRefs(domDoc));
+  nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
+  if (!doc) {
+    return LOCK_DENIED;
+  }
+
+  // Apps can always lock the screen orientation.
+  if (doc->NodePrincipal()->GetAppStatus() >=
+        nsIPrincipal::APP_STATUS_INSTALLED) {
+    return LOCK_ALLOWED;
+  }
+
+  // Other content must be full-screen in order to lock orientation.
+  bool fullscreen;
+  domDoc->GetMozFullScreen(&fullscreen);
+
+  return fullscreen ? FULLSCREEN_LOCK_ALLOWED : LOCK_DENIED;
+}
+
 NS_IMETHODIMP
-nsScreen::MozLockOrientation(const nsAString& aOrientation, bool* aReturn)
+nsScreen::MozLockOrientation(const jsval& aOrientation, JSContext* aCx, bool* aReturn)
 {
-  ScreenOrientation orientation;
   *aReturn = false;
 
-  if (aOrientation.EqualsLiteral("portrait")) {
-    orientation = eScreenOrientation_Portrait;
-  } else if (aOrientation.EqualsLiteral("portrait-primary")) {
-    orientation = eScreenOrientation_PortraitPrimary;
-  } else if (aOrientation.EqualsLiteral("portrait-secondary")) {
-    orientation = eScreenOrientation_PortraitSecondary;
-  } else if (aOrientation.EqualsLiteral("landscape")) {
-    orientation = eScreenOrientation_Landscape;
-  } else if (aOrientation.EqualsLiteral("landscape-primary")) {
-    orientation = eScreenOrientation_LandscapePrimary;
-  } else if (aOrientation.EqualsLiteral("landscape-secondary")) {
-    orientation = eScreenOrientation_LandscapeSecondary;
+  nsAutoTArray<nsString, 8> orientations;
+  // Preallocating 8 elements to make it faster.
+
+  if (aOrientation.isString()) {
+    nsDependentJSString item;
+    item.init(aCx, aOrientation.toString());
+    orientations.AppendElement(item);
   } else {
-    return NS_OK;
-  }
-
-  // Determine whether we can lock the screen orientation.
-  bool canLockOrientation = false;
-  do {
-    nsCOMPtr<nsPIDOMWindow> owner = GetOwner();
-    if (!owner) {
-      break;
+    // If we don't have a string, we must have an Array.
+    if (!aOrientation.isObject()) {
+      return NS_ERROR_INVALID_ARG;
     }
 
-    // Chrome can always lock the screen orientation.
-    if (IsChromeType(owner->GetDocShell())) {
-      canLockOrientation = true;
-      break;
+    JSObject& obj = aOrientation.toObject();
+    uint32_t length;
+    if (!JS_GetArrayLength(aCx, &obj, &length) || length <= 0) {
+      return NS_ERROR_INVALID_ARG;
     }
 
-    nsCOMPtr<nsIDOMDocument> domDoc;
-    owner->GetDocument(getter_AddRefs(domDoc));
-    nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
-    if (!doc) {
-      break;
-    }
+    orientations.SetCapacity(length);
 
-    // Apps can always lock the screen orientation.
-    if (doc->NodePrincipal()->GetAppStatus() >=
-          nsIPrincipal::APP_STATUS_INSTALLED) {
-      canLockOrientation = true;
-      break;
-    }
+    for (uint32_t i = 0; i < length; ++i) {
+      jsval value;
+      NS_ENSURE_TRUE(JS_GetElement(aCx, &obj, i, &value), NS_ERROR_UNEXPECTED);
+      if (!value.isString()) {
+        return NS_ERROR_INVALID_ARG;
+      }
 
-    // Other content must be full-screen in order to lock orientation.
-    bool fullscreen;
-    domDoc->GetMozFullScreen(&fullscreen);
-    if (!fullscreen) {
-      break;
+      nsDependentJSString item;
+      item.init(aCx, value);
+      orientations.AppendElement(item);
     }
-
-    // If we're full-screen, register a listener so we learn when we leave
-    // full-screen.
-    nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(owner);
-    if (!target) {
-      break;
-    }
-
-    if (!mEventListener) {
-      mEventListener = new FullScreenEventListener();
-    }
-
-    target->AddSystemEventListener(NS_LITERAL_STRING("mozfullscreenchange"),
-                                   mEventListener, /* useCapture = */ true);
-    canLockOrientation = true;
-  } while(0);
-
-  if (canLockOrientation) {
-    *aReturn = hal::LockScreenOrientation(orientation);
   }
 
+  ScreenOrientation orientation = eScreenOrientation_None;
+
+  for (uint32_t i=0; i<orientations.Length(); ++i) {
+    nsString& item = orientations[i];
+
+    if (item.EqualsLiteral("portrait")) {
+      orientation |= eScreenOrientation_Portrait;
+    } else if (item.EqualsLiteral("portrait-primary")) {
+      orientation |= eScreenOrientation_PortraitPrimary;
+    } else if (item.EqualsLiteral("portrait-secondary")) {
+      orientation |= eScreenOrientation_PortraitSecondary;
+    } else if (item.EqualsLiteral("landscape")) {
+      orientation |= eScreenOrientation_Landscape;
+    } else if (item.EqualsLiteral("landscape-primary")) {
+      orientation |= eScreenOrientation_LandscapePrimary;
+    } else if (item.EqualsLiteral("landscape-secondary")) {
+      orientation |= eScreenOrientation_LandscapeSecondary;
+    } else {
+      // If we don't recognize that the token, we should just return 'false'
+      // without throwing.
+      return NS_OK;
+    }
+  }
+
+  switch (GetLockOrientationPermission()) {
+    case LOCK_DENIED:
+      return NS_OK;
+    case LOCK_ALLOWED:
+      *aReturn = hal::LockScreenOrientation(orientation);
+      return NS_OK;
+    case FULLSCREEN_LOCK_ALLOWED:
+      *aReturn = hal::LockScreenOrientation(orientation);
+      if (!*aReturn) {
+        return NS_OK;
+      }
+
+      // We are fullscreen and lock has been accepted.
+      // Now, we need to register a listener so we learn when we leave
+      // full-screen and when we will have to unlock the screen.
+      nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner());
+      if (!target) {
+        return NS_OK;
+      }
+
+      if (!mEventListener) {
+        mEventListener = new FullScreenEventListener();
+      }
+
+      return target->AddSystemEventListener(NS_LITERAL_STRING("mozfullscreenchange"),
+                                            mEventListener, /* useCapture = */ true);
+  }
+
+  // This is only for compilers that don't understand that the previous switch
+  // will always return.
+  MOZ_NOT_REACHED();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScreen::MozUnlockOrientation()
 {
   hal::UnlockScreenOrientation();
   return NS_OK;
--- a/dom/base/nsScreen.h
+++ b/dom/base/nsScreen.h
@@ -52,12 +52,20 @@ private:
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIDOMEVENTLISTENER
   };
 
   nsScreen();
   virtual ~nsScreen();
 
+  enum LockPermission {
+    LOCK_DENIED,
+    FULLSCREEN_LOCK_ALLOWED,
+    LOCK_ALLOWED
+  };
+
+  LockPermission GetLockOrientationPermission() const;
+
   nsRefPtr<FullScreenEventListener> mEventListener;
 };
 
 #endif /* nsScreen_h___ */
--- a/dom/base/test/test_screen_orientation.html
+++ b/dom/base/test/test_screen_orientation.html
@@ -41,24 +41,87 @@ try {
 
   // Negative tests
   ok(!window.screen.mozLockOrientation("Foobar-Bazbam"), "Cannot lock to an invalid string");
   is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged");
 
   ok(!window.screen.mozLockOrientation(""), "Cannot lock to an empty string");
   is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged");
 
-  ok(!window.screen.mozLockOrientation(42), "Cannot lock to a number");
+  ok(!window.screen.mozLockOrientation(["Foobar", "Bazbam"]), "Cannot lock to an invalid string");
+  is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged");
+
+  ok(!window.screen.mozLockOrientation(["foo"]), "Cannot lock to an invalid string");
+  is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged");
+
+  ok(!window.screen.mozLockOrientation([""]), "Cannot lock to an empty string");
   is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged");
 
-  ok(!window.screen.mozLockOrientation(undefined), "Cannot lock to undefined");
-  is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged");
+  var exception = false;
+  try {
+    ok(!window.screen.mozLockOrientation(42), "Cannot lock to a number");
+    is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged");
+  } catch(e) {
+    exception = true;
+  }
+  is(exception, true, "We should get an exception");
+
+  exception = false;
+  try {
+    ok(!window.screen.mozLockOrientation(undefined), "Cannot lock to undefined");
+    is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged");
+  } catch(e) {
+    exception = true;
+  }
+  is(exception, true, "We should get an exception");
+
+  exception = false;
+  try {
+    ok(!window.screen.mozLockOrientation(null), "Cannot lock to null");
+    is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged");
+  } catch(e) {
+    exception = true;
+  }
+  is(exception, true, "We should get an exception");
 
-  ok(!window.screen.mozLockOrientation(null), "Cannot lock to null");
-  is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged");
+  exception = false;
+  try {
+    ok(!window.screen.mozLockOrientation({}), "Cannot lock to a non-Array object");
+    is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged");
+  } catch(e) {
+    exception = true;
+  }
+  is(exception, true, "We should get an exception");
+
+  exception = false;
+  try {
+    ok(!window.screen.mozLockOrientation(["Foobar", 42]), "Cannot lock to a number");
+    is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged");
+  } catch(e) {
+    exception = true;
+  }
+  is(exception, true, "We should get an exception");
+
+  exception = false;
+  try {
+    ok(!window.screen.mozLockOrientation(["Foobar", null]), "Cannot lock to null");
+    is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged");
+  } catch(e) {
+    exception = true;
+  }
+  is(exception, true, "We should get an exception");
+
+  exception = false;
+  try {
+    ok(!window.screen.mozLockOrientation(["Foobar", undefined]), "Cannot lock to undefined");
+    is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged");
+  } catch(e) {
+    exception = true;
+  }
+  is(exception, true, "We should get an exception");
 }
 finally {
   window.screen.removeEventListener("mozorientationchange", unexpectedEvent);
 }
 </script>
 </pre>
 </body>
 </html>
--- a/dom/battery/Makefile.in
+++ b/dom/battery/Makefile.in
@@ -38,10 +38,11 @@ XPIDLSRCS = \
 
 TEST_DIRS += test
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
 XPIDL_FLAGS += \
+  -I$(topsrcdir)/dom/interfaces/base \
   -I$(topsrcdir)/dom/interfaces/events \
   $(NULL)
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -959,21 +959,16 @@ class MethodDefiner(PropertyDefiner):
                                  "pref": None })
 
         if not descriptor.interface.parent and not static and not descriptor.workers:
             self.chrome.append({"name": 'QueryInterface',
                                 "methodInfo": False,
                                 "length": 1,
                                 "flags": "0",
                                 "pref": None })
-            self.regular.append({"name": 'QueryInterface',
-                                 "methodInfo": False,
-                                 "length": 1,
-                                 "flags": "0",
-                                 "pref": None })
 
         if static:
             if not descriptor.interface.hasInterfaceObject():
                 # static methods go on the interface object
                 assert not self.hasChromeOnly() and not self.hasNonChromeOnly()
         else:
             if not descriptor.interface.hasInterfacePrototypeObject():
                 # non-static methods go on the interface prototype object
@@ -3481,17 +3476,26 @@ class CGSpecializedGetter(CGAbstractStat
         args = [ Argument('JSContext*', 'cx'),
                  Argument('JSHandleObject', 'obj'),
                  Argument('%s*' % descriptor.nativeType, 'self'),
                  Argument('JS::Value*', 'vp') ]
         CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args)
 
     def definition_body(self):
         name = self.attr.identifier.name
-        nativeName = "Get" + MakeNativeName(self.descriptor.binaryNames.get(name, name))
+        nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
+        # resultOutParam does not depend on whether resultAlreadyAddRefed is set
+        (_, resultOutParam) = getRetvalDeclarationForType(self.attr.type,
+                                                          self.descriptor,
+                                                          False)
+        infallible = ('infallible' in
+                      self.descriptor.getExtendedAttributes(self.attr,
+                                                            getter=True))
+        if resultOutParam or self.attr.type.nullable() or not infallible:
+            nativeName = "Get" + nativeName
         return CGIndenter(CGGetterCall(self.attr.type, nativeName,
                                        self.descriptor, self.attr)).define()
 
 class CGGenericSetter(CGAbstractBindingMethod):
     """
     A class for generating the C++ code for an IDL attribute setter.
     """
     def __init__(self, descriptor):
@@ -4722,17 +4726,17 @@ class CGDOMJSProxyHandler_getOwnProperty
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'),
                 Argument('JS::AutoIdVector&', 'props')]
         ClassMethod.__init__(self, "getOwnPropertyNames", "bool", args)
         self.descriptor = descriptor
     def getBody(self):
         indexedGetter = self.descriptor.operations['IndexedGetter']
         if indexedGetter:
-            addIndices = """uint32_t length = UnwrapProxy(proxy)->GetLength();
+            addIndices = """uint32_t length = UnwrapProxy(proxy)->Length();
 MOZ_ASSERT(int32_t(length) >= 0);
 for (int32_t i = 0; i < int32_t(length); ++i) {
   if (!props.append(INT_TO_JSID(i))) {
     return false;
   }
 }
 
 """
@@ -4982,20 +4986,21 @@ class CGDOMJSProxyHandler(CGClass):
                         CGDOMJSProxyHandler_getElementIfPresent(descriptor),
                         CGDOMJSProxyHandler_getInstance()])
         CGClass.__init__(self, 'DOMProxyHandler',
                          bases=[ClassBase('mozilla::dom::DOMProxyHandler')],
                          constructors=constructors,
                          methods=methods)
 
 def stripTrailingWhitespace(text):
+    tail = '\n' if text.endswith('\n') else ''
     lines = text.splitlines()
     for i in range(len(lines)):
         lines[i] = lines[i].rstrip()
-    return '\n'.join(lines)
+    return '\n'.join(lines) + tail
 
 class CGDescriptor(CGThing):
     def __init__(self, descriptor):
         CGThing.__init__(self)
 
         assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject()
 
         cgThings = []
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -45,18 +45,18 @@ class IndirectlyImplementedInterface : p
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_INDIRECTLY_IMPLEMENTED_INTERFACE_IID)
   NS_DECL_ISUPPORTS
 
   // We need a GetParentObject to make binding codegen happy
   virtual nsISupports* GetParentObject();
 
-  bool GetIndirectlyImplementedProperty();
-  void SetIndirectlyImplementedProperty(bool);
+  bool IndirectlyImplementedProperty();
+  void IndirectlyImplementedProperty(bool);
   void IndirectlyImplementedMethod();
 };
 
 // IID for the TestExternalInterface
 #define NS_TEST_EXTERNAL_INTERFACE_IID \
 { 0xd5ba0c99, 0x9b1d, 0x4e71, \
  { 0x8a, 0x94, 0x56, 0x38, 0x6c, 0xa3, 0xda, 0x3d } }
 class TestExternalInterface : public nsISupports
@@ -123,91 +123,91 @@ public:
   /*  static
   already_AddRefed<TestInterface> Constructor(nsISupports*,
                                               uint32_t, uint32_t,
                                               const TestInterfaceOrOnlyForUseInConstructor&,
                                               ErrorResult&);
   */
   
   // Integer types
-  int8_t GetReadonlyByte();
-  int8_t GetWritableByte();
+  int8_t ReadonlyByte();
+  int8_t WritableByte();
   void SetWritableByte(int8_t);
   void PassByte(int8_t);
   int8_t ReceiveByte();
   void PassOptionalByte(const Optional<int8_t>&);
   void PassOptionalByteWithDefault(int8_t);
   void PassNullableByte(Nullable<int8_t>&);
   void PassOptionalNullableByte(const Optional< Nullable<int8_t> >&);
 
-  int16_t GetReadonlyShort();
-  int16_t GetWritableShort();
+  int16_t ReadonlyShort();
+  int16_t WritableShort();
   void SetWritableShort(int16_t);
   void PassShort(int16_t);
   int16_t ReceiveShort();
   void PassOptionalShort(const Optional<int16_t>&);
   void PassOptionalShortWithDefault(int16_t);
 
-  int32_t GetReadonlyLong();
-  int32_t GetWritableLong();
+  int32_t ReadonlyLong();
+  int32_t WritableLong();
   void SetWritableLong(int32_t);
   void PassLong(int32_t);
   int16_t ReceiveLong();
   void PassOptionalLong(const Optional<int32_t>&);
   void PassOptionalLongWithDefault(int32_t);
 
-  int64_t GetReadonlyLongLong();
-  int64_t GetWritableLongLong();
+  int64_t ReadonlyLongLong();
+  int64_t WritableLongLong();
   void SetWritableLongLong(int64_t);
   void PassLongLong(int64_t);
   int64_t ReceiveLongLong();
   void PassOptionalLongLong(const Optional<int64_t>&);
   void PassOptionalLongLongWithDefault(int64_t);
 
-  uint8_t GetReadonlyOctet();
-  uint8_t GetWritableOctet();
+  uint8_t ReadonlyOctet();
+  uint8_t WritableOctet();
   void SetWritableOctet(uint8_t);
   void PassOctet(uint8_t);
   uint8_t ReceiveOctet();
   void PassOptionalOctet(const Optional<uint8_t>&);
   void PassOptionalOctetWithDefault(uint8_t);
 
-  uint16_t GetReadonlyUnsignedShort();
-  uint16_t GetWritableUnsignedShort();
+  uint16_t ReadonlyUnsignedShort();
+  uint16_t WritableUnsignedShort();
   void SetWritableUnsignedShort(uint16_t);
   void PassUnsignedShort(uint16_t);
   uint16_t ReceiveUnsignedShort();
   void PassOptionalUnsignedShort(const Optional<uint16_t>&);
   void PassOptionalUnsignedShortWithDefault(uint16_t);
 
-  uint32_t GetReadonlyUnsignedLong();
-  uint32_t GetWritableUnsignedLong();
+  uint32_t ReadonlyUnsignedLong();
+  uint32_t WritableUnsignedLong();
   void SetWritableUnsignedLong(uint32_t);
   void PassUnsignedLong(uint32_t);
   uint32_t ReceiveUnsignedLong();
   void PassOptionalUnsignedLong(const Optional<uint32_t>&);
   void PassOptionalUnsignedLongWithDefault(uint32_t);
 
-  uint64_t GetReadonlyUnsignedLongLong();
-  uint64_t GetWritableUnsignedLongLong();
+  uint64_t ReadonlyUnsignedLongLong();
+  uint64_t WritableUnsignedLongLong();
   void SetWritableUnsignedLongLong(uint64_t);
   void PassUnsignedLongLong(uint64_t);
   uint64_t ReceiveUnsignedLongLong();
   void PassOptionalUnsignedLongLong(const Optional<uint64_t>&);
   void PassOptionalUnsignedLongLongWithDefault(uint64_t);
 
   // Interface types
   already_AddRefed<TestInterface> ReceiveSelf();
   already_AddRefed<TestInterface> ReceiveNullableSelf();
   TestInterface* ReceiveWeakSelf();
   TestInterface* ReceiveWeakNullableSelf();
   void PassSelf(TestInterface&);
   void PassSelf2(NonNull<TestInterface>&);
   void PassNullableSelf(TestInterface*);
-  already_AddRefed<TestInterface> GetNonNullSelf();
+  already_AddRefed<TestInterface> NonNullSelf();
   void SetNonNullSelf(TestInterface&);
   already_AddRefed<TestInterface> GetNullableSelf();
   void SetNullableSelf(TestInterface*);
   void PassOptionalSelf(const Optional<TestInterface*> &);
   void PassOptionalNonNullSelf(const Optional<NonNull<TestInterface> >&);
   void PassOptionalSelfWithDefault(TestInterface*);
 
   already_AddRefed<TestNonWrapperCacheInterface> ReceiveNonWrapperCacheInterface();
@@ -219,47 +219,47 @@ public:
 
   already_AddRefed<TestNonCastableInterface> ReceiveOther();
   already_AddRefed<TestNonCastableInterface> ReceiveNullableOther();
   TestNonCastableInterface* ReceiveWeakOther();
   TestNonCastableInterface* ReceiveWeakNullableOther();
   void PassOther(TestNonCastableInterface&);
   void PassOther2(NonNull<TestNonCastableInterface>&);
   void PassNullableOther(TestNonCastableInterface*);
-  already_AddRefed<TestNonCastableInterface> GetNonNullOther();
+  already_AddRefed<TestNonCastableInterface> NonNullOther();
   void SetNonNullOther(TestNonCastableInterface&);
   already_AddRefed<TestNonCastableInterface> GetNullableOther();
   void SetNullableOther(TestNonCastableInterface*);
   void PassOptionalOther(const Optional<TestNonCastableInterface*>&);
   void PassOptionalNonNullOther(const Optional<NonNull<TestNonCastableInterface> >&);
   void PassOptionalOtherWithDefault(TestNonCastableInterface*);
 
   already_AddRefed<TestExternalInterface> ReceiveExternal();
   already_AddRefed<TestExternalInterface> ReceiveNullableExternal();
   TestExternalInterface* ReceiveWeakExternal();
   TestExternalInterface* ReceiveWeakNullableExternal();
   void PassExternal(TestExternalInterface*);
   void PassExternal2(TestExternalInterface*);
   void PassNullableExternal(TestExternalInterface*);
-  already_AddRefed<TestExternalInterface> GetNonNullExternal();
+  already_AddRefed<TestExternalInterface> NonNullExternal();
   void SetNonNullExternal(TestExternalInterface*);
   already_AddRefed<TestExternalInterface> GetNullableExternal();
   void SetNullableExternal(TestExternalInterface*);
   void PassOptionalExternal(const Optional<TestExternalInterface*>&);
   void PassOptionalNonNullExternal(const Optional<TestExternalInterface*>&);
   void PassOptionalExternalWithDefault(TestExternalInterface*);
 
   already_AddRefed<TestCallbackInterface> ReceiveCallbackInterface();
   already_AddRefed<TestCallbackInterface> ReceiveNullableCallbackInterface();
   TestCallbackInterface* ReceiveWeakCallbackInterface();
   TestCallbackInterface* ReceiveWeakNullableCallbackInterface();
   void PassCallbackInterface(TestCallbackInterface&);
   void PassCallbackInterface2(OwningNonNull<TestCallbackInterface>);
   void PassNullableCallbackInterface(TestCallbackInterface*);
-  already_AddRefed<TestCallbackInterface> GetNonNullCallbackInterface();
+  already_AddRefed<TestCallbackInterface> NonNullCallbackInterface();
   void SetNonNullCallbackInterface(TestCallbackInterface&);
   already_AddRefed<TestCallbackInterface> GetNullableCallbackInterface();
   void SetNullableCallbackInterface(TestCallbackInterface*);
   void PassOptionalCallbackInterface(const Optional<nsRefPtr<TestCallbackInterface> >&);
   void PassOptionalNonNullCallbackInterface(const Optional<OwningNonNull<TestCallbackInterface> >&);
   void PassOptionalCallbackInterfaceWithDefault(TestCallbackInterface*);
 
   already_AddRefed<IndirectlyImplementedInterface> ReceiveConsequentialInterface();
@@ -321,18 +321,18 @@ public:
   void PassOptionalNullableString(const Optional<nsAString>&);
   void PassOptionalNullableStringWithDefaultValue(const nsAString&);
 
   // Enumarated types
   void PassEnum(TestEnum);
   void PassOptionalEnum(const Optional<TestEnum>&);
   void PassEnumWithDefault(TestEnum);
   TestEnum ReceiveEnum();
-  TestEnum GetEnumAttribute();
-  TestEnum GetReadonlyEnumAttribute();
+  TestEnum EnumAttribute();
+  TestEnum ReadonlyEnumAttribute();
   void SetEnumAttribute(TestEnum);
 
   // Callback types
   void PassCallback(JSContext*, JSObject*);
   void PassNullableCallback(JSContext*, JSObject*);
   void PassOptionalCallback(JSContext*, const Optional<JSObject*>&);
   void PassOptionalNullableCallback(JSContext*, const Optional<JSObject*>&);
   void PassOptionalNullableCallbackWithDefaultValue(JSContext*, JSObject*);
@@ -379,44 +379,44 @@ public:
   void PassUnionWithString(JSContext*, const StringOrObject&);
   //void PassUnionWithEnum(JSContext*, const TestEnumOrObject&);
   void PassUnionWithCallback(JSContext*, const TestCallbackOrLong&);
   void PassUnionWithObject(JSContext*, const ObjectOrLong&);
 
   // binaryNames tests
   void MethodRenamedTo();
   void MethodRenamedTo(int8_t);
-  int8_t GetAttributeGetterRenamedTo();
-  int8_t GetAttributeRenamedTo();
+  int8_t AttributeGetterRenamedTo();
+  int8_t AttributeRenamedTo();
   void SetAttributeRenamedTo(int8_t);
 
   // Dictionary tests
   void PassDictionary(const Dict&);
   void PassOtherDictionary(const GrandparentDict&);
   void PassSequenceOfDictionaries(const Sequence<Dict>&);
   void PassDictionaryOrLong(const Dict&);
   void PassDictionaryOrLong(int32_t);
   void PassDictContainingDict(const DictContainingDict&);
 
   // Typedefs
   void ExerciseTypedefInterfaces1(TestInterface&);
   already_AddRefed<TestInterface> ExerciseTypedefInterfaces2(TestInterface*);
   void ExerciseTypedefInterfaces3(TestInterface&);
 
   // Methods and properties imported via "implements"
-  bool GetImplementedProperty();
+  bool ImplementedProperty();
   void SetImplementedProperty(bool);
   void ImplementedMethod();
-  bool GetImplementedParentProperty();
+  bool ImplementedParentProperty();
   void SetImplementedParentProperty(bool);
   void ImplementedParentMethod();
-  bool GetIndirectlyImplementedProperty();
+  bool IndirectlyImplementedProperty();
   void SetIndirectlyImplementedProperty(bool);
   void IndirectlyImplementedMethod();
-  uint32_t GetDiamondImplementedProperty();
+  uint32_t DiamondImplementedProperty();
 
   // Test EnforceRange/Clamp
   void DontEnforceRangeOrClamp(int8_t);
   void DoEnforceRange(int8_t);
   void DoClamp(int8_t);
 
 private:
   // We add signatures here that _could_ start matching if the codegen
@@ -551,17 +551,17 @@ public:
 
   // We need a GetParentObject to make binding codegen happy
   virtual nsISupports* GetParentObject();
 
   uint32_t IndexedGetter(uint32_t, bool&);
   uint32_t IndexedGetter(uint32_t&) MOZ_DELETE;
   uint32_t Item(uint32_t&);
   uint32_t Item(uint32_t, bool&) MOZ_DELETE;
-  uint32_t GetLength();
+  uint32_t Length();
 };
 
 class TestNamedGetterInterface : public nsISupports,
                                  public nsWrapperCache
 {
 public:
   NS_DECL_ISUPPORTS
 
@@ -578,17 +578,17 @@ public:
   NS_DECL_ISUPPORTS
 
   // We need a GetParentObject to make binding codegen happy
   virtual nsISupports* GetParentObject();
 
   uint32_t IndexedGetter(uint32_t, bool&);
   void NamedGetter(const nsAString&, bool&, nsAString&);
   void NamedItem(const nsAString&, nsAString&);
-  uint32_t GetLength();
+  uint32_t Length();
 };
 
 class TestIndexedSetterInterface : public nsISupports,
                                    public nsWrapperCache
 {
 public:
   NS_DECL_ISUPPORTS
 
@@ -631,15 +631,15 @@ public:
   uint32_t IndexedGetter(uint32_t, bool&);
   uint32_t Item(uint32_t);
   void NamedGetter(const nsAString&, bool&, nsAString&);
   void NamedItem(const nsAString&, nsAString&);
   void IndexedSetter(uint32_t, int32_t&);
   void IndexedSetter(uint32_t, const nsAString&) MOZ_DELETE;
   void NamedSetter(const nsAString&, const nsAString&);
   void Stringify(nsAString&);
-  uint32_t GetLength();
+  uint32_t Length();
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif /* TestBindingHeader_h */
--- a/dom/bluetooth/Makefile.in
+++ b/dom/bluetooth/Makefile.in
@@ -83,10 +83,11 @@ LOCAL_INCLUDES += -I$(DEPTH)/ipc/ipdl/_i
 LOCAL_INCLUDES += $(VPATH:%=-I%)
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
 
 XPIDL_FLAGS += \
+  -I$(topsrcdir)/dom/interfaces/base \
   -I$(topsrcdir)/dom/interfaces/events \
   $(NULL)
--- a/dom/camera/Makefile.in
+++ b/dom/camera/Makefile.in
@@ -49,10 +49,11 @@ EXPORTS = \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 XPIDL_FLAGS += \
   -I$(topsrcdir)/dom/base \
   -I$(topsrcdir)/dom/interfaces/base \
+  -I$(topsrcdir)/dom/interfaces/events \
   -I$(topsrcdir)/dom/media \
   $(NULL)
--- a/dom/dom-config.mk
+++ b/dom/dom-config.mk
@@ -14,16 +14,17 @@ DOM_SRCDIRS = \
   dom/contacts \
   dom/alarm \
   dom/src/events \
   dom/src/storage \
   dom/src/offline \
   dom/src/geolocation \
   dom/src/notification \
   dom/workers \
+  dom/time \
   content/xbl/src \
   content/xul/document/src \
   content/events/src \
   content/base/src \
   content/html/content/src \
   content/html/document/src \
   content/media/webaudio \
   content/svg/content/src \
--- a/dom/file/Makefile.in
+++ b/dom/file/Makefile.in
@@ -67,9 +67,11 @@ XPIDLSRCS = \
   $(NULL)
 
 TEST_DIRS += test
 
 include $(topsrcdir)/config/rules.mk
 
 XPIDL_FLAGS += \
   -I$(topsrcdir)/dom/base \
+  -I$(topsrcdir)/dom/interfaces/base \
+  -I$(topsrcdir)/dom/interfaces/events \
   $(NULL)
--- a/dom/icc/interfaces/Makefile.in
+++ b/dom/icc/interfaces/Makefile.in
@@ -14,8 +14,12 @@ XPIDL_MODULE = dom_icc
 include $(topsrcdir)/dom/dom-config.mk
 
 XPIDLSRCS = \
   nsIDOMIccManager.idl \
   SimToolKit.idl \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
+XPIDL_FLAGS += \
+  -I$(topsrcdir)/dom/interfaces/base \
+  -I$(topsrcdir)/dom/interfaces/events \
+  $(NULL)
--- a/dom/indexedDB/Makefile.in
+++ b/dom/indexedDB/Makefile.in
@@ -98,10 +98,11 @@ XPIDLSRCS = \
 DIRS += ipc
 TEST_DIRS += test
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
 XPIDL_FLAGS += \
+  -I$(topsrcdir)/dom/interfaces/base \
   -I$(topsrcdir)/dom/interfaces/events \
   $(NULL)
--- a/dom/interfaces/apps/Makefile.in
+++ b/dom/interfaces/apps/Makefile.in
@@ -12,16 +12,17 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE         = dom
 XPIDL_MODULE   = dom_apps
 GRE_MODULE     = 1
 
 XPIDLSRCS =                               \
             mozIApplication.idl \
             nsIDOMApplicationRegistry.idl \
+            nsIDOMApplicationRegistry2.idl \
             nsIAppsService.idl \
             nsIDOMMozApplicationEvent.idl \
             $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 XPIDL_FLAGS += \
   -I$(topsrcdir)/dom/interfaces/base \
--- a/dom/interfaces/apps/nsIDOMApplicationRegistry.idl
+++ b/dom/interfaces/apps/nsIDOMApplicationRegistry.idl
@@ -68,17 +68,17 @@ interface mozIDOMApplicationMgmt : nsISu
   /**
    * event listener to get notified of application uninstalls. Only settable by
    * privileged callers.
    * the event will be a mozIDOMApplicationEvent
    */
   attribute nsIDOMEventListener onuninstall;
 };
 
-[scriptable, uuid(8ce06dd2-4c2e-4523-8ea1-960f4a7f0456)]
+[scriptable, uuid(dd9a044c-1073-4d2b-a17d-c9b5834b3420)]
 interface mozIDOMApplicationRegistry : nsISupports
 {
   /**
    * Install a web app.
    *
    * @param manifestUrl : the URL of the webapps manifest.
    * @param parameters  : A structure with optional information.
    *                      {
@@ -94,23 +94,10 @@ interface mozIDOMApplicationRegistry : n
    */
   nsIDOMDOMRequest getSelf();
 
   /**
    * the request will return the applications installed from this origin, or null.
    */
   nsIDOMDOMRequest getInstalled();
 
-  /**
-   * Install a packaged web app.
-   *
-   * @param packageUrl : the URL of the webapps manifest.
-   * @param parameters : A structure with optional information.
-   *                      {
-   *                       receipts: ...    Will be used to specify the payment receipts for this installation.
-   *                       categories: ...  Will be used to specify the categories of the webapp.
-   *                      }
-   * @returns          : A DOMRequest object, returning the app object in |result| if install succeeds.
-   */
-  nsIDOMDOMRequest installPackage(in DOMString packageUrl, [optional] in jsval parameters);
-
   readonly attribute mozIDOMApplicationMgmt mgmt;
 };
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/apps/nsIDOMApplicationRegistry2.idl
@@ -0,0 +1,24 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIDOMApplicationRegistry.idl"
+
+interface nsIDOMDOMRequest;
+
+[scriptable, uuid(34498a66-3aee-4b80-8b8b-a9c5d5ba32b6)]
+interface mozIDOMApplicationRegistry2 : mozIDOMApplicationRegistry
+{
+  /**
+   * Install a packaged web app.
+   *
+   * @param packageUrl : the URL of the webapps manifest.
+   * @param parameters : A structure with optional information.
+   *                      {
+   *                       receipts: ...    Will be used to specify the payment receipts for this installation.
+   *                       categories: ...  Will be used to specify the categories of the webapp.
+   *                      }
+   * @returns          : A DOMRequest object, returning the app object in |result| if install succeeds.
+   */
+  nsIDOMDOMRequest installPackage(in DOMString packageUrl, [optional] in jsval parameters);
+};
--- a/dom/interfaces/base/Makefile.in
+++ b/dom/interfaces/base/Makefile.in
@@ -54,9 +54,11 @@ XPIDLSRCS =					\
 	nsIDOMGlobalPropertyInitializer.idl	\
 	nsIDOMGlobalObjectConstructor.idl \
 	nsIStructuredCloneContainer.idl		\
 	nsIIdleObserver.idl			\
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
-XPIDL_FLAGS += -I$(topsrcdir)/dom/interfaces/events/
+XPIDL_FLAGS += \
+  -I$(topsrcdir)/dom/interfaces/events \
+  $(NULL)
--- a/dom/interfaces/base/nsIDOMScreen.idl
+++ b/dom/interfaces/base/nsIDOMScreen.idl
@@ -1,16 +1,16 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMEventTarget.idl"
 
-[scriptable, builtinclass, uuid(5a8294df-ffe4-48e5-803f-f57bebc29289)]
+[scriptable, builtinclass, uuid(01e8587b-35a9-4a59-8349-c7ee93846fb2)]
 interface nsIDOMScreen : nsIDOMEventTarget
 {
   readonly attribute long             top;
   readonly attribute long             left;
   readonly attribute long             width;
   readonly attribute long             height;
   readonly attribute long             pixelDepth;
   readonly attribute long             colorDepth;
@@ -24,17 +24,38 @@ interface nsIDOMScreen : nsIDOMEventTarg
    * Can be: landscape-primary, landscape-secondary,
    *         portrait-primary or portrait-secondary.
    */
   readonly attribute DOMString       mozOrientation;
 
   [implicit_jscontext] attribute jsval      onmozorientationchange;
 
   /**
-   * Lock screen orientation to the specified type.
+   * Lock the screen to the specified orientations(s).  This method returns true
+   * if the lock was acquired successfully, and false otherwise.
+   *
+   * The parameter can be a DOMString or an Array of DOMStrings.  If you pass a
+   * string, we lock the screen to that one orientation.  If you pass an Array,
+   * we ensure that the screen is always in one of the given orientations.
+   *
+   * Valid orientations are "portrait", "portrait-primary",
+   * "portrait-secondary", "landscape", "landscape-primary", and
+   * "landscape-secondary".
+   * These tokens are case-sensitive.
+   *
+   * If you pass a string that's not one of the valid orientations, or if you
+   * pass an array of orientations and any of the orientations in the array is
+   * not valid, we reject the lock and return false.
+   *
+   * The "-primary" orientations correspond to holding the device right-side up,
+   * while the "-secondary" orientations correspond to holding the device
+   * upside-down.	Locking the orientation in "portrait" is the same as locking
+   * the orientation in ['portrait-primary', 'portrait-secondary'], and the
+   * "landscape" orientation similarly corresponds to the set
+   * ['landscape-primary', 'landscape-secondary'].
    */
-  boolean mozLockOrientation(in DOMString orientation);
+  [implicit_jscontext] boolean mozLockOrientation(in jsval orientation);
 
   /**
    * Unlock the screen orientation.
    */
   void mozUnlockOrientation();
 };
--- a/dom/interfaces/base/nsIDOMWindow.idl
+++ b/dom/interfaces/base/nsIDOMWindow.idl
@@ -27,17 +27,17 @@ interface nsIDOMMozURLProperty : nsISupp
  * The nsIDOMWindow interface is the primary interface for a DOM
  * window object. It represents a single window object that may
  * contain child windows if the document in the window contains a
  * HTML frameset document or if the document contains iframe elements.
  *
  * @see <http://www.whatwg.org/html/#window>
  */
 
-[scriptable, uuid(afeb6529-06f1-47e8-98c6-c7bfadb4c1ff)]
+[scriptable, uuid(AB4ED3B8-84F8-4585-B413-0996A7F96D20)]
 interface nsIDOMWindow : nsISupports
 {
   // the current browsing context
   readonly attribute nsIDOMWindow                       window;
 
   /* [replaceable] self */
   readonly attribute nsIDOMWindow                       self;
 
@@ -492,16 +492,17 @@ interface nsIDOMWindow : nsISupports
   /**
    * Non-HTML5 window-specific event attributes
    */
   [implicit_jscontext] attribute jsval ondevicemotion;
   [implicit_jscontext] attribute jsval ondeviceorientation;
   [implicit_jscontext] attribute jsval ondeviceproximity;
   [implicit_jscontext] attribute jsval onuserproximity;
   [implicit_jscontext] attribute jsval ondevicelight;
+  [implicit_jscontext] attribute jsval onmoztimechange;
 
   [implicit_jscontext] attribute jsval onmouseenter;
   [implicit_jscontext] attribute jsval onmouseleave;
 };
 
 [scriptable, uuid(2146c906-57f7-486c-a1b4-8cdb57ef577f)]
 interface nsIDOMWindowPerformance : nsISupports
 {
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -33,18 +33,19 @@ interface nsIDOMEvent;
 interface nsITransferable;
 interface nsIQueryContentEventResult;
 interface nsIDOMWindow;
 interface nsIDOMBlob;
 interface nsIDOMFile;
 interface nsIFile;
 interface nsIDOMTouch;
 interface nsIDOMClientRect;
+interface nsIURI;
 
-[scriptable, uuid(8A7DA5AF-26FD-4449-8887-9BEADC938B0A)]
+[scriptable, uuid(37cf79ee-fe7a-4d5a-9e41-e2186553969f)]
 interface nsIDOMWindowUtils : nsISupports {
 
   /**
    * Image animation mode of the window. When this attribute's value
    * is changed, the implementation should set all images in the window
    * to the given value. That is, when set to kDontAnimMode, all images
    * will stop animating. The attribute's value must be one of the
    * animationMode values from imgIContainer.
@@ -1231,9 +1232,31 @@ interface nsIDOMWindowUtils : nsISupport
    */
   void setScrollPositionClampingScrollPortSize(in float aWidth, in float aHeight);
 
   /**
    * Prevent this window (and any child windows) from displaying any further
    * dialogs (e.g. window.alert()).
    */
   void preventFurtherDialogs();
+
+  const unsigned long AGENT_SHEET = 0;
+  const unsigned long USER_SHEET = 1;
+  /**
+   * Synchronously loads a style sheet from |sheetURI| and adds it to the list
+   * of additional style sheets of the document.
+   *
+   * These additional style sheets are very much like user/agent sheets loaded 
+   * with loadAndRegisterSheet. The only difference is that they are applied only
+   * on the document owned by this window.
+   *
+   * Sheets added via this API take effect immediately on the document.
+   */
+  void loadSheet(in nsIURI sheetURI,
+                           in unsigned long type);
+
+  /**
+   * Remove the document style sheet at |sheetURI| from the list of additional 
+   * style sheets of the document.  The removal takes effect immediately.
+   */
+  void removeSheet(in nsIURI sheetURI,
+                                in unsigned long type);
 };
--- a/dom/interfaces/load-save/Makefile.in
+++ b/dom/interfaces/load-save/Makefile.in
@@ -14,10 +14,11 @@ XPIDL_MODULE	= dom_loadsave
 
 XPIDLSRCS =                                     \
 		nsIDOMLSProgressEvent.idl       \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 XPIDL_FLAGS += \
+  -I$(topsrcdir)/dom/interfaces/base \
   -I$(topsrcdir)/dom/interfaces/events \
   $(NULL)
--- a/dom/interfaces/smil/Makefile.in
+++ b/dom/interfaces/smil/Makefile.in
@@ -17,11 +17,13 @@ XPIDL_MODULE	= dom_smil
 XPIDLSRCS	= \
 		nsIDOMElementTimeControl.idl \
 		nsIDOMTimeEvent.idl \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 XPIDL_FLAGS += \
+  -I$(topsrcdir)/dom/interfaces/base \
+  -I$(topsrcdir)/dom/interfaces/core \
   -I$(topsrcdir)/dom/interfaces/events \
   -I$(topsrcdir)/dom/interfaces/svg \
   $(NULL)
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -20,16 +20,17 @@
 #include "mozilla/layout/RenderFrameParent.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/unused.h"
 #include "nsCOMPtr.h"
 #include "nsContentPermissionHelper.h"
 #include "nsContentUtils.h"
 #include "nsDebug.h"
 #include "nsEventDispatcher.h"
+#include "nsEventStateManager.h"
 #include "nsFocusManager.h"
 #include "nsFrameLoader.h"
 #include "nsIContent.h"
 #include "nsIDOMApplicationRegistry.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMHTMLFrameElement.h"
@@ -61,29 +62,32 @@ using namespace mozilla::dom::indexedDB;
 
 // The flags passed by the webProgress notifications are 16 bits shifted
 // from the ones registered by webProgressListeners.
 #define NOTIFY_FLAG_SHIFT 16
 
 namespace mozilla {
 namespace dom {
 
+TabParent* sEventCapturer;
+
 TabParent *TabParent::mIMETabParent = nullptr;
 
 NS_IMPL_ISUPPORTS3(TabParent, nsITabParent, nsIAuthPromptProvider, nsISecureBrowserUI)
 
 TabParent::TabParent(mozIApplication* aApp, bool aIsBrowserElement)
   : mFrameElement(NULL)
   , mApp(aApp)
   , mIMESelectionAnchor(0)
   , mIMESelectionFocus(0)
   , mIMEComposing(false)
   , mIMECompositionEnding(false)
   , mIMECompositionStart(0)
   , mIMESeqno(0)
+  , mEventCaptureDepth(0)
   , mDPI(0)
   , mActive(false)
   , mIsBrowserElement(aIsBrowserElement)
   , mShown(false)
 {
 }
 
 TabParent::~TabParent()
@@ -116,18 +120,22 @@ TabParent::Recv__delete__()
   ContentParent* cp = static_cast<ContentParent*>(Manager());
   cp->NotifyTabDestroyed(this);
   return true;
 }
 
 void
 TabParent::ActorDestroy(ActorDestroyReason why)
 {
-  if (mIMETabParent == this)
+  if (sEventCapturer == this) {
+    sEventCapturer = nullptr;
+  }
+  if (mIMETabParent == this) {
     mIMETabParent = nullptr;
+  }
   nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
   if (frameLoader) {
     frameLoader->DestroyChild();
 
     if (why == AbnormalShutdown) {
       nsCOMPtr<nsIObserverService> os = services::GetObserverService();
       if (os) {
         os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, frameLoader),
@@ -356,31 +364,82 @@ bool TabParent::SendRealKeyEvent(nsKeyEv
 {
   nsKeyEvent e(event);
   MaybeForwardEventToRenderFrame(event, &e);
   return PBrowserParent::SendRealKeyEvent(e);
 }
 
 bool TabParent::SendRealTouchEvent(nsTouchEvent& event)
 {
+  if (event.message == NS_TOUCH_START) {
+    MOZ_ASSERT((!sEventCapturer && mEventCaptureDepth == 0) ||
+               (sEventCapturer == this && mEventCaptureDepth > 0));
+    // We want to capture all remaining touch events in this series
+    // for fast-path dispatch.
+    sEventCapturer = this;
+    ++mEventCaptureDepth;
+  }
+
   nsTouchEvent e(event);
-  // PresShell::HandleEventInternal adds touches on touch end/cancel.
+  // PresShell::HandleEventInternal adds touches on touch end/cancel,
+  // when we're not capturing raw events from the widget backend.
   // This hack filters those out. Bug 785554
-  if (event.message == NS_TOUCH_END || event.message == NS_TOUCH_CANCEL) {
+  if (sEventCapturer != this &&
+      (event.message == NS_TOUCH_END || event.message == NS_TOUCH_CANCEL)) {
     for (int i = e.touches.Length() - 1; i >= 0; i--) {
       if (!e.touches[i]->mChanged)
         e.touches.RemoveElementAt(i);
     }
   }
+
   MaybeForwardEventToRenderFrame(event, &e);
   return (e.message == NS_TOUCH_MOVE) ?
     PBrowserParent::SendRealTouchMoveEvent(e) :
     PBrowserParent::SendRealTouchEvent(e);
 }
 
+/*static*/ TabParent*
+TabParent::GetEventCapturer()
+{
+  return sEventCapturer;
+}
+
+bool
+TabParent::TryCapture(const nsGUIEvent& aEvent)
+{
+  MOZ_ASSERT(sEventCapturer == this && mEventCaptureDepth > 0);
+
+  if (aEvent.eventStructType != NS_TOUCH_EVENT) {
+    // Only capture of touch events is implemented, for now.
+    return false;
+  }
+
+  nsTouchEvent event(static_cast<const nsTouchEvent&>(aEvent));
+
+  bool isTouchPointUp = (event.message == NS_TOUCH_END ||
+                         event.message == NS_TOUCH_CANCEL);
+  if (event.message == NS_TOUCH_START || isTouchPointUp) {
+    // Let the DOM see touch start/end events so that its touch-point
+    // state stays consistent.
+    if (isTouchPointUp && 0 == --mEventCaptureDepth) {
+      // All event series are un-captured, don't try to catch any
+      // more.
+      sEventCapturer = nullptr;
+    }
+    return false;
+  }
+
+  // Adjust the widget coordinates to be relative to our frame.
+  nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
+  nsEventStateManager::MapEventCoordinatesForChildProcess(frameLoader, &event);
+
+  SendRealTouchEvent(event);
+  return true;
+}
+
 bool
 TabParent::RecvSyncMessage(const nsString& aMessage,
                            const ClonedMessageData& aData,
                            InfallibleTArray<nsString>* aJSONRetVal)
 {
   const SerializedStructuredCloneBuffer& buffer = aData.data();
   const InfallibleTArray<PBlobParent*>& blobParents = aData.blobsParent();
   StructuredCloneData cloneData;
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -61,16 +61,40 @@ public:
     nsIBrowserDOMWindow *GetBrowserDOMWindow() { return mBrowserDOMWindow; }
     void SetBrowserDOMWindow(nsIBrowserDOMWindow* aBrowserDOMWindow) {
         mBrowserDOMWindow = aBrowserDOMWindow;
     }
  
     mozIApplication* GetApp() { return mApp; }
     bool IsBrowserElement() { return mIsBrowserElement; }
 
+    /**
+     * Return the TabParent that has decided it wants to capture an
+     * event series for fast-path dispatch to its subprocess, if one
+     * has.
+     *
+     * DOM event dispatch and widget are free to ignore capture
+     * requests from TabParents; the end result wrt remote content is
+     * (must be) always the same, albeit usually slower without
+     * subprocess capturing.  This allows frontends/widget backends to
+     * "opt in" to faster cross-process dispatch.
+     */
+    static TabParent* GetEventCapturer();
+    /**
+     * If this is the current event capturer, give this a chance to
+     * capture the event.  If it was captured, return true, false
+     * otherwise.  Un-captured events should follow normal DOM
+     * dispatch; captured events should result in no further
+     * processing from the caller of TryCapture().
+     *
+     * It's an error to call TryCapture() if this isn't the event
+     * capturer.
+     */
+    bool TryCapture(const nsGUIEvent& aEvent);
+
     void Destroy();
 
     virtual bool RecvMoveFocus(const bool& aForward);
     virtual bool RecvEvent(const RemoteDOMEvent& aEvent);
     virtual bool RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
                                             const nsString& aURL,
                                             const nsString& aName,
                                             const nsString& aFeatures,
@@ -241,16 +265,19 @@ protected:
     bool mIMEComposing;
     bool mIMECompositionEnding;
     // Buffer to store composition text during ResetInputState
     // Compositions in almost all cases are small enough for nsAutoString
     nsAutoString mIMECompositionText;
     uint32_t mIMECompositionStart;
     uint32_t mIMESeqno;
 
+    // The number of event series we're currently capturing.
+    int32_t mEventCaptureDepth;
+
     float mDPI;
     bool mActive;
     bool mIsBrowserElement;
     bool mShown;
 
 private:
     already_AddRefed<nsFrameLoader> GetFrameLoader() const;
     already_AddRefed<nsIWidget> GetWidget() const;
--- a/dom/network/tests/unit/test_tcpsocket.js
+++ b/dom/network/tests/unit/test_tcpsocket.js
@@ -471,9 +471,14 @@ add_test(bufferTwice);
 
 // clean up
 add_test(cleanup);
 
 function run_test() {
   server = new TestServer();
 
   run_next_test();
+
+  do_timeout(10000, function() {
+    do_throw(
+      "The test should never take this long unless the system is hosed.");
+  });
 }
--- a/dom/payment/interfaces/Makefile.in
+++ b/dom/payment/interfaces/Makefile.in
@@ -13,8 +13,11 @@ XPIDL_MODULE = dom_payment
 
 XPIDLSRCS = nsIDOMNavigatorPayment.idl \
             nsIDOMPaymentRequestInfo.idl \
             nsIPaymentFlowInfo.idl \
             nsIPaymentUIGlue.idl \
             $(NULL)
 
 include $(topsrcdir)/config/rules.mk
+XPIDL_FLAGS += \
+  -I$(topsrcdir)/dom/interfaces/base \
+  $(NULL)
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -1439,16 +1439,19 @@ nsNPAPIPluginInstance::TimerWithID(uint3
     }
   }
   return nullptr;
 }
 
 uint32_t
 nsNPAPIPluginInstance::ScheduleTimer(uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID))
 {
+  if (RUNNING != mRunning)
+    return 0;
+
   nsNPAPITimer *newTimer = new nsNPAPITimer();
 
   newTimer->inCallback = false;
   newTimer->npp = &mNPP;
 
   // generate ID that is unique to this instance
   uint32_t uniqueID = mTimers.Length();
   while ((uniqueID == 0) || TimerWithID(uniqueID, NULL))
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -1801,16 +1801,19 @@ already_AddRefed<ImageContainer> nsPlugi
   pluginImage->SetData(data);
   container->SetCurrentImageInTransaction(img);
 
   return container.forget();
 }
 
 nsIntRect nsPluginInstanceOwner::GetVisibleRect()
 {
+  if (!mObjectFrame || !mPluginWindow)
+    return nsIntRect(0, 0, 0, 0);
+  
   gfxRect r = nsIntRect(0, 0, mPluginWindow->width, mPluginWindow->height);
 
   float xResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetXResolution();
   float yResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetYResolution();
   r.Scale(xResolution, yResolution);
 
   return nsIntRect(r.x, r.y, r.width, r.height);
 }
--- a/dom/sms/interfaces/Makefile.in
+++ b/dom/sms/interfaces/Makefile.in
@@ -25,10 +25,11 @@ XPIDLSRCS = \
   nsISmsRequestManager.idl \
   nsISmsService.idl \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 XPIDL_FLAGS += \
   -I$(topsrcdir)/dom/base \
+  -I$(topsrcdir)/dom/interfaces/base \
   -I$(topsrcdir)/dom/interfaces/events \
   $(NULL)
--- a/dom/telephony/Makefile.in
+++ b/dom/telephony/Makefile.in
@@ -34,10 +34,11 @@ XPIDLSRCS = \
   nsIDOMVoicemailEvent.idl \
   nsIDOMVoicemailStatus.idl \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 XPIDL_FLAGS += \
   -I$(topsrcdir)/dom/base \
+  -I$(topsrcdir)/dom/interfaces/base \
   -I$(topsrcdir)/dom/interfaces/events \
   $(NULL)
--- a/dom/tests/mochitest/webapps/test_install_errors.xul
+++ b/dom/tests/mochitest/webapps/test_install_errors.xul
@@ -19,16 +19,17 @@
 <script> 
 
 var steps = [
   noArgs,
   parseError,
   invalidManifest,
   permissionDenied,
   invalidContent,
+  installPackageNotImplemented,
 ];
 
 runAll(steps);
 
 function noArgs(next) {
   try { 
     navigator.mozApps.install();
   } catch (e) {
@@ -91,10 +92,16 @@ function invalidContent(next) {
   request.onsuccess = function onInstall() {
     todo(false, "manifest with bad content type fails");
     this.result.uninstall().onsuccess = function onUninstall() {
       next();
     };
   };
 }
 
+function installPackageNotImplemented(next) {
+  ok(!("installPackage" in navigator.mozApps),
+     "installPackage not in navigator.mozApps");
+  next();
+}
+
 </script>
 </window>
--- a/dom/tests/mochitest/webapps/test_list_api.xul
+++ b/dom/tests/mochitest/webapps/test_list_api.xul
@@ -18,17 +18,16 @@
 
 <script>
 
 var props = {
   QueryInterface: "function",
   getInstalled: "function",
   getSelf: "function",
   install: "function",
-  installPackage: "function",
   mgmt: "object",
 };
 
 isDeeply([p for (p in navigator.mozApps)].sort(), Object.keys(props).sort(),
          "navigator.mozApps has only the expected properties");
 
 for (var p in props) {
   is(typeof navigator.mozApps[p], props[p], "typeof " + p);
new file mode 100644
--- /dev/null
+++ b/dom/time/Makefile.in
@@ -0,0 +1,35 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH            = ../..
+topsrcdir        = @top_srcdir@
+srcdir           = @srcdir@
+VPATH            = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+LIBRARY_NAME     = dom_time_s
+XPIDL_MODULE     = dom_time
+LIBXUL_LIBRARY   = 1
+FORCE_STATIC_LIB = 1
+
+include $(topsrcdir)/dom/dom-config.mk
+
+CPPSRCS = \
+  TimeManager.cpp \
+  TimeChangeObserver.cpp \
+  $(NULL)
+
+EXPORTS = \
+  TimeChangeObserver.h \
+  $(NULL)
+
+XPIDLSRCS = \
+  nsIDOMNavigatorTime.idl \
+  nsIDOMTimeManager.idl \
+  $(NULL)
+
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/dom/time/TimeChangeObserver.cpp
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "TimeChangeObserver.h"
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/StaticPtr.h"
+#include "nsPIDOMWindow.h"
+#include "nsDOMEvent.h"
+#include "nsContentUtils.h"
+
+using namespace mozilla::hal;
+using namespace mozilla;
+
+StaticAutoPtr<nsSystemTimeChangeObserver> sObserver;
+
+nsSystemTimeChangeObserver* nsSystemTimeChangeObserver::GetInstance()
+{
+  if (!sObserver) {
+    sObserver = new nsSystemTimeChangeObserver();
+    ClearOnShutdown(&sObserver);
+  }
+  return sObserver;
+}
+
+nsSystemTimeChangeObserver::~nsSystemTimeChangeObserver()
+{
+  mWindowListeners.Clear();
+  UnregisterSystemTimeChangeObserver(this);
+}
+
+void
+nsSystemTimeChangeObserver::Notify(const SystemTimeChange& aReason)
+{
+  //Copy mWindowListeners and iterate over windowListeners instead because
+  //mWindowListeners may be modified while we loop.
+  nsTArray<nsWeakPtr> windowListeners;
+  for (uint32 i = 0; i < mWindowListeners.Length(); i++) {
+    windowListeners.AppendElement(mWindowListeners.SafeElementAt(i));
+  }
+
+  for (int32 i = windowListeners.Length() - 1; i >= 0; i--) {
+    nsCOMPtr<nsIDOMWindow> window = do_QueryReferent(windowListeners[i]);
+    if (!window) {
+      mWindowListeners.RemoveElement(windowListeners[i]);
+      return;
+    }
+
+    nsCOMPtr<nsIDOMDocument> domdoc;
+    window->GetDocument(getter_AddRefs(domdoc));
+    nsCOMPtr<nsIDocument> doc(do_QueryInterface(domdoc));
+    if (!domdoc) {
+      return;
+    }
+
+    nsContentUtils::DispatchTrustedEvent(doc, window,
+      NS_LITERAL_STRING("moztimechange"), /* bubbles = */ true,
+      /* canceable = */ false);
+  }
+}
+
+nsresult
+nsSystemTimeChangeObserver::AddWindowListener(nsIDOMWindow* aWindow)
+{
+  return GetInstance()->AddWindowListenerImpl(aWindow);
+}
+
+nsresult
+nsSystemTimeChangeObserver::AddWindowListenerImpl(nsIDOMWindow* aWindow)
+{
+  if (!aWindow) {
+    return NS_ERROR_ILLEGAL_VALUE;
+  }
+
+  if (mWindowListeners.IndexOf(NS_GetWeakReference(aWindow)) !=
+      nsTArray<nsIDOMWindow*>::NoIndex) {
+    return NS_OK;
+  }
+
+  if (mWindowListeners.Length() == 0) {
+    RegisterSystemTimeChangeObserver(sObserver);
+  }
+
+  mWindowListeners.AppendElement(NS_GetWeakReference(aWindow));
+  return NS_OK;
+}
+
+nsresult
+nsSystemTimeChangeObserver::RemoveWindowListener(nsIDOMWindow* aWindow)
+{
+  if (!sObserver) {
+    return NS_OK;
+  }
+
+  return GetInstance()->RemoveWindowListenerImpl(aWindow);
+}
+
+nsresult
+nsSystemTimeChangeObserver::RemoveWindowListenerImpl(nsIDOMWindow* aWindow)
+{
+  mWindowListeners.RemoveElement(NS_GetWeakReference(aWindow));
+
+  if (mWindowListeners.Length() == 0) {
+    UnregisterSystemTimeChangeObserver(sObserver);
+  }
+
+  return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/dom/time/TimeChangeObserver.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _mozilla_time_change_observer_h_
+#define _mozilla_time_change_observer_h_
+
+#include "mozilla/Hal.h"
+#include "mozilla/Observer.h"
+#include "mozilla/HalTypes.h"
+#include "nsPIDOMWindow.h"
+#include "nsWeakPtr.h"
+
+typedef mozilla::Observer<mozilla::hal::SystemTimeChange> SystemTimeChangeObserver;
+
+class nsSystemTimeChangeObserver : public SystemTimeChangeObserver
+{
+public:
+  static nsSystemTimeChangeObserver* GetInstance();
+  virtual ~nsSystemTimeChangeObserver();
+  void Notify(const mozilla::hal::SystemTimeChange& aReason);
+  static nsresult AddWindowListener(nsIDOMWindow* aWindow);
+  static nsresult RemoveWindowListener(nsIDOMWindow* aWindow);
+private:
+  nsresult AddWindowListenerImpl(nsIDOMWindow* aWindow);
+  nsresult RemoveWindowListenerImpl(nsIDOMWindow* aWindow);
+  nsSystemTimeChangeObserver() { };
+  nsTArray<nsWeakPtr> mWindowListeners;
+};
+
+#endif //_mozilla_time_change_observer_h_
new file mode 100644
--- /dev/null
+++ b/dom/time/TimeManager.cpp
@@ -0,0 +1,57 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#include "jsapi.h"
+#include "mozilla/Hal.h"
+#include "nsDOMEvent.h"
+#include "nsDOMEventTargetHelper.h"
+#include "nsIDOMClassInfo.h"
+#include "prtime.h"
+#include "TimeManager.h"
+
+using namespace mozilla::hal;
+
+DOMCI_DATA(MozTimeManager, mozilla::dom::time::TimeManager)
+
+namespace mozilla {
+namespace dom {
+namespace time {
+
+NS_INTERFACE_MAP_BEGIN(TimeManager)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMMozTimeManager)
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozTimeManager)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_ADDREF(TimeManager)
+NS_IMPL_RELEASE(TimeManager)
+
+nsresult
+TimeManager::Set(const JS::Value& date, JSContext* ctx) {
+  double nowMSec = JS_Now() / 1000;
+  double dateMSec;
+
+  if (date.isObject()) {
+    JSObject* dateObj = JSVAL_TO_OBJECT(date);
+
+    if (JS_ObjectIsDate(ctx, dateObj) && js_DateIsValid(ctx, dateObj)) {
+      dateMSec = js_DateGetMsecSinceEpoch(ctx, dateObj);
+    }
+    else {
+      NS_WARN_IF_FALSE(JS_ObjectIsDate(ctx, dateObj), "This is not a Date object");
+      NS_WARN_IF_FALSE(js_DateIsValid(ctx, dateObj), "Date is not valid");
+      return NS_ERROR_INVALID_ARG;
+    }
+  } else if (date.isNumber()) {
+    dateMSec = date.toNumber();
+  } else {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  hal::AdjustSystemClock(JS_DoubleToInt32(dateMSec - nowMSec));
+  return NS_OK;
+}
+
+} // namespace time
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/time/TimeManager.h
@@ -0,0 +1,31 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_time_TimeManager_h
+#define mozilla_dom_time_TimeManager_h
+
+#include "mozilla/HalTypes.h"
+#include "nsIDOMTimeManager.h"
+#include "mozilla/Observer.h"
+
+class nsPIDOMWindow;
+
+namespace mozilla {
+
+typedef Observer<hal::SystemTimeChange> SystemTimeObserver;
+
+namespace dom {
+namespace time {
+class TimeManager : public nsIDOMMozTimeManager
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIDOMMOZTIMEMANAGER
+};
+
+} // namespace time
+} // namespace dom
+} // namespace mozilla
+
+#endif //mozilla_dom_time_TimeManager_h
new file mode 100644
--- /dev/null
+++ b/dom/time/nsIDOMNavigatorTime.idl
@@ -0,0 +1,13 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsIDOMMozTimeManager;
+
+[scriptable, uuid(befc186d-c249-4acb-8e70-8080f7b45e5c)]
+interface nsIDOMMozNavigatorTime : nsISupports
+{
+  readonly attribute nsIDOMMozTimeManager mozTime;
+};
new file mode 100644
--- /dev/null
+++ b/dom/time/nsIDOMTimeManager.idl
@@ -0,0 +1,20 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+[scriptable, builtinclass, uuid(d29beaaa-bd54-4fd5-9f18-e0eedb1dc96d)]
+interface nsIDOMMozTimeManager : nsISupports
+{
+  /* Set the system time.
+   *
+   * The |time| argument can be either a Date object or a number.
+   *
+   * - If |time| is a number, it's interpreted as seconds since the epoch 
+   *   (midnight UTC on January 1, 1970)
+   * - If |time| is a Date object, |set(time)| is equivalent to 
+   *   |set(time.getTime())|.
+   */
+  [implicit_jscontext] void set(in jsval time);
+};
--- a/dom/webidl/CSSStyleDeclaration.webidl
+++ b/dom/webidl/CSSStyleDeclaration.webidl
@@ -25,10 +25,10 @@ interface CSSStyleDeclaration {
   DOMString getPropertyPriority(DOMString property);
   // This would be nicer if it used a string default value of "".
   // See bug 759622.
   [Throws]
   void setProperty(DOMString property, DOMString value, [TreatNullAs=EmptyString] optional DOMString priority);
   [Throws]
   DOMString removeProperty(DOMString property);
 
-  readonly attribute CSSRule parentRule;
+  readonly attribute CSSRule? parentRule;
 };
--- a/dom/webidl/CanvasRenderingContext2D.webidl
+++ b/dom/webidl/CanvasRenderingContext2D.webidl
@@ -19,18 +19,19 @@ interface HTMLImageElement;
 interface HTMLVideoElement;
 interface ImageData;
 interface TextMetrics;
 interface Window;
 interface XULElement;
 
 interface CanvasRenderingContext2D {
 
-  // back-reference to the canvas
-  readonly attribute HTMLCanvasElement canvas;
+  // back-reference to the canvas.  Might be null if we're not
+  // associated with a canvas.
+  readonly attribute HTMLCanvasElement? canvas;
 
   // state
   void save(); // push state on state stack
   void restore(); // pop state stack and restore state
 
   // transformations (default transform is the identity matrix)
 // NOT IMPLEMENTED           attribute SVGMatrix currentTransform;
   [Throws]
--- a/dom/webidl/WebGLRenderingContext.webidl
+++ b/dom/webidl/WebGLRenderingContext.webidl
@@ -20,16 +20,33 @@
 // XXXbz all sorts of forward declarations for things that are not new
 // bindings yet.
 interface Event;
 interface HTMLCanvasElement;
 interface HTMLImageElement;
 interface HTMLVideoElement;
 interface ImageData;
 interface WebGLContextAttributes;
+
+typedef unsigned long  GLenum;
+typedef boolean        GLboolean;
+typedef unsigned long  GLbitfield;
+typedef byte           GLbyte;         /* 'byte' should be a signed 8 bit type. */
+typedef short          GLshort;
+typedef long           GLint;
+typedef long           GLsizei;
+typedef long long      GLintptr;
+typedef long long      GLsizeiptr;
+// Ideally the typedef below would use 'unsigned byte', but that doesn't currently exist in Web IDL.
+typedef octet          GLubyte;        /* 'octet' should be an unsigned 8 bit type. */
+typedef unsigned short GLushort;
+typedef unsigned long  GLuint;
+typedef float          GLfloat;
+typedef float          GLclampf;  
+
 /*dictionary WebGLContextAttributes {
     boolean alpha = true;
     boolean depth = true;
     boolean stencil = false;
     boolean antialias = true;
     boolean premultipliedAlpha = true;
     boolean preserveDrawingBuffer = false;
     };*/
@@ -53,739 +70,687 @@ interface WebGLUniformLocation {
 
 interface WebGLActiveInfo;
 
 interface WebGLShaderPrecisionFormat;
 
 interface WebGLRenderingContext {
 
     /* ClearBufferMask */
-    const unsigned long DEPTH_BUFFER_BIT               = 0x00000100;
-    const unsigned long STENCIL_BUFFER_BIT             = 0x00000400;
-    const unsigned long COLOR_BUFFER_BIT               = 0x00004000;
+    const GLenum DEPTH_BUFFER_BIT               = 0x00000100;
+    const GLenum STENCIL_BUFFER_BIT             = 0x00000400;
+    const GLenum COLOR_BUFFER_BIT               = 0x00004000;
     
     /* BeginMode */
-    const unsigned long POINTS                         = 0x0000;
-    const unsigned long LINES                          = 0x0001;
-    const unsigned long LINE_LOOP                      = 0x0002;
-    const unsigned long LINE_STRIP                     = 0x0003;
-    const unsigned long TRIANGLES                      = 0x0004;
-    const unsigned long TRIANGLE_STRIP                 = 0x0005;
-    const unsigned long TRIANGLE_FAN                   = 0x0006;
+    const GLenum POINTS                         = 0x0000;
+    const GLenum LINES                          = 0x0001;
+    const GLenum LINE_LOOP                      = 0x0002;
+    const GLenum LINE_STRIP                     = 0x0003;
+    const GLenum TRIANGLES                      = 0x0004;
+    const GLenum TRIANGLE_STRIP                 = 0x0005;
+    const GLenum TRIANGLE_FAN                   = 0x0006;
     
     /* AlphaFunction (not supported in ES20) */
     /*      NEVER */
     /*      LESS */
     /*      EQUAL */
     /*      LEQUAL */
     /*      GREATER */
     /*      NOTEQUAL */
     /*      GEQUAL */
     /*      ALWAYS */
     
     /* BlendingFactorDest */
-    const unsigned long ZERO                           = 0;
-    const unsigned long ONE                            = 1;
-    const unsigned long SRC_COLOR                      = 0x0300;
-    const unsigned long ONE_MINUS_SRC_COLOR            = 0x0301;
-    const unsigned long SRC_ALPHA                      = 0x0302;
-    const unsigned long ONE_MINUS_SRC_ALPHA            = 0x0303;
-    const unsigned long DST_ALPHA                      = 0x0304;
-    const unsigned long ONE_MINUS_DST_ALPHA            = 0x0305;
+    const GLenum ZERO                           = 0;
+    const GLenum ONE                            = 1;
+    const GLenum SRC_COLOR                      = 0x0300;
+    const GLenum ONE_MINUS_SRC_COLOR            = 0x0301;
+    const GLenum SRC_ALPHA                      = 0x0302;
+    const GLenum ONE_MINUS_SRC_ALPHA            = 0x0303;
+    const GLenum DST_ALPHA                      = 0x0304;
+    const GLenum ONE_MINUS_DST_ALPHA            = 0x0305;
     
     /* BlendingFactorSrc */
     /*      ZERO */
     /*      ONE */
-    const unsigned long DST_COLOR                      = 0x0306;
-    const unsigned long ONE_MINUS_DST_COLOR            = 0x0307;
-    const unsigned long SRC_ALPHA_SATURATE             = 0x0308;
+    const GLenum DST_COLOR                      = 0x0306;
+    const GLenum ONE_MINUS_DST_COLOR            = 0x0307;
+    const GLenum SRC_ALPHA_SATURATE             = 0x0308;
     /*      SRC_ALPHA */
     /*      ONE_MINUS_SRC_ALPHA */
     /*      DST_ALPHA */
     /*      ONE_MINUS_DST_ALPHA */
     
     /* BlendEquationSeparate */
-    const unsigned long FUNC_ADD                       = 0x8006;
-    const unsigned long BLEND_EQUATION                 = 0x8009;
-    const unsigned long BLEND_EQUATION_RGB             = 0x8009;   /* same as BLEND_EQUATION */
-    const unsigned long BLEND_EQUATION_ALPHA           = 0x883D;
+    const GLenum FUNC_ADD                       = 0x8006;
+    const GLenum BLEND_EQUATION                 = 0x8009;
+    const GLenum BLEND_EQUATION_RGB             = 0x8009;   /* same as BLEND_EQUATION */
+    const GLenum BLEND_EQUATION_ALPHA           = 0x883D;
     
     /* BlendSubtract */
-    const unsigned long FUNC_SUBTRACT                  = 0x800A;
-    const unsigned long FUNC_REVERSE_SUBTRACT          = 0x800B;
+    const GLenum FUNC_SUBTRACT                  = 0x800A;
+    const GLenum FUNC_REVERSE_SUBTRACT          = 0x800B;
     
     /* Separate Blend Functions */
-    const unsigned long BLEND_DST_RGB                  = 0x80C8;
-    const unsigned long BLEND_SRC_RGB                  = 0x80C9;
-    const unsigned long BLEND_DST_ALPHA                = 0x80CA;
-    const unsigned long BLEND_SRC_ALPHA                = 0x80CB;
-    const unsigned long CONSTANT_COLOR                 = 0x8001;
-    const unsigned long ONE_MINUS_CONSTANT_COLOR       = 0x8002;
-    const unsigned long CONSTANT_ALPHA                 = 0x8003;
-    const unsigned long ONE_MINUS_CONSTANT_ALPHA       = 0x8004;
-    const unsigned long BLEND_COLOR                    = 0x8005;
+    const GLenum BLEND_DST_RGB                  = 0x80C8;
+    const GLenum BLEND_SRC_RGB                  = 0x80C9;
+    const GLenum BLEND_DST_ALPHA                = 0x80CA;
+    const GLenum BLEND_SRC_ALPHA                = 0x80CB;
+    const GLenum CONSTANT_COLOR                 = 0x8001;
+    const GLenum ONE_MINUS_CONSTANT_COLOR       = 0x8002;
+    const GLenum CONSTANT_ALPHA                 = 0x8003;
+    const GLenum ONE_MINUS_CONSTANT_ALPHA       = 0x8004;
+    const GLenum BLEND_COLOR                    = 0x8005;
     
     /* Buffer Objects */
-    const unsigned long ARRAY_BUFFER                   = 0x8892;
-    const unsigned long ELEMENT_ARRAY_BUFFER           = 0x8893;
-    const unsigned long ARRAY_BUFFER_BINDING           = 0x8894;
-    const unsigned long ELEMENT_ARRAY_BUFFER_BINDING   = 0x8895;
+    const GLenum ARRAY_BUFFER                   = 0x8892;
+    const GLenum ELEMENT_ARRAY_BUFFER           = 0x8893;
+    const GLenum ARRAY_BUFFER_BINDING           = 0x8894;
+    const GLenum ELEMENT_ARRAY_BUFFER_BINDING   = 0x8895;
     
-    const unsigned long STREAM_DRAW                    = 0x88E0;
-    const unsigned long STATIC_DRAW                    = 0x88E4;
-    const unsigned long DYNAMIC_DRAW                   = 0x88E8;
+    const GLenum STREAM_DRAW                    = 0x88E0;
+    const GLenum STATIC_DRAW                    = 0x88E4;
+    const GLenum DYNAMIC_DRAW                   = 0x88E8;
     
-    const unsigned long BUFFER_SIZE                    = 0x8764;
-    const unsigned long BUFFER_USAGE                   = 0x8765;
+    const GLenum BUFFER_SIZE                    = 0x8764;
+    const GLenum BUFFER_USAGE                   = 0x8765;
     
-    const unsigned long CURRENT_VERTEX_ATTRIB          = 0x8626;
+    const GLenum CURRENT_VERTEX_ATTRIB          = 0x8626;
     
     /* CullFaceMode */
-    const unsigned long FRONT                          = 0x0404;
-    const unsigned long BACK                           = 0x0405;
-    const unsigned long FRONT_AND_BACK                 = 0x0408;
+    const GLenum FRONT                          = 0x0404;
+    const GLenum BACK                           = 0x0405;
+    const GLenum FRONT_AND_BACK                 = 0x0408;
     
     /* DepthFunction */
     /*      NEVER */
     /*      LESS */
     /*      EQUAL */
     /*      LEQUAL */
     /*      GREATER */
     /*      NOTEQUAL */
     /*      GEQUAL */
     /*      ALWAYS */
     
     /* EnableCap */
     /* TEXTURE_2D */
-    const unsigned long CULL_FACE                      = 0x0B44;
-    const unsigned long BLEND                          = 0x0BE2;
-    const unsigned long DITHER                         = 0x0BD0;
-    const unsigned long STENCIL_TEST                   = 0x0B90;
-    const unsigned long DEPTH_TEST                     = 0x0B71;
-    const unsigned long SCISSOR_TEST                   = 0x0C11;
-    const unsigned long POLYGON_OFFSET_FILL            = 0x8037;
-    const unsigned long SAMPLE_ALPHA_TO_COVERAGE       = 0x809E;
-    const unsigned long SAMPLE_COVERAGE                = 0x80A0;
+    const GLenum CULL_FACE                      = 0x0B44;
+    const GLenum BLEND                          = 0x0BE2;
+    const GLenum DITHER                         = 0x0BD0;
+    const GLenum STENCIL_TEST                   = 0x0B90;
+    const GLenum DEPTH_TEST                     = 0x0B71;
+    const GLenum SCISSOR_TEST                   = 0x0C11;
+    const GLenum POLYGON_OFFSET_FILL            = 0x8037;
+    const GLenum SAMPLE_ALPHA_TO_COVERAGE       = 0x809E;
+    const GLenum SAMPLE_COVERAGE                = 0x80A0;
     
     /* ErrorCode */
-    const unsigned long NO_ERROR                       = 0;
-    const unsigned long INVALID_ENUM                   = 0x0500;
-    const unsigned long INVALID_VALUE                  = 0x0501;
-    const unsigned long INVALID_OPERATION              = 0x0502;
-    const unsigned long OUT_OF_MEMORY                  = 0x0505;
+    const GLenum NO_ERROR                       = 0;
+    const GLenum INVALID_ENUM                   = 0x0500;
+    const GLenum INVALID_VALUE                  = 0x0501;
+    const GLenum INVALID_OPERATION              = 0x0502;
+    const GLenum OUT_OF_MEMORY                  = 0x0505;
     
     /* FrontFaceDirection */
-    const unsigned long CW                             = 0x0900;
-    const unsigned long CCW                            = 0x0901;
+    const GLenum CW                             = 0x0900;
+    const GLenum CCW                            = 0x0901;
     
     /* GetPName */
-    const unsigned long LINE_WIDTH                     = 0x0B21;
-    const unsigned long ALIASED_POINT_SIZE_RANGE       = 0x846D;
-    const unsigned long ALIASED_LINE_WIDTH_RANGE       = 0x846E;
-    const unsigned long CULL_FACE_MODE                 = 0x0B45;
-    const unsigned long FRONT_FACE                     = 0x0B46;
-    const unsigned long DEPTH_RANGE                    = 0x0B70;
-    const unsigned long DEPTH_WRITEMASK                = 0x0B72;
-    const unsigned long DEPTH_CLEAR_VALUE              = 0x0B73;
-    const unsigned long DEPTH_FUNC                     = 0x0B74;
-    const unsigned long STENCIL_CLEAR_VALUE            = 0x0B91;
-    const unsigned long STENCIL_FUNC                   = 0x0B92;
-    const unsigned long STENCIL_FAIL                   = 0x0B94;
-    const unsigned long STENCIL_PASS_DEPTH_FAIL        = 0x0B95;
-    const unsigned long STENCIL_PASS_DEPTH_PASS        = 0x0B96;
-    const unsigned long STENCIL_REF                    = 0x0B97;
-    const unsigned long STENCIL_VALUE_MASK             = 0x0B93;
-    const unsigned long STENCIL_WRITEMASK              = 0x0B98;
-    const unsigned long STENCIL_BACK_FUNC              = 0x8800;
-    const unsigned long STENCIL_BACK_FAIL              = 0x8801;
-    const unsigned long STENCIL_BACK_PASS_DEPTH_FAIL   = 0x8802;
-    const unsigned long STENCIL_BACK_PASS_DEPTH_PASS   = 0x8803;
-    const unsigned long STENCIL_BACK_REF               = 0x8CA3;
-    const unsigned long STENCIL_BACK_VALUE_MASK        = 0x8CA4;
-    const unsigned long STENCIL_BACK_WRITEMASK         = 0x8CA5;
-    const unsigned long VIEWPORT                       = 0x0BA2;
-    const unsigned long SCISSOR_BOX                    = 0x0C10;
+    const GLenum LINE_WIDTH                     = 0x0B21;
+    const GLenum ALIASED_POINT_SIZE_RANGE       = 0x846D;
+    const GLenum ALIASED_LINE_WIDTH_RANGE       = 0x846E;
+    const GLenum CULL_FACE_MODE                 = 0x0B45;
+    const GLenum FRONT_FACE                     = 0x0B46;
+    const GLenum DEPTH_RANGE                    = 0x0B70;
+    const GLenum DEPTH_WRITEMASK                = 0x0B72;
+    const GLenum DEPTH_CLEAR_VALUE              = 0x0B73;
+    const GLenum DEPTH_FUNC                     = 0x0B74;
+    const GLenum STENCIL_CLEAR_VALUE            = 0x0B91;
+    const GLenum STENCIL_FUNC                   = 0x0B92;
+    const GLenum STENCIL_FAIL                   = 0x0B94;
+    const GLenum STENCIL_PASS_DEPTH_FAIL        = 0x0B95;
+    const GLenum STENCIL_PASS_DEPTH_PASS        = 0x0B96;
+    const GLenum STENCIL_REF                    = 0x0B97;
+    const GLenum STENCIL_VALUE_MASK             = 0x0B93;
+    const GLenum STENCIL_WRITEMASK              = 0x0B98;
+    const GLenum STENCIL_BACK_FUNC              = 0x8800;
+    const GLenum STENCIL_BACK_FAIL              = 0x8801;
+    const GLenum STENCIL_BACK_PASS_DEPTH_FAIL   = 0x8802;
+    const GLenum STENCIL_BACK_PASS_DEPTH_PASS   = 0x8803;
+    const GLenum STENCIL_BACK_REF               = 0x8CA3;
+    const GLenum STENCIL_BACK_VALUE_MASK        = 0x8CA4;
+    const GLenum STENCIL_BACK_WRITEMASK         = 0x8CA5;
+    const GLenum VIEWPORT                       = 0x0BA2;
+    const GLenum SCISSOR_BOX                    = 0x0C10;
     /*      SCISSOR_TEST */
-    const unsigned long COLOR_CLEAR_VALUE              = 0x0C22;
-    const unsigned long COLOR_WRITEMASK                = 0x0C23;
-    const unsigned long UNPACK_ALIGNMENT               = 0x0CF5;
-    const unsigned long PACK_ALIGNMENT                 = 0x0D05;
-    const unsigned long MAX_TEXTURE_SIZE               = 0x0D33;
-    const unsigned long MAX_VIEWPORT_DIMS              = 0x0D3A;
-    const unsigned long SUBPIXEL_BITS                  = 0x0D50;
-    const unsigned long RED_BITS                       = 0x0D52;
-    const unsigned long GREEN_BITS                     = 0x0D53;
-    const unsigned long BLUE_BITS                      = 0x0D54;
-    const unsigned long ALPHA_BITS                     = 0x0D55;
-    const unsigned long DEPTH_BITS                     = 0x0D56;
-    const unsigned long STENCIL_BITS                   = 0x0D57;
-    const unsigned long POLYGON_OFFSET_UNITS           = 0x2A00;
+    const GLenum COLOR_CLEAR_VALUE              = 0x0C22;
+    const GLenum COLOR_WRITEMASK                = 0x0C23;
+    const GLenum UNPACK_ALIGNMENT               = 0x0CF5;
+    const GLenum PACK_ALIGNMENT                 = 0x0D05;
+    const GLenum MAX_TEXTURE_SIZE               = 0x0D33;
+    const GLenum MAX_VIEWPORT_DIMS              = 0x0D3A;
+    const GLenum SUBPIXEL_BITS                  = 0x0D50;
+    const GLenum RED_BITS                       = 0x0D52;
+    const GLenum GREEN_BITS                     = 0x0D53;
+    const GLenum BLUE_BITS                      = 0x0D54;
+    const GLenum ALPHA_BITS                     = 0x0D55;
+    const GLenum DEPTH_BITS                     = 0x0D56;
+    const GLenum STENCIL_BITS                   = 0x0D57;
+    const GLenum POLYGON_OFFSET_UNITS           = 0x2A00;
     /*      POLYGON_OFFSET_FILL */
-    const unsigned long POLYGON_OFFSET_FACTOR          = 0x8038;
-    const unsigned long TEXTURE_BINDING_2D             = 0x8069;
-    const unsigned long SAMPLE_BUFFERS                 = 0x80A8;
-    const unsigned long SAMPLES                        = 0x80A9;
-    const unsigned long SAMPLE_COVERAGE_VALUE          = 0x80AA;
-    const unsigned long SAMPLE_COVERAGE_INVERT         = 0x80AB;
+    const GLenum POLYGON_OFFSET_FACTOR          = 0x8038;
+    const GLenum TEXTURE_BINDING_2D             = 0x8069;
+    const GLenum SAMPLE_BUFFERS                 = 0x80A8;
+    const GLenum SAMPLES                        = 0x80A9;
+    const GLenum SAMPLE_COVERAGE_VALUE          = 0x80AA;
+    const GLenum SAMPLE_COVERAGE_INVERT         = 0x80AB;
     
     /* GetTextureParameter */
     /*      TEXTURE_MAG_FILTER */
     /*      TEXTURE_MIN_FILTER */
     /*      TEXTURE_WRAP_S */
     /*      TEXTURE_WRAP_T */
     
-    const unsigned long COMPRESSED_TEXTURE_FORMATS     = 0x86A3;
+    const GLenum COMPRESSED_TEXTURE_FORMATS     = 0x86A3;
     
     /* HintMode */
-    const unsigned long DONT_CARE                      = 0x1100;
-    const unsigned long FASTEST                        = 0x1101;
-    const unsigned long NICEST                         = 0x1102;
+    const GLenum DONT_CARE                      = 0x1100;
+    const GLenum FASTEST                        = 0x1101;
+    const GLenum NICEST                         = 0x1102;
     
     /* HintTarget */
-    const unsigned long GENERATE_MIPMAP_HINT            = 0x8192;
+    const GLenum GENERATE_MIPMAP_HINT            = 0x8192;
     
     /* DataType */
-    const unsigned long BYTE                           = 0x1400;
-    const unsigned long UNSIGNED_BYTE                  = 0x1401;
-    const unsigned long SHORT                          = 0x1402;
-    const unsigned long UNSIGNED_SHORT                 = 0x1403;
-    const unsigned long INT                            = 0x1404;
-    const unsigned long UNSIGNED_INT                   = 0x1405;
-    const unsigned long FLOAT                          = 0x1406;
+    const GLenum BYTE                           = 0x1400;
+    const GLenum UNSIGNED_BYTE                  = 0x1401;
+    const GLenum SHORT                          = 0x1402;
+    const GLenum UNSIGNED_SHORT                 = 0x1403;
+    const GLenum INT                            = 0x1404;
+    const GLenum UNSIGNED_INT                   = 0x1405;
+    const GLenum FLOAT                          = 0x1406;
     
     /* PixelFormat */
-    const unsigned long DEPTH_COMPONENT                = 0x1902;
-    const unsigned long ALPHA                          = 0x1906;
-    const unsigned long RGB                            = 0x1907;
-    const unsigned long RGBA                           = 0x1908;
-    const unsigned long LUMINANCE                      = 0x1909;
-    const unsigned long LUMINANCE_ALPHA                = 0x190A;
+    const GLenum DEPTH_COMPONENT                = 0x1902;
+    const GLenum ALPHA                          = 0x1906;
+    const GLenum RGB                            = 0x1907;
+    const GLenum RGBA                           = 0x1908;
+    const GLenum LUMINANCE                      = 0x1909;
+    const GLenum LUMINANCE_ALPHA                = 0x190A;
     
     /* PixelType */
     /*      UNSIGNED_BYTE */
-    const unsigned long UNSIGNED_SHORT_4_4_4_4         = 0x8033;
-    const unsigned long UNSIGNED_SHORT_5_5_5_1         = 0x8034;
-    const unsigned long UNSIGNED_SHORT_5_6_5           = 0x8363;
+    const GLenum UNSIGNED_SHORT_4_4_4_4         = 0x8033;
+    const GLenum UNSIGNED_SHORT_5_5_5_1         = 0x8034;
+    const GLenum UNSIGNED_SHORT_5_6_5           = 0x8363;
     
     /* Shaders */
-    const unsigned long FRAGMENT_SHADER                  = 0x8B30;
-    const unsigned long VERTEX_SHADER                    = 0x8B31;
-    const unsigned long MAX_VERTEX_ATTRIBS               = 0x8869;
-    const unsigned long MAX_VERTEX_UNIFORM_VECTORS       = 0x8DFB;
-    const unsigned long MAX_VARYING_VECTORS              = 0x8DFC;
-    const unsigned long MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
-    const unsigned long MAX_VERTEX_TEXTURE_IMAGE_UNITS   = 0x8B4C;
-    const unsigned long MAX_TEXTURE_IMAGE_UNITS          = 0x8872;
-    const unsigned long MAX_FRAGMENT_UNIFORM_VECTORS     = 0x8DFD;
-    const unsigned long SHADER_TYPE                      = 0x8B4F;
-    const unsigned long DELETE_STATUS                    = 0x8B80;
-    const unsigned long LINK_STATUS                      = 0x8B82;
-    const unsigned long VALIDATE_STATUS                  = 0x8B83;
-    const unsigned long ATTACHED_SHADERS                 = 0x8B85;
-    const unsigned long ACTIVE_UNIFORMS                  = 0x8B86;
-    const unsigned long ACTIVE_ATTRIBUTES                = 0x8B89;
-    const unsigned long SHADING_LANGUAGE_VERSION         = 0x8B8C;
-    const unsigned long CURRENT_PROGRAM                  = 0x8B8D;
+    const GLenum FRAGMENT_SHADER                  = 0x8B30;
+    const GLenum VERTEX_SHADER                    = 0x8B31;
+    const GLenum MAX_VERTEX_ATTRIBS               = 0x8869;
+    const GLenum MAX_VERTEX_UNIFORM_VECTORS       = 0x8DFB;
+    const GLenum MAX_VARYING_VECTORS              = 0x8DFC;
+    const GLenum MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
+    const GLenum MAX_VERTEX_TEXTURE_IMAGE_UNITS   = 0x8B4C;
+    const GLenum MAX_TEXTURE_IMAGE_UNITS          = 0x8872;
+    const GLenum MAX_FRAGMENT_UNIFORM_VECTORS     = 0x8DFD;
+    const GLenum SHADER_TYPE                      = 0x8B4F;
+    const GLenum DELETE_STATUS                    = 0x8B80;
+    const GLenum LINK_STATUS                      = 0x8B82;
+    const GLenum VALIDATE_STATUS                  = 0x8B83;
+    const GLenum ATTACHED_SHADERS                 = 0x8B85;
+    const GLenum ACTIVE_UNIFORMS                  = 0x8B86;
+    const GLenum ACTIVE_ATTRIBUTES                = 0x8B89;
+    const GLenum SHADING_LANGUAGE_VERSION         = 0x8B8C;
+    const GLenum CURRENT_PROGRAM                  = 0x8B8D;
     
     /* StencilFunction */
-    const unsigned long NEVER                          = 0x0200;
-    const unsigned long LESS                           = 0x0201;
-    const unsigned long EQUAL                          = 0x0202;
-    const unsigned long LEQUAL                         = 0x0203;
-    const unsigned long GREATER                        = 0x0204;
-    const unsigned long NOTEQUAL                       = 0x0205;
-    const unsigned long GEQUAL                         = 0x0206;
-    const unsigned long ALWAYS                         = 0x0207;
+    const GLenum NEVER                          = 0x0200;
+    const GLenum LESS                           = 0x0201;
+    const GLenum EQUAL                          = 0x0202;
+    const GLenum LEQUAL                         = 0x0203;
+    const GLenum GREATER                        = 0x0204;
+    const GLenum NOTEQUAL                       = 0x0205;
+    const GLenum GEQUAL                         = 0x0206;
+    const GLenum ALWAYS                         = 0x0207;
     
     /* StencilOp */
     /*      ZERO */
-    const unsigned long KEEP                           = 0x1E00;
-    const unsigned long REPLACE                        = 0x1E01;
-    const unsigned long INCR                           = 0x1E02;
-    const unsigned long DECR                           = 0x1E03;
-    const unsigned long INVERT                         = 0x150A;
-    const unsigned long INCR_WRAP                      = 0x8507;
-    const unsigned long DECR_WRAP                      = 0x8508;
+    const GLenum KEEP                           = 0x1E00;
+    const GLenum REPLACE                        = 0x1E01;
+    const GLenum INCR                           = 0x1E02;
+    const GLenum DECR                           = 0x1E03;
+    const GLenum INVERT                         = 0x150A;
+    const GLenum INCR_WRAP                      = 0x8507;
+    const GLenum DECR_WRAP                      = 0x8508;
     
     /* StringName */
-    const unsigned long VENDOR                         = 0x1F00;
-    const unsigned long RENDERER                       = 0x1F01;
-    const unsigned long VERSION                        = 0x1F02;
+    const GLenum VENDOR                         = 0x1F00;
+    const GLenum RENDERER                       = 0x1F01;
+    const GLenum VERSION                        = 0x1F02;
     
     /* TextureMagFilter */
-    const unsigned long NEAREST                        = 0x2600;
-    const unsigned long LINEAR                         = 0x2601;
+    const GLenum NEAREST                        = 0x2600;
+    const GLenum LINEAR                         = 0x2601;
     
     /* TextureMinFilter */
     /*      NEAREST */
     /*      LINEAR */
-    const unsigned long NEAREST_MIPMAP_NEAREST         = 0x2700;
-    const unsigned long LINEAR_MIPMAP_NEAREST          = 0x2701;
-    const unsigned long NEAREST_MIPMAP_LINEAR          = 0x2702;
-    const unsigned long LINEAR_MIPMAP_LINEAR           = 0x2703;
+    const GLenum NEAREST_MIPMAP_NEAREST         = 0x2700;
+    const GLenum LINEAR_MIPMAP_NEAREST          = 0x2701;
+    const GLenum NEAREST_MIPMAP_LINEAR          = 0x2702;
+    const GLenum LINEAR_MIPMAP_LINEAR           = 0x2703;
     
     /* TextureParameterName */
-    const unsigned long TEXTURE_MAG_FILTER             = 0x2800;
-    const unsigned long TEXTURE_MIN_FILTER             = 0x2801;
-    const unsigned long TEXTURE_WRAP_S                 = 0x2802;
-    const unsigned long TEXTURE_WRAP_T                 = 0x2803;
+    const GLenum TEXTURE_MAG_FILTER             = 0x2800;
+    const GLenum TEXTURE_MIN_FILTER             = 0x2801;
+    const GLenum TEXTURE_WRAP_S                 = 0x2802;
+    const GLenum TEXTURE_WRAP_T                 = 0x2803;
     
     /* TextureTarget */
-    const unsigned long TEXTURE_2D                     = 0x0DE1;
-    const unsigned long TEXTURE                        = 0x1702;
+    const GLenum TEXTURE_2D                     = 0x0DE1;
+    const GLenum TEXTURE                        = 0x1702;
     
-    const unsigned long TEXTURE_CUBE_MAP               = 0x8513;
-    const unsigned long TEXTURE_BINDING_CUBE_MAP       = 0x8514;
-    const unsigned long TEXTURE_CUBE_MAP_POSITIVE_X    = 0x8515;
-    const unsigned long TEXTURE_CUBE_MAP_NEGATIVE_X    = 0x8516;
-    const unsigned long TEXTURE_CUBE_MAP_POSITIVE_Y    = 0x8517;
-    const unsigned long TEXTURE_CUBE_MAP_NEGATIVE_Y    = 0x8518;
-    const unsigned long TEXTURE_CUBE_MAP_POSITIVE_Z    = 0x8519;
-    const unsigned long TEXTURE_CUBE_MAP_NEGATIVE_Z    = 0x851A;
-    const unsigned long MAX_CUBE_MAP_TEXTURE_SIZE      = 0x851C;
+    const GLenum TEXTURE_CUBE_MAP               = 0x8513;
+    const GLenum TEXTURE_BINDING_CUBE_MAP       = 0x8514;
+    const GLenum TEXTURE_CUBE_MAP_POSITIVE_X    = 0x8515;
+    const GLenum TEXTURE_CUBE_MAP_NEGATIVE_X    = 0x8516;
+    const GLenum TEXTURE_CUBE_MAP_POSITIVE_Y    = 0x8517;
+    const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Y    = 0x8518;
+    const GLenum TEXTURE_CUBE_MAP_POSITIVE_Z    = 0x8519;
+    const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Z    = 0x851A;
+    const GLenum MAX_CUBE_MAP_TEXTURE_SIZE      = 0x851C;
     
     /* TextureUnit */
-    const unsigned long TEXTURE0                       = 0x84C0;
-    const unsigned long TEXTURE1                       = 0x84C1;
-    const unsigned long TEXTURE2                       = 0x84C2;
-    const unsigned long TEXTURE3                       = 0x84C3;
-    const unsigned long TEXTURE4                       = 0x84C4;
-    const unsigned long TEXTURE5                       = 0x84C5;
-    const unsigned long TEXTURE6                       = 0x84C6;
-    const unsigned long TEXTURE7                       = 0x84C7;
-    const unsigned long TEXTURE8                       = 0x84C8;
-    const unsigned long TEXTURE9                       = 0x84C9;
-    const unsigned long TEXTURE10                      = 0x84CA;
-    const unsigned long TEXTURE11                      = 0x84CB;
-    const unsigned long TEXTURE12                      = 0x84CC;
-    const unsigned long TEXTURE13                      = 0x84CD;
-    const unsigned long TEXTURE14                      = 0x84CE;
-    const unsigned long TEXTURE15                      = 0x84CF;
-    const unsigned long TEXTURE16                      = 0x84D0;
-    const unsigned long TEXTURE17                      = 0x84D1;
-    const unsigned long TEXTURE18                      = 0x84D2;
-    const unsigned long TEXTURE19                      = 0x84D3;
-    const unsigned long TEXTURE20                      = 0x84D4;
-    const unsigned long TEXTURE21                      = 0x84D5;
-    const unsigned long TEXTURE22                      = 0x84D6;
-    const unsigned long TEXTURE23                      = 0x84D7;
-    const unsigned long TEXTURE24                      = 0x84D8;
-    const unsigned long TEXTURE25                      = 0x84D9;
-    const unsigned long TEXTURE26                      = 0x84DA;
-    const unsigned long TEXTURE27                      = 0x84DB;
-    const unsigned long TEXTURE28                      = 0x84DC;
-    const unsigned long TEXTURE29                      = 0x84DD;
-    const unsigned long TEXTURE30                      = 0x84DE;
-    const unsigned long TEXTURE31                      = 0x84DF;
-    const unsigned long ACTIVE_TEXTURE                 = 0x84E0;
+    const GLenum TEXTURE0                       = 0x84C0;
+    const GLenum TEXTURE1                       = 0x84C1;
+    const GLenum TEXTURE2                       = 0x84C2;
+    const GLenum TEXTURE3                       = 0x84C3;
+    const GLenum TEXTURE4                       = 0x84C4;
+    const GLenum TEXTURE5                       = 0x84C5;
+    const GLenum TEXTURE6                       = 0x84C6;
+    const GLenum TEXTURE7                       = 0x84C7;
+    const GLenum TEXTURE8                       = 0x84C8;
+    const GLenum TEXTURE9                       = 0x84C9;
+    const GLenum TEXTURE10                      = 0x84CA;
+    const GLenum TEXTURE11                      = 0x84CB;
+    const GLenum TEXTURE12                      = 0x84CC;
+    const GLenum TEXTURE13                      = 0x84CD;
+    const GLenum TEXTURE14                      = 0x84CE;
+    const GLenum TEXTURE15                      = 0x84CF;
+    const GLenum TEXTURE16                      = 0x84D0;
+    const GLenum TEXTURE17                      = 0x84D1;
+    const GLenum TEXTURE18                      = 0x84D2;
+    const GLenum TEXTURE19                      = 0x84D3;
+    const GLenum TEXTURE20                      = 0x84D4;
+    const GLenum TEXTURE21                      = 0x84D5;
+    const GLenum TEXTURE22                      = 0x84D6;
+    const GLenum TEXTURE23                      = 0x84D7;
+    const GLenum TEXTURE24                      = 0x84D8;
+    const GLenum TEXTURE25                      = 0x84D9;
+    const GLenum TEXTURE26                      = 0x84DA;
+    const GLenum TEXTURE27                      = 0x84DB;
+    const GLenum TEXTURE28                      = 0x84DC;
+    const GLenum TEXTURE29                      = 0x84DD;
+    const GLenum TEXTURE30                      = 0x84DE;
+    const GLenum TEXTURE31                      = 0x84DF;
+    const GLenum ACTIVE_TEXTURE                 = 0x84E0;
     
     /* TextureWrapMode */
-    const unsigned long REPEAT                         = 0x2901;
-    const unsigned long CLAMP_TO_EDGE                  = 0x812F;
-    const unsigned long MIRRORED_REPEAT                = 0x8370;
+    const GLenum REPEAT                         = 0x2901;
+    const GLenum CLAMP_TO_EDGE                  = 0x812F;
+    const GLenum MIRRORED_REPEAT                = 0x8370;
     
     /* Uniform Types */
-    const unsigned long FLOAT_VEC2                     = 0x8B50;
-    const unsigned long FLOAT_VEC3                     = 0x8B51;
-    const unsigned long FLOAT_VEC4                     = 0x8B52;
-    const unsigned long INT_VEC2                       = 0x8B53;
-    const unsigned long INT_VEC3                       = 0x8B54;
-    const unsigned long INT_VEC4                       = 0x8B55;
-    const unsigned long BOOL                           = 0x8B56;
-    const unsigned long BOOL_VEC2                      = 0x8B57;
-    const unsigned long BOOL_VEC3                      = 0x8B58;
-    const unsigned long BOOL_VEC4                      = 0x8B59;
-    const unsigned long FLOAT_MAT2                     = 0x8B5A;
-    const unsigned long FLOAT_MAT3                     = 0x8B5B;
-    const unsigned long FLOAT_MAT4                     = 0x8B5C;
-    const unsigned long SAMPLER_2D                     = 0x8B5E;
-    const unsigned long SAMPLER_CUBE                   = 0x8B60;
+    const GLenum FLOAT_VEC2                     = 0x8B50;
+    const GLenum FLOAT_VEC3                     = 0x8B51;
+    const GLenum FLOAT_VEC4                     = 0x8B52;
+    const GLenum INT_VEC2                       = 0x8B53;
+    const GLenum INT_VEC3                       = 0x8B54;
+    const GLenum INT_VEC4                       = 0x8B55;
+    const GLenum BOOL                           = 0x8B56;
+    const GLenum BOOL_VEC2                      = 0x8B57;
+    const GLenum BOOL_VEC3                      = 0x8B58;
+    const GLenum BOOL_VEC4                      = 0x8B59;
+    const GLenum FLOAT_MAT2                     = 0x8B5A;
+    const GLenum FLOAT_MAT3                     = 0x8B5B;
+    const GLenum FLOAT_MAT4                     = 0x8B5C;
+    const GLenum SAMPLER_2D                     = 0x8B5E;
+    const GLenum SAMPLER_CUBE                   = 0x8B60;
     
     /* Vertex Arrays */
-    const unsigned long VERTEX_ATTRIB_ARRAY_ENABLED        = 0x8622;
-    const unsigned long VERTEX_ATTRIB_ARRAY_SIZE           = 0x8623;
-    const unsigned long VERTEX_ATTRIB_ARRAY_STRIDE         = 0x8624;
-    const unsigned long VERTEX_ATTRIB_ARRAY_TYPE           = 0x8625;
-    const unsigned long VERTEX_ATTRIB_ARRAY_NORMALIZED     = 0x886A;
-    const unsigned long VERTEX_ATTRIB_ARRAY_POINTER        = 0x8645;
-    const unsigned long VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
+    const GLenum VERTEX_ATTRIB_ARRAY_ENABLED        = 0x8622;
+    const GLenum VERTEX_ATTRIB_ARRAY_SIZE           = 0x8623;
+    const GLenum VERTEX_ATTRIB_ARRAY_STRIDE         = 0x8624;
+    const GLenum VERTEX_ATTRIB_ARRAY_TYPE           = 0x8625;
+    const GLenum VERTEX_ATTRIB_ARRAY_NORMALIZED     = 0x886A;
+    const GLenum VERTEX_ATTRIB_ARRAY_POINTER        = 0x8645;
+    const GLenum VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
     
     /* Shader Source */
-    const unsigned long COMPILE_STATUS                 = 0x8B81;
+    const GLenum COMPILE_STATUS                 = 0x8B81;
     
     /* Shader Precision-Specified Types */
-    const unsigned long LOW_FLOAT                      = 0x8DF0;
-    const unsigned long MEDIUM_FLOAT                   = 0x8DF1;
-    const unsigned long HIGH_FLOAT                     = 0x8DF2;
-    const unsigned long LOW_INT                        = 0x8DF3;
-    const unsigned long MEDIUM_INT                     = 0x8DF4;
-    const unsigned long HIGH_INT                       = 0x8DF5;
+    const GLenum LOW_FLOAT                      = 0x8DF0;
+    const GLenum MEDIUM_FLOAT                   = 0x8DF1;
+    const GLenum HIGH_FLOAT                     = 0x8DF2;
+    const GLenum LOW_INT                        = 0x8DF3;
+    const GLenum MEDIUM_INT                     = 0x8DF4;
+    const GLenum HIGH_INT                       = 0x8DF5;
     
     /* Framebuffer Object. */
-    const unsigned long FRAMEBUFFER                    = 0x8D40;
-    const unsigned long RENDERBUFFER                   = 0x8D41;
+    const GLenum FRAMEBUFFER                    = 0x8D40;
+    const GLenum RENDERBUFFER                   = 0x8D41;
     
-    const unsigned long RGBA4                          = 0x8056;
-    const unsigned long RGB5_A1                        = 0x8057;
-    const unsigned long RGB565                         = 0x8D62;
-    const unsigned long DEPTH_COMPONENT16              = 0x81A5;
-    const unsigned long STENCIL_INDEX                  = 0x1901;
-    const unsigned long STENCIL_INDEX8                 = 0x8D48;
-    const unsigned long DEPTH_STENCIL                  = 0x84F9;
+    const GLenum RGBA4                          = 0x8056;
+    const GLenum RGB5_A1                        = 0x8057;
+    const GLenum RGB565                         = 0x8D62;
+    const GLenum DEPTH_COMPONENT16              = 0x81A5;
+    const GLenum STENCIL_INDEX                  = 0x1901;
+    const GLenum STENCIL_INDEX8                 = 0x8D48;
+    const GLenum DEPTH_STENCIL                  = 0x84F9;
     
-    const unsigned long RENDERBUFFER_WIDTH             = 0x8D42;
-    const unsigned long RENDERBUFFER_HEIGHT            = 0x8D43;
-    const unsigned long RENDERBUFFER_INTERNAL_FORMAT   = 0x8D44;
-    const unsigned long RENDERBUFFER_RED_SIZE          = 0x8D50;
-    const unsigned long RENDERBUFFER_GREEN_SIZE        = 0x8D51;
-    const unsigned long RENDERBUFFER_BLUE_SIZE         = 0x8D52;
-    const unsigned long RENDERBUFFER_ALPHA_SIZE        = 0x8D53;
-    const unsigned long RENDERBUFFER_DEPTH_SIZE        = 0x8D54;
-    const unsigned long RENDERBUFFER_STENCIL_SIZE      = 0x8D55;
+    const GLenum RENDERBUFFER_WIDTH             = 0x8D42;
+    const GLenum RENDERBUFFER_HEIGHT            = 0x8D43;
+    const GLenum RENDERBUFFER_INTERNAL_FORMAT   = 0x8D44;
+    const GLenum RENDERBUFFER_RED_SIZE          = 0x8D50;
+    const GLenum RENDERBUFFER_GREEN_SIZE        = 0x8D51;
+    const GLenum RENDERBUFFER_BLUE_SIZE         = 0x8D52;
+    const GLenum RENDERBUFFER_ALPHA_SIZE        = 0x8D53;
+    const GLenum RENDERBUFFER_DEPTH_SIZE        = 0x8D54;
+    const GLenum RENDERBUFFER_STENCIL_SIZE      = 0x8D55;
     
-    const unsigned long FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE           = 0x8CD0;
-    const unsigned long FRAMEBUFFER_ATTACHMENT_OBJECT_NAME           = 0x8CD1;
-    const unsigned long FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL         = 0x8CD2;
-    const unsigned long FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
+    const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE           = 0x8CD0;
+    const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_NAME           = 0x8CD1;
+    const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL         = 0x8CD2;
+    const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
     
-    const unsigned long COLOR_ATTACHMENT0              = 0x8CE0;
-    const unsigned long DEPTH_ATTACHMENT               = 0x8D00;
-    const unsigned long STENCIL_ATTACHMENT             = 0x8D20;
-    const unsigned long DEPTH_STENCIL_ATTACHMENT       = 0x821A;
+    const GLenum COLOR_ATTACHMENT0              = 0x8CE0;
+    const GLenum DEPTH_ATTACHMENT               = 0x8D00;
+    const GLenum STENCIL_ATTACHMENT             = 0x8D20;
+    const GLenum DEPTH_STENCIL_ATTACHMENT       = 0x821A;
     
-    const unsigned long NONE                           = 0;
+    const GLenum NONE                           = 0;
     
-    const unsigned long FRAMEBUFFER_COMPLETE                      = 0x8CD5;
-    const unsigned long FRAMEBUFFER_INCOMPLETE_ATTACHMENT         = 0x8CD6;
-    const unsigned long FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
-    const unsigned long FRAMEBUFFER_INCOMPLETE_DIMENSIONS         = 0x8CD9;
-    const unsigned long FRAMEBUFFER_UNSUPPORTED                   = 0x8CDD;
+    const GLenum FRAMEBUFFER_COMPLETE                      = 0x8CD5;
+    const GLenum FRAMEBUFFER_INCOMPLETE_ATTACHMENT         = 0x8CD6;
+    const GLenum FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
+    const GLenum FRAMEBUFFER_INCOMPLETE_DIMENSIONS         = 0x8CD9;
+    const GLenum FRAMEBUFFER_UNSUPPORTED                   = 0x8CDD;
     
-    const unsigned long FRAMEBUFFER_BINDING            = 0x8CA6;
-    const unsigned long RENDERBUFFER_BINDING           = 0x8CA7;
-    const unsigned long MAX_RENDERBUFFER_SIZE          = 0x84E8;
+    const GLenum FRAMEBUFFER_BINDING            = 0x8CA6;
+    const GLenum RENDERBUFFER_BINDING           = 0x8CA7;
+    const GLenum MAX_RENDERBUFFER_SIZE          = 0x84E8;
     
-    const unsigned long INVALID_FRAMEBUFFER_OPERATION  = 0x0506;
+    const GLenum INVALID_FRAMEBUFFER_OPERATION  = 0x0506;
     
     /* WebGL-specific enums */
-    const unsigned long UNPACK_FLIP_Y_WEBGL            = 0x9240;
-    const unsigned long UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
-    const unsigned long CONTEXT_LOST_WEBGL             = 0x9242;
-    const unsigned long UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
-    const unsigned long BROWSER_DEFAULT_WEBGL          = 0x9244;
+    const GLenum UNPACK_FLIP_Y_WEBGL            = 0x9240;
+    const GLenum UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
+    const GLenum CONTEXT_LOST_WEBGL             = 0x9242;
+    const GLenum UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
+    const GLenum BROWSER_DEFAULT_WEBGL          = 0x9244;
 
-    readonly attribute HTMLCanvasElement canvas;
-
-    readonly attribute long drawingBufferWidth;
-
-    readonly attribute long drawingBufferHeight;
+    // The canvas might actually be null in some cases, apparently.
+    readonly attribute HTMLCanvasElement? canvas;
+    readonly attribute GLsizei drawingBufferWidth;
+    readonly attribute GLsizei drawingBufferHeight;
 
     [WebGLHandlesContextLoss, Throws] WebGLContextAttributes getContextAttributes();
     [WebGLHandlesContextLoss] boolean isContextLost();
-
+    
     sequence<DOMString>? getSupportedExtensions();
 
     // XXXbz In the spec, this is "object?"; I'm making it
     // WebGLExtension? just for ease of implementation.
     WebGLExtension? getExtension(DOMString name);
 
-    void activeTexture(unsigned long texture);
-
+    void activeTexture(GLenum texture);
     void attachShader(WebGLProgram? program, WebGLShader? shader);
-
-    void bindAttribLocation(WebGLProgram? program, unsigned long index, DOMString name);
-
-    void bindBuffer(unsigned long target, WebGLBuffer? buffer);
-
-    void bindFramebuffer(unsigned long target, WebGLFramebuffer? framebuffer);
-
-    void bindRenderbuffer(unsigned long target, WebGLRenderbuffer? renderbuffer);
-
-    void bindTexture(unsigned long target, WebGLTexture? texture);
-
-    void blendColor(float red, float green, float blue, float alpha);
-
-    void blendEquation(unsigned long mode);
-
-    void blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha);
-
-    void blendFunc(unsigned long sfactor, unsigned long dfactor);
+    void bindAttribLocation(WebGLProgram? program, GLuint index, DOMString name);
+    void bindBuffer(GLenum target, WebGLBuffer? buffer);
+    void bindFramebuffer(GLenum target, WebGLFramebuffer? framebuffer);
+    void bindRenderbuffer(GLenum target, WebGLRenderbuffer? renderbuffer);
+    void bindTexture(GLenum target, WebGLTexture? texture);
+    void blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+    void blendEquation(GLenum mode);
+    void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+    void blendFunc(GLenum sfactor, GLenum dfactor);
+    void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, 
+                           GLenum srcAlpha, GLenum dstAlpha);
 
-    void blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, 
-                           unsigned long srcAlpha, unsigned long dstAlpha);
-
-    void bufferData(unsigned long target, long long size, unsigned long usage);
-    void bufferData(unsigned long target, ArrayBufferView data, unsigned long usage);
-    void bufferData(unsigned long target, ArrayBuffer? data, unsigned long usage);
-    void bufferSubData(unsigned long target, long long offset, ArrayBufferView data);
-    void bufferSubData(unsigned long target, long long offset, ArrayBuffer? data);
+    void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
+    void bufferData(GLenum target, ArrayBufferView data, GLenum usage);
+    void bufferData(GLenum target, ArrayBuffer? data, GLenum usage);
+    void bufferSubData(GLenum target, GLintptr offset, ArrayBufferView data);
+    void bufferSubData(GLenum target, GLintptr offset, ArrayBuffer? data);
 
-    [WebGLHandlesContextLoss]
-    unsigned long checkFramebufferStatus(unsigned long target);
-
-    void clear(unsigned long mask);
-
-    void clearColor(float red, float green, float blue, float alpha);
-
-    void clearDepth(float depth);
-
-    void clearStencil(long s);
-
-    void colorMask(boolean red, boolean green, boolean blue, boolean alpha);
-
+    [WebGLHandlesContextLoss] GLenum checkFramebufferStatus(GLenum target);
+    void clear(GLbitfield mask);
+    void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+    void clearDepth(GLclampf depth);
+    void clearStencil(GLint s);
+    void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
     void compileShader(WebGLShader? shader);
 
-    void compressedTexImage2D(unsigned long target, long level, unsigned long internalformat,
-                              long width, long height, long border,
+    void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
+                              GLsizei width, GLsizei height, GLint border,
                               ArrayBufferView data);
-    void compressedTexSubImage2D(unsigned long target, long level,
-                                 long xoffset, long yoffset,
-                                 long width, long height, unsigned long format,
+    void compressedTexSubImage2D(GLenum target, GLint level,
+                                 GLint xoffset, GLint yoffset,
+                                 GLsizei width, GLsizei height, GLenum format,
                                  ArrayBufferView data);
 
-    void copyTexImage2D(unsigned long target, long level, unsigned long internalformat, 
-                        long x, long y, long width, long height, 
-                        long border);
-    void copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, 
-                           long x, long y, long width, long height);
+    void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, 
+                        GLint x, GLint y, GLsizei width, GLsizei height, 
+                        GLint border);
+    void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 
+                           GLint x, GLint y, GLsizei width, GLsizei height);
 
     WebGLBuffer? createBuffer();
-
     WebGLFramebuffer? createFramebuffer();
-
     WebGLProgram? createProgram();
-
     WebGLRenderbuffer? createRenderbuffer();
-
-    WebGLShader? createShader(unsigned long type);
-
+    WebGLShader? createShader(GLenum type);
     WebGLTexture? createTexture();
 
-    void cullFace(unsigned long mode);
+    void cullFace(GLenum mode);
 
     void deleteBuffer(WebGLBuffer? buffer);
     void deleteFramebuffer(WebGLFramebuffer? framebuffer);
     void deleteProgram(WebGLProgram? program);
     void deleteRenderbuffer(WebGLRenderbuffer? renderbuffer);
     void deleteShader(WebGLShader? shader);
     void deleteTexture(WebGLTexture? texture);
 
-    void depthFunc(unsigned long func);
-    void depthMask(boolean flag);
-    void depthRange(float zNear, float zFar);
+    void depthFunc(GLenum func);
+    void depthMask(GLboolean flag);
+    void depthRange(GLclampf zNear, GLclampf zFar);
     void detachShader(WebGLProgram? program, WebGLShader? shader);
-    void disable(unsigned long cap);
-    void disableVertexAttribArray(unsigned long index);
-    void drawArrays(unsigned long mode, long first, long count);
-    void drawElements(unsigned long mode, long count, unsigned long type, long long offset);
+    void disable(GLenum cap);
+    void disableVertexAttribArray(GLuint index);
+    void drawArrays(GLenum mode, GLint first, GLsizei count);
+    void drawElements(GLenum mode, GLsizei count, GLenum type, GLintptr offset);
 
-    void enable(unsigned long cap);
-    void enableVertexAttribArray(unsigned long index);
+    void enable(GLenum cap);
+    void enableVertexAttribArray(GLuint index);
     void finish();
     void flush();
-
-    void framebufferRenderbuffer(unsigned long target, unsigned long attachment, 
-                                 unsigned long renderbuffertarget, 
+    void framebufferRenderbuffer(GLenum target, GLenum attachment, 
+                                 GLenum renderbuffertarget, 
                                  WebGLRenderbuffer? renderbuffer);
-    void framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, 
-                              WebGLTexture? texture, long level);
-    void frontFace(unsigned long mode);
+    void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, 
+                              WebGLTexture? texture, GLint level);
+    void frontFace(GLenum mode);
 
-    void generateMipmap(unsigned long target);
+    void generateMipmap(GLenum target);
 
-    WebGLActiveInfo? getActiveAttrib(WebGLProgram? program, unsigned long index);
-    WebGLActiveInfo? getActiveUniform(WebGLProgram? program, unsigned long index);
+    WebGLActiveInfo? getActiveAttrib(WebGLProgram? program, GLuint index);
+    WebGLActiveInfo? getActiveUniform(WebGLProgram? program, GLuint index);
     sequence<WebGLShader>? getAttachedShaders(WebGLProgram? program);
 
-    [WebGLHandlesContextLoss]
-    long getAttribLocation(WebGLProgram? program, DOMString name);
+    [WebGLHandlesContextLoss] GLint getAttribLocation(WebGLProgram? program, DOMString name);
 
-    any getBufferParameter(unsigned long target, unsigned long pname);
+    any getBufferParameter(GLenum target, GLenum pname);
     [Throws]
-    any getParameter(unsigned long pname);
+    any getParameter(GLenum pname);
 
-    [WebGLHandlesContextLoss] unsigned long getError();
+    [WebGLHandlesContextLoss] GLenum getError();
 
     [Throws]
-    any getFramebufferAttachmentParameter(unsigned long target, unsigned long attachment, 
-                                          unsigned long pname);
-    any getProgramParameter(WebGLProgram? program, unsigned long pname);
+    any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, 
+                                          GLenum pname);
+    any getProgramParameter(WebGLProgram? program, GLenum pname);
     DOMString? getProgramInfoLog(WebGLProgram? program);
-    any getRenderbufferParameter(unsigned long target, unsigned long pname);
-    any getShaderParameter(WebGLShader? shader, unsigned long pname);
-    WebGLShaderPrecisionFormat? getShaderPrecisionFormat(unsigned long shadertype, unsigned long precisiontype);
+    any getRenderbufferParameter(GLenum target, GLenum pname);
+    any getShaderParameter(WebGLShader? shader, GLenum pname);
+    WebGLShaderPrecisionFormat? getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
     DOMString? getShaderInfoLog(WebGLShader? shader);
 
     DOMString? getShaderSource(WebGLShader? shader);
 
-    any getTexParameter(unsigned long target, unsigned long pname);
+    any getTexParameter(GLenum target, GLenum pname);
 
     [Throws]
     any getUniform(WebGLProgram? program, WebGLUniformLocation? location);
 
     [Creator]
     WebGLUniformLocation? getUniformLocation(WebGLProgram? program, DOMString name);
 
     [Throws]
-    any getVertexAttrib(unsigned long index, unsigned long pname);
-
-    [WebGLHandlesContextLoss]
-    long long getVertexAttribOffset(unsigned long index, unsigned long pname);
-
-    void hint(unsigned long target, unsigned long mode);
+    any getVertexAttrib(GLuint index, GLenum pname);
 
-    [WebGLHandlesContextLoss]
-    boolean isBuffer(WebGLBuffer? buffer);
-
-    [WebGLHandlesContextLoss]
-    boolean isEnabled(unsigned long cap);
-
-    [WebGLHandlesContextLoss]
-    boolean isFramebuffer(WebGLFramebuffer? framebuffer);
+    [WebGLHandlesContextLoss] GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname);
 
-    [WebGLHandlesContextLoss]
-    boolean isProgram(WebGLProgram? program);
-
-    [WebGLHandlesContextLoss]
-    boolean isRenderbuffer(WebGLRenderbuffer? renderbuffer);
-
-    [WebGLHandlesContextLoss]
-    boolean isShader(WebGLShader? shader);
-
-    [WebGLHandlesContextLoss]
-    boolean isTexture(WebGLTexture? texture);
-
-    void lineWidth(float width);
-
+    void hint(GLenum target, GLenum mode);
+    [WebGLHandlesContextLoss] GLboolean isBuffer(WebGLBuffer? buffer);
+    [WebGLHandlesContextLoss] GLboolean isEnabled(GLenum cap);
+    [WebGLHandlesContextLoss] GLboolean isFramebuffer(WebGLFramebuffer? framebuffer);
+    [WebGLHandlesContextLoss] GLboolean isProgram(WebGLProgram? program);
+    [WebGLHandlesContextLoss] GLboolean isRenderbuffer(WebGLRenderbuffer? renderbuffer);
+    [WebGLHandlesContextLoss] GLboolean isShader(WebGLShader? shader);
+    [WebGLHandlesContextLoss] GLboolean isTexture(WebGLTexture? texture);
+    void lineWidth(GLfloat width);
     void linkProgram(WebGLProgram? program);
-
-    void pixelStorei(unsigned long pname, long param);
-
-    void polygonOffset(float factor, float units);
+    void pixelStorei(GLenum pname, GLint param);
+    void polygonOffset(GLfloat factor, GLfloat units);
 
     [Throws]
-    void readPixels(long x, long y, long width, long height, 
-                    unsigned long format, unsigned long type, ArrayBufferView? pixels);
+    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, 
+                    GLenum format, GLenum type, ArrayBufferView? pixels);
 
-    void renderbufferStorage(unsigned long target, unsigned long internalformat, 
-                             long width, long height);
-
-    void sampleCoverage(float value, boolean invert);
-
-    void scissor(long x, long y, long width, long height);
+    void renderbufferStorage(GLenum target, GLenum internalformat, 
+                             GLsizei width, GLsizei height);
+    void sampleCoverage(GLclampf value, GLboolean invert);
+    void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
 
     void shaderSource(WebGLShader? shader, DOMString source);
 
-    void stencilFunc(unsigned long func, long ref, unsigned long mask);
-
-    void stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask);
-
-    void stencilMask(unsigned long mask);
-
-    void stencilMaskSeparate(unsigned long face, unsigned long mask);
-
-    void stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass);
-
-    void stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass);
+    void stencilFunc(GLenum func, GLint ref, GLuint mask);
+    void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+    void stencilMask(GLuint mask);
+    void stencilMaskSeparate(GLenum face, GLuint mask);
+    void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+    void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
 
 
     [Throws]
-    void texImage2D(unsigned long target, long level, unsigned long internalformat, 
-                    long width, long height, long border, unsigned long format, 
-                    unsigned long type, ArrayBufferView? pixels);
+    void texImage2D(GLenum target, GLint level, GLenum internalformat, 
+                    GLsizei width, GLsizei height, GLint border, GLenum format, 
+                    GLenum type, ArrayBufferView? pixels);
     [Throws]
-    void texImage2D(unsigned long target, long level, unsigned long internalformat,
-                    unsigned long format, unsigned long type, ImageData? pixels);
+    void texImage2D(GLenum target, GLint level, GLenum internalformat,
+                    GLenum format, GLenum type, ImageData? pixels);
     [Throws]
-    void texImage2D(unsigned long target, long level, unsigned long internalformat,
-                    unsigned long format, unsigned long type, HTMLImageElement image); // May throw DOMException
+    void texImage2D(GLenum target, GLint level, GLenum internalformat,
+                    GLenum format, GLenum type, HTMLImageElement image); // May throw DOMException
     [Throws]
-    void texImage2D(unsigned long target, long level, unsigned long internalformat,
-                    unsigned long format, unsigned long type, HTMLCanvasElement canvas); // May throw DOMException
+    void texImage2D(GLenum target, GLint level, GLenum internalformat,
+                    GLenum format, GLenum type, HTMLCanvasElement canvas); // May throw DOMException
     [Throws]
-    void texImage2D(unsigned long target, long level, unsigned long internalformat,
-                    unsigned long format, unsigned long type, HTMLVideoElement video); // May throw DOMException
+    void texImage2D(GLenum target, GLint level, GLenum internalformat,
+                    GLenum format, GLenum type, HTMLVideoElement video); // May throw DOMException
 
-    void texParameterf(unsigned long target, unsigned long pname, float param);
-    void texParameteri(unsigned long target, unsigned long pname, long param);
+    void texParameterf(GLenum target, GLenum pname, GLfloat param);
+    void texParameteri(GLenum target, GLenum pname, GLint param);
 
     [Throws]
-    void texSubImage2D(unsigned long target, long level, long xoffset, long yoffset, 
-                       long width, long height, 
-                       unsigned long format, unsigned long type, ArrayBufferView? pixels);
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 
+                       GLsizei width, GLsizei height, 
+                       GLenum format, GLenum type, ArrayBufferView? pixels);
     [Throws]
-    void texSubImage2D(unsigned long target, long level, long xoffset, long yoffset, 
-                       unsigned long format, unsigned long type, ImageData? pixels);
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 
+                       GLenum format, GLenum type, ImageData? pixels);
     [Throws]
-    void texSubImage2D(unsigned long target, long level, long xoffset, long yoffset, 
-                       unsigned long format, unsigned long type, HTMLImageElement image); // May throw DOMException
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 
+                       GLenum format, GLenum type, HTMLImageElement image); // May throw DOMException
     [Throws]
-    void texSubImage2D(unsigned long target, long level, long xoffset, long yoffset, 
-                       unsigned long format, unsigned long type, HTMLCanvasElement canvas); // May throw DOMException
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 
+                       GLenum format, GLenum type, HTMLCanvasElement canvas); // May throw DOMException
     [Throws]
-    void texSubImage2D(unsigned long target, long level, long xoffset, long yoffset, 
-                       unsigned long format, unsigned long type, HTMLVideoElement video); // May throw DOMException
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 
+                       GLenum format, GLenum type, HTMLVideoElement video); // May throw DOMException
 
-    void uniform1f(WebGLUniformLocation? location, float x);
+    void uniform1f(WebGLUniformLocation? location, GLfloat x);
     void uniform1fv(WebGLUniformLocation? location, Float32Array v);
     void uniform1fv(WebGLUniformLocation? location, sequence<float> v);
-    void uniform1i(WebGLUniformLocation? location, long x);
+    void uniform1i(WebGLUniformLocation? location, GLint x);
     void uniform1iv(WebGLUniformLocation? location, Int32Array v);
     void uniform1iv(WebGLUniformLocation? location, sequence<long> v);
-    void uniform2f(WebGLUniformLocation? location, float x, float y);
+    void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y);
     void uniform2fv(WebGLUniformLocation? location, Float32Array v);
     void uniform2fv(WebGLUniformLocation? location, sequence<float> v);
-    void uniform2i(WebGLUniformLocation? location, long x, long y);
+    void uniform2i(WebGLUniformLocation? location, GLint x, GLint y);
     void uniform2iv(WebGLUniformLocation? location, Int32Array v);
     void uniform2iv(WebGLUniformLocation? location, sequence<long> v);
-    void uniform3f(WebGLUniformLocation? location, float x, float y, float z);
+    void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z);
     void uniform3fv(WebGLUniformLocation? location, Float32Array v);
     void uniform3fv(WebGLUniformLocation? location, sequence<float> v);
-    void uniform3i(WebGLUniformLocation? location, long x, long y, long z);
+    void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z);
     void uniform3iv(WebGLUniformLocation? location, Int32Array v);
     void uniform3iv(WebGLUniformLocation? location, sequence<long> v);
-    void uniform4f(WebGLUniformLocation? location, float x, float y, float z, float w);
+    void uniform4f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
     void uniform4fv(WebGLUniformLocation? location, Float32Array v);
     void uniform4fv(WebGLUniformLocation? location, sequence<float> v);
-    void uniform4i(WebGLUniformLocation? location, long x, long y, long z, long w);
+    void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w);
     void uniform4iv(WebGLUniformLocation? location, Int32Array v);
     void uniform4iv(WebGLUniformLocation? location, sequence<long> v);
 
-    void uniformMatrix2fv(WebGLUniformLocation? location, boolean transpose, 
+    void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, 
                           Float32Array value);
-    void uniformMatrix2fv(WebGLUniformLocation? location, boolean transpose, 
+    void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, 
                           sequence<float> value);
-    void uniformMatrix3fv(WebGLUniformLocation? location, boolean transpose, 
+    void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, 
                           Float32Array value);
-    void uniformMatrix3fv(WebGLUniformLocation? location, boolean transpose, 
+    void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, 
                           sequence<float> value);
-    void uniformMatrix4fv(WebGLUniformLocation? location, boolean transpose, 
+    void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, 
                           Float32Array value);
-    void uniformMatrix4fv(WebGLUniformLocation? location, boolean transpose, 
+    void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, 
                           sequence<float> value);
 
     void useProgram(WebGLProgram? program);
     void validateProgram(WebGLProgram? program);
 
-    void vertexAttrib1f(unsigned long indx, float x);
-    void vertexAttrib1fv(unsigned long indx, Float32Array values);
-    void vertexAttrib1fv(unsigned long indx, sequence<float> values);
-    void vertexAttrib2f(unsigned long indx, float x, float y);
-    void vertexAttrib2fv(unsigned long indx, Float32Array values);
-    void vertexAttrib2fv(unsigned long indx, sequence<float> values);
-    void vertexAttrib3f(unsigned long indx, float x, float y, float z);
-    void vertexAttrib3fv(unsigned long indx, Float32Array values);
-    void vertexAttrib3fv(unsigned long indx, sequence<float> values);
-    void vertexAttrib4f(unsigned long indx, float x, float y, float z, float w);
-    void vertexAttrib4fv(unsigned long indx, Float32Array values);
-    void vertexAttrib4fv(unsigned long indx, sequence<float> values);
-    void vertexAttribPointer(unsigned long indx, long size, unsigned long type, 
-                             boolean normalized, long stride, long long offset);
+    void vertexAttrib1f(GLuint indx, GLfloat x);
+    void vertexAttrib1fv(GLuint indx, Float32Array values);
+    void vertexAttrib1fv(GLuint indx, sequence<float> values);
+    void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
+    void vertexAttrib2fv(GLuint indx, Float32Array values);
+    void vertexAttrib2fv(GLuint indx, sequence<float> values);
+    void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+    void vertexAttrib3fv(GLuint indx, Float32Array values);
+    void vertexAttrib3fv(GLuint indx, sequence<float> values);
+    void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+    void vertexAttrib4fv(GLuint indx, Float32Array values);
+    void vertexAttrib4fv(GLuint indx, sequence<float> values);
+    void vertexAttribPointer(GLuint indx, GLint size, GLenum type, 
+                             GLboolean normalized, GLsizei stride, GLintptr offset);
 
-    void viewport(long x, long y, long width, long height);
+    void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
 };
 
 /*[Constructor(DOMString type, optional WebGLContextEventInit eventInit)]
 interface WebGLContextEvent : Event {
     readonly attribute DOMString statusMessage;
     };*/
 
 // EventInit is defined in the DOM4 specification.
--- a/dom/webidl/XMLHttpRequest.webidl
+++ b/dom/webidl/XMLHttpRequest.webidl
@@ -132,18 +132,18 @@ interface XMLHttpRequest : XMLHttpReques
   // Mozilla-specific stuff
   [SetterThrows=Workers]
   attribute boolean multipart;
 
   [SetterThrows=Workers]
   attribute boolean mozBackgroundRequest;
 
   [ChromeOnly]
-  readonly attribute MozChannel channel;
+  readonly attribute MozChannel? channel;
 
   [Throws]
   void sendAsBinary(DOMString body);
-  [Throws]
+  [Throws, ChromeOnly]
   any getInterface(IID iid);
 
   readonly attribute boolean mozAnon;
   readonly attribute boolean mozSystem;
 };
--- a/dom/wifi/Makefile.in
+++ b/dom/wifi/Makefile.in
@@ -33,10 +33,12 @@ EXTRA_JS_MODULES = \
   wifi_worker.js \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 
 XPIDL_FLAGS += \
   -I$(topsrcdir)/dom/base \
+  -I$(topsrcdir)/dom/interfaces/base \
   -I$(topsrcdir)/dom/interfaces/events \
+  -I$(topsrcdir)/dom/system/gonk \
   $(NULL)
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -601,17 +601,17 @@ public:
         }
       }
     }
 
     mStatusResult = xhr->GetStatus(&mStatus);
 
     xhr->GetStatusText(mStatusText);
 
-    mReadyState = xhr->GetReadyState();
+    mReadyState = xhr->ReadyState();
 
     return true;
   }
 
   bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
   {
     if (mEventStreamId != mProxy->mOuterEventStreamId) {
--- a/dom/workers/XMLHttpRequest.h
+++ b/dom/workers/XMLHttpRequest.h
@@ -108,59 +108,59 @@ public:
     SetEventListener(NS_LITERAL_STRING(#_type), aListener, aRv);               \
   }
 
   IMPL_GETTER_AND_SETTER(readystatechange)
 
 #undef IMPL_GETTER_AND_SETTER
 
   uint16_t
-  GetReadyState() const
+  ReadyState() const
   {
     return mStateData.mReadyState;
   }
 
   void
   Open(const nsAString& aMethod, const nsAString& aUrl, bool aAsync,
        const Optional<nsAString>& aUser, const Optional<nsAString>& aPassword,
        ErrorResult& aRv);
 
   void
   SetRequestHeader(const nsAString& aHeader, const nsAString& aValue,
                    ErrorResult& aRv);
 
   uint32_t
-  GetTimeout() const
+  Timeout() const
   {
     return mTimeout;
   }
 
   void
   SetTimeout(uint32_t aTimeout, ErrorResult& aRv);
 
   bool
-  GetWithCredentials() const
+  WithCredentials() const
   {
     return mWithCredentials;
   }
 
   void
   SetWithCredentials(bool aWithCredentials, ErrorResult& aRv);
 
   bool
-  GetMultipart() const
+  Multipart() const
   {
     return mMultipart;
   }
 
   void
   SetMultipart(bool aMultipart, ErrorResult& aRv);
 
   bool
-  GetMozBackgroundRequest() const
+  MozBackgroundRequest() const
   {
     return mBackgroundRequest;
   }
 
   void
   SetMozBackgroundRequest(bool aBackgroundRequest, ErrorResult& aRv);
 
   XMLHttpRequestUpload*
@@ -205,17 +205,17 @@ public:
 
   void
   GetAllResponseHeaders(nsAString& aResponseHeaders, ErrorResult& aRv);
 
   void
   OverrideMimeType(const nsAString& aMimeType, ErrorResult& aRv);
 
   XMLHttpRequestResponseType
-  GetResponseType() const
+  ResponseType() const
   {
     return mResponseType;
   }
 
   void
   SetResponseType(XMLHttpRequestResponseType aResponseType, ErrorResult& aRv);
 
   jsval
@@ -257,22 +257,22 @@ public:
 
   void
   NullResponseText()
   {
     mStateData.mResponseText.SetIsVoid(true);
     mStateData.mResponse = JSVAL_NULL;
   }
 
-  bool GetMozAnon() {
+  bool MozAnon() {
     // TODO: bug 761227
     return false;
   }
 
-  bool GetMozSystem() {
+  bool MozSystem() {
     // TODO: bug 761227
     return false;
   }
 
 private:
   enum ReleaseType { Default, XHRIsGoingAway, WorkerIsGoingAway };
 
   void
--- a/extensions/cookie/nsPermissionManager.cpp
+++ b/extensions/cookie/nsPermissionManager.cpp
@@ -493,28 +493,28 @@ nsPermissionManager::InitDB(bool aRemove
       break;
     }
   }
 
   // make operations on the table asynchronous, for performance
   mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("PRAGMA synchronous = OFF"));
 
   // cache frequently used statements (for insertion, deletion, and updating)
-  rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
+  rv = mDBConn->CreateAsyncStatement(NS_LITERAL_CSTRING(
     "INSERT INTO moz_hosts "
     "(id, host, type, permission, expireType, expireTime, appId, isInBrowserElement) "
     "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)"), getter_AddRefs(mStmtInsert));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
+  rv = mDBConn->CreateAsyncStatement(NS_LITERAL_CSTRING(
     "DELETE FROM moz_hosts "
     "WHERE id = ?1"), getter_AddRefs(mStmtDelete));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
+  rv = mDBConn->CreateAsyncStatement(NS_LITERAL_CSTRING(
     "UPDATE moz_hosts "
     "SET permission = ?2, expireType= ?3, expireTime = ?4 WHERE id = ?1"),
     getter_AddRefs(mStmtUpdate));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // check whether to import or just read in the db
   if (tableExists)
     return Read();
@@ -1133,30 +1133,33 @@ nsPermissionManager::GetPermissionsForAp
 
 NS_IMETHODIMP
 nsPermissionManager::RemovePermissionsForApp(uint32_t aAppId)
 {
   ENSURE_NOT_CHILD_PROCESS;
   NS_ENSURE_ARG(aAppId != nsIScriptSecurityManager::NO_APP_ID);
 
   // We begin by removing all the permissions from the DB.
-  // This is not using a mozIStorageStatement because removing an app should be
-  // rare enough to not have to worry too much about performance.
   // After clearing the DB, we call AddInternal() to make sure that all
   // processes are aware of this change and the representation of the DB in
   // memory is updated.
   // We have to get all permissions associated with an application and then
   // remove those because doing so in EnumerateEntries() would fail because
   // we might happen to actually delete entries from the list.
 
   nsAutoCString sql;
   sql.AppendLiteral("DELETE FROM moz_hosts WHERE appId=");
   sql.AppendInt(aAppId);
 
-  nsresult rv = mDBConn->ExecuteSimpleSQL(sql);
+  nsCOMPtr<mozIStorageAsyncStatement> removeStmt;
+  nsresult rv = mDBConn->CreateAsyncStatement(sql, getter_AddRefs(removeStmt));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<mozIStoragePendingStatement> pending;
+  rv = removeStmt->ExecuteAsync(nullptr, getter_AddRefs(pending));
   NS_ENSURE_SUCCESS(rv, rv);
 
   GetPermissionsForAppStruct data(aAppId);
   mPermissionTable.EnumerateEntries(GetPermissionsForApp, &data);
 
   for (int32_t i=0; i<data.permissions.Count(); ++i) {
     nsAutoCString host;
     bool isInBrowserElement;
@@ -1422,26 +1425,26 @@ nsPermissionManager::NormalizeToACE(nsCS
     mIDNService = do_GetService(NS_IDNSERVICE_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return mIDNService->ConvertUTF8toACE(aHost, aHost);
 }
 
 void
-nsPermissionManager::UpdateDB(OperationType         aOp,
-                              mozIStorageStatement* aStmt,
-                              int64_t               aID,
-                              const nsACString     &aHost,
-                              const nsACString     &aType,
-                              uint32_t              aPermission,
-                              uint32_t              aExpireType,
-                              int64_t               aExpireTime,
-                              uint32_t              aAppId,
-                              bool                  aIsInBrowserElement)
+nsPermissionManager::UpdateDB(OperationType aOp,
+                              mozIStorageAsyncStatement* aStmt,
+                              int64_t aID,
+                              const nsACString &aHost,
+                              const nsACString &aType,
+                              uint32_t aPermission,
+                              uint32_t aExpireType,
+                              int64_t aExpireTime,
+                              uint32_t aAppId,
+                              bool aIsInBrowserElement)
 {
   ENSURE_NOT_CHILD_PROCESS_NORET;
 
   nsresult rv;
 
   // no statement is ok - just means we don't have a profile
   if (!aStmt)
     return;
@@ -1498,18 +1501,18 @@ nsPermissionManager::UpdateDB(OperationT
   default:
     {
       NS_NOTREACHED("need a valid operation in UpdateDB()!");
       rv = NS_ERROR_UNEXPECTED;
       break;
     }
   }
 
-  if (NS_SUCCEEDED(rv)) {
-    bool hasResult;
-    rv = aStmt->ExecuteStep(&hasResult);
-    aStmt->Reset();
+  if (NS_FAILED(rv)) {
+    NS_WARNING("db change failed!");
+    return;
   }
 
-  if (NS_FAILED(rv))
-    NS_WARNING("db change failed!");
+  nsCOMPtr<mozIStoragePendingStatement> pending;
+  rv = aStmt->ExecuteAsync(nullptr, getter_AddRefs(pending));
+  MOZ_ASSERT(NS_SUCCEEDED(rv));
 }
 
--- a/extensions/cookie/nsPermissionManager.h
+++ b/extensions/cookie/nsPermissionManager.h
@@ -18,17 +18,17 @@
 #include "nsPermission.h"
 #include "nsHashKeys.h"
 #include "nsAutoPtr.h"
 #include "nsCOMArray.h"
 
 class nsIPermission;
 class nsIIDNService;
 class mozIStorageConnection;
-class mozIStorageStatement;
+class mozIStorageAsyncStatement;
 
 ////////////////////////////////////////////////////////////////////////////////
 
 class nsPermissionManager : public nsIPermissionManager,
                             public nsIObserver,
                             public nsSupportsWeakReference
 {
 public:
@@ -230,26 +230,26 @@ private:
 
   // Finalize all statements, close the DB and null it.
   // if aRebuildOnSuccess, reinitialize database
   void     CloseDB(bool aRebuildOnSuccess = false);
 
   nsresult RemoveAllInternal(bool aNotifyObservers);
   nsresult RemoveAllFromMemory();
   nsresult NormalizeToACE(nsCString &aHost);
-  static void UpdateDB(OperationType         aOp,
-                       mozIStorageStatement* aStmt,
-                       int64_t               aID,
-                       const nsACString     &aHost,
-                       const nsACString     &aType,
-                       uint32_t              aPermission,
-                       uint32_t              aExpireType,
-                       int64_t               aExpireTime,
-                       uint32_t              aAppId,
-                       bool                  aIsInBrowserElement);
+  static void UpdateDB(OperationType aOp,
+                       mozIStorageAsyncStatement* aStmt,
+                       int64_t aID,
+                       const nsACString& aHost,
+                       const nsACString& aType,
+                       uint32_t aPermission,
+                       uint32_t aExpireType,
+                       int64_t aExpireTime,
+                       uint32_t aAppId,
+                       bool aIsInBrowserElement);
 
   /**
    * This struct has to be passed as an argument to GetPermissionsForApp.
    * |appId| has to be defined.
    * |permissions| will be filed with permissions that are related to the app.
    */
   struct GetPermissionsForAppStruct {
     uint32_t                  appId;
@@ -267,19 +267,19 @@ private:
    * @param arg has to be an instance of GetPermissionsForAppStruct.
    */
   static PLDHashOperator GetPermissionsForApp(nsPermissionManager::PermissionHashKey* entry, void* arg);
 
   nsCOMPtr<nsIObserverService> mObserverService;
   nsCOMPtr<nsIIDNService>      mIDNService;
 
   nsCOMPtr<mozIStorageConnection> mDBConn;
-  nsCOMPtr<mozIStorageStatement> mStmtInsert;
-  nsCOMPtr<mozIStorageStatement> mStmtDelete;
-  nsCOMPtr<mozIStorageStatement> mStmtUpdate;
+  nsCOMPtr<mozIStorageAsyncStatement> mStmtInsert;
+  nsCOMPtr<mozIStorageAsyncStatement> mStmtDelete;
+  nsCOMPtr<mozIStorageAsyncStatement> mStmtUpdate;
 
   nsTHashtable<PermissionHashKey> mPermissionTable;
   // a unique, monotonically increasing id used to identify each database entry
   int64_t                      mLargestID;
 
   // An array to store the strings identifying the different types.
   nsTArray<nsCString>          mTypeArray;
 
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -244,21 +244,23 @@ TemporaryRef<ScaledFont>
 Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize)
 {
   switch (aNativeFont.mType) {
 #ifdef WIN32
   case NATIVE_FONT_DWRITE_FONT_FACE:
     {
       return new ScaledFontDWrite(static_cast<IDWriteFontFace*>(aNativeFont.mFont), aSize);
     }
+#if defined(USE_SKIA)
   case NATIVE_FONT_GDI_FONT_FACE:
     {
       return new ScaledFontWin(static_cast<LOGFONT*>(aNativeFont.mFont), aSize);
     }
 #endif
+#endif
 #ifdef XP_MACOSX
   case NATIVE_FONT_MAC_FONT_FACE:
     {
       return new ScaledFontMac(static_cast<CGFontRef>(aNativeFont.mFont), aSize);
     }
 #endif
 #ifdef USE_SKIA
 #ifdef MOZ_ENABLE_FREETYPE
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -144,17 +144,17 @@ struct GradientStop
 
   Float offset;
   Color color;
 };
 
 }
 }
 
-#ifdef XP_WIN
+#if defined(XP_WIN) && defined(MOZ_GFX)
 #ifdef GFX2D_INTERNAL
 #define GFX2D_API __declspec(dllexport)
 #else
 #define GFX2D_API __declspec(dllimport)
 #endif
 #else
 #define GFX2D_API
 #endif
--- a/gfx/2d/gfx2d.vcxproj
+++ b/gfx/2d/gfx2d.vcxproj
@@ -30,16 +30,17 @@
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LinkIncremental>true</LinkIncremental>
     <ExecutablePath>$(DXSDK_DIR)\Utilities\bin\x86;$(ExecutablePath)</ExecutablePath>
+    <IncludePath>$(ProjectDir);$(IncludePath)</IncludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LinkIncremental>true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <PreprocessorDefinitions>USE_SSE2;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);GFX_LOG_DEBUG;GFX_LOG_WARNING;MFBT_STAND_ALONE;XP_WIN</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -49,16 +50,20 @@
     </ClCompile>
     <Link>
       <TargetMachine>MachineX86</TargetMachine>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <EntryPointSymbol>
       </EntryPointSymbol>
     </Link>
+    <PreBuildEvent>
+      <Command>xcopy $(ProjectDir)..\..\mfbt\*.h mozilla\ /Y</Command>
+      <Message>Copying MFBT files</Message>
+    </PreBuildEvent>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <PreprocessorDefinitions>USE_SSE2;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
@@ -81,32 +86,34 @@
     <ClInclude Include="GradientStopsD2D.h" />
     <ClInclude Include="HelpersD2D.h" />
     <ClInclude Include="ImageScaling.h" />
     <ClInclude Include="Logging.h" />
     <ClInclude Include="Matrix.h" />
     <ClInclude Include="PathD2D.h" />
     <ClInclude Include="Point.h" />
     <ClInclude Include="Rect.h" />
+    <ClInclude Include="ScaledFontBase.h" />
     <ClInclude Include="ScaledFontDWrite.h" />
     <ClInclude Include="SourceSurfaceD2D.h" />
     <ClInclude Include="SourceSurfaceD2DTarget.h" />
     <ClInclude Include="SourceSurfaceRawData.h" />
     <ClInclude Include="Tools.h" />
     <ClInclude Include="Types.h" />
     <ClInclude Include="UserData.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="DrawTargetD2D.cpp" />
     <ClCompile Include="DrawTargetDual.cpp" />
     <ClCompile Include="Factory.cpp" />
     <ClCompile Include="ImageScaling.cpp" />
     <ClCompile Include="ImageScalingSSE2.cpp" />
     <ClCompile Include="Matrix.cpp" />
     <ClCompile Include="PathD2D.cpp" />
+    <ClCompile Include="ScaledFontBase.cpp" />
     <ClCompile Include="ScaledFontDWrite.cpp" />
     <ClCompile Include="SourceSurfaceD2D.cpp" />
     <ClCompile Include="SourceSurfaceD2DTarget.cpp" />
     <ClCompile Include="SourceSurfaceRawData.cpp" />
   </ItemGroup>
   <ItemGroup>
     <None Include="Makefile.in" />
     <CustomBuild Include="ShadersD2D.fx">
--- a/gfx/2d/unittest/unittest.vcxproj
+++ b/gfx/2d/unittest/unittest.vcxproj
@@ -33,16 +33,17 @@
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LibraryPath>$(DXSDK_DIR)\Lib\x86;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib</LibraryPath>
+    <IncludePath>$(ProjectDir)..\;$(IncludePath)</IncludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LibraryPath>$(DXSDK_DIR)\Lib\x86;$(VCInstallDir)lib;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib</LibraryPath>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -1020,40 +1020,38 @@ public:
 private:
    TextureImageGLX(GLuint aTexture,
                    const nsIntSize& aSize,
                    GLenum aWrapMode,
                    ContentType aContentType,
                    GLContext* aContext,
                    gfxASurface* aSurface,
                    GLXPixmap aPixmap,
-                   TextureImage::Flags aFlags = TextureImage::NoFlags,
-                   LibType aLibType = GLXLibrary::OPENGL_LIB)
+                   TextureImage::Flags aFlags,
+                   LibType aLibType)
         : TextureImage(aSize, aWrapMode, aContentType, aFlags)
         , mGLContext(aContext)
         , mUpdateSurface(aSurface)
         , mPixmap(aPixmap)
         , mInUpdate(false)
         , mTexture(aTexture)
-        , mLibType(aLibType)
         , sGLXLib(sGLXLibrary[aLibType])
     {
         if (aSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA) {
             mShaderType = gl::RGBALayerProgramType;
         } else {
             mShaderType = gl::RGBXLayerProgramType;
         }
     }
 
     GLContext* mGLContext;
     nsRefPtr<gfxASurface> mUpdateSurface;
     GLXPixmap mPixmap;
     bool mInUpdate;
     GLuint mTexture;
-    LibType mLibType;
     GLXLibrary& sGLXLib;
 
     virtual void ApplyFilter()
     {
         mGLContext->ApplyFilterToBoundTexture(mFilter);
     }
 };
 
--- a/hal/Hal.cpp
+++ b/hal/Hal.cpp
@@ -401,17 +401,49 @@ bool SetLight(LightType light, const hal
 }
 
 bool GetLight(LightType light, hal::LightConfiguration* aConfig)
 {
   AssertMainThread();
   RETURN_PROXY_IF_SANDBOXED(GetLight(light, aConfig));
 }
 
+static StaticAutoPtr<ObserverList<SystemTimeChange>> sSystemTimeObserver;
 
+static void
+InitializeSystemTimeChangeObserver()
+{
+  if (!sSystemTimeObserver) {
+    sSystemTimeObserver = new ObserverList<SystemTimeChange>;
+    ClearOnShutdown(&sSystemTimeObserver);
+  }
+}
+
+void
+RegisterSystemTimeChangeObserver(SystemTimeObserver *aObserver)
+{
+  AssertMainThread();
+  InitializeSystemTimeChangeObserver();
+  sSystemTimeObserver->AddObserver(aObserver);
+}
+
+void
+UnregisterSystemTimeChangeObserver(SystemTimeObserver *aObserver)
+{
+  AssertMainThread();
+  sSystemTimeObserver->RemoveObserver(aObserver);
+}
+
+void
+NotifySystemTimeChange(const hal::SystemTimeChange& aReason)
+{
+  InitializeSystemTimeChangeObserver();
+  sSystemTimeObserver->Broadcast(aReason);
+}
+ 
 void 
 AdjustSystemClock(int32_t aDeltaMilliseconds)
 {
   AssertMainThread();
   PROXY_IF_SANDBOXED(AdjustSystemClock(aDeltaMilliseconds));
 }
 
 void 
--- a/hal/Hal.h
+++ b/hal/Hal.h
@@ -45,16 +45,18 @@ namespace hal {
 typedef Observer<void_t> AlarmObserver;
 typedef Observer<ScreenConfiguration> ScreenConfigurationObserver;
 
 class WindowIdentifier;
 
 extern PRLogModuleInfo *sHalLog;
 #define HAL_LOG(msg) PR_LOG(mozilla::hal::sHalLog, PR_LOG_DEBUG, msg)
 
+typedef Observer<SystemTimeChange> SystemTimeObserver;
+
 } // namespace hal
 
 namespace MOZ_HAL_NAMESPACE {
 
 /**
  * Turn the default vibrator device on/off per the pattern specified
  * by |pattern|.  Each element in the pattern is the number of
  * milliseconds to turn the vibrator on or off.  The first element in
@@ -251,16 +253,34 @@ void SetTimezone(const nsCString& aTimez
 
 /**
  * Get timezone
  * http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
  */
 nsCString GetTimezone();
 
 /**
+ * Register observer for system time changed notification.
+ * @param aObserver The observer that should be added.
+ */
+void RegisterSystemTimeChangeObserver(hal::SystemTimeObserver* aObserver);
+
+/**
+ * Unregister the observer for system time changed.
+ * @param aObserver The observer that should be removed.
+ */
+void UnregisterSystemTimeChangeObserver(hal::SystemTimeObserver* aObserver);
+
+/**
+ * Notify of a change in the system cloeck or time zone.
+ * @param aReason
+ */
+void NotifySystemTimeChange(const hal::SystemTimeChange& aReason);
+
+/**
  * Reboot the device.
  */
 void Reboot();
 
 /**
  * Power off the device.
  */
 void PowerOff();
--- a/hal/HalTypes.h
+++ b/hal/HalTypes.h
@@ -69,16 +69,23 @@ enum ProcessPriority {
  */
 enum WakeLockControl {
   WAKE_LOCK_REMOVE_ONE = -1,
   WAKE_LOCK_NO_CHANGE  = 0,
   WAKE_LOCK_ADD_ONE    = 1,
   NUM_WAKE_LOCK
 };
 
+enum SystemTimeChange {
+  SYS_TIME_CHANGE_UNKNOWN = -1,
+  SYS_TIME_CHANGE_CLOCK,
+  SYS_TIME_CHANGE_TZ,
+  SYS_TIME_CHANGE_GUARD
+};
+
 } // namespace hal
 } // namespace mozilla
 
 namespace IPC {
 
 /**
  * Light type serializer.
  */
@@ -141,12 +148,21 @@ struct ParamTraits<mozilla::hal::SwitchD
 
 template <>
 struct ParamTraits<mozilla::hal::ProcessPriority>:
   public EnumSerializer<mozilla::hal::ProcessPriority,
                         mozilla::hal::PROCESS_PRIORITY_BACKGROUND,
                         mozilla::hal::NUM_PROCESS_PRIORITY> {
 };
 
-
+/**
+ * SystemTimeChange serializer.
+ */
+template <>
+struct ParamTraits<mozilla::hal::SystemTimeChange>
+  : public EnumSerializer<mozilla::hal::SystemTimeChange,
+                          mozilla::hal::SYS_TIME_CHANGE_UNKNOWN,
+                          mozilla::hal::SYS_TIME_CHANGE_GUARD>
+{};
+ 
 } // namespace IPC
 
 #endif // mozilla_hal_Types_h
--- a/hal/android/AndroidHal.cpp
+++ b/hal/android/AndroidHal.cpp
@@ -180,18 +180,29 @@ GetCurrentScreenConfiguration(ScreenConf
 bool
 LockScreenOrientation(const ScreenOrientation& aOrientation)
 {
   AndroidBridge* bridge = AndroidBridge::Bridge();
   if (!bridge) {
     return false;
   }
 
-  bridge->LockScreenOrientation(aOrientation);
-  return true;
+  switch (aOrientation) {
+    // The Android backend only supports these orientations.
+    case eScreenOrientation_PortraitPrimary:
+    case eScreenOrientation_PortraitSecondary:
+    case eScreenOrientation_Portrait:
+    case eScreenOrientation_LandscapePrimary:
+    case eScreenOrientation_LandscapeSecondary:
+    case eScreenOrientation_Landscape:
+      bridge->LockScreenOrientation(aOrientation);
+      return true;
+    default:
+      return false;
+  }
 }
 
 void
 UnlockScreenOrientation()
 {
   AndroidBridge* bridge = AndroidBridge::Bridge();
   if (!bridge) {
     return;
--- a/hal/gonk/GonkHal.cpp
+++ b/hal/gonk/GonkHal.cpp
@@ -576,16 +576,20 @@ static int
 sys_clock_settime(clockid_t clk_id, const struct timespec *tp)
 {
   return syscall(__NR_clock_settime, clk_id, tp);
 }
 
 void 
 AdjustSystemClock(int32_t aDeltaMilliseconds)
 {
+  if (aDeltaMilliseconds == 0) {
+    return;
+  }
+  
   struct timespec now;
   
   // Preventing context switch before setting system clock 
   sched_yield();
   clock_gettime(CLOCK_REALTIME, &now);
   now.tv_sec += aDeltaMilliseconds/1000;
   now.tv_nsec += (aDeltaMilliseconds%1000)*NsecPerMsec;
   if (now.tv_nsec >= NsecPerSec)
@@ -595,26 +599,36 @@ AdjustSystemClock(int32_t aDeltaMillisec
   }
 
   if (now.tv_nsec < 0)
   {
     now.tv_nsec += NsecPerSec;
     now.tv_sec -= 1;  
   }
   // we need to have root privilege. 
-  sys_clock_settime(CLOCK_REALTIME, &now);   
+  if (sys_clock_settime(CLOCK_REALTIME, &now) != 0) {
+    NS_ERROR("sys_clock_settime failed");
+    return;
+  }
+  
+  hal::NotifySystemTimeChange(hal::SYS_TIME_CHANGE_CLOCK);
 }
 
 void 
 SetTimezone(const nsCString& aTimezoneSpec)
-{ 
+{
+  if (aTimezoneSpec.Equals(GetTimezone())) {
+    return;
+  }
+
   property_set("persist.sys.timezone", aTimezoneSpec.get());
   // this function is automatically called by the other time conversion 
   // functions that depend on the timezone. To be safe, we call it manually.  
   tzset();
+  hal::NotifySystemTimeChange(hal::SYS_TIME_CHANGE_TZ);
 }
 
 nsCString 
 GetTimezone()
 {
   char timezone[32];
   property_get("persist.sys.timezone", timezone, "");
   return nsCString(timezone);
--- a/hal/sandbox/PHal.ipdl
+++ b/hal/sandbox/PHal.ipdl
@@ -19,16 +19,17 @@ using mozilla::hal::LightMode;
 using mozilla::hal::SensorType;
 using mozilla::hal::SensorAccuracyType;
 using mozilla::hal::WakeLockControl;
 using mozilla::hal::SwitchState;
 using mozilla::hal::SwitchDevice;
 using mozilla::hal::ProcessPriority;
 using nsIntRect;
 using PRTime;
+using mozilla::hal::SystemTimeChange;
 
 namespace mozilla {
 
 namespace hal {
 struct BatteryInformation {
   double level;
   bool   charging;
   double remainingTime;
@@ -81,16 +82,17 @@ sync protocol PHal {
     manager PContent;
 
 child:
     NotifyBatteryChange(BatteryInformation aBatteryInfo);
     NotifyNetworkChange(NetworkInformation aNetworkInfo);
     NotifyWakeLockChange(WakeLockInformation aWakeLockInfo);
     NotifyScreenConfigurationChange(ScreenConfiguration aScreenOrientation);
     NotifySwitchChange(SwitchEvent aEvent);
+    NotifySystemTimeChange(SystemTimeChange aReason); 
 
 parent:
     Vibrate(uint32_t[] pattern, uint64_t[] id, PBrowser browser);
     CancelVibrate(uint64_t[] id, PBrowser browser);
 
     EnableBatteryNotifications();
     DisableBatteryNotifications();
     sync GetCurrentBatteryInformation()
--- a/hal/sandbox/SandboxHal.cpp
+++ b/hal/sandbox/SandboxHal.cpp
@@ -671,16 +671,21 @@ public:
   virtual bool
   RecvSetProcessPriority(const int& aPid, const ProcessPriority& aPriority)
   {
     // TODO As a security check, we should ensure that aPid is either the pid
     // of our child, or the pid of one of the child's children.
     hal::SetProcessPriority(aPid, aPriority);
     return true;
   }
+
+  void Notify(const SystemTimeChange& aReason)
+  {
+    unused << SendNotifySystemTimeChange(aReason);
+  }
 };
 
 class HalChild : public PHalChild {
 public:
   virtual bool
   RecvNotifyBatteryChange(const BatteryInformation& aBatteryInfo) MOZ_OVERRIDE {
     hal::NotifyBatteryChange(aBatteryInfo);
     return true;
@@ -707,16 +712,22 @@ public:
     return true;
   }
 
   virtual bool
   RecvNotifySwitchChange(const mozilla::hal::SwitchEvent& aEvent) MOZ_OVERRIDE {
     hal::NotifySwitchChange(aEvent);
     return true;
   }
+
+  virtual bool
+  RecvNotifySystemTimeChange(const SystemTimeChange& aReason) {
+    hal::NotifySystemTimeChange(aReason);
+    return true;
+  }
 };
 
 bool
 HalChild::RecvNotifySensorChange(const hal::SensorData &aSensorData) {
   hal::NotifySensorChange(aSensorData);
   
   return true;
 }
--- a/js/src/build/autoconf/compiler-opts.m4
+++ b/js/src/build/autoconf/compiler-opts.m4
@@ -36,16 +36,18 @@ case "$target" in
 *-darwin*)
     # GCC on darwin is based on gcc 4.2 and we don't support it anymore.
     MOZ_PATH_PROGS(CC, $CC clang)
     MOZ_PATH_PROGS(CXX, $CXX clang++)
     IS_GCC=$($CC -v 2>&1 | grep gcc)
     if test -n "$IS_GCC"
     then
       echo gcc is known to be broken on OS X, please use clang.
+      echo see http://developer.mozilla.org/en-US/docs/Developer_Guide/Build_Instructions/Mac_OS_X_Prerequisites
+      echo for more information.
       exit 1
     fi
     ;;
 esac
 fi
 ])
 
 dnl ============================================================================
--- a/js/src/builtin/ParallelArray-inl.h
+++ b/js/src/builtin/ParallelArray-inl.h
@@ -9,16 +9,30 @@
 #define ParallelArray_inl_h__
 
 #include "builtin/ParallelArray.h"
 
 #include "jsobjinlines.h"
 
 namespace js {
 
+inline bool
+ParallelArrayObject::IndexInfo::inBounds() const
+{
+    JS_ASSERT(isInitialized());
+    JS_ASSERT(indices.length() <= dimensions.length());
+
+    for (uint32_t d = 0; d < indices.length(); d++) {
+        if (indices[d] >= dimensions[d])
+            return false;
+    }
+
+    return true;
+}
+
 inline uint32_t
 ParallelArrayObject::IndexInfo::scalarLengthOfDimensions()
 {
     JS_ASSERT(isInitialized());
     return dimensions[0] * partialProducts[0];
 }
 
 inline uint32_t
--- a/js/src/builtin/ParallelArray.cpp
+++ b/js/src/builtin/ParallelArray.cpp
@@ -27,17 +27,17 @@ using namespace js::types;
 //
 // Utilities
 //
 
 typedef ParallelArrayObject::IndexVector IndexVector;
 typedef ParallelArrayObject::IndexInfo IndexInfo;
 
 bool
-ParallelArrayObject::IndexInfo::isInitialized()
+ParallelArrayObject::IndexInfo::isInitialized() const
 {
     return (dimensions.length() > 0 &&
             indices.capacity() >= dimensions.length() &&
             partialProducts.length() == dimensions.length());
 }
 
 // Check if obj is a parallel array, and if so, cast to pa and initialize
 // the IndexInfo accordingly.
@@ -443,25 +443,25 @@ ParallelArrayObject::SequentialMode::sca
 
     // Index vector and parallel array pointer for targets, in case targets is
     // a ParallelArray object. If not, these are uninitialized.
     IndexInfo tiv(cx);
     RootedParallelArrayObject targetsPA(cx);
 
     // The length of the scatter vector.
     uint32_t targetsLength;
-
     if (!MaybeGetParallelArrayObjectAndLength(cx, targets, &targetsPA, &tiv, &targetsLength))
         return ExecutionFailed;
 
-    // Iterate over the scatter vector.
+    // Iterate over the scatter vector, but not more than the length of the
+    // source array.
     RootedValue elem(cx);
     RootedValue telem(cx);
     RootedValue targetElem(cx);
-    for (uint32_t i = 0; i < targetsLength; i++) {
+    for (uint32_t i = 0; i < Min(targetsLength, source->outermostDimension()); i++) {
         uint32_t targetIndex;
 
         if (!GetElementFromArrayLikeObject(cx, targets, targetsPA, tiv, i, &telem) ||
             !ToUint32(cx, telem, &targetIndex))
         {
             return ExecutionFailed;
         }
 
@@ -907,30 +907,28 @@ ParallelArrayObject::getParallelArrayEle
             vp.set(buffer()->getDenseArrayElement(index));
         return true;
     }
 
     // If we aren't indexing a leaf value, we should return a new
     // ParallelArray of lesser dimensionality. Here we create a new 'view' on
     // the underlying buffer, though whether a ParallelArray is a view or a
     // copy is not observable by the user.
-    uint32_t rowLength = iv.partialProducts[d - 1];
-    uint32_t offset = base + iv.toScalar();
-
-    // Make sure both the start of the extent and the end of the extent are
-    // within bounds, in case one or both are 0.
-    if (offset >= end || offset + rowLength > end) {
+    //
+    // It is not enough to compute the scalar index and check bounds that way,
+    // since the row length can be 0.
+    if (!iv.inBounds()) {
         vp.setUndefined();
         return true;
     }
 
     RootedObject buf(cx, buffer());
     IndexVector newDims(cx);
     return (newDims.append(iv.dimensions.begin() + d, iv.dimensions.end()) &&
-            create(cx, buf, offset, newDims, vp));
+            create(cx, buf, base + iv.toScalar(), newDims, vp));
 }
 
 bool
 ParallelArrayObject::getParallelArrayElement(JSContext *cx, uint32_t index, IndexInfo *maybeIV,
                                              MutableHandleValue vp)
 {
     // If we are one dimensional, we don't need to use IndexInfo.
     if (isOneDimensional()) {
@@ -1256,23 +1254,16 @@ ParallelArrayObject::scatter(JSContext *
         return false;
     }
 
     RootedParallelArrayObject obj(cx, as(&args.thisv().toObject()));
     uint32_t outer = obj->outermostDimension();
 
     // Get the scatter vector.
     RootedObject targets(cx, &args[0].toObject());
-    uint32_t targetsLength;
-    if (!GetLengthProperty(cx, targets, &targetsLength))
-        return false;
-
-    // Don't iterate more than the length of the source array.
-    if (targetsLength > outer)
-        targetsLength = outer;
 
     // The default value is optional and defaults to undefined.
     Value defaultValue;
     if (args.length() >= 2)
         defaultValue = args[1];
     else
         defaultValue.setUndefined();
 
--- a/js/src/builtin/ParallelArray.h
+++ b/js/src/builtin/ParallelArray.h
@@ -124,17 +124,18 @@ class ParallelArrayObject : public JSObj
         inline uint32_t scalarLengthOfDimensions();
 
         // Compute the scalar index from the current index vector.
         inline uint32_t toScalar();
 
         // Set the index vector according to a scalar index.
         inline bool fromScalar(uint32_t index);
 
-        bool isInitialized();
+        inline bool inBounds() const;
+        bool isInitialized() const;
     };
 
     static JSObject *initClass(JSContext *cx, JSObject *obj);
     static Class class_;
 
     static inline bool is(const Value &v);
     static inline bool is(JSObject *obj);
     static inline ParallelArrayObject *as(JSObject *obj);
--- a/js/src/frontend/NameFunctions.cpp
+++ b/js/src/frontend/NameFunctions.cpp
@@ -259,17 +259,17 @@ class NameResolver
      * This is the case for functions which do things like simply create a scope
      * for new variables and then return an anonymous function using this scope.
      */
     bool isDirectCall(int pos, ParseNode *cur) {
         return pos >= 0 && call(parents[pos]) && parents[pos]->pn_head == cur;
     }
 
   public:
-    NameResolver(JSContext *cx) : cx(cx), nparents(0), buf(NULL) {}
+    explicit NameResolver(JSContext *cx) : cx(cx), nparents(0), buf(NULL) {}
 
     /*
      * Resolve all names for anonymous functions recursively within the
      * ParseNode instance given. The prefix is for each subsequent name, and
      * should initially be NULL.
      */
     void resolve(ParseNode *cur, JSAtom *prefix = NULL) {
         if (cur == NULL)
--- a/js/src/jit-test/tests/parallelarray/element-2.js
+++ b/js/src/jit-test/tests/parallelarray/element-2.js
@@ -6,12 +6,14 @@ function testElement() {
   var p0 = new ParallelArray([2,2], function () { return 0; });
   assertEqParallelArray(p[0], p0);
   // Should create new wrapper
   assertEq(p[0] !== p[0], true);
   // Test out of bounds
   assertEq(p[42], undefined);
   // Test getting element from 0-lengthed higher dimension
   var pp = new ParallelArray([0,0], function() { return 0; });
-  assertEq(p[2], undefined);
+  assertEq(pp[2], undefined);
+  var pp2 = new ParallelArray([2,0], function() { return 0; });
+  assertEqParallelArray(pp2[0], new ParallelArray());
 }
 
 testElement();
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1243,16 +1243,17 @@ js::Interpret(JSContext *cx, StackFrame 
     RootedValue rootValue0(cx), rootValue1(cx);
     RootedString rootString0(cx), rootString1(cx);
     RootedObject rootObject0(cx), rootObject1(cx), rootObject2(cx);
     RootedFunction rootFunction0(cx);
     RootedTypeObject rootType0(cx);
     RootedPropertyName rootName0(cx);
     RootedId rootId0(cx);
     RootedShape rootShape0(cx);
+    DebugOnly<uint32_t> blockDepth;
 
     if (!entryFrame)
         entryFrame = regs.fp();
 
 #if JS_HAS_GENERATORS
     if (JS_UNLIKELY(regs.fp()->isGeneratorFrame())) {
         JS_ASSERT(size_t(regs.pc - script->code) <= script->length);
         JS_ASSERT(regs.stackDepth() <= script->nslots);
@@ -3710,17 +3711,17 @@ BEGIN_CASE(JSOP_ENTERLET1)
         goto error;
 }
 END_CASE(JSOP_ENTERBLOCK)
 
 BEGIN_CASE(JSOP_LEAVEBLOCK)
 BEGIN_CASE(JSOP_LEAVEFORLETIN)
 BEGIN_CASE(JSOP_LEAVEBLOCKEXPR)
 {
-    DebugOnly<uint32_t> blockDepth = regs.fp()->blockChain().stackDepth();
+    blockDepth = regs.fp()->blockChain().stackDepth();
 
     regs.fp()->popBlock(cx);
 
     if (op == JSOP_LEAVEBLOCK) {
         /* Pop the block's slots. */
         regs.sp -= GET_UINT16(regs.pc);
         JS_ASSERT(regs.stackDepth() == blockDepth);
     } else if (op == JSOP_LEAVEBLOCKEXPR) {
--- a/js/src/jsutil.h
+++ b/js/src/jsutil.h
@@ -449,20 +449,20 @@ typedef size_t jsbitmap;
                                  ((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
 #define JS_CLEAR_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &=     \
                                  ~((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
 
 /* Wrapper for various macros to stop warnings coming from their expansions. */
 #if defined(__clang__)
 # define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr)                                \
     JS_BEGIN_MACRO                                                            \
-        _Pragma("clang diagnostic push")                                      \
-        _Pragma("clang diagnostic ignored \"-Wunused-value\"")                \
-        expr;                                                                 \
-        _Pragma("clang diagnostic pop")                                       \
+        _Pragma("(clang diagnostic push)")                                    \
+        _Pragma("(clang diagnostic ignored \"-Wunused-value\")")              \
+        {expr;}                                                               \
+        _Pragma("(clang diagnostic pop)")                                     \
     JS_END_MACRO
 #elif (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 # define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr)                                \
     JS_BEGIN_MACRO                                                            \
         _Pragma("GCC diagnostic push")                                        \
         _Pragma("GCC diagnostic ignored \"-Wunused-but-set-variable\"")       \
         expr;                                                                 \
         _Pragma("GCC diagnostic pop")                                         \
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -195,16 +195,53 @@ IndirectWrapper::delete_(JSContext *cx, 
 bool
 IndirectWrapper::enumerate(JSContext *cx, JSObject *wrapper, AutoIdVector &props)
 {
     // if we refuse to perform this action, props remains empty
     static jsid id = JSID_VOID;
     GET(IndirectProxyHandler::enumerate(cx, wrapper, props));
 }
 
+/*
+ * Ordinarily, the convert trap would require a PUNCTURE. However, the default
+ * implementation of convert, JS_ConvertStub, obtains a default value by calling
+ * the toString/valueOf method on the wrapper, if any. Doing a PUNCTURE in this
+ * case would be overly conservative. To make matters worse, XPConnect sometimes
+ * installs a custom convert trap that obtains a default value by calling the
+ * toString method on the wrapper. Doing a puncture in this case would be overly
+ * conservative as well. We deal with these anomalies by clearing the pending
+ * exception and falling back to the DefaultValue algorithm whenever the
+ * PUNCTURE fails.
+ */
+bool
+IndirectWrapper::defaultValue(JSContext *cx, JSObject *wrapper_, JSType hint, Value *vp)
+{
+    RootedObject wrapper(cx, wrapper_);
+
+    bool status;
+    if (!enter(cx, wrapper_, JSID_VOID, PUNCTURE, &status)) {
+        RootedValue v(cx);
+        JS_ClearPendingException(cx);
+        if (!DefaultValue(cx, wrapper, hint, &v))
+            return false;
+        *vp = v;
+        return true;
+    }
+    /*
+     * We enter the compartment of the wrappee here, even if we're not a cross
+     * compartment wrapper. Moreover, cross compartment wrappers do not enter
+     * the compartment of the wrappee before calling this function. This is
+     * necessary because the DefaultValue algorithm above operates on the
+     * wrapper, not the wrappee, so we want to delay the decision to switch
+     * compartments until this point.
+     */
+    AutoCompartment call(cx, wrappedObject(wrapper));
+    return IndirectProxyHandler::defaultValue(cx, wrapper_, hint, vp);
+}
+
 DirectWrapper::DirectWrapper(unsigned flags, bool hasPrototype) : Wrapper(flags),
         DirectProxyHandler(&sWrapperFamily)
 {
     setHasPrototype(hasPrototype);
 }
 
 DirectWrapper::~DirectWrapper()
 {
@@ -257,16 +294,53 @@ bool
 DirectWrapper::enumerate(JSContext *cx, JSObject *wrapper, AutoIdVector &props)
 {
     JS_ASSERT(!hasPrototype()); // Should never be called when there's a prototype.
     // if we refuse to perform this action, props remains empty
     static jsid id = JSID_VOID;
     GET(DirectProxyHandler::enumerate(cx, wrapper, props));
 }
 
+/*
+ * Ordinarily, the convert trap would require a PUNCTURE. However, the default
+ * implementation of convert, JS_ConvertStub, obtains a default value by calling
+ * the toString/valueOf method on the wrapper, if any. Doing a PUNCTURE in this
+ * case would be overly conservative. To make matters worse, XPConnect sometimes
+ * installs a custom convert trap that obtains a default value by calling the
+ * toString method on the wrapper. Doing a puncture in this case would be overly
+ * conservative as well. We deal with these anomalies by clearing the pending
+ * exception and falling back to the DefaultValue algorithm whenever the
+ * PUNCTURE fails.
+ */
+bool
+DirectWrapper::defaultValue(JSContext *cx, JSObject *wrapper_, JSType hint, Value *vp)
+{
+    RootedObject wrapper(cx, wrapper_);
+
+    bool status;
+    if (!enter(cx, wrapper_, JSID_VOID, PUNCTURE, &status)) {
+        RootedValue v(cx);
+        JS_ClearPendingException(cx);
+        if (!DefaultValue(cx, wrapper, hint, &v))
+            return false;
+        *vp = v;
+        return true;
+    }
+    /*
+     * We enter the compartment of the wrappee here, even if we're not a cross
+     * compartment wrapper. Moreover, cross compartment wrappers do not enter
+     * the compartment of the wrappee before calling this function. This is
+     * necessary because the DefaultValue algorithm above operates on the
+     * wrapper, not the wrappee, so we want to delay the decision to switch
+     * compartments until this point.
+     */
+    AutoCompartment call(cx, wrappedObject(wrapper));
+    return DirectProxyHandler::defaultValue(cx, wrapper_, hint, vp);
+}
+
 bool
 DirectWrapper::has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp)
 {
     JS_ASSERT(!hasPrototype()); // Should never be called when there's a prototype.
     *bp = false; // default result if we refuse to perform this action
     GET(DirectProxyHandler::has(cx, wrapper, id, bp));
 }
 
@@ -747,21 +821,18 @@ CrossCompartmentWrapper::regexp_toShared
 {
     AutoCompartment call(cx, wrappedObject(wrapper));
     return DirectWrapper::regexp_toShared(cx, wrapper, g);
 }
 
 bool
 CrossCompartmentWrapper::defaultValue(JSContext *cx, JSObject *wrapper, JSType hint, Value *vp)
 {
-    {
-        AutoCompartment call(cx, wrappedObject(wrapper));
-        if (!IndirectProxyHandler::defaultValue(cx, wrapper, hint, vp))
-            return false;
-    }
+    if (!DirectWrapper::defaultValue(cx, wrapper, hint, vp))
+        return false;
     return cx->compartment->wrap(cx, vp);
 }
 
 bool
 CrossCompartmentWrapper::iteratorNext(JSContext *cx, JSObject *wrapper, Value *vp)
 {
     PIERCE(cx, wrapper, GET,
            NOTHING,
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -147,16 +147,20 @@ class JS_FRIEND_API(IndirectWrapper) : p
     virtual bool defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
                                 PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper,
                                      AutoIdVector &props) MOZ_OVERRIDE;
     virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id,
                          bool *bp) MOZ_OVERRIDE;
     virtual bool enumerate(JSContext *cx, JSObject *wrapper,
                            AutoIdVector &props) MOZ_OVERRIDE;
+
+    /* Spidermonkey extensions. */
+    virtual bool defaultValue(JSContext *cx, JSObject *wrapper_, JSType hint,
+                              Value *vp) MOZ_OVERRIDE;
 };
 
 /*
  * DirectWrapper forwards its traps by forwarding them to DirectProxyHandler.
  * In effect, DirectWrapper behaves the same as DirectProxyHandler, except that
  * it adds policy enforcement checks to each trap.
  */
 class JS_FRIEND_API(DirectWrapper) : public Wrapper, public DirectProxyHandler
@@ -202,16 +206,18 @@ class JS_FRIEND_API(DirectWrapper) : pub
     /* Spidermonkey extensions. */
     virtual bool call(JSContext *cx, JSObject *wrapper, unsigned argc, Value *vp) MOZ_OVERRIDE;
     virtual bool construct(JSContext *cx, JSObject *wrapper, unsigned argc, Value *argv, Value *rval) MOZ_OVERRIDE;
     virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
                             CallArgs args) MOZ_OVERRIDE;
     virtual bool hasInstance(JSContext *cx, HandleObject wrapper, MutableHandleValue v, bool *bp) MOZ_OVERRIDE;
     virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
     virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, unsigned indent) MOZ_OVERRIDE;
+    virtual bool defaultValue(JSContext *cx, JSObject *wrapper_, JSType hint,
+                              Value *vp) MOZ_OVERRIDE;
 
     static DirectWrapper singleton;
     static DirectWrapper singletonWithPrototype;
 
     static void *getWrapperFamily();
 };
 
 /* Base class for all cross compartment wrapper handlers. */
--- a/js/xpconnect/tests/chrome/Makefile.in
+++ b/js/xpconnect/tests/chrome/Makefile.in
@@ -54,16 +54,17 @@ MOCHITEST_CHROME_FILES = \
 		test_getweakmapkeys.xul \
 		test_mozMatchesSelector.xul \
 		test_nodelists.xul \
 		test_precisegc.xul \
 		test_sandboxImport.xul \
 		test_weakmaps.xul \
 		test_weakref.xul \
 		test_wrappers.xul \
+		test_bug720619.xul \
 		$(NULL)
 
 # Disabled until this test gets updated to test the new proxy based
 # wrappers.
 #		test_wrappers-2.xul \
 
 # Disabled due to apparent conservative stack scanner false positives on Linux64 debug.
 #		test_watchpoints.xul \
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/chrome/test_bug720619.xul
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=720619
+-->
+<window title="Mozilla Bug 720619"
+  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <!-- test results are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=720619"
+     target="_blank">Mozilla Bug 720619</a>
+
+  <!-- test code goes here -->
+  <script type="application/javascript"><![CDATA[
+  /** Test for Bug 720619 **/
+  const Cu = Components.utils;
+
+  var obj = {
+    valueOf: function () {
+      return 42;
+    },
+    toString: function () {
+      return 'str';
+    }
+  };
+
+  var content = new Cu.Sandbox("about:blank");
+  content.obj = obj;
+
+  ok(Cu.evalInSandbox("obj + ''", content) == "[object Object]");
+  ok(Cu.evalInSandbox("'' + obj", content) == "[object Object]");
+  ok(isNaN(Cu.evalInSandbox("obj - 0", content)));
+  ok(Cu.evalInSandbox("String(obj)", content) == "[object Object]");
+
+  var chrome = new Cu.Sandbox(window);
+  chrome.obj = obj;
+
+  ok(Cu.evalInSandbox("obj + ''", chrome) == "42");
+  ok(Cu.evalInSandbox("'' + obj", chrome) == "42");
+  ok(Cu.evalInSandbox("obj - 0", chrome) == 42);
+  ok(Cu.evalInSandbox("String(obj)", chrome) == "str");
+  ]]></script>
+  </body>
+</window>
--- a/js/xpconnect/tests/mochitest/Makefile.in
+++ b/js/xpconnect/tests/mochitest/Makefile.in
@@ -61,24 +61,27 @@ MOCHITEST_FILES =	bug500931_helper.html 
 		test_bug691059.html \
 		file_bug706301.html \
 		test_bug745483.html \
 		file_bug760131.html \
 		test_bug764389.html \
 		test_bug772288.html \
 		test_bug781476.html \
 		file_bug781476.html \
+		test_bug789713.html \
 		file_nodelists.html \
 		file_exnstack.html \
 		file_expandosharing.html \
 		file_empty.html \
 		file_documentdomain.html \
 		test_lookupMethod.html \
 		file_bug738244.html \
 		file_mozMatchesSelector.html \
+		file_bug720619.html \
+		test_bug720619.html \
 		$(NULL)
 
 MOCHITEST_CHROME_FILES	= \
 		test_bug361111.xul \
 		test_bug760131.html \
 		$(NULL)
 
 ifneq ($(OS_TARGET),Android)
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug720619.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <script>
+            valueOf = function() { return "v"; }
+            toString = function() { return "s"; }
+        </script>
+    </head>
+    <body></body>
+</html>
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug720619.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=720619
+-->
+<head>
+  <title>Test for Bug 629227</title>
+  <script type="application/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=720619">Mozilla Bug 720619</a>
+<p id="display">
+  <iframe id="testTarget"></iframe>
+</p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 720619 **/
+SimpleTest.waitForExplicitFinish();
+
+function checkThrows(f, exception) {
+    try {
+        f();
+        ok(false, "should have thrown: " + f);
+    } catch (e) {
+        ok(exception.test(e.toString()), "correctly threw");
+    }
+}
+
+function go() {
+    var loc = $('ifr').contentWindow.location;
+    checkThrows(function() {loc + '';}, /Permission denied/);
+    checkThrows(function() {'' + loc;}, /Permission denied/);
+    checkThrows(function() {String(loc);}, /Permission denied/);
+
+    var win = $('ifr').contentWindow;
+    checkThrows(function() {win + '';}, /Permission denied/);
+    checkThrows(function() {'' + win;}, /Permission denied/);
+    checkThrows(function() {String(win);}, /Permission denied/);
+
+    SimpleTest.finish();
+}
+
+</script>
+
+<iframe id="ifr" onload="go()"
+        src="http://example.org/tests/js/xpconnect/tests/mochitest/file_bug720619.html">
+</iframe>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug789713.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=789713
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 789713</title>
+  <script type="application/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=789713">Mozilla Bug 789713</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe id="ifr"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 789713 **/
+
+function go() {
+  var pass = true;
+  var doc = document.getElementById('ifr').contentDocument;
+
+  // Tree walkers use nsDOMGenericSH, which has a spineless PreCreate.
+  var walker = doc.createTreeWalker(doc.body);
+  pass = pass && (walker.root === doc.body);
+
+  // First, do the document.domain operation. This shouldn't crash.
+  document.domain = "example.org";
+
+  // Now, make sure that we still can't access cross-origin properties despite
+  // the fact that the WN is shared under the hood.
+  try {
+    walker.root;
+    pass = false;
+  } catch (e) { pass = pass && /Permission denied/.exec(e.message); }
+  window.parent.postMessage(pass, '*');
+}
+
+// We can't set document.domain on mochi.test, because it's forbidden to set
+// document.domain to a TLD.
+var ifr = document.getElementById('ifr');
+if (window.location.hostname == "mochi.test") {
+  SimpleTest.waitForExplicitFinish();
+  ifr.src = window.location.toString().replace("mochi.test:8888", "test1.example.org").split('?')[0];
+  window.onmessage = function(message) { ok(message.data, "Test succeeded and didn't crash"); SimpleTest.finish(); };
+} else {
+  ifr.src = "file_empty.html";
+  ifr.onload = go;
+}
+
+</script>
+</pre>
+</body>
+</html>
--- a/js/xpconnect/wrappers/AccessCheck.cpp
+++ b/js/xpconnect/wrappers/AccessCheck.cpp
@@ -47,16 +47,33 @@ AccessCheck::subsumes(JSCompartment *a, 
 
     bool subsumes;
     nsresult rv = aprin->Subsumes(bprin, &subsumes);
     NS_ENSURE_SUCCESS(rv, false);
 
     return subsumes;
 }
 
+// Same as above, but ignoring document.domain.
+bool
+AccessCheck::subsumesIgnoringDomain(JSCompartment *a, JSCompartment *b)
+{
+    nsIPrincipal *aprin = GetCompartmentPrincipal(a);
+    nsIPrincipal *bprin = GetCompartmentPrincipal(b);
+
+    if (!aprin || !bprin)
+        return false;
+
+    bool subsumes;
+    nsresult rv = aprin->SubsumesIgnoringDomain(bprin, &subsumes);
+    NS_ENSURE_SUCCESS(rv, false);
+
+    return subsumes;
+}
+
 // Does the compartment of the wrapper subsumes the compartment of the wrappee?
 bool
 AccessCheck::wrapperSubsumes(JSObject *wrapper)
 {
     MOZ_ASSERT(js::IsWrapper(wrapper));
     JSObject *wrapped = js::UnwrapObject(wrapper);
     return AccessCheck::subsumes(js::GetObjectCompartment(wrapper),
                                  js::GetObjectCompartment(wrapped));
--- a/js/xpconnect/wrappers/AccessCheck.h
+++ b/js/xpconnect/wrappers/AccessCheck.h
@@ -15,16 +15,17 @@
 class nsIPrincipal;
 
 namespace xpc {
 
 class AccessCheck {
   public:
     static bool subsumes(JSCompartment *a, JSCompartment *b);
     static bool wrapperSubsumes(JSObject *wrapper);
+    static bool subsumesIgnoringDomain(JSCompartment *a, JSCompartment *b);
     static bool isChrome(JSCompartment *compartment);
     static bool isChrome(JSObject *obj);
     static bool callerIsChrome();
     static nsIPrincipal *getPrincipal(JSCompartment *compartment);
     static bool isCrossOriginAccessPermitted(JSContext *cx, JSObject *obj, jsid id,
                                              js::Wrapper::Action act);
     static bool isSystemOnlyAccessPermitted(JSContext *cx);
     static bool isLocationObjectSameOrigin(JSContext *cx, JSObject *wrapper);
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -222,19 +222,29 @@ WrapperFactory::PrepareForWrapping(JSCon
                     return DoubleWrap(cx, obj, flags);
                 }
 
                 // Ok, must be case (1). Fall through and create a new wrapper.
             }
 
             // Nasty hack for late-breaking bug 781476. This will confuse identity checks,
             // but it's probably better than any of our alternatives.
+            //
+            // Note: We have to ignore domain here. The JS engine assumes that, given a
+            // compartment c, if c->wrap(x) returns a cross-compartment wrapper at time t0,
+            // it will also return a cross-compartment wrapper for any time t1 > t0 unless
+            // an explicit transplant is performed. In particular, wrapper recomputation
+            // assumes that recomputing a wrapper will always result in a wrapper.
+            //
+            // This doesn't actually pose a security issue, because we'll still compute
+            // the correct (opaque) wrapper for the object below given the security
+            // characteristics of the two compartments.
             if (!AccessCheck::isChrome(js::GetObjectCompartment(scope)) &&
-                 AccessCheck::subsumes(js::GetObjectCompartment(scope),
-                                       js::GetObjectCompartment(obj)))
+                 AccessCheck::subsumesIgnoringDomain(js::GetObjectCompartment(scope),
+                                                     js::GetObjectCompartment(obj)))
             {
                 return DoubleWrap(cx, obj, flags);
             }
         }
     }
 
     // NB: Passing a holder here inhibits slim wrappers under
     // WrapNativeToJSVal.
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -1996,17 +1996,19 @@ FrameLayerBuilder::AddThebesDisplayItem(
                                         nsIFrame* aContainerLayerFrame,
                                         LayerState aLayerState)
 {
   AddLayerDisplayItem(aLayer, aItem, aLayerState);
 
   ThebesLayerItemsEntry* entry = mThebesLayerItems.PutEntry(aLayer);
   if (entry) {
     entry->mContainerLayerFrame = aContainerLayerFrame;
-    entry->mContainerLayerGeneration = mContainerLayerGeneration;
+    if (entry->mContainerLayerGeneration == 0) {
+      entry->mContainerLayerGeneration = mContainerLayerGeneration;
+    }
     NS_ASSERTION(aItem->GetUnderlyingFrame(), "Must have frame");
     ClippedDisplayItem* cdi =
       entry->mItems.AppendElement(ClippedDisplayItem(aItem, aClip,
                                                      mContainerLayerGeneration));
     cdi->mInactiveLayer = aLayerState != LAYER_NONE;
   }
 }
 
@@ -2042,29 +2044,33 @@ FrameLayerBuilder::AddLayerDisplayItem(L
   }
 }
 
 nsIntPoint
 FrameLayerBuilder::GetLastPaintOffset(ThebesLayer* aLayer)
 {
   ThebesLayerItemsEntry* entry = mThebesLayerItems.PutEntry(aLayer);
   if (entry) {
-    entry->mContainerLayerGeneration = mContainerLayerGeneration;
+    if (entry->mContainerLayerGeneration == 0) {
+      entry->mContainerLayerGeneration = mContainerLayerGeneration;
+    }
     if (entry->mHasExplicitLastPaintOffset)
       return entry->mLastPaintOffset;
   }
   return GetTranslationForThebesLayer(aLayer);
 }
 
 void
 FrameLayerBuilder::SaveLastPaintOffset(ThebesLayer* aLayer)
 {
   ThebesLayerItemsEntry* entry = mThebesLayerItems.PutEntry(aLayer);
   if (entry) {
-    entry->mContainerLayerGeneration = mContainerLayerGeneration;
+    if (entry->mContainerLayerGeneration == 0) {
+      entry->mContainerLayerGeneration = mContainerLayerGeneration;
+    }
     entry->mLastPaintOffset = GetTranslationForThebesLayer(aLayer);
     entry->mHasExplicitLastPaintOffset = true;
   }
 }
 
 nscolor
 FrameLayerBuilder::FindOpaqueColorCovering(nsDisplayListBuilder* aBuilder,
                                            ThebesLayer* aLayer,
--- a/layout/base/FrameLayerBuilder.h
+++ b/layout/base/FrameLayerBuilder.h
@@ -561,16 +561,17 @@ protected:
    * We accumulate ClippedDisplayItem elements in a hashtable during
    * the paint process. This is the hashentry for that hashtable.
    */
 public:
   class ThebesLayerItemsEntry : public nsPtrHashKey<ThebesLayer> {
   public:
     ThebesLayerItemsEntry(const ThebesLayer *key) :
         nsPtrHashKey<ThebesLayer>(key), mContainerLayerFrame(nullptr),
+        mContainerLayerGeneration(0),
         mHasExplicitLastPaintOffset(false), mCommonClipCount(0) {}
     ThebesLayerItemsEntry(const ThebesLayerItemsEntry &toCopy) :
       nsPtrHashKey<ThebesLayer>(toCopy.mKey), mItems(toCopy.mItems)
     {
       NS_ERROR("Should never be called, since we ALLOW_MEMMOVE");
     }
 
     nsTArray<ClippedDisplayItem> mItems;
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -3989,16 +3989,19 @@ PresShell::DocumentStatesChanged(nsIDocu
                                         eRestyle_Subtree, NS_STYLE_HINT_NONE);
     VERIFY_STYLE_TREE;
   }
 
   if (aStateMask.HasState(NS_DOCUMENT_STATE_WINDOW_INACTIVE)) {
     nsIFrame* root = mFrameConstructor->GetRootFrame();
     if (root) {
       root->InvalidateFrameSubtree();
+      if (root->HasView()) {
+        root->GetView()->SetForcedRepaint(true);
+      }
     }
   }
 }
 
 void
 PresShell::AttributeWillChange(nsIDocument* aDocument,
                                Element*     aElement,
                                int32_t      aNameSpaceID,
@@ -5293,17 +5296,17 @@ PresShell::Paint(nsIView*           aVie
       }
       layerManager->BeginTransaction();
       if (layerManager->EndEmptyTransaction()) {
         return;
       }
       NS_WARNING("Must complete empty transaction when compositing!");
     } else  if (!(frame->GetStateBits() & NS_FRAME_UPDATE_LAYER_TREE)) {
       layerManager->BeginTransaction();
-      if (layerManager->EndEmptyTransaction(LayerManager::END_NO_COMPOSITE)) {
+      if (layerManager->EndEmptyTransaction((aType == PaintType_NoComposite) ? LayerManager::END_NO_COMPOSITE : LayerManager::END_DEFAULT)) {
         frame->UpdatePaintCountForPaintedPresShells();
         presContext->NotifyDidPaintForSubtree();
         return;
       }
     } else {
       layerManager->BeginTransaction();
     }
 
@@ -6523,17 +6526,17 @@ PresShell::DispatchTouchEvent(nsEvent *a
 
       // If someone is capturing, all touch events are filtered to their target
       nsCOMPtr<nsIContent> content = GetCapturingContent();
 
       // if no one is capturing, set the capturing target
       if (!content) {
         content = do_QueryInterface(targetPtr);
       }
-      PresShell* contentPresShell = nullptr;
+      nsRefPtr<PresShell> contentPresShell;
       if (content && content->OwnerDoc() == mDocument) {
         contentPresShell = static_cast<PresShell*>
             (content->OwnerDoc()->GetShell());
         if (contentPresShell) {
           contentPresShell->PushCurrentEventInfo(
               content->GetPrimaryFrame(), content);
         }
       }
--- a/layout/build/Makefile.in
+++ b/layout/build/Makefile.in
@@ -78,16 +78,17 @@ SHARED_LIBRARY_LIBS = \
 	$(DEPTH)/dom/src/offline/$(LIB_PREFIX)jsdomoffline_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/src/geolocation/$(LIB_PREFIX)jsdomgeolocation_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/src/notification/$(LIB_PREFIX)jsdomnotification_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/system/$(LIB_PREFIX)domsystem_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/workers/$(LIB_PREFIX)domworkers_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/indexedDB/$(LIB_PREFIX)dom_indexeddb_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/indexedDB/ipc/$(LIB_PREFIX)dom_indexeddb_ipc_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/browser-element/$(LIB_PREFIX)dom_browserelement_s.$(LIB_SUFFIX) \
+	$(DEPTH)/dom/time/$(LIB_PREFIX)dom_time_s.$(LIB_SUFFIX) \
 	$(DEPTH)/editor/libeditor/text/$(LIB_PREFIX)texteditor_s.$(LIB_SUFFIX) \
 	$(DEPTH)/editor/libeditor/base/$(LIB_PREFIX)editorbase_s.$(LIB_SUFFIX) \
 	$(DEPTH)/parser/html/$(LIB_PREFIX)html5p_s.$(LIB_SUFFIX) \
 	$(DEPTH)/caps/src/$(LIB_PREFIX)caps_s.$(LIB_SUFFIX) \
 	$(DEPTH)/editor/libeditor/html/$(LIB_PREFIX)htmleditor_s.$(LIB_SUFFIX) \
 	$(DEPTH)/editor/txtsvc/src/$(LIB_PREFIX)txtsvc_s.$(LIB_SUFFIX) \
 	$(DEPTH)/content/mathml/content/src/$(LIB_PREFIX)gkcontentmathml_s.$(LIB_SUFFIX) \
 	$(NULL)
--- a/layout/forms/nsGfxButtonControlFrame.cpp
+++ b/layout/forms/nsGfxButtonControlFrame.cpp
@@ -52,17 +52,17 @@ nsGfxButtonControlFrame::GetType() const
   return nsGkAtoms::gfxButtonControlFrame;
 }
 
 // Special check for the browse button of a file input.
 //
 // We'll return true if type is NS_FORM_INPUT_BUTTON and our parent
 // is a file input.
 bool
-nsGfxButtonControlFrame::IsFileBrowseButton(int32_t type)
+nsGfxButtonControlFrame::IsFileBrowseButton(int32_t type) const
 {
   bool rv = false;
   if (NS_FORM_INPUT_BUTTON == type) {
     // Check to see if parent is a file input
     nsCOMPtr<nsIFormControl> formCtrl =
       do_QueryInterface(mContent->GetParent());
 
     rv = formCtrl && formCtrl->GetType() == NS_FORM_INPUT_FILE;
@@ -137,17 +137,17 @@ nsGfxButtonControlFrame::CreateFrameFor(
 nsresult
 nsGfxButtonControlFrame::GetFormProperty(nsIAtom* aName, nsAString& aValue) const
 {
   nsresult rv = NS_OK;
   if (nsGkAtoms::defaultLabel == aName) {
     // This property is used by accessibility to get
     // the default label of the button.
     nsXPIDLString temp;
-    rv = const_cast<nsGfxButtonControlFrame*>(this)->GetDefaultLabel(temp);
+    rv = GetDefaultLabel(temp);
     aValue = temp;
   } else {
     aValue.Truncate();
   }
   return rv;
 }
 
 NS_QUERYFRAME_HEAD(nsGfxButtonControlFrame)
@@ -156,29 +156,29 @@ NS_QUERYFRAME_TAIL_INHERITING(nsHTMLButt
 
 // Initially we hardcoded the default strings here.
 // Next, we used html.css to store the default label for various types
 // of buttons. (nsGfxButtonControlFrame::DoNavQuirksReflow rev 1.20)
 // However, since html.css is not internationalized, we now grab the default
 // label from a string bundle as is done for all other UI strings.
 // See bug 16999 for further details.
 nsresult
-nsGfxButtonControlFrame::GetDefaultLabel(nsXPIDLString& aString)
+nsGfxButtonControlFrame::GetDefaultLabel(nsXPIDLString& aString) const
 {
   nsCOMPtr<nsIFormControl> form = do_QueryInterface(mContent);
   NS_ENSURE_TRUE(form, NS_ERROR_UNEXPECTED);
 
   int32_t type = form->GetType();
   const char *prop;
   if (type == NS_FORM_INPUT_RESET) {
     prop = "Reset";
-  } 
+  }
   else if (type == NS_FORM_INPUT_SUBMIT) {
     prop = "Submit";
-  } 
+  }
   else if (IsFileBrowseButton(type)) {
     prop = "Browse";
   }
   else {
     aString.Truncate();
     return NS_OK;
   }
 
--- a/layout/forms/nsGfxButtonControlFrame.h
+++ b/layout/forms/nsGfxButtonControlFrame.h
@@ -56,21 +56,21 @@ public:
                               nsIAtom*        aAttribute,
                               int32_t         aModType);
 
   virtual bool IsLeaf() const;
 
   virtual nsIFrame* GetContentInsertionFrame();
 
 protected:
-  nsresult GetDefaultLabel(nsXPIDLString& aLabel);
+  nsresult GetDefaultLabel(nsXPIDLString& aLabel) const;
 
   nsresult GetLabel(nsXPIDLString& aLabel);
 
-  bool IsFileBrowseButton(int32_t type); // Browse button of file input
+  bool IsFileBrowseButton(int32_t type) const; // Browse button of file input
 
   virtual bool IsInput() { return true; }
 private:
   nsCOMPtr<nsIContent> mTextContent;
 };
 
 
 #endif
--- a/layout/style/nsICSSDeclaration.h
+++ b/layout/style/nsICSSDeclaration.h
@@ -89,17 +89,17 @@ public:
   void SetCssText(const nsAString& aString, mozilla::ErrorResult& rv) {
     rv = SetCssText(aString);
   }
   void GetCssText(nsString& aString) {
     // Cast to nsAString& so we end up calling our virtual
     // |GetCssText(nsAString& aCssText)| overload, which does the real work.
     GetCssText(static_cast<nsAString&>(aString));
   }
-  uint32_t GetLength() {
+  uint32_t Length() {
     uint32_t length;
     GetLength(&length);
     return length;
   }
   void Item(uint32_t aIndex, nsString& aPropName) {
     Item(aIndex, static_cast<nsAString&>(aPropName));
   }
 
--- a/layout/style/test/chrome/Makefile.in
+++ b/layout/style/test/chrome/Makefile.in
@@ -13,15 +13,17 @@ include $(DEPTH)/config/autoconf.mk
 MOCHITEST_CHROME_FILES = \
     test_bug535806.xul \
     bug535806-css.css \
     bug535806-html.html \
     bug535806-xul.xul \
     test_hover.html \
     test_moz_document_rules.html \
     hover_helper.html \
+    test_additional_sheets.html \
     $(NULL)
 
 MOCHITEST_FILES = \
     moz_document_helper.html \
+    additional_sheets_helper.html \
     $(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/layout/style/test/chrome/additional_sheets_helper.html
@@ -0,0 +1,7 @@
+<html>
+<head>
+</head>
+<body>
+  some text
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/style/test/chrome/test_additional_sheets.html
@@ -0,0 +1,252 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for additional sheets</title>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+</head>
+<body onload="run()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=737003">Mozilla Bug 737003</a>
+<iframe id="iframe" src="http://mochi.test:8888/tests/layout/style/test/chrome/additional_sheets_helper.html"></iframe>
+<pre id="test">
+<script type="application/javascript; version=1.8">
+
+
+
+var gIOService = Components.classes["@mozilla.org/network/io-service;1"]
+  .getService(Components.interfaces.nsIIOService)
+
+function getUri(style)
+{
+  return "data:text/css," + style;
+}
+
+function getStyle(color, swapped)
+{
+  return "body {color: " + color +  (swapped ? " !important" : "") +
+    "; background-color: " + color + (swapped ? "" : " !important;") + ";}";
+}
+
+function loadUserSheet(win, style)
+{
+  loadSheet(win, style, "USER_SHEET");
+}
+
+function loadAgentSheet(win, style)
+{
+  loadSheet(win, style, "AGENT_SHEET");
+}
+
+function removeUserSheet(win, style)
+{
+  removeSheet(win, style, "USER_SHEET");
+}
+
+function removeAgentSheet(win, style)
+{
+  removeSheet(win, style, "AGENT_SHEET");
+}
+
+function loadSheet(win, style, type)
+{
+  var uri = gIOService.newURI(getUri(style), null, null);
+  var windowUtils = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+    .getInterface(Components.interfaces.nsIDOMWindowUtils);
+  windowUtils.loadSheet(uri, windowUtils[type]);
+}
+
+function removeSheet(win, style, type)
+{
+  var uri = gIOService.newURI(getUri(style), null, null);
+  var windowUtils = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+    .getInterface(Components.interfaces.nsIDOMWindowUtils);
+  windowUtils.removeSheet(uri, windowUtils[type]);
+}
+
+function loadAndRegisterUserSheet(win, style)
+{
+  loadAndRegisterSheet(win, style, "USER_SHEET");
+}
+
+function loadAndRegisterAgentSheet(win, style)
+{
+  loadAndRegisterSheet(win, style, "AGENT_SHEET");
+}
+
+function unregisterUserSheet(win, style)
+{
+  unregisterSheet(win, style, "USER_SHEET");
+}
+
+function unregisterAgentSheet(win, style)
+{
+  unregisterSheet(win, style, "AGENT_SHEET");
+}
+
+function loadAndRegisterSheet(win, style, type)
+{
+  var sss = Components.classes["@mozilla.org/content/style-sheet-service;1"]
+    .getService(Components.interfaces.nsIStyleSheetService);
+  var ios = Components.classes["@mozilla.org/network/io-service;1"]
+    .getService(Components.interfaces.nsIIOService);
+  uri = ios.newURI(getUri(style), null, null);
+  sss.loadAndRegisterSheet(uri, sss[type]);
+  is (sss.sheetRegistered(uri, sss[type]), true);
+}
+
+function unregisterSheet(win, style, type)
+{
+  var sss = Components.classes["@mozilla.org/content/style-sheet-service;1"]
+    .getService(Components.interfaces.nsIStyleSheetService);
+  var ios = Components.classes["@mozilla.org/network/io-service;1"]
+    .getService(Components.interfaces.nsIIOService);
+  var uri = ios.newURI(getUri(style), null, null);
+  sss.unregisterSheet(uri, sss[type]);
+  is (sss.sheetRegistered(uri, sss[type]), false);
+}
+
+function setDocSheet(win, style)
+{
+  var subdoc = win.document;
+  var headID = subdoc.getElementsByTagName("head")[0];
+  var cssNode = subdoc.createElement('style');
+  cssNode.type = 'text/css';
+  cssNode.innerHTML = style;
+  cssNode.id = 'docsheet';
+  headID.appendChild(cssNode);
+}
+
+function removeDocSheet(win)
+{
+  var subdoc = win.document;
+  var node = subdoc.getElementById('docsheet');
+  node.parentNode.removeChild(node);
+}
+
+var agent = {
+  type: 'agent',
+  color: 'rgb(255, 0, 0)',
+  addRules: loadAndRegisterAgentSheet,
+  removeRules: unregisterAgentSheet
+};
+
+var user = {
+  type: 'user',
+  color: 'rgb(0, 255, 0)',
+  addRules: loadAndRegisterUserSheet,
+  removeRules: unregisterUserSheet
+};
+
+var additionalAgent = {
+  type: 'additionalAgent',
+  color: 'rgb(0, 0, 255)',
+  addRules: loadAgentSheet,
+  removeRules: removeAgentSheet
+};
+
+var additionalUser = {
+  type: 'additionalUser',
+  color: 'rgb(255, 255, 0)',
+  addRules: loadUserSheet,
+  removeRules: removeUserSheet
+};
+
+var author = {
+  type: 'author',
+  color: 'rgb(0, 255, 255)',
+  addRules: setDocSheet,
+  removeRules: removeDocSheet
+};
+
+function loadAndCheck(win, firstType, secondType, swap, result1, result2)
+{
+  var firstStyle = getStyle(firstType.color, false);
+  var secondStyle = getStyle(secondType.color, swap);
+
+  firstType.addRules(win, firstStyle);
+  secondType.addRules(win, secondStyle);
+
+  var cs = win.getComputedStyle(win.document.body, null);
+  is(cs.getPropertyValue('color'), result1,
+    firstType.type + "(normal)" + " vs " + secondType.type + (swap ? "(important)" : "(normal)" ) + " 1");
+  is(cs.getPropertyValue('background-color'), result2,
+    firstType.type + "(important)" + " vs " + secondType.type + (swap ? "(normal)" : "(important)" ) + " 2");
+
+  firstType.removeRules(win, firstStyle);
+  secondType.removeRules(win, secondStyle);
+
+  is(cs.getPropertyValue('color'), 'rgb(0, 0, 0)', firstType.type + " vs " + secondType.type + " 3");
+  is(cs.getPropertyValue('background-color'), 'transparent', firstType.type + " vs " + secondType.type + " 4");
+}
+
+// There are 8 cases. Regular against regular, regular against important, important
+// against regular, important against important. We can load style from typeA first
+// then typeB or the other way around so that's 4*2=8 cases.
+
+function testStyleVsStyle(win, typeA, typeB, results)
+{
+  function color(res)
+  {
+    return res ? typeB.color : typeA.color;
+  }
+
+  loadAndCheck(win, typeA, typeB, false, color(results.AB.rr), color(results.AB.ii));
+  loadAndCheck(win, typeB, typeA, false, color(results.BA.rr), color(results.BA.ii));
+
+  loadAndCheck(win, typeA, typeB, true, color(results.AB.ri), color(results.AB.ir));
+  loadAndCheck(win, typeB, typeA, true, color(results.BA.ir), color(results.BA.ri));
+}
+
+// 5 user agent normal declarations
+// 4 user normal declarations
+// 3 author normal declarations
+// 2 author important declarations
+// 1 user important declarations
+// 0 user agent important declarations
+
+function run()
+{
+  var iframe = document.getElementById("iframe");
+  var win = iframe.contentWindow;
+
+// Some explanation how to interpret this result table...
+// in case of loading the agent style first and the user style later (AB)
+// if there is an important rule in both for let's say color (ii)
+// the rule specified in the agent style will lead (AB.ii == 0)
+// If both rules would be just regular rules the one specified in the user style
+// would lead. (AB.rr == 1). If we would load/add the rules in reverse order that
+// would not change that (BA.rr == 1)
+  testStyleVsStyle(win, agent, user,
+                   {AB:{rr:1, ii:0, ri:1, ir:0}, BA:{rr:1, ii:0, ri:1, ir:0}});
+
+  testStyleVsStyle(win, agent, author,
+                   {AB:{rr:1, ii:0, ri:1, ir:0}, BA:{rr:1, ii:0, ri:1, ir:0}});
+
+
+  testStyleVsStyle(win, additionalUser, agent,
+                   {AB:{rr:0, ii:1, ri:1, ir:0}, BA:{rr:0, ii:1, ri:1, ir:0}});
+
+  testStyleVsStyle(win, additionalUser, author,
+                   {AB:{rr:1, ii:0, ri:1, ir:0}, BA:{rr:1, ii:0, ri:1, ir:0}});
+
+  testStyleVsStyle(win, additionalAgent, user,
+                   {AB:{rr:1, ii:0, ri:1, ir:0}, BA:{rr:1, ii:0, ri:1, ir:0}});
+
+  testStyleVsStyle(win, additionalAgent, author,
+                   {AB:{rr:1, ii:0, ri:1, ir:0}, BA:{rr:1, ii:0, ri:1, ir:0}});
+
+
+  testStyleVsStyle(win, additionalAgent, additionalUser,
+                   {AB:{rr:1, ii:0, ri:1, ir:0}, BA:{rr:1, ii:0, ri:1, ir:0}});
+
+
+  SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+</body>
+</html>
--- a/mobile/android/base/AwesomeBar.java
+++ b/mobile/android/base/AwesomeBar.java
@@ -524,17 +524,17 @@ public class AwesomeBar extends GeckoAct
                 break;
             }
             case R.id.open_in_reader: {
                 if (url == null) {
                     Log.e(LOGTAG, "Can't open in reader mode because URL is null");
                     break;
                 }
 
-                openUrlAndFinish(getReaderForUrl(url));
+                openUrlAndFinish(ReaderModeUtils.getAboutReaderForUrl(url, true));
                 break;
             }
             case R.id.edit_bookmark: {
                 AlertDialog.Builder editPrompt = new AlertDialog.Builder(this);
                 View editView = getLayoutInflater().inflate(R.layout.bookmark_edit, null);
                 editPrompt.setTitle(R.string.bookmark_edit_title);
                 editPrompt.setView(editView);
 
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -781,18 +781,22 @@ abstract public class BrowserApp extends
         } else {
             readingList.setChecked(false);
             readingList.setIcon(R.drawable.ic_menu_reading_list_add);
         }
 
         forward.setEnabled(tab.canDoForward());
         desktopMode.setChecked(tab.getDesktopMode());
 
+        String url = tab.getURL();
+        if (ReaderModeUtils.isAboutReader(url))
+            url = ReaderModeUtils.getUrlFromAboutReader(url);
+
         // Disable share menuitem for about:, chrome:, file:, and resource: URIs
-        String scheme = Uri.parse(tab.getURL()).getScheme();
+        String scheme = Uri.parse(url).getScheme();
         share.setEnabled(!(scheme.equals("about") || scheme.equals("chrome") ||
                            scheme.equals("file") || scheme.equals("resource")));
 
         // Disable save as PDF for about:home and xul pages
         saveAsPDF.setEnabled(!(tab.getURL().equals("about:home") ||
                                tab.getContentType().equals("application/vnd.mozilla.xul+xml")));
 
         // Disable find in page for about:home, since it won't work on Java content
--- a/mobile/android/base/BrowserToolbar.java
+++ b/mobile/android/base/BrowserToolbar.java
@@ -559,16 +559,20 @@ public class BrowserToolbar implements V
     public void setTitle(CharSequence title) {
         Tab tab = Tabs.getInstance().getSelectedTab();
 
         // We use about:empty as a placeholder for an external page load and
         // we don't want to change the title
         if (tab != null && "about:empty".equals(tab.getURL()))
             return;
 
+        // Keep the title unchanged if the tab is entering reader mode
+        if (tab != null && tab.isEnteringReaderMode())
+            return;
+
         // Setting a null title for about:home will ensure we just see
         // the "Enter Search or Address" placeholder text
         if (tab != null && "about:home".equals(tab.getURL()))
             title = null;
 
         mTitle.setText(title);
         mAwesomeBar.setContentDescription(title != null ? title : mTitle.getHint());
     }
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -593,16 +593,19 @@ abstract public class GeckoApp
       Tab tab = Tabs.getInstance().getSelectedTab();
       if (tab == null)
         return;
 
       String url = tab.getURL();
       if (url == null)
           return;
 
+      if (ReaderModeUtils.isAboutReader(url))
+          url = ReaderModeUtils.getUrlFromAboutReader(url);
+
       GeckoAppShell.openUriExternal(url, "text/plain", "", "",
                                     Intent.ACTION_SEND, tab.getDisplayTitle());
     }
 
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
 
         Log.i(LOGTAG, "onSaveInstanceState");
@@ -1081,17 +1084,17 @@ abstract public class GeckoApp
         });
     }
 
     void handleDocumentStart(int tabId, final boolean showProgress, String uri) {
         final Tab tab = Tabs.getInstance().getTab(tabId);
         if (tab == null)
             return;
 
-        tab.setState("about:home".equals(uri) ? Tab.STATE_SUCCESS : Tab.STATE_LOADING);
+        tab.setState(shouldShowProgress(uri) ? Tab.STATE_SUCCESS : Tab.STATE_LOADING);
         tab.updateIdentityData(null);
         tab.setReaderEnabled(false);
         if (Tabs.getInstance().isSelectedTab(tab))
             mLayerView.getRenderer().resetCheckerboard();
         mMainHandler.post(new Runnable() {
             public void run() {
                 Tabs.getInstance().notifyListeners(tab, Tabs.TabEvents.START, showProgress);
             }
@@ -2667,16 +2670,20 @@ abstract public class GeckoApp
                     }
                 }
                 return true;
             }
         }
         return false;
     }
 
+    public static boolean shouldShowProgress(String url) {
+        return "about:home".equals(url) || ReaderModeUtils.isAboutReader(url);
+    }
+
     public static void assertOnUiThread() {
         Thread uiThread = mAppContext.getMainLooper().getThread();
         assertOnThread(uiThread);
     }
 
     public static void assertOnGeckoThread() {
         assertOnThread(sGeckoThread);
     }
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -99,16 +99,17 @@ FENNEC_JAVA_FILES = \
   PrivateDataPreference.java \
   PropertyAnimator.java \
   ProfileMigrator.java \
   PromptService.java \
   sqlite/ByteBufferInputStream.java \
   sqlite/MatrixBlobCursor.java \
   sqlite/SQLiteBridge.java \
   sqlite/SQLiteBridgeException.java \
+  ReaderModeUtils.java \
   RemoteTabs.java \
   RobocopAPI.java \
   SetupScreen.java \
   ShapedButton.java \
   SiteIdentityPopup.java \
   SuggestClient.java \
   SurfaceBits.java \
   Tab.java \
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/ReaderModeUtils.java
@@ -0,0 +1,78 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.gecko;
+
+import android.net.Uri;
+import android.text.TextUtils;
+
+public class ReaderModeUtils {
+    private static final String LOGTAG = "ReaderModeUtils";
+
+    public static boolean isAboutReader(String url) {
+        if (url == null)
+            return false;
+
+        return url.startsWith("about:reader");
+    }
+
+    public static String getUrlFromAboutReader(String aboutReaderUrl) {
+        if (aboutReaderUrl == null)
+            return null;
+
+        String[] urlParts = aboutReaderUrl.split("\\?");
+        if (urlParts.length < 2)
+            return null;
+
+        String query = urlParts[1];
+        for (String param : query.split("&")) {
+            String pair[] = param.split("=");
+            String key = Uri.decode(pair[0]);
+
+            // Key is empty or not "url", discard
+            if (TextUtils.isEmpty(key) || !key.equals("url"))
+                continue;
+
+            // No value associated with key, discard
+            if (pair.length < 2)
+                continue;
+
+            String url = Uri.decode(pair[1]);
+            if (TextUtils.isEmpty(url))
+                return null;
+
+            return url;
+        }
+
+        return null;
+    }
+
+    public static boolean isEnteringReaderMode(String currentUrl, String newUrl) {
+        if (currentUrl == null || newUrl == null)
+            return false;
+
+        if (!isAboutReader(newUrl))
+            return false;
+
+        String urlFromAboutReader = getUrlFromAboutReader(newUrl);
+        if (urlFromAboutReader == null)
+            return false;
+
+        return urlFromAboutReader.equals(currentUrl);
+    }
+
+    public static String getAboutReaderForUrl(String url, boolean inReadingList) {
+        return getAboutReaderForUrl(url, -1, inReadingList);
+    }
+
+    public static String getAboutReaderForUrl(String url, int tabId, boolean inReadingList) {
+        String aboutReaderUrl = "about:reader?url=" + Uri.encode(url) +
+                                "&readingList=" + (inReadingList ? 1 : 0);
+
+        if (tabId >= 0)
+            aboutReaderUrl += "&tabId=" + tabId;
+
+        return aboutReaderUrl;
+    }
+}
--- a/mobile/android/base/Tab.java
+++ b/mobile/android/base/Tab.java
@@ -15,16 +15,17 @@ import org.json.JSONObject;
 
 import android.content.ContentResolver;
 import android.database.ContentObserver;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
 
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -60,16 +61,17 @@ public final class Tab {
     private HashMap<Object, Layer> mPluginLayers;
     private ContentResolver mContentResolver;
     private ContentObserver mContentObserver;
     private int mCheckerboardColor = Color.WHITE;
     private int mState;
     private ByteBuffer mThumbnailBuffer;
     private Bitmap mThumbnailBitmap;
     private boolean mDesktopMode;
+    private boolean mEnteringReaderMode;
 
     public static final int STATE_DELAYED = 0;
     public static final int STATE_LOADING = 1;
     public static final int STATE_SUCCESS = 2;
     public static final int STATE_ERROR = 3;
 
     public Tab(int id, String url, boolean external, int parentId, String title) {
         mId = id;
@@ -78,28 +80,29 @@ public final class Tab {
         mExternal = external;
         mParentId = parentId;
         mTitle = title == null ? "" : title;
         mFavicon = null;
         mFaviconUrl = null;
         mFaviconSize = 0;
         mIdentityData = null;
         mReaderEnabled = false;
+        mEnteringReaderMode = false;
         mThumbnail = null;
         mHistoryIndex = -1;
         mHistorySize = 0;
         mBookmark = false;
         mReadingListItem = false;
         mFaviconLoadId = 0;
         mDocumentURI = "";
         mContentType = "";
         mZoomConstraints = new ZoomConstraints(false);
         mPluginViews = new ArrayList<View>();
         mPluginLayers = new HashMap<Object, Layer>();
-        mState = "about:home".equals(url) ? STATE_SUCCESS : STATE_LOADING;
+        mState = GeckoApp.shouldShowProgress(url) ? STATE_SUCCESS : STATE_LOADING;
         mContentResolver = Tabs.getInstance().getContentResolver();
         mContentObserver = new ContentObserver(GeckoAppShell.getHandler()) {
             public void onChange(boolean selfChange) {
                 updateBookmark();
             }
         };
         BrowserDB.registerBookmarkObserver(mContentResolver, mContentObserver);
     }
@@ -263,16 +266,20 @@ public final class Tab {
         mContentType = contentType;
     }
 
     public String getContentType() {
         return mContentType;
     }
 
     public synchronized void updateTitle(String title) {
+        // Keep the title unchanged while entering reader mode
+        if (mEnteringReaderMode)
+            return;
+
         mTitle = (title == null ? "" : title);
 
         Log.d(LOGTAG, "Updated title for tab with id: " + mId);
         updateHistory(mUrl, mTitle);
         final Tab tab = this;
 
         GeckoAppShell.getMainHandler().post(new Runnable() {
             public void run() {
@@ -286,17 +293,20 @@ public final class Tab {
             public void run() {
                 GlobalHistory.getInstance().update(uri, title);
             }
         });
     }
 
     public void setState(int state) {
         mState = state;
-    }
+
+        if (mState != Tab.STATE_LOADING)
+            mEnteringReaderMode = false;
+        }
 
     public int getState() {
         return mState;
     }
 
     public void setZoomConstraints(ZoomConstraints constraints) {
         mZoomConstraints = constraints;
     }
@@ -336,16 +346,20 @@ public final class Tab {
         if (size == -1 || size >= mFaviconSize) {
             mFaviconUrl = faviconUrl;
             mFaviconSize = size;
             Log.d(LOGTAG, "Updated favicon URL for tab with id: " + mId);
         }
     }
 
     public synchronized void clearFavicon() {
+        // Keep the favicon unchanged while entering reader mode
+        if (mEnteringReaderMode)
+            return;
+
         mFavicon = null;
         mFaviconUrl = null;
         mFaviconSize = 0;
     }
 
     public void updateIdentityData(JSONObject identityData) {
         mIdentityData = identityData;
     }
@@ -434,19 +448,22 @@ public final class Tab {
             }
         });
     }
 
     public void readerMode() {
         if (!mReaderEnabled)
             return;
 
-        GeckoApp.mAppContext.loadUrl("about:reader?tabId=" + mId +
-                                     "&url=" + Uri.encode(getURL()) +
-                                     "&readingList=" + (mReadingListItem ? 1 : 0));
+        mEnteringReaderMode = true;
+        GeckoApp.mAppContext.loadUrl(ReaderModeUtils.getAboutReaderForUrl(getURL(), mId, mReadingListItem));
+    }
+
+    public boolean isEnteringReaderMode() {
+        return mEnteringReaderMode;
     }
 
     public void doReload() {
         GeckoEvent e = GeckoEvent.createBroadcastEvent("Session:Reload", "");
         GeckoAppShell.sendEventToGecko(e);
     }
 
     // Our version of nsSHistory::GetCanGoBack
@@ -526,16 +543,17 @@ public final class Tab {
             // If we weren't at the last history entry, mHistoryIndex may have become too small
             if (mHistoryIndex < -1)
                  mHistoryIndex = -1;
         }
     }
 
     void handleLocationChange(JSONObject message) throws JSONException {
         final String uri = message.getString("uri");
+        mEnteringReaderMode = ReaderModeUtils.isEnteringReaderMode(mUrl, uri);
         updateURL(uri);
 
         setDocumentURI(message.getString("documentURI"));
         if (message.getBoolean("sameDocument")) {
             // We can get a location change event for the same document with an anchor tag
             return;
         }
 
--- a/mobile/android/base/awesomebar/BookmarksTab.java
+++ b/mobile/android/base/awesomebar/BookmarksTab.java
@@ -198,17 +198,17 @@ public class BookmarksTab extends Awesom
         AwesomeBarTabs.OnUrlOpenListener listener = getUrlListener();
         if (listener == null) {
             return;
         }
 
         String url = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.URL));
         long parentId = cursor.getLong(cursor.getColumnIndexOrThrow(Bookmarks.PARENT));
         if (parentId == Bookmarks.FIXED_READING_LIST_ID) {
-            url = AwesomeBar.getReaderForUrl(url);
+            url = ReaderModeUtils.getAboutReaderForUrl(url, true);
         }
         listener.onUrlOpen(url);
     }
 
     private class BookmarksListAdapter extends SimpleCursorAdapter {
         private static final int VIEW_TYPE_ITEM = 0;
         private static final int VIEW_TYPE_FOLDER = 1;
         private static final int VIEW_TYPE_COUNT = 2;
--- a/mobile/android/base/tests/BaseTest.java.in
+++ b/mobile/android/base/tests/BaseTest.java.in
@@ -51,18 +51,19 @@ abstract class BaseTest extends Activity
     public BaseTest() {
         super(TARGET_PACKAGE_ID, mLauncherActivityClass);
     }
 
     protected abstract int getTestType();
 
     @Override
     protected void setUp() throws Exception {
-        // Load config file from sdcard (setup by python script)
-        String configFile = FennecNativeDriver.getFile("/mnt/sdcard/robotium.config");
+        // Load config file from root path (setup by python script)
+        String rootPath = FennecInstrumentationTestRunner.getArguments().getString("deviceroot");
+        String configFile = FennecNativeDriver.getFile(rootPath + "/robotium.config");
         HashMap config = FennecNativeDriver.convertTextToTable(configFile);
 
         // Create the intent to be used with all the important arguments.
         Intent i = new Intent(Intent.ACTION_MAIN);
         mProfile = (String)config.get("profile");
         i.putExtra("args", "-no-remote -profile " + mProfile);
 
         // Start the activity
@@ -79,17 +80,17 @@ abstract class BaseTest extends Activity
         } else {
             mAsserter = new FennecMochitestAssert();
         }
         mAsserter.setLogFile(mLogFile);
         mAsserter.setTestName(this.getClass().getName());
 
         // Set up Robotium.solo and Driver objects
         mSolo = new Solo(getInstrumentation(), mActivity);
-        mDriver = new FennecNativeDriver(mActivity, mSolo);
+        mDriver = new FennecNativeDriver(mActivity, mSolo, rootPath);
         mActions = new FennecNativeActions(mActivity, mSolo, getInstrumentation(), mAsserter);
     }
 
     @Override
     protected void runTest() throws Throwable {
         try {
             super.runTest();
         } catch (Throwable t) {
--- a/mobile/android/base/ui/PanZoomController.java
+++ b/mobile/android/base/ui/PanZoomController.java
@@ -452,27 +452,28 @@ public class PanZoomController
             setState(PanZoomState.NOTHING);
             return true;
         }
         Log.e(LOGTAG, "Unhandled case " + mState + " in onTouchEnd");
         return false;
     }
 
     private boolean onTouchCancel(MotionEvent event) {
+        cancelTouch();
+
         if (mState == PanZoomState.WAITING_LISTENERS) {
             // we might get a cancel event from the TouchEventHandler while in the
             // WAITING_LISTENERS state if the touch listeners prevent-default the
             // block of events. at this point being in WAITING_LISTENERS is equivalent
             // to being in NOTHING with the exception of possibly being in overscroll.
             // so here we don't want to do anything right now; the overscroll will be
             // corrected in preventedTouchFinished().
             return false;
         }
 
-        cancelTouch();
         // ensure we snap back if we're overscrolled
         bounce();
         return false;
     }
 
     private void startTouch(float x, float y, long time) {
         mX.startTouch(x);
         mY.startTouch(y);
--- a/mobile/android/chrome/content/Readability.js
+++ b/mobile/android/chrome/content/Readability.js
@@ -126,19 +126,18 @@ Readability.prototype = {
       return pathBase + uri;
     }
 
     function convertRelativeURIs(tagName, propName) {
       let elems = articleContent.getElementsByTagName(tagName);
       for (let i = elems.length; --i >= 0;) {
         let elem = elems[i];
         let relativeURI = elem.getAttribute(propName);
-        if (relativeURI != null) {
+        if (relativeURI != null)
           elems[i].setAttribute(propName, toAbsoluteURI(relativeURI));
-        }
       }
     }
 
      // Fix links.
     convertRelativeURIs("a", "href");
 
      // Fix images.
     convertRelativeURIs("img", "src");
@@ -273,19 +272,18 @@ Readability.prototype = {
         let p = this._doc.createElement("p");
         br.parentNode.replaceChild(p, br);
 
         next = p.nextSibling;
         while (next) {
           // If we've hit another <br><br>, we're done adding children to this <p>.
           if (next.tagName == "BR") {
             let nextElem = this._nextElement(next);
-            if (nextElem && nextElem.tagName == "BR") {
+            if (nextElem && nextElem.tagName == "BR")
               break;
-            }
           }
           
           // Otherwise, make this node a child of the new <p>.
           let sibling = next.nextSibling;
           p.appendChild(next);
           next = sibling;
         }
       }
@@ -331,28 +329,26 @@ Readability.prototype = {
     for (let i = articleParagraphs.length - 1; i >= 0; i -= 1) {
       let imgCount = articleParagraphs[i].getElementsByTagName('img').length;
       let embedCount = articleParagraphs[i].getElementsByTagName('embed').length;
       let objectCount = articleParagraphs[i].getElementsByTagName('object').length;
 
       if (imgCount === 0 &&
         embedCount === 0 &&
         objectCount === 0 &&
-        this._getInnerText(articleParagraphs[i], false) === '') {
+        this._getInnerText(articleParagraphs[i], false) === '')
         articleParagraphs[i].parentNode.removeChild(articleParagraphs[i]);
-      }
     }
 
     let brs = articleContent.getElementsByTagName("BR");
     for (let i = brs.length; --i >= 0;) {
       let br = brs[i];
       let next = this._nextElement(br.nextSibling);
-      if (next && next.tagName == "P") {
+      if (next && next.tagName == "P")
         br.parentNode.removeChild(br);
-      }
     }
   },
 
   /**
    * Initialize a node with the readability object. Also checks the
    * className/id for special names to add to its score.
    *
    * @param Element
@@ -622,19 +618,18 @@ Readability.prototype = {
 
         let contentBonus = 0;
 
         // Give a bonus if sibling nodes and top candidates have the example same classname
         if (siblingNode.className === topCandidate.className && topCandidate.className !== "")
           contentBonus += topCandidate.readability.contentScore * 0.2;
 
         if (typeof siblingNode.readability !== 'undefined' &&
-          (siblingNode.readability.contentScore+contentBonus) >= siblingScoreThreshold) {
+          (siblingNode.readability.contentScore+contentBonus) >= siblingScoreThreshold)
           append = true;
-        }
 
         if (siblingNode.nodeName === "P") {
           let linkDensity = this._getLinkDensity(siblingNode);
           let nodeContent = this._getInnerText(siblingNode);
           let nodeLength = nodeContent.length;
 
           if (nodeLength > 80 && linkDensity < 0.25) {
             append = true;
@@ -1065,19 +1060,18 @@ Readability.prototype = {
 
     // Loop thrugh all of our possible pages from above and find our top
     // candidate for the next page URL. Require at least a score of 50, which
     // is a relatively high confidence that this page is the next link.
     let topPage = null;
     for (let page in possiblePages) {
       if (possiblePages.hasOwnProperty(page)) {
         if (possiblePages[page].score >= 50 &&
-          (!topPage || topPage.score < possiblePages[page].score)) {
+          (!topPage || topPage.score < possiblePages[page].score))
           topPage = possiblePages[page];
-        }
       }
     }
 
     if (topPage) {
       let nextHref = topPage.href.replace(/\/$/,'');
 
       this.log('NEXT PAGE IS ' + nextHref);
       this._parsedPages[nextHref] = true;
@@ -1094,23 +1088,21 @@ Readability.prototype = {
   },
 
   _ajax: function(url, options) {
     let request = new XMLHttpRequest();
 
     function respondToReadyState(readyState) {
       if (request.readyState === 4) {
         if (this._successfulRequest(request)) {
-          if (options.success) {
+          if (options.success)
             options.success(request);
-          }
         } else {
-          if (options.error) {
+          if (options.error)
             options.error(request);
-          }
         }
       }
     }
 
     if (typeof options === 'undefined')
       options = {};
 
     request.onreadystatechange = respondToReadyState;
@@ -1420,19 +1412,18 @@ Readability.prototype = {
 
     // Pull out any possible next page link first.
     // let nextPageLink = this._findNextPageLink(doc.body);
 
     this._prepDocument();
 
     let articleTitle = this._getArticleTitle();
     let articleContent = this._grabArticle();
-    if (!articleContent) {
+    if (!articleContent)
       return null;
-    }
 
     this._postProcessContent(articleContent);
 
     // if (nextPageLink) {
     //   // Append any additional pages after a small timeout so that people
     //   // can start reading without having to wait for this to finish processing.
     //   setTimeout((function() {
     //     this._appendNextPage(nextPageLink);
--- a/mobile/android/chrome/content/aboutReader.html
+++ b/mobile/android/chrome/content/aboutReader.html
@@ -14,16 +14,19 @@
     <div id="reader-domain" class="domain"></div>
     <h1 id="reader-title"></h1>
     <div id="reader-credits" class="credits"></div>
   </div>
 
   <div id="reader-content" class="content">
   </div>
 
+  <div id="reader-message" class="message">
+  </div>
+
   <ul id="reader-toolbar" class="toolbar toolbar-hidden">
     <li><a id="share-button" class="button share-button" href="#"></a></li>
     <ul class="dropdown">
       <li><a class="dropdown-toggle button style-button" href="#"></a></li>
       <li class="dropdown-popup">
         <ul id="color-scheme-buttons" class="segmented-button"></ul>
         <hr></hr>
         <div id="font-size-control" class="step-control"></div>
--- a/mobile/android/chrome/content/aboutReader.js
+++ b/mobile/android/chrome/content/aboutReader.js
@@ -34,16 +34,17 @@ let AboutReader = function(doc, win) {
 
   dump("Feching toolbar, header and content notes from about:reader");
   this._headerElementRef = Cu.getWeakReference(doc.getElementById("reader-header"));
   this._domainElementRef = Cu.getWeakReference(doc.getElementById("reader-domain"));
   this._titleElementRef = Cu.getWeakReference(doc.getElementById("reader-title"));
   this._creditsElementRef = Cu.getWeakReference(doc.getElementById("reader-credits"));
   this._contentElementRef = Cu.getWeakReference(doc.getElementById("reader-content"));
   this._toolbarElementRef = Cu.getWeakReference(doc.getElementById("reader-toolbar"));
+  this._messageElementRef = Cu.getWeakReference(doc.getElementById("reader-message"));
 
   this._toolbarEnabled = false;
 
   this._scrollOffset = win.pageYOffset;
 
   let body = doc.body;
   body.addEventListener("touchstart", this, false);
   body.addEventListener("click", this, false);
@@ -131,17 +132,21 @@ AboutReader.prototype = {
   get _contentElement() {
     return this._contentElementRef.get();
   },
 
   get _toolbarElement() {
     return this._toolbarElementRef.get();
   },
 
-  observe: function(aMessage, aTopic, aData) {
+  get _messageElement() {
+    return this._messageElementRef.get();
+  },
+
+  observe: function Reader_observe(aMessage, aTopic, aData) {
     switch(aTopic) {
       case "Reader:FaviconReturn": {
         let info = JSON.parse(aData);
         this._loadFavicon(info.url, info.faviconUrl);
         Services.obs.removeObserver(this, "Reader:FaviconReturn", false);
         break;
       }
     }
@@ -330,28 +335,28 @@ AboutReader.prototype = {
     }
   },
 
   _toggleToolbarVisibility: function Reader_toggleToolbarVisibility(visible) {
     this._setToolbarVisibility(!this._getToolbarVisibility());
   },
 
   _loadFromURL: function Reader_loadFromURL(url) {
-    this._showProgress();
+    this._showProgressDelayed();
 
     gChromeWin.Reader.parseDocumentFromURL(url, function(article) {
       if (article)
         this._showContent(article);
       else
         this._showError(gStrings.GetStringFromName("aboutReader.loadError"));
     }.bind(this));
   },
 
   _loadFromTab: function Reader_loadFromTab(tabId, url) {
-    this._showProgress();
+    this._showProgressDelayed();
 
     gChromeWin.Reader.getArticleForTab(tabId, url, function(article) {
       if (article)
         this._showContent(article);
       else
         this._showError(gStrings.GetStringFromName("aboutReader.loadError"));
     }.bind(this));
   },
@@ -419,23 +424,27 @@ AboutReader.prototype = {
           setImageMargins(img);
         }
       }
     }
   },
 
   _showError: function Reader_showError(error) {
     this._headerElement.style.display = "none";
-    this._contentElement.innerHTML = error;
-    this._contentElement.style.display = "block";
+    this._contentElement.style.display = "none";
+
+    this._messageElement.innerHTML = error;
+    this._messageElement.style.display = "block";
 
     this._doc.title = error;
   },
 
   _showContent: function Reader_showContent(article) {
+    this._messageElement.style.display = "none";
+
     this._article = article;
 
     let articleUri = Services.io.newURI(article.url, null, null);
     let domain = articleUri.host;
 
     this._domainElement.innerHTML = domain;
 
     this._creditsElement.innerHTML = article.byline;
@@ -460,20 +469,29 @@ AboutReader.prototype = {
     this._requestFavicon();
   },
 
   _hideContent: function Reader_hideContent() {
     this._headerElement.style.display = "none";
     this._contentElement.style.display = "none";
   },
 
-  _showProgress: function Reader_showProgress() {
-    this._headerElement.style.display = "none";
-    this._contentElement.innerHTML = gStrings.GetStringFromName("aboutReader.loading");
-    this._contentElement.style.display = "block";
+  _showProgressDelayed: function Reader_showProgressDelayed() {
+    this._win.setTimeout(function() {
+      // Article has already been loaded, no need to show
+      // progress anymore.
+      if (this._article)
+        return;
+
+      this._headerElement.style.display = "none";
+      this._contentElement.style.display = "none";
+
+      this._messageElement.innerHTML = gStrings.GetStringFromName("aboutReader.loading");
+      this._messageElement.style.display = "block";
+    }.bind(this), 300);
   },
 
   _decodeQueryString: function Reader_decodeQueryString(url) {
     let result = {};
     let query = url.split("?")[1];
     if (query) {
       let pairs = query.split("&");
       for (let i = 0; i < pairs.length; i++) {
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -112,16 +112,20 @@ function resolveGeckoURI(aURI) {
     return registry.convertChromeURL(Services.io.newURI(aURI, null, null)).spec;
   } else if (aURI.indexOf("resource://") == 0) {
     let handler = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
     return handler.resolveURI(Services.io.newURI(aURI, null, null));
   }
   return aURI;
 }
 
+function shouldShowProgress(url) {
+  return (url != "about:home" && !/^about:reader/.test(url));
+}
+
 /**
  * Cache of commonly used string bundles.
  */
 var Strings = {};
 [
   ["brand",      "chrome://branding/locale/brand.properties"],
   ["browser",    "chrome://browser/locale/browser.properties"],
   ["charset",    "chrome://global/locale/charsetTitles.properties"]
@@ -306,17 +310,17 @@ var BrowserApp = {
           });
         }
       };
       Services.obs.addObserver(restoreCleanup, "sessionstore-windows-restored", false);
 
       // Start the restore
       ss.restoreLastSession(restoreToFront, restoreMode == 1);
     } else {
-      loadParams.showProgress = (url != "about:home");
+      loadParams.showProgress = shouldShowProgress(url);
       loadParams.pinned = pinned;
       this.addTab(url, loadParams);
 
       // show telemetry door hanger if we aren't restoring a session
 #ifdef MOZ_TELEMETRY_REPORTING
       Telemetry.prompt();
 #endif
     }
@@ -1051,18 +1055,18 @@ var BrowserApp = {
         let engine = Services.search.getEngineByName(data.engine);
         if (engine) {
           let submission = engine.getSubmission(url);
           url = submission.uri.spec;
           params.postData = submission.postData;
         }
       }
 
-      // Don't show progress throbber for about:home
-      if (url == "about:home")
+      // Don't show progress throbber for about:home or about:reader
+      if (!shouldShowProgress(url))
         params.showProgress = false;
 
       if (aTopic == "Tab:Add")
         this.addTab(url, params);
       else
         this.loadURI(url, browser, params);
     } else if (aTopic == "Tab:Selected") {
       this._handleTabSelected(this.getTabForId(parseInt(aData)));
--- a/mobile/android/themes/core/aboutReader.css
+++ b/mobile/android/themes/core/aboutReader.css
@@ -1,15 +1,12 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-%filter substitution
-%include defines.inc
-
 html {
   -moz-text-size-adjust: none;
 }
 
 body {
   font-family: "OpenSansRegular","Droid Sans",sans-serif;
   margin-top: 20px;
   margin-bottom: 20px;
@@ -20,16 +17,24 @@ body {
   color: #222222;
 }
 
 .dark {
   background-color: #000000;
   color: #eeeeee;
 }
 
+.message {
+  margin-top: 40px;
+  display: none;
+  text-align: center;
+  width: 100%;
+  font-size: 16px;
+}
+
 .header {
   text-align: left;
   display: none;
 }
 
 .header > .domain {
   margin-top: 10px;
   padding-bottom: 10px;
@@ -312,32 +317,32 @@ body {
 }
 
 .font-size7 > .content {
   font-size: 22px !important;
 }
 
 .toolbar {
   font-family: "Droid Sans",helvetica,arial,clean,sans-serif;
-  -moz-transition-property: visibility opacity;
+  -moz-transition-property: visibility, opacity;
   -moz-transition-duration: 0.7s;
   visibility: visible;
   opacity: 1.0;
   position: fixed;
   width: 100%;
   bottom: 0px;
   left: 0px;
   margin: 0;
   padding: 0;
   list-style: none;
   background-repeat: repeat;
 }
 
 .toolbar-hidden {
-  -moz-transition-property: visibility opacity;
+  -moz-transition-property: visibility, opacity;
   -moz-transition-duration: 0.7s;
   visibility: hidden;
   opacity: 0.0;
 }
 
 .toolbar > * {
   float: right;
   width: 25%;
--- a/netwerk/cookie/nsCookieService.cpp
+++ b/netwerk/cookie/nsCookieService.cpp
@@ -2482,17 +2482,17 @@ nsCookieService::GetCookieStringInternal
       } else {
         // just write value
         aCookieString += cookie->Value();
       }
     }
   }
 
   if (!aCookieString.IsEmpty())
-    COOKIE_LOGSUCCESS(GET_COOKIE, aHostURI, aCookieString, nullptr, nullptr);
+    COOKIE_LOGSUCCESS(GET_COOKIE, aHostURI, aCookieString, nullptr, false);
 }
 
 // processes a single cookie, and returns true if there are more cookies
 // to be processed
 bool
 nsCookieService::SetCookieInternal(nsIURI                        *aHostURI,
                                    const nsCString               &aBaseDomain,
                                    bool                           aRequireHostMatch,
--- a/netwerk/wifi/Makefile.in
+++ b/netwerk/wifi/Makefile.in
@@ -36,17 +36,18 @@ CPPSRCS = \
 ifeq ($(OS_ARCH),Darwin)
 CPPSRCS += nsWifiScannerMac.cpp
 CMMSRCS = osx_corewlan.mm
 else
 ifneq (,$(filter WINNT,$(OS_ARCH)))
 CPPSRCS += nsWifiScannerWin.cpp
 else
 ifeq ($(OS_ARCH),Linux)
-CPPSRCS += nsWifiScannerUnix.cpp
+CPPSRCS += nsWifiScannerDBus.cpp
+OS_INCLUDES += $(MOZ_DBUS_GLIB_CFLAGS)
 else
 ifeq ($(OS_ARCH),SunOS)
 CPPSRCS += nsWifiScannerSolaris.cpp
 OS_INCLUDES += $(GLIB_CFLAGS)
 endif # solaris
 endif # linux
 endif # windows
 endif # mac
new file mode 100644
--- /dev/null
+++ b/netwerk/wifi/nsWifiScannerDBus.cpp
@@ -0,0 +1,339 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsWifiScannerDBus.h"
+#include "nsWifiAccessPoint.h"
+
+namespace mozilla {
+
+nsWifiScannerDBus::nsWifiScannerDBus(nsCOMArray<nsWifiAccessPoint> *aAccessPoints)
+: mAccessPoints(aAccessPoints)
+{
+  MOZ_ASSERT(mAccessPoints);
+
+  mConnection = dbus_bus_get(DBUS_BUS_SYSTEM, nullptr);
+  MOZ_ASSERT(mConnection);
+  dbus_connection_set_exit_on_disconnect(mConnection, false);
+
+  MOZ_COUNT_CTOR(nsWifiScannerDBus);
+}
+
+nsWifiScannerDBus::~nsWifiScannerDBus()
+{
+  if (!mConnection) {
+    dbus_connection_unref(mConnection);
+  }
+  MOZ_COUNT_DTOR(nsWifiScannerDBus);
+}
+
+nsresult
+nsWifiScannerDBus::Scan()
+{
+  return SendMessage("org.freedesktop.NetworkManager",
+                     "/org/freedesktop/NetworkManager",
+                     "GetDevices");
+}
+
+nsresult
+nsWifiScannerDBus::SendMessage(const char* aInterface,
+                               const char* aPath,
+                               const char* aFuncCall)
+{
+  DBusMessage* msg =
+    dbus_message_new_method_call("org.freedesktop.NetworkManager",
+                                 aPath, aInterface, aFuncCall);
+  if (!msg) {
+    return NS_ERROR_FAILURE;
+  }
+
+  DBusMessageIter argsIter;
+  dbus_message_iter_init_append(msg, &argsIter);
+
+  if (!strcmp(aFuncCall, "Get")) {
+    const char* paramInterface = "org.freedesktop.NetworkManager.Device";
+    if (!dbus_message_iter_append_basic(&argsIter, DBUS_TYPE_STRING,
+                                        &paramInterface)) {
+      return NS_ERROR_FAILURE;
+    }
+
+    const char* paramDeviceType = "DeviceType";
+    if (!dbus_message_iter_append_basic(&argsIter, DBUS_TYPE_STRING,
+                                        &paramDeviceType)) {
+      return NS_ERROR_FAILURE;
+    }
+  } else if (!strcmp(aFuncCall, "GetAll")) {
+    const char* param = "";
+    if (!dbus_message_iter_append_basic(&argsIter, DBUS_TYPE_STRING, &param)) {
+      return NS_ERROR_FAILURE;
+    }
+  }
+
+  DBusError err;
+  dbus_error_init(&err);
+
+  // http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html
+  // Refer to function dbus_connection_send_with_reply_and_block.
+  const uint32_t DBUS_DEFAULT_TIMEOUT = -1;
+  DBusMessage* reply = nullptr;
+  reply = dbus_connection_send_with_reply_and_block(mConnection, msg,
+                                                    DBUS_DEFAULT_TIMEOUT, &err);
+  if (dbus_error_is_set(&err)) {
+    dbus_error_free(&err);
+
+    // In the GetAccessPoints case, if there are no access points, error is set.
+    // We don't want to error out here.
+    if (!strcmp(aFuncCall, "GetAccessPoints")) {
+      return NS_OK;
+    }
+    return NS_ERROR_FAILURE;
+  }
+
+  nsresult rv;
+  if (!strcmp(aFuncCall, "GetDevices")) {
+    rv = IdentifyDevices(reply);
+  } else if (!strcmp(aFuncCall, "Get")) {
+    rv = IdentifyDeviceType(reply, aPath);
+  } else if (!strcmp(aFuncCall, "GetAccessPoints")) {
+    rv = IdentifyAccessPoints(reply);
+  } else if (!strcmp(aFuncCall, "GetAll")) {
+    rv = IdentifyAPProperties(reply);
+  } else {
+    rv = NS_ERROR_FAILURE;
+  }
+  dbus_message_unref(reply);
+  return rv;
+}
+
+nsresult
+nsWifiScannerDBus::IdentifyDevices(DBusMessage* aMsg)
+{
+  DBusMessageIter iter;
+  nsresult rv = GetDBusIterator(aMsg, &iter);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  const char* devicePath;
+  do {
+    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH) {
+      return NS_ERROR_FAILURE;
+    }
+
+    dbus_message_iter_get_basic(&iter, &devicePath);
+    if (!devicePath) {
+      return NS_ERROR_FAILURE;
+    }
+
+    rv = SendMessage("org.freedesktop.DBus.Properties", devicePath, "Get");
+    NS_ENSURE_SUCCESS(rv, rv);
+  } while (dbus_message_iter_next(&iter));
+
+  return NS_OK;
+}
+
+nsresult
+nsWifiScannerDBus::IdentifyDeviceType(DBusMessage* aMsg, const char* aDevicePath)
+{
+  DBusMessageIter args;
+  if (!dbus_message_iter_init(aMsg, &args)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_VARIANT) {
+    return NS_ERROR_FAILURE;
+  }
+
+  DBusMessageIter variantIter;
+  dbus_message_iter_recurse(&args, &variantIter);
+  if (dbus_message_iter_get_arg_type(&variantIter) != DBUS_TYPE_UINT32) {
+    return NS_ERROR_FAILURE;
+  }
+
+  uint32_t deviceType;
+  dbus_message_iter_get_basic(&variantIter, &deviceType);
+
+  // http://projects.gnome.org/NetworkManager/developers/api/07/spec-07.html
+  // Refer to NM_DEVICE_TYPE_WIFI under NM_DEVICE_TYPE.
+  const uint32_t NM_DEVICE_TYPE_WIFI = 2;
+  nsresult rv = NS_OK;
+  if (deviceType == NM_DEVICE_TYPE_WIFI) {
+    rv = SendMessage("org.freedesktop.NetworkManager.Device.Wireless",
+                     aDevicePath, "GetAccessPoints");
+  }
+
+  return rv;
+}
+
+nsresult
+nsWifiScannerDBus::IdentifyAccessPoints(DBusMessage* aMsg)
+{
+  DBusMessageIter iter;
+  nsresult rv = GetDBusIterator(aMsg, &iter);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  const char* path;
+  do {
+    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH) {
+      return NS_ERROR_FAILURE;
+    }
+    dbus_message_iter_get_basic(&iter, &path);
+    if (!path) {
+      return NS_ERROR_FAILURE;
+    }
+
+    rv = SendMessage("org.freedesktop.DBus.Properties", path, "GetAll");
+    NS_ENSURE_SUCCESS(rv, rv);
+  } while (dbus_message_iter_next(&iter));
+
+  return NS_OK;
+}
+
+nsresult
+nsWifiScannerDBus::IdentifyAPProperties(DBusMessage* aMsg)
+{
+  DBusMessageIter arr;
+  nsresult rv = GetDBusIterator(aMsg, &arr);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsRefPtr<nsWifiAccessPoint> ap = new nsWifiAccessPoint();
+  do {
+    DBusMessageIter dict;
+    dbus_message_iter_recurse(&arr, &dict);
+
+    do {
+      const char* key;
+      dbus_message_iter_get_basic(&dict, &key);
+      if (!key) {
+        return NS_ERROR_FAILURE;
+      }
+      dbus_message_iter_next(&dict);
+
+      DBusMessageIter variant;
+      dbus_message_iter_recurse(&dict, &variant);
+
+      if (!strncmp(key, "Ssid", strlen("Ssid"))) {
+        nsresult rv = StoreSsid(&variant, ap);
+        NS_ENSURE_SUCCESS(rv, rv);
+        break;
+      }
+
+      if (!strncmp(key, "HwAddress", strlen("HwAddress"))) {
+        nsresult rv = SetMac(&variant, ap);
+        NS_ENSURE_SUCCESS(rv, rv);
+        break;
+      }
+
+      if (!strncmp(key, "Strength", strlen("Strength&quo