Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Thu, 29 Dec 2011 18:05:06 -0800
changeset 105481 2e59a622b0900d82c1e2a7fd0153ff22c7291f46
parent 105475 1370f99d4c39c6fe09b981bd7444c8a16698b78b (current diff)
parent 83500 1d0a814ebf12fd72b68691dd6aa092e0be8644d6 (diff)
child 105482 31c5b5d7c30c7f071aff7ffee9150d0d4671007b
push idunknown
push userunknown
push dateunknown
milestone12.0a1
Merge from mozilla-central.
b2g/installer/package-manifest.in
browser/app/profile/firefox.js
browser/base/content/browser.js
browser/base/content/browser.xul
browser/devtools/highlighter/test/browser_inspector_highlighter.js
config/autoconf.mk.in
configure.in
content/base/src/Makefile.in
content/base/src/nsCCUncollectableMarker.cpp
content/base/src/nsContentList.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsGenericElement.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
content/xbl/src/nsXBLDocumentInfo.h
content/xul/document/src/nsXULPrototypeCache.cpp
content/xul/document/src/nsXULPrototypeCache.h
content/xul/document/src/nsXULPrototypeDocument.cpp
content/xul/document/src/nsXULPrototypeDocument.h
db/sqlite3/src/Makefile.in
dom/Makefile.in
dom/base/nsDOMClassInfo.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsStructuredCloneContainer.cpp
dom/base/nsWrapperCache.h
dom/workers/WorkerScope.cpp
embedding/android/GeckoAppShell.java
extensions/spellcheck/src/mozPersonalDictionary.cpp
extensions/spellcheck/src/mozPersonalDictionary.h
intl/uconv/ucvlatin/8859-9.ut
ipc/glue/GeckoChildProcessHost.cpp
js/src/config/autoconf.mk.in
js/src/configure.in
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/ParseNode.h
js/src/frontend/Parser.cpp
js/src/gc/Barrier.h
js/src/jsarray.cpp
js/src/jscntxt.h
js/src/jsexn.cpp
js/src/jsfun.cpp
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsinfer.cpp
js/src/jsinfer.h
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsreflect.cpp
js/src/jsstr.cpp
js/src/jstypedarray.cpp
js/src/jsutil.h
js/src/methodjit/Compiler.cpp
js/src/methodjit/Compiler.h
js/src/methodjit/FastOps.cpp
js/src/methodjit/LoopState.cpp
js/src/shell/js.cpp
js/src/shell/jsworkers.cpp
js/src/tests/src/jstests.jar
js/src/vm/RegExpObject.h
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/public/xpc_map_end.h
js/xpconnect/shell/xpcshell.cpp
js/xpconnect/src/XPCInlines.h
js/xpconnect/src/XPCWrappedNativeProto.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
layout/base/nsBidiPresUtils.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsDisplayList.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/base/nsPresShell.cpp
layout/base/tests/Makefile.in
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsFieldSetFrame.cpp
layout/forms/nsHTMLButtonControlFrame.cpp
layout/forms/nsHTMLButtonControlFrame.h
layout/forms/nsListControlFrame.h
layout/forms/nsProgressFrame.cpp
layout/forms/nsProgressFrame.h
layout/generic/nsAbsoluteContainingBlock.cpp
layout/generic/nsBlockFrame.h
layout/generic/nsBlockReflowContext.cpp
layout/generic/nsBulletFrame.cpp
layout/generic/nsCanvasFrame.cpp
layout/generic/nsCanvasFrame.h
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsContainerFrame.cpp
layout/generic/nsContainerFrame.h
layout/generic/nsFirstLetterFrame.cpp
layout/generic/nsFirstLetterFrame.h
layout/generic/nsFrame.cpp
layout/generic/nsFrameSetFrame.cpp
layout/generic/nsFrameSetFrame.h
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/generic/nsHTMLContainerFrame.cpp
layout/generic/nsHTMLContainerFrame.h
layout/generic/nsHTMLReflowMetrics.h
layout/generic/nsIFrame.h
layout/generic/nsImageFrame.cpp
layout/generic/nsInlineFrame.cpp
layout/generic/nsInlineFrame.h
layout/generic/nsLeafFrame.cpp
layout/generic/nsLineLayout.cpp
layout/generic/nsPageContentFrame.cpp
layout/generic/nsQueryFrame.h
layout/mathml/nsMathMLContainerFrame.cpp
layout/mathml/nsMathMLContainerFrame.h
layout/reftests/reftest-sanity/reftest.list
layout/svg/base/src/nsSVGForeignObjectFrame.cpp
layout/svg/base/src/nsSVGForeignObjectFrame.h
layout/tables/nsTableCellFrame.cpp
layout/tables/nsTableCellFrame.h
layout/tables/nsTableColGroupFrame.h
layout/tables/nsTableFrame.cpp
layout/tables/nsTableFrame.h
layout/tables/nsTableOuterFrame.cpp
layout/tables/nsTableOuterFrame.h
layout/tables/nsTableRowFrame.cpp
layout/tables/nsTableRowFrame.h
layout/tables/nsTableRowGroupFrame.cpp
layout/tables/nsTableRowGroupFrame.h
layout/tools/reftest/reftest.js
layout/xul/base/src/nsBox.cpp
layout/xul/base/src/nsBoxFrame.cpp
layout/xul/base/src/nsImageBoxFrame.cpp
layout/xul/base/src/nsLeafBoxFrame.cpp
layout/xul/base/src/nsSplitterFrame.cpp
layout/xul/base/src/nsSprocketLayout.cpp
layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
mobile/android/base/GeckoApp.java
mobile/xul/installer/package-manifest.in
other-licenses/android/APKOpen.cpp
other-licenses/android/APKOpen.h
other-licenses/android/Makefile.in
other-licenses/android/nsGeckoUtils.cpp
storage/test/test_AsXXX_helpers.cpp
toolkit/mozapps/extensions/XPIProvider.jsm
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/installer/packager.mk
toolkit/xre/nsSigHandlers.cpp
toolkit/xre/nsUpdateDriver.cpp
xpcom/base/nsMemoryReporterManager.cpp
xpcom/base/nsStackWalk.cpp
xpcom/base/nsTraceRefcntImpl.cpp
xpcom/ds/nsAtomTable.cpp
xpcom/ds/nsAtomTable.h
xpcom/string/public/nsStringBuffer.h
xpcom/string/src/nsSubstring.cpp
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -142,16 +142,17 @@
 @BINPATH@/components/content_xtf.xpt
 @BINPATH@/components/cookie.xpt
 @BINPATH@/components/directory.xpt
 @BINPATH@/components/docshell.xpt
 @BINPATH@/components/dom.xpt
 @BINPATH@/components/dom_base.xpt
 #ifdef MOZ_B2G_RIL
 @BINPATH@/components/dom_telephony.xpt
+@BINPATH@/components/dom_wifi.xpt
 @BINPATH@/components/dom_system_b2g.xpt
 #endif
 @BINPATH@/components/dom_battery.xpt
 @BINPATH@/components/dom_canvas.xpt
 @BINPATH@/components/dom_core.xpt
 @BINPATH@/components/dom_css.xpt
 @BINPATH@/components/dom_events.xpt
 @BINPATH@/components/dom_geolocation.xpt
@@ -391,16 +392,18 @@
 @BINPATH@/components/messageWakeupService.manifest
 @BINPATH@/components/nsFilePicker.js
 @BINPATH@/components/nsFilePicker.manifest
 #ifdef MOZ_B2G_RIL
 @BINPATH@/components/nsTelephonyWorker.manifest
 @BINPATH@/components/nsTelephonyWorker.js
 @BINPATH@/components/Telephony.manifest
 @BINPATH@/components/Telephony.js
+@BINPATH@/components/nsWifiWorker.js
+@BINPATH@/components/nsWifiWorker.manifest
 #endif
 #ifdef XP_MACOSX
 @BINPATH@/components/libalerts_s.dylib
 #endif
 #ifdef MOZ_ENABLE_DBUS
 @BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
 #endif
 @BINPATH@/components/nsINIProcessor.manifest
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -62,17 +62,17 @@ pref("extensions.strictCompatibility", f
 pref("extensions.minCompatibleAppVersion", "4.0");
 
 // Preferences for AMO integration
 pref("extensions.getAddons.cache.enabled", true);
 pref("extensions.getAddons.maxResults", 15);
 pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%");
 pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/firefox/search?q=%TERMS%");
 pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%/%COMPATIBILITY_MODE%?src=firefox");
-pref("extensions.webservice.discoverURL", "https://services.addons.mozilla.org/%LOCALE%/firefox/discovery/pane/%VERSION%/%OS%");
+pref("extensions.webservice.discoverURL", "https://services.addons.mozilla.org/%LOCALE%/firefox/discovery/pane/%VERSION%/%OS%/%COMPATIBILITY_MODE%");
 
 // Blocklist preferences
 pref("extensions.blocklist.enabled", true);
 pref("extensions.blocklist.interval", 86400);
 // Controls what level the blocklist switches from warning about items to forcibly
 // blocking them.
 pref("extensions.blocklist.level", 2);
 pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/3/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/%PING_COUNT%/%TOTAL_PING_COUNT%/%DAYS_SINCE_LAST_PING%/");
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -42,24 +42,17 @@ tabbrowser {
                    max-width 250ms ease-out,
                    opacity 50ms ease-out 100ms /* hide the tab for the last 100ms of the max-width transition */;
 }
 
 .tab-throbber:not([fadein]):not([pinned]),
 .tab-label:not([fadein]):not([pinned]),
 .tab-icon-image:not([fadein]):not([pinned]),
 .tab-close-button:not([fadein]):not([pinned]) {
-  opacity: 0 !important;
-}
-
-.tab-throbber,
-.tab-label,
-.tab-icon-image,
-.tab-close-button {
-  -moz-transition: opacity 250ms;
+  display: none;
 }
 
 .tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned] {
   position: fixed !important;
   display: block; /* position:fixed already does this (bug 579776), but let's be explicit */
 }
 
 #alltabs-popup {
@@ -102,20 +95,25 @@ toolbar[printpreview="true"] {
 }
 
 #main-window[tabsintitlebar] #appmenu-button-container,
 #main-window[tabsintitlebar] #titlebar-buttonbox {
   position: relative;
 }
 %endif
 
-toolbarpaletteitem[place="palette"] > toolbaritem > hbox[type="places"] {
+.bookmarks-toolbar-customize,
+#wrapper-personal-bookmarks > #personal-bookmarks > #PlacesToolbar > hbox > #PlacesToolbarItems {
   display: none;
 }
 
+#wrapper-personal-bookmarks[place="toolbar"] > #personal-bookmarks > #PlacesToolbar > .bookmarks-toolbar-customize {
+  display: -moz-box;
+}
+
 #main-window[disablechrome] #navigator-toolbox[tabsontop="true"] > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
   visibility: collapse;
 }
 
 #wrapper-urlbar-container #urlbar-container > #urlbar > toolbarbutton,
 #urlbar-container:not([combined]) > #urlbar > toolbarbutton,
 #urlbar-container[combined] + #reload-button + #stop-button,
 #urlbar-container[combined] + #reload-button,
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1559,33 +1559,37 @@ function delayedStartup(isLoadingBlank, 
     try {
       var ss = Cc["@mozilla.org/browser/sessionstartup;1"].
                getService(Ci.nsISessionStartup);
       willRecoverSession =
         (ss.sessionType == Ci.nsISessionStartup.RECOVER_SESSION);
     }
     catch (ex) { /* never mind; suppose SessionStore is broken */ }
     if (shouldCheck && !shell.isDefaultBrowser(true) && !willRecoverSession) {
-      var brandBundle = document.getElementById("bundle_brand");
-      var shellBundle = document.getElementById("bundle_shell");
-
-      var brandShortName = brandBundle.getString("brandShortName");
-      var promptTitle = shellBundle.getString("setDefaultBrowserTitle");
-      var promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage",
-                                                         [brandShortName]);
-      var checkboxLabel = shellBundle.getFormattedString("setDefaultBrowserDontAsk",
-                                                         [brandShortName]);
-      var checkEveryTime = { value: shouldCheck };
-      var ps = Services.prompt;
-      var rv = ps.confirmEx(window, promptTitle, promptMessage,
-                            ps.STD_YES_NO_BUTTONS,
-                            null, null, null, checkboxLabel, checkEveryTime);
-      if (rv == 0)
-        shell.setDefaultBrowser(true, false);
-      shell.shouldCheckDefaultBrowser = checkEveryTime.value;
+      // Delay the set-default-browser prompt so it doesn't block
+      // initialisation of the session store service.
+      setTimeout(function () {
+        var brandBundle = document.getElementById("bundle_brand");
+        var shellBundle = document.getElementById("bundle_shell");
+
+        var brandShortName = brandBundle.getString("brandShortName");
+        var promptTitle = shellBundle.getString("setDefaultBrowserTitle");
+        var promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage",
+                                                           [brandShortName]);
+        var checkboxLabel = shellBundle.getFormattedString("setDefaultBrowserDontAsk",
+                                                           [brandShortName]);
+        var checkEveryTime = { value: shouldCheck };
+        var ps = Services.prompt;
+        var rv = ps.confirmEx(window, promptTitle, promptMessage,
+                              ps.STD_YES_NO_BUTTONS,
+                              null, null, null, checkboxLabel, checkEveryTime);
+        if (rv == 0)
+          shell.setDefaultBrowser(true, false);
+        shell.shouldCheckDefaultBrowser = checkEveryTime.value;
+      }, 0);
     }
   }
 #endif
 
   // BiDi UI
   gBidiUI = isBidiEnabled();
   if (gBidiUI) {
     document.getElementById("documentDirection-separator").hidden = false;
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -393,30 +393,30 @@
       <iframe id="customizeToolbarSheetIFrame"
               style="&dialog.style;"
               hidden="true"/>
     </panel>
 
     <tooltip id="tabbrowser-tab-tooltip" onpopupshowing="gBrowser.createTooltip(event);"/>
 
     <tooltip id="back-button-tooltip">
-      <label value="&backButton.tooltip;"/>
+      <label class="tooltip-label" value="&backButton.tooltip;"/>
 #ifdef XP_MACOSX
-      <label value="&backForwardButtonMenuMac.tooltip;"/>
+      <label class="tooltip-label" value="&backForwardButtonMenuMac.tooltip;"/>
 #else
-      <label value="&backForwardButtonMenu.tooltip;"/>
+      <label class="tooltip-label" value="&backForwardButtonMenu.tooltip;"/>
 #endif
     </tooltip>
   
     <tooltip id="forward-button-tooltip">
-      <label value="&forwardButton.tooltip;"/>
+      <label class="tooltip-label" value="&forwardButton.tooltip;"/>
 #ifdef XP_MACOSX
-      <label value="&backForwardButtonMenuMac.tooltip;"/>
+      <label class="tooltip-label" value="&backForwardButtonMenuMac.tooltip;"/>
 #else
-      <label value="&backForwardButtonMenu.tooltip;"/>
+      <label class="tooltip-label" value="&backForwardButtonMenu.tooltip;"/>
 #endif
     </tooltip>
   </popupset>
 
 #ifdef CAN_DRAW_IN_TITLEBAR
 <vbox id="titlebar">
   <hbox id="titlebar-content">
     <hbox id="appmenu-button-container">
--- a/browser/components/build/Makefile.in
+++ b/browser/components/build/Makefile.in
@@ -7,23 +7,22 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE = browsercomps
 LIBRARY_NAME = browsercomps
 SHORT_LIBNAME = brwsrcmp
 IS_COMPONENT = 1
 MODULE_NAME = nsBrowserCompsModule
 FORCE_SHARED_LIB = 1
 
-# Because we are an application component, link against the CRT statically
-# (on Windows, but only if we're not building our own CRT for jemalloc)
-ifndef MOZ_MEMORY
+# Statically link the CRT on Windows if building against
+# a XULRunner SDK.
+ifdef LIBXUL_SDK
 USE_STATIC_LIBS = 1
 endif
 
-
 EXPORTS = nsBrowserCompsCID.h
 
 CPPSRCS = nsModule.cpp \
           $(NULL)
 
 ifeq ($(OS_ARCH),WINNT)
 OS_LIBS	+= $(call EXPAND_LIBNAME,ole32 shell32)
 endif
@@ -65,8 +64,11 @@ SHARED_LIBRARY_LIBS += ../migration/src/
 # GTK2: Need to link with glib for GNOME shell service
 ifneq (,$(filter cocoa gtk2,$(MOZ_WIDGET_TOOLKIT)))
 EXTRA_DSO_LDOPTS += \
   $(TK_LIBS) \
   $(NULL)
 endif
 
 include $(topsrcdir)/config/rules.mk
+
+# Ensure that we don't embed a manifest referencing the CRT.
+EMBED_MANIFEST_AT =
--- a/browser/components/places/content/places.css
+++ b/browser/components/places/content/places.css
@@ -1,21 +1,12 @@
 tree[type="places"] {
   -moz-binding: url("chrome://browser/content/places/tree.xml#places-tree");
 }
 
-.bookmarks-toolbar-customize,
-toolbarpaletteitem #PlacesToolbarItems {
-  display: none;
-}
-
-toolbarpaletteitem .bookmarks-toolbar-customize {
-  display: -moz-box;
-}
-
 .toolbar-drop-indicator {
   position: relative;
   z-index: 1;
 }
 
 menupopup[placespopup="true"] {
   -moz-binding: url("chrome://browser/content/places/menu.xml#places-popup-base");
 }
--- a/browser/devtools/highlighter/inspector.jsm
+++ b/browser/devtools/highlighter/inspector.jsm
@@ -155,16 +155,17 @@ Highlighter.prototype = {
       this.nodeInfo.container.setAttribute("locked", true);
     }
 
     this.browser.addEventListener("resize", this, true);
     this.browser.addEventListener("scroll", this, true);
 
     this.transitionDisabler = null;
 
+    this.computeZoomFactor();
     this.handleResize();
   },
 
   /**
    * Build the veil:
    *
    * <vbox id="highlighter-veil-container">
    *   <box id="highlighter-veil-topbox" class="highlighter-veil"/>
@@ -436,26 +437,20 @@ Highlighter.prototype = {
 
     let oldRect = this._contentRect;
 
     if (oldRect && aRect.top == oldRect.top && aRect.left == oldRect.left &&
         aRect.width == oldRect.width && aRect.height == oldRect.height) {
       return this._highlighting; // same rectangle
     }
 
-    // get page zoom factor, if any
-    let zoom =
-      this.win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
-      .getInterface(Components.interfaces.nsIDOMWindowUtils)
-      .screenPixelsPerCSSPixel;
-
     // adjust rect for zoom scaling
     let aRectScaled = {};
     for (let prop in aRect) {
-      aRectScaled[prop] = aRect[prop] * zoom;
+      aRectScaled[prop] = aRect[prop] * this.zoom;
     }
 
     if (aRectScaled.left >= 0 && aRectScaled.top >= 0 &&
         aRectScaled.width > 0 && aRectScaled.height > 0) {
 
       this.veilTransparentBox.style.visibility = "visible";
 
       // The bottom div and the right div are flexibles (flex=1).
@@ -518,24 +513,39 @@ Highlighter.prototype = {
     }
   },
 
   /**
    * Move the Infobar to the right place in the highlighter.
    */
   moveInfobar: function Highlighter_moveInfobar()
   {
-    let rect = this._highlightRect;
-    if (rect && this._highlighting) {
+    if (this._highlightRect) {
+      let winHeight = this.win.innerHeight * this.zoom;
+      let winWidth = this.win.innerWidth * this.zoom;
+
+      let rect = {top: this._highlightRect.top,
+                  left: this._highlightRect.left,
+                  width: this._highlightRect.width,
+                  height: this._highlightRect.height};
+
+      rect.top = Math.max(rect.top, 0);
+      rect.left = Math.max(rect.left, 0);
+      rect.width = Math.max(rect.width, 0);
+      rect.height = Math.max(rect.height, 0);
+
+      rect.top = Math.min(rect.top, winHeight);
+      rect.left = Math.min(rect.left, winWidth);
+
       this.nodeInfo.container.removeAttribute("disabled");
       // Can the bar be above the node?
       if (rect.top < this.nodeInfo.barHeight) {
         // No. Can we move the toolbar under the node?
         if (rect.top + rect.height +
-            this.nodeInfo.barHeight > this.win.innerHeight) {
+            this.nodeInfo.barHeight > winHeight) {
           // No. Let's move it inside.
           this.nodeInfo.container.style.top = rect.top + "px";
           this.nodeInfo.container.setAttribute("position", "overlap");
         } else {
           // Yes. Let's move it under the node.
           this.nodeInfo.container.style.top = rect.top + rect.height + "px";
           this.nodeInfo.container.setAttribute("position", "bottom");
         }
@@ -549,18 +559,18 @@ Highlighter.prototype = {
       let barWidth = this.nodeInfo.container.getBoundingClientRect().width;
       let left = rect.left + rect.width / 2 - barWidth / 2;
 
       // Make sure the whole infobar is visible
       if (left < 0) {
         left = 0;
         this.nodeInfo.container.setAttribute("hide-arrow", "true");
       } else {
-        if (left + barWidth > this.win.innerWidth) {
-          left = this.win.innerWidth - barWidth;
+        if (left + barWidth > winWidth) {
+          left = winWidth - barWidth;
           this.nodeInfo.container.setAttribute("hide-arrow", "true");
         } else {
           this.nodeInfo.container.removeAttribute("hide-arrow");
         }
       }
       this.nodeInfo.container.style.left = left + "px";
     } else {
       this.nodeInfo.container.style.left = "0";
@@ -633,16 +643,26 @@ Highlighter.prototype = {
   {
     if (aNode.nodeType != aNode.ELEMENT_NODE) {
       return false;
     }
     let nodeName = aNode.nodeName.toLowerCase();
     return !INSPECTOR_INVISIBLE_ELEMENTS[nodeName];
   },
 
+  /**
+   * Store page zoom factor.
+   */
+  computeZoomFactor: function Highlighter_computeZoomFactor() {
+    this.zoom =
+      this.win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+      .getInterface(Components.interfaces.nsIDOMWindowUtils)
+      .screenPixelsPerCSSPixel;
+  },
+
   /////////////////////////////////////////////////////////////////////////
   //// Event Handling
 
   attachInspectListeners: function Highlighter_attachInspectListeners()
   {
     this.browser.addEventListener("mousemove", this, true);
     this.browser.addEventListener("click", this, true);
     this.browser.addEventListener("dblclick", this, true);
@@ -671,16 +691,17 @@ Highlighter.prototype = {
     switch (aEvent.type) {
       case "click":
         this.handleClick(aEvent);
         break;
       case "mousemove":
         this.handleMouseMove(aEvent);
         break;
       case "resize":
+        this.computeZoomFactor();
         this.brieflyDisableTransitions();
         this.handleResize(aEvent);
         break;
       case "dblclick":
       case "mousedown":
       case "mouseup":
         aEvent.stopPropagation();
         aEvent.preventDefault();
--- a/browser/devtools/highlighter/test/browser_inspector_highlighter.js
+++ b/browser/devtools/highlighter/test/browser_inspector_highlighter.js
@@ -148,39 +148,37 @@ function finishTestComparisons()
 
   is(veilBoxWidth, divWidth, "transparent veil box width matches dimensions of element (no zoom)");
   is(veilBoxHeight, divHeight, "transparent veil box height matches dimensions of element (no zoom)");
   // zoom the page by a factor of 2
   let contentViewer = InspectorUI.browser.docShell.contentViewer
                              .QueryInterface(Ci.nsIMarkupDocumentViewer);
   contentViewer.fullZoom = 2;
 
-  // check what zoom factor we're at, should be 2
-  let zoom =
-      InspectorUI.win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
-      .getInterface(Components.interfaces.nsIDOMWindowUtils)
-      .screenPixelsPerCSSPixel;
+  executeSoon(function() {
+    // check what zoom factor we're at, should be 2
+    let zoom = InspectorUI.highlighter.zoom;
+    is(zoom, 2, "zoom is 2?");
 
-  is(zoom, 2, "zoom is 2?");
+    // simulate the zoomed dimensions of the div element
+    let divDims = div.getBoundingClientRect();
+    let divWidth = divDims.width * zoom;
+    let divHeight = divDims.height * zoom;
 
-  // simulate the zoomed dimensions of the div element
-  let divDims = div.getBoundingClientRect();
-  let divWidth = divDims.width * zoom;
-  let divHeight = divDims.height * zoom;
+    // now zoomed, get new dimensions of transparent veil box over element
+    let veilBoxDims = InspectorUI.highlighter.veilTransparentBox.getBoundingClientRect();
+    let veilBoxWidth = veilBoxDims.width;
+    let veilBoxHeight = veilBoxDims.height;
 
-  // now zoomed, get new dimensions of transparent veil box over element
-  let veilBoxDims = InspectorUI.highlighter.veilTransparentBox.getBoundingClientRect();
-  let veilBoxWidth = veilBoxDims.width;
-  let veilBoxHeight = veilBoxDims.height;
+    is(veilBoxWidth, divWidth, "transparent veil box width matches width of element (2x zoom)");
+    is(veilBoxHeight, divHeight, "transparent veil box height matches width of element (2x zoom)");
 
-  is(veilBoxWidth, divWidth, "transparent veil box width matches width of element (2x zoom)");
-  is(veilBoxHeight, divHeight, "transparent veil box height matches width of element (2x zoom)");
-
-  doc = h1 = div = null;
-  executeSoon(finishUp);
+    doc = h1 = div = null;
+    executeSoon(finishUp);
+  });
 }
 
 function finishUp() {
   InspectorUI.closeInspectorUI();
   gBrowser.removeCurrentTab();
   finish();
 }
 
--- a/browser/devtools/highlighter/test/browser_inspector_infobar.js
+++ b/browser/devtools/highlighter/test/browser_inspector_infobar.js
@@ -12,28 +12,29 @@ function test()
 
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function onload() {
     gBrowser.selectedBrowser.removeEventListener("load", onload, true);
     doc = content.document;
     waitForFocus(setupInfobarTest, content);
   }, true);
 
-  let style = "body{width:100%;height: 100%} div {position: absolute;height: 100px;width: 500px}#bottom {bottom: 0px}#vertical {height: 100%}";
-  let html = "<style>" + style + "</style><div id=vertical></div><div id=top class='class1 class2'></div><div id=bottom></div>"
+  let style = "body{width:100%;height: 100%} div {position: absolute;height: 100px;width: 500px}#bottom {bottom: 0px}#vertical {height: 100%}#farbottom{bottom: -200px}";
+  let html = "<style>" + style + "</style><div id=vertical></div><div id=top class='class1 class2'></div><div id=bottom></div><div id=farbottom></div>"
 
   content.location = "data:text/html," + encodeURIComponent(html);
 
   function setupInfobarTest()
   {
     nodes = [
       {node: doc.querySelector("#top"), position: "bottom", tag: "DIV", id: "#top", classes: ".class1 .class2"},
       {node: doc.querySelector("#vertical"), position: "overlap", tag: "DIV", id: "#vertical", classes: ""},
       {node: doc.querySelector("#bottom"), position: "top", tag: "DIV", id: "#bottom", classes: ""},
       {node: doc.querySelector("body"), position: "overlap", tag: "BODY", id: "", classes: ""},
+      {node: doc.querySelector("#farbottom"), position: "top", tag: "DIV", id: "#farbottom", classes: ""},
     ]
 
     for (let i = 0; i < nodes.length; i++) {
       ok(nodes[i].node, "node " + i + " found");
     }
 
     Services.obs.addObserver(runTests,
       InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
@@ -42,41 +43,38 @@ function test()
 
   function runTests()
   {
     Services.obs.removeObserver(runTests,
       InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED);
 
     cursor = 0;
     executeSoon(function() {
-      Services.obs.addObserver(nodeSelected,
-        InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING, false);
-
       InspectorUI.inspectNode(nodes[0].node);
+      nodeSelected();
     });
   }
 
   function nodeSelected()
   {
     executeSoon(function() {
       performTest();
       cursor++;
       if (cursor >= nodes.length) {
 
-        Services.obs.removeObserver(nodeSelected,
-          InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING);
         Services.obs.addObserver(finishUp,
           InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
 
         executeSoon(function() {
           InspectorUI.closeInspectorUI();
         });
       } else {
         let node = nodes[cursor].node;
         InspectorUI.inspectNode(node);
+        nodeSelected();
       }
     });
   }
 
   function performTest()
   {
     let container = document.getElementById("highlighter-nodeinfobar-container");
     is(container.getAttribute("position"), nodes[cursor].position, "node " + cursor + ": position matches.");
--- a/browser/devtools/scratchpad/scratchpad.js
+++ b/browser/devtools/scratchpad/scratchpad.js
@@ -576,18 +576,22 @@ var Scratchpad = {
     let channel = NetUtil.newChannel(aFile);
     channel.contentType = "application/javascript";
 
     let self = this;
     NetUtil.asyncFetch(channel, function(aInputStream, aStatus) {
       let content = null;
 
       if (Components.isSuccessCode(aStatus)) {
+        let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
+                        createInstance(Ci.nsIScriptableUnicodeConverter);
+        converter.charset = "UTF-8";
         content = NetUtil.readInputStreamToString(aInputStream,
                                                   aInputStream.available());
+        content = converter.ConvertToUnicode(content);
         self.setText(content);
         self.editor.resetUndo();
       }
       else if (!aSilentError) {
         window.alert(self.strings.GetStringFromName("openFile.failed"));
       }
 
       if (aCallback) {
--- a/browser/devtools/styleeditor/styleeditor.css
+++ b/browser/devtools/styleeditor/styleeditor.css
@@ -84,26 +84,28 @@ li.error > .stylesheet-info > .styleshee
   display: -moz-box;
 }
 
 .stylesheet-saveButton {
   display: none;
 }
 
 .stylesheet-rule-count,
-li:hover > hgroup > .stylesheet-more > h3 >  .stylesheet-saveButton {
+li.splitview-active > hgroup > .stylesheet-more > h3 > .stylesheet-saveButton,
+li:hover > hgroup > .stylesheet-more > h3 > .stylesheet-saveButton {
   display: -moz-box;
 }
 
 .stylesheet-more > spacer {
   -moz-box-flex: 1;
 }
 
 /* portrait mode */
 @media (max-aspect-ratio: 5/3) {
+  li.splitview-active > hgroup > .stylesheet-more > .stylesheet-rule-count,
   li:hover > hgroup > .stylesheet-more > .stylesheet-rule-count {
     display: none;
   }
 
   .stylesheet-more {
     -moz-box-flex: 1;
     -moz-box-direction: reverse;
   }
--- a/browser/devtools/styleinspector/CssRuleView.jsm
+++ b/browser/devtools/styleinspector/CssRuleView.jsm
@@ -8,25 +8,26 @@
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
  *
  * Software distributed under the License is distributed on an "AS IS" basis,
  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is the Mozilla Inspector Module.
+ * The Original Code is the Mozilla CSS Rule View.
  *
  * The Initial Developer of the Original Code is
  * The Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2011
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
- *   Dave Camp (dcamp@mozilla.com) (Original Author)
+ *   Dave Camp <dcamp@mozilla.com> (Original Author)
+ *   Rob Campbell <rcampbell@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -773,17 +774,26 @@ RuleEditor.prototype = {
     });
 
     let header = createChild(code, "div", {});
 
     let selectors = createChild(header, "span", {
       class: "ruleview-selector",
       textContent: this.rule.selectorText
     });
-    appendText(header, " {");
+
+    this.openBrace = createChild(header, "span", {
+      class: "ruleview-ruleopen",
+      tabindex: "0",
+      textContent: " {"
+    });
+
+    this.openBrace.addEventListener("click", function() {
+      this.newProperty();
+    }.bind(this), true);
 
     this.propertyList = createChild(code, "ul", {
       class: "ruleview-propertylist"
     });
 
     for each (let prop in this.rule.textProps) {
       let propEditor = new TextPropertyEditor(this, prop);
       this.propertyList.appendChild(propEditor.element);
--- a/browser/devtools/tilt/TiltVisualizer.jsm
+++ b/browser/devtools/tilt/TiltVisualizer.jsm
@@ -848,16 +848,17 @@ TiltVisualizer.Controller = function TV_
   aCanvas.addEventListener("mouseup", this.onMouseUp, false);
   aCanvas.addEventListener("click", this.onMouseClick, false);
   aCanvas.addEventListener("mousemove", this.onMouseMove, false);
   aCanvas.addEventListener("mouseover", this.onMouseOver, false);
   aCanvas.addEventListener("mouseout", this.onMouseOut, false);
   aCanvas.addEventListener("MozMousePixelScroll", this.onMozScroll, false);
   aCanvas.addEventListener("keydown", this.onKeyDown, false);
   aCanvas.addEventListener("keyup", this.onKeyUp, false);
+  aCanvas.addEventListener("blur", this.onBlur, false);
 
   // handle resize events to change the arcball dimensions
   aPresenter.contentWindow.addEventListener("resize", this.onResize, false);
 
   // attach this controller's update function to the presenter ondraw event
   aPresenter.ondraw = this.update;
 };
 
@@ -1004,16 +1005,23 @@ TiltVisualizer.Controller.prototype = {
     if (code === e.DOM_VK_ESCAPE) {
       this.presenter.tiltUI.destroy(this.presenter.tiltUI.currentWindowId);
       return;
     }
     this.arcball.keyUp(code);
   },
 
   /**
+   * Called when the canvas looses focus.
+   */
+  onBlur: function TVC_onBlur(e) {
+    this.arcball._keyCode = {};
+  },
+
+  /**
    * Called when the content window of the current browser is resized.
    */
   onResize: function TVC_onResize(e)
   {
     let width = e.target.innerWidth;
     let height = e.target.innerHeight;
 
     this.arcball.resize(width, height);
@@ -1044,16 +1052,17 @@ TiltVisualizer.Controller.prototype = {
     canvas.removeEventListener("mouseup", this.onMouseUp, false);
     canvas.removeEventListener("click", this.onMouseClick, false);
     canvas.removeEventListener("mousemove", this.onMouseMove, false);
     canvas.removeEventListener("mouseover", this.onMouseOver, false);
     canvas.removeEventListener("mouseout", this.onMouseOut, false);
     canvas.removeEventListener("MozMousePixelScroll", this.onMozScroll, false);
     canvas.removeEventListener("keydown", this.onKeyDown, false);
     canvas.removeEventListener("keyup", this.onKeyUp, false);
+    canvas.removeEventListener("blur", this.onBlur, false);
     presenter.contentWindow.removeEventListener("resize", this.onResize,false);
     presenter.ondraw = null;
   }
 };
 
 /**
  * This is a general purpose 3D rotation controller described by Ken Shoemake
  * in the Graphics Interface ’92 Proceedings. It features good behavior
--- a/browser/devtools/tilt/test/Makefile.in
+++ b/browser/devtools/tilt/test/Makefile.in
@@ -48,16 +48,17 @@ include $(topsrcdir)/config/rules.mk
 	head.js \
 	browser_tilt_01_lazy_getter.js \
 	browser_tilt_02_notifications.js \
 	browser_tilt_03_tab_switch.js \
 	browser_tilt_04_initialization.js \
 	browser_tilt_05_destruction-esc.js \
 	browser_tilt_05_destruction.js \
 	browser_tilt_arcball.js \
+	browser_tilt_controller.js \
 	browser_tilt_gl01.js \
 	browser_tilt_gl02.js \
 	browser_tilt_gl03.js \
 	browser_tilt_gl04.js \
 	browser_tilt_gl05.js \
 	browser_tilt_gl06.js \
 	browser_tilt_gl07.js \
 	browser_tilt_gl08.js \
new file mode 100644
--- /dev/null
+++ b/browser/devtools/tilt/test/browser_tilt_controller.js
@@ -0,0 +1,86 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*global ok, is, info, waitForExplicitFinish, finish, executeSoon, gBrowser */
+/*global isEqualVec, isTiltEnabled, isWebGLSupported, createTab, createTilt */
+/*global EventUtils, vec3, mat4, quat4 */
+"use strict";
+
+function test() {
+  if (!isTiltEnabled()) {
+    info("Skipping controller test because Tilt isn't enabled.");
+    return;
+  }
+  if (!isWebGLSupported()) {
+    info("Skipping controller test because WebGL isn't supported.");
+    return;
+  }
+
+  waitForExplicitFinish();
+
+  createTab(function() {
+    createTilt({
+      onTiltOpen: function(instance)
+      {
+        let canvas = instance.presenter.canvas;
+        let prev_tran = vec3.create([0, 0, 0]);
+        let prev_rot = quat4.create([0, 0, 0, 1]);
+
+        function tran() {
+          return instance.presenter.transforms.translation;
+        }
+
+        function rot() {
+          return instance.presenter.transforms.rotation;
+        }
+
+        function save() {
+          prev_tran = vec3.create(tran());
+          prev_rot = quat4.create(rot());
+        }
+
+        ok(isEqualVec(tran(), prev_tran),
+          "At init, the translation should be zero.");
+        ok(isEqualVec(rot(), prev_rot),
+          "At init, the rotation should be zero.");
+
+
+        EventUtils.synthesizeKey("VK_A", { type: "keydown" });
+        EventUtils.synthesizeKey("VK_LEFT", { type: "keydown" });
+        instance.controller.update();
+
+        ok(!isEqualVec(tran(), prev_tran),
+          "After a translation key is pressed, the vector should change.");
+        ok(!isEqualVec(rot(), prev_rot),
+          "After a rotation key is pressed, the quaternion should change.");
+
+        save();
+
+
+        gBrowser.selectedBrowser.contentWindow.focus();
+        instance.controller.update();
+
+        ok(!isEqualVec(tran(), prev_tran),
+          "Even if the canvas lost focus, the vector has some inertia.");
+        ok(!isEqualVec(rot(), prev_rot),
+          "Even if the canvas lost focus, the quaternion has some inertia.");
+
+        save();
+
+
+        while (!isEqualVec(tran(), prev_tran) || !isEqualVec(rot(), prev_rot)) {
+          instance.controller.update();
+          save();
+        }
+
+        ok(isEqualVec(tran(), prev_tran) && isEqualVec(rot(), prev_rot),
+          "After the focus is lost, the transforms inertia eventually stops.");
+      },
+      onEnd: function()
+      {
+        gBrowser.removeCurrentTab();
+        finish();
+      }
+    }, true);
+  });
+}
--- a/browser/devtools/tilt/test/head.js
+++ b/browser/devtools/tilt/test/head.js
@@ -64,16 +64,27 @@ function isApproxVec(vec1, vec2) {
   for (let i = 0, len = vec1.length; i < len; i++) {
     if (!isApprox(vec1[i], vec2[i])) {
       return false;
     }
   }
   return true;
 }
 
+function isEqualVec(vec1, vec2) {
+  if (vec1.length !== vec2.length) {
+    return false;
+  }
+  for (let i = 0, len = vec1.length; i < len; i++) {
+    if (vec1[i] !== vec2[i]) {
+      return false;
+    }
+  }
+  return true;
+}
 
 function createCanvas() {
   return document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
 }
 
 
 function createTab(callback, location) {
   let tab = gBrowser.selectedTab = gBrowser.addTab();
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -133,16 +133,17 @@
 @BINPATH@/components/cookie.xpt
 @BINPATH@/components/directory.xpt
 @BINPATH@/components/docshell.xpt
 @BINPATH@/components/dom.xpt
 @BINPATH@/components/dom_apps.xpt
 @BINPATH@/components/dom_base.xpt
 #ifdef MOZ_B2G_RIL
 @BINPATH@/components/dom_telephony.xpt
+@BINPATH@/components/dom_wifi.xpt
 @BINPATH@/components/dom_system_b2g.xpt
 #endif
 @BINPATH@/components/dom_battery.xpt
 @BINPATH@/components/dom_canvas.xpt
 @BINPATH@/components/dom_core.xpt
 @BINPATH@/components/dom_css.xpt
 @BINPATH@/components/dom_events.xpt
 @BINPATH@/components/dom_geolocation.xpt
@@ -361,16 +362,18 @@
 @BINPATH@/components/contentSecurityPolicy.js
 @BINPATH@/components/contentAreaDropListener.manifest
 @BINPATH@/components/contentAreaDropListener.js
 #ifdef MOZ_B2G_RIL
 @BINPATH@/components/nsTelephonyWorker.manifest
 @BINPATH@/components/nsTelephonyWorker.js
 @BINPATH@/components/Telephony.manifest
 @BINPATH@/components/Telephony.js
+@BINPATH@/components/nsWifiWorker.js
+@BINPATH@/components/nsWifiWorker.manifest
 #endif
 @BINPATH@/components/BrowserProfileMigrators.manifest
 @BINPATH@/components/ChromeProfileMigrator.js
 #ifdef XP_MACOSX
 @BINPATH@/components/libalerts_s.dylib
 #endif
 #ifdef MOZ_ENABLE_DBUS
 @BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -65,16 +65,17 @@ components/nsExtensionManager.js
 components/nsInterfaceInfoToIDL.js
 components/nsScriptableIO.js
 components/nsUrlClassifierTable.js
 components/nsXmlRpcClient.js
 components/pluginGlue.js
 components/sidebar.xpt
 #ifdef MOZ_B2G_RIL
 components/dom_telephony.xpt
+components/dom_wifi.xpt
 components/dom_system_b2g.xpt
 #endif
 components/uconvd.dll
 components/WeaveCrypto.js
 components/WeaveCrypto.manifest
 components/xmlextras.xpt
 components/xpcom.xpt
 components/xpti.dat
@@ -917,16 +918,18 @@ xpicleanup@BIN_SUFFIX@
   components/PlacesProtocolHandler.js
   components/storage-Legacy.js
   components/storage-mozStorage.js
 #ifdef MOZ_B2G_RIL
   components/nsTelephonyWorker.manifest
   components/nsTelephonyWorker.js
   components/Telephony.manifest
   components/Telephony.js
+  components/nsWifiWorker.js
+  components/nsWifiWorker.manifest
 #endif
   components/txEXSLTRegExFunctions.js
   components/Weave.js
   components/WebContentConverter.js
   defaults/autoconfig/platform.js
   defaults/autoconfig/prefcalls.js
   defaults/pref/firefox-branding.js
   defaults/pref/firefox.js
@@ -1138,16 +1141,17 @@ xpicleanup@BIN_SUFFIX@
   components/cookie.xpt
   components/crashreporter.xpt
   components/directory.xpt
   components/docshell.xpt
   components/dom.xpt
   components/dom_base.xpt
 #ifdef MOZ_B2G_RIL
   components/dom_telephony.xpt
+  components/dom_wifi.xpt
   components/dom_system_b2g.xpt
 #endif
   components/dom_canvas.xpt
   components/dom_core.xpt
   components/dom_css.xpt
   components/dom_events.xpt
   components/dom_geolocation.xpt
   components/dom_html.xpt
--- a/browser/locales/en-US/chrome/browser/aboutDialog.dtd
+++ b/browser/locales/en-US/chrome/browser/aboutDialog.dtd
@@ -26,17 +26,17 @@
 <!-- LOCALIZATION NOTE (contribute.getInvolvedLink): This is a link title that links to http://www.mozilla.org/contribute/. -->
 <!ENTITY contribute.getInvolvedLink "Get involved!">
 <!ENTITY contribute.end             "">
 
 <!-- LOCALIZATION NOTE (bottomLinks.license): This is a link title that links to about:license. -->
 <!ENTITY bottomLinks.license        "Licensing Information">
 
 <!-- LOCALIZATION NOTE (bottomLinks.rights): This is a link title that links to about:rights. -->
-<!ENTITY bottomLinks.rights         "End User Rights">
+<!ENTITY bottomLinks.rights         "End-User Rights">
 
 <!-- LOCALIZATION NOTE (bottomLinks.privacy): This is a link title that links to http://www.mozilla.com/legal/privacy/. -->
 <!ENTITY bottomLinks.privacy        "Privacy Policy">
 
 <!-- LOCALIZATION NOTE (update.checkingForUpdates): try to make the localized text short (see bug 596813 for screenshots). -->
 <!ENTITY update.checkingForUpdates  "Checking for updates…">
 <!-- LOCALIZATION NOTE (update.checkingAddonCompat): try to make the localized text short (see bug 596813 for screenshots). -->
 <!ENTITY update.checkingAddonCompat "Checking Add-on compatibility…">
--- a/browser/themes/gnomestripe/browser.css
+++ b/browser/themes/gnomestripe/browser.css
@@ -143,19 +143,17 @@ toolbarbutton.bookmark-item[open="true"]
 }
 
 /* Dropmarker for folder bookmarks */
 .bookmark-item[container] > .toolbarbutton-menu-dropmarker {
   display: -moz-box !important;
 }
 
 #wrapper-personal-bookmarks[place="palette"] > .toolbarpaletteitem-box {
-  width: 16px;
-  height: 16px;
-  background: url("chrome://browser/skin/places/bookmarksToolbar.png") no-repeat;
+  background: url("chrome://browser/skin/places/bookmarksToolbar.png") no-repeat center;
 }
 
 .bookmarks-toolbar-customize {
   max-width: 15em !important;
   list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png") !important;
 }
 
 /* Bookmark menus */
--- a/browser/themes/gnomestripe/devtools/csshtmltree.css
+++ b/browser/themes/gnomestripe/devtools/csshtmltree.css
@@ -18,16 +18,17 @@
  * Portions created by the Initial Developer are Copyright (C) 2011
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Joe Walker <jwalker@mozilla.com> (original author)
  *   Mihai Șucan <mihai.sucan@gmail.com>
  *   Michael Ratcliffe <mratcliffe@mozilla.com>
  *   Dão Gottwald <dao@mozilla.com>
+ *   Rob Campbell <rcampbell@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -224,16 +225,20 @@
   background-color: -moz-dialog;
   padding: 2px 5px;
 }
 
 .ruleview-code {
   padding: 2px 5px;
 }
 
+.ruleview-ruleopen {
+  -moz-padding-end: 5px;
+}
+
 .ruleview-propertylist {
   list-style: none;
   padding: 0;
   margin: 0;
 }
 
 .ruleview-enableproperty {
   height: 10px;
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -262,19 +262,17 @@ toolbarbutton.bookmark-item > menupopup 
 }
 
 .bookmark-item menuitem[openInTabs],
 .bookmark-item menuitem[siteURI] {
   list-style-image: none;
 }
 
 #wrapper-personal-bookmarks[place="palette"] > .toolbarpaletteitem-box {
-  width: 16px;
-  height: 16px;
-  background: url("chrome://browser/skin/places/bookmarksToolbar.png") no-repeat;
+  background: url("chrome://browser/skin/places/bookmarksToolbar.png") no-repeat center;
 }
 
 .bookmarks-toolbar-customize {
   max-width: 15em !important;
   list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png") !important;
 }
 
 /* ----- BOOKMARK MENUS ----- */
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bde8d4683cb727d0739675de12e0f9a590ef0a51
GIT binary patch
literal 1131
zc$@)i1eE)UP)<h;3K|Lk000e1NJLTq0015U000~a1^@s6cK8pe00001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipu4
z5C%B|V}Kq200ZkuL_t(Y$8A@!P6Im-9A}?|(_j~LDV>rUAw_h#l>7&!Lk$Hj&X4d3
zX(%00Q>INvaY_?i6Tc#F{Pqk;r|8c1dObTcUSO@2Qi>R3q?95tMk%G#C#56+B*s|h
z0Fa!slv0H2yRH*sjC5UB$4V&@LKwvaARz<+H)Vi!bLX7ooa=Z9p^kN3Cm{q$Db*xW
zN@9$W5Q5~K>wM>2U1P14f7a_Y0ALsftX3=B-rfQL=JPrB`#t);2LPN-CwTAC_dTZ5
zDXy-ra6BGyKA!;qlgR|<^SS=&7~Xpvk4Jd#F$@D99v%R~$x~ZvCB`^{%orm%=ZXY?
ziVPv<srlrbC8Z=e=UN&)4>3lu)>cTJbEEgRj$PN)+B@eY#wgA?an4CfNn(r@-nN8H
zsFWgLT^Nj+aS~6-n(4qgDb|qdi3X9g)>b}*5H1@tkcNwsQ%a)e@R!8m283QSnkaC-
z{)MiubFOB|lky$FpY^OY`>*bL%v$?PT1<Qb0PpYbn9XJwh5_5{7TfK%vXbvHMtpsJ
zRmO6Bu~@)+k5UR&s}%sidta4se}9k7W`p&5jl<!9$H&LZVxH7FSH-QhNAk7g&~?@3
z&}yCK(A+V`T%aZ_#Gexw*cda~gqt&2e(SpK*F45;zk@H_tR;hHu1>~UD*&noa2?Sj
zZ^#uYhT{|OJtmV0uCK2#pU-RU-rnA7El;NtcDo%mn+*V9I-TP4^ApCHI_LTM8SC{L
zec$8e<_72U8K=_;-{0Tx-ea*?;N#;1cXxMqd3m`wmv$C?dY+6Y*3LzlQF85N!1>fP
z%M(JllqjV%l8=70h0^fpY??fO-AY>5v|PGfDdqnfv#za8^1JqDYi&h^#A)?Sr_-b&
zNv*YlRvx_4G*Or-zjKYYPi-W6TqiOrmocWEh5=%Xm907F3NvBTry$fsiOK3qhI|-l
zK7>#|QX;J>gb+rC&*VrPeWkVrqIIs(h1QwArT)6D=)FutCrks;TxsuU61kLesj<#R
z|B~$_iH1xECNC%}-M?`@55`yk@T*~KWkc&@?X;g$zbqL$4kp1`hY%|4&biBpb@$j3
ztwp3Y6K$>SqjjsvWv!L!T>7$a`>-l{b^8zz-R5Y&9&G}Q)R1$Q$$UOX&KUr(-|sP<
zP5}Ui!vV|X5>HQ07={4=5JJFix5LlR5Bk2x)zuXaheP#v{;@L!fZ1$@QVN#KW&QU0
z`U>d2iu!GDB{uXVo361wX^e4HF71Q>My(L^2KsK+nqz;Zn>o!|)|u<tc1Od{|4hKZ
x+>|oWogxE}^*ZwyW0f53QX@iy=#Vs;e*t^H?DDeC0m%RW002ovPDHLkV1n^E5@P@W
--- a/browser/themes/pinstripe/devtools/common.css
+++ b/browser/themes/pinstripe/devtools/common.css
@@ -38,17 +38,17 @@
 %include ../shared.inc
 
 /* Toolbar and Toolbar items */
 
 .devtools-toolbar {
   -moz-appearance: none;
   padding: 4px 3px;
   box-shadow: 0 1px 0 0 hsla(210, 16%, 76%, .2) inset;
-  background-image: -moz-linear-gradient(top, hsl(210,11%,36%), hsl(210,11%,18%));
+  background-image: url(background-noise-toolbar.png), -moz-linear-gradient(top, hsl(210,11%,36%), hsl(210,11%,18%));
 }
 
 .devtools-toolbarbutton {
   -moz-appearance: none;
   min-width: 78px;
   min-height: 22px;
   color: hsl(210,30%,85%);
   text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
--- a/browser/themes/pinstripe/devtools/csshtmltree.css
+++ b/browser/themes/pinstripe/devtools/csshtmltree.css
@@ -18,16 +18,17 @@
  * Portions created by the Initial Developer are Copyright (C) 2011
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Joe Walker <jwalker@mozilla.com> (original author)
  *   Mihai Șucan <mihai.sucan@gmail.com>
  *   Michael Ratcliffe <mratcliffe@mozilla.com>
  *   Dão Gottwald <dao@mozilla.com>
+ *   Rob Campbell <rcampbell@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -226,16 +227,20 @@
   background-color: -moz-dialog;
   padding: 2px 5px;
 }
 
 .ruleview-code {
   padding: 2px 5px;
 }
 
+.ruleview-ruleopen {
+  -moz-padding-end: 5px;
+}
+
 .ruleview-propertylist {
   list-style: none;
   padding: 0;
   margin: 0;
 }
 
 .ruleview-enableproperty {
   height: 10px;
--- a/browser/themes/pinstripe/jar.mn
+++ b/browser/themes/pinstripe/jar.mn
@@ -155,16 +155,17 @@ browser.jar:
   skin/classic/browser/devtools/breadcrumbs/rtl-start.png                    (devtools/breadcrumbs/rtl-start.png)
   skin/classic/browser/devtools/breadcrumbs/rtl-start-selected.png           (devtools/breadcrumbs/rtl-start-selected.png)
   skin/classic/browser/devtools/splitview.css               (devtools/splitview.css)
   skin/classic/browser/devtools/styleeditor.css             (devtools/styleeditor.css)
   skin/classic/browser/devtools/magnifying-glass.png	    (devtools/magnifying-glass.png)
   skin/classic/browser/devtools/itemToggle.png		    (devtools/itemToggle.png)
   skin/classic/browser/devtools/itemArrow-rtl.png	    (devtools/itemArrow-rtl.png)
   skin/classic/browser/devtools/itemArrow-ltr.png	    (devtools/itemArrow-ltr.png)
+  skin/classic/browser/devtools/background-noise-toolbar.png (devtools/background-noise-toolbar.png)
 #ifdef MOZ_SERVICES_SYNC
   skin/classic/browser/sync-throbber.png
   skin/classic/browser/sync-16.png
   skin/classic/browser/sync-32.png
   skin/classic/browser/sync-bg.png
   skin/classic/browser/sync-128.png
   skin/classic/browser/sync-desktopIcon.png
   skin/classic/browser/sync-mobileIcon.png
--- a/browser/themes/winstripe/browser-aero.css
+++ b/browser/themes/winstripe/browser-aero.css
@@ -289,31 +289,33 @@
   #tab-view:-moz-lwtheme {
     background-image: url("chrome://browser/skin/tabview/grain.png"),
                       -moz-linear-gradient(rgba(255,255,255,0), #CCD9EA 200px, #C7D5E7);
     background-attachment: fixed;
   }
 }
 
 @media not all and (-moz-windows-compositor) {
-  #main-window:-moz-system-metric(windows-default-theme) {
-    background-color: rgb(185,209,234);
-  }
-  #main-window:-moz-system-metric(windows-default-theme):-moz-window-inactive {
-    background-color: rgb(215,228,242);
-  }
+  @media (-moz-windows-default-theme) {
+    #main-window {
+      background-color: rgb(185,209,234);
+    }
+    #main-window:-moz-window-inactive {
+      background-color: rgb(215,228,242);
+    }
 
-  #toolbar-menubar:not([autohide=true]):not(:-moz-lwtheme):-moz-system-metric(windows-default-theme),
-  #TabsToolbar[tabsontop=true]:not(:-moz-lwtheme):-moz-system-metric(windows-default-theme),
-  #navigator-toolbox[tabsontop=false] > toolbar:not(#toolbar-menubar):not(:-moz-lwtheme):-moz-system-metric(windows-default-theme) {
-    -moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
-    background-color: transparent;
-  }
-  #toolbar-menubar[autohide=true]:-moz-system-metric(windows-default-theme) {
-    background-color: transparent;
+    #toolbar-menubar:not([autohide=true]):not(:-moz-lwtheme),
+    #TabsToolbar[tabsontop=true]:not(:-moz-lwtheme),
+    #navigator-toolbox[tabsontop=false] > toolbar:not(#toolbar-menubar):not(:-moz-lwtheme) {
+      -moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
+      background-color: transparent;
+    }
+    #toolbar-menubar[autohide=true] {
+      background-color: transparent !important;
+    }
   }
 
   #print-preview-toolbar:not(:-moz-lwtheme) {
     -moz-appearance: -moz-win-browsertabbar-toolbox;
   }
 }
 
 /* ::::: fullscreen window controls ::::: */
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -558,19 +558,17 @@ toolbarbutton.bookmark-item[open="true"]
   display: -moz-box !important;
 }
 
 .bookmark-item > .toolbarbutton-menu-dropmarker {
   display: none;
 }
 
 #wrapper-personal-bookmarks[place="palette"] > .toolbarpaletteitem-box {
-  width: 16px;
-  height: 16px;
-  background: url("chrome://browser/skin/places/bookmarksToolbar.png") no-repeat;
+  background: url("chrome://browser/skin/places/bookmarksToolbar.png") no-repeat center;
 }
 
 .bookmarks-toolbar-customize {
   max-width: 15em !important;
   list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png") !important;
 }
 
 /* ::::: bookmark menus ::::: */
@@ -1546,19 +1544,21 @@ html|*.urlbar-input:-moz-lwtheme:-moz-pl
 }
 
 .ac-url-text,
 .ac-action-text {
   color: -moz-nativehyperlinktext;
 }
 
 %ifndef WINSTRIPE_AERO
-.ac-url-text:-moz-system-metric(windows-default-theme),
-.ac-action-text:-moz-system-metric(windows-default-theme) {
-  color: #006600;
+@media (-moz-windows-default-theme) {
+  .ac-url-text,
+  .ac-action-text {
+    color: #006600;
+  }
 }
 %endif
 
 richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
   list-style-image: url("chrome://browser/skin/actionicon-tab.png");
 }
 
 .autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
--- a/browser/themes/winstripe/devtools/csshtmltree.css
+++ b/browser/themes/winstripe/devtools/csshtmltree.css
@@ -18,16 +18,17 @@
  * Portions created by the Initial Developer are Copyright (C) 2011
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Joe Walker <jwalker@mozilla.com> (original author)
  *   Mihai Șucan <mihai.sucan@gmail.com>
  *   Michael Ratcliffe <mratcliffe@mozilla.com>
  *   Dão Gottwald <dao@mozilla.com>
+ *   Rob Campbell <rcampbell@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -225,16 +226,20 @@
   background-color: -moz-dialog;
   padding: 2px 5px;
 }
 
 .ruleview-code {
   padding: 2px 5px;
 }
 
+.ruleview-ruleopen {
+  -moz-padding-end: 5px;
+}
+
 .ruleview-propertylist {
   list-style: none;
   padding: 0;
   margin: 0;
 }
 
 .ruleview-enableproperty {
   height: 10px;
--- a/browser/themes/winstripe/places/places-aero.css
+++ b/browser/themes/winstripe/places/places-aero.css
@@ -1,12 +1,14 @@
 %include places.css
 
 /* Style Places sidebars as Vista media collection */
-#bookmarksPanel:-moz-system-metric(windows-default-theme),
-#history-panel:-moz-system-metric(windows-default-theme) {
-  background-color: #EEF3FA;
-}
+@media (-moz-windows-default-theme) {
+  #bookmarksPanel,
+  #history-panel {
+    background-color: #EEF3FA;
+  }
 
-.sidebar-placesTree:-moz-system-metric(windows-default-theme) {
-  background-color: transparent;
-  border-top: none;
+  .sidebar-placesTree {
+    background-color: transparent;
+    border-top: none;
+  }
 }
--- a/configure.in
+++ b/configure.in
@@ -1859,46 +1859,65 @@ if test "$GNU_CC"; then
     fi
     WARNINGS_AS_ERRORS='-Werror'
     DSO_CFLAGS=''
     DSO_PIC_CFLAGS='-fPIC'
     ASFLAGS="$ASFLAGS -fPIC"
     _MOZ_RTTI_FLAGS_ON=-frtti
     _MOZ_RTTI_FLAGS_OFF=-fno-rtti
 
-    # Turn on GNU specific features
-    # -Wall - turn on all warnings
-    # -pedantic - make compiler warn about non-ANSI stuff, and
-    #             be a little bit stricter
-    # -Wdeclaration-after-statement - MSVC doesn't like these
-    # Warnings slamm took out for now (these were giving more noise than help):
-    # -Wbad-function-cast - warns when casting a function to a new return type
-    # -Wshadow - removed because it generates more noise than help --pete
-    _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall -W -Wno-unused -Wpointer-arith -Wdeclaration-after-statement"
+    # Turn on GNU-specific warnings:
+    # -Wall - turn on a lot of warnings
+    # -pedantic - this is turned on below
+    # -Wpointer-arith - enabled with -pedantic, but good to have even if not
+    # -Werror=declaration-after-statement - MSVC doesn't like these
+    # -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
+    #
+    _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall -Wpointer-arith -Wdeclaration-after-statement -Wempty-body"
+    
+    # Turn off the following warnings that -Wall/-pedantic turn on:
+    # -Woverlength-strings - we exceed the minimum maximum length all the time
+    #
+    _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wno-overlength-strings"
+
     if test -z "$INTEL_CC" -a -z "$CLANG_CC"; then
        # Don't use -Wcast-align with ICC or clang
        case "$CPU_ARCH" in
            # And don't use it on hppa, ia64, sparc, arm, since it's noisy there
            hppa | ia64 | sparc | arm)
            ;;
            *)
         _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wcast-align"
            ;;
        esac
     fi
 
     dnl Turn pedantic on but disable the warnings for long long
     _PEDANTIC=1
 
-    if test -z "$INTEL_CC"; then
-      _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -W"
-    fi
-
     _DEFINES_CFLAGS='-include $(DEPTH)/mozilla-config.h -DMOZILLA_CLIENT'
     _USE_CPP_INCLUDE_FLAG=1
+
+    AC_CACHE_CHECK(whether the compiler supports -Wtype-limits,
+                   ac_cc_has_wtype_limits,
+        [
+            AC_LANG_SAVE
+            AC_LANG_C
+            _SAVE_CFLAGS="$CFLAGS"
+            CFLAGS="$CFLAGS -Wtype-limits"
+            AC_TRY_COMPILE([],
+                           [return(0);],
+                           ac_cc_has_wtype_limits="yes",
+                           ac_cc_has_wtype_limits="no")
+            CFLAGS="$_SAVE_CFLAGS"
+            AC_LANG_RESTORE
+        ])
+    if test "$ac_cc_has_wtype_limits" = "yes"; then
+        _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wtype-limits"
+    fi
 elif test "$SOLARIS_SUNPRO_CC"; then
     DSO_CFLAGS=''
     if test "$CPU_ARCH" = "sparc"; then
         # for Sun Studio on Solaris/SPARC
         DSO_PIC_CFLAGS='-xcode=pic32'
     else
         DSO_PIC_CFLAGS='-KPIC'
     fi
@@ -1916,18 +1935,32 @@ else
     DSO_CFLAGS=''
     DSO_PIC_CFLAGS='-KPIC'
     _DEFINES_CFLAGS='$(ACDEFINES) -D_MOZILLA_CONFIG_H_ -DMOZILLA_CLIENT'
 fi
 
 if test "$GNU_CXX"; then
     # FIXME: Let us build with strict aliasing. bug 414641.
     CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-strict-aliasing"
-    # Turn on GNU specific features
-    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall -Wpointer-arith -Woverloaded-virtual -Wsynth -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor"
+
+    # Turn on GNU-specific warnings:
+    # -Wall - turn on a lot of warnings
+    # -pedantic - this is turned on below
+    # -Wpointer-arith - enabled with -pedantic, but good to have even if not
+    # -Woverloaded-virtual - ???
+    # -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
+    #
+    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall -Wpointer-arith -Woverloaded-virtual -Wempty-body"
+
+    # Turn off the following warnings that -Wall/-pedantic turn on:
+    # -Woverlength-strings - we exceed the minimum maximum length all the time
+    # -Wctor-dtor-privacy - ???
+    #
+    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-overlength-strings -Wno-ctor-dtor-privacy"
+
     if test -z "$INTEL_CXX" -a -z "$CLANG_CXX"; then
        # Don't use -Wcast-align with ICC or clang
        case "$CPU_ARCH" in
            # And don't use it on hppa, ia64, sparc, arm, since it's noisy there
            hppa | ia64 | sparc | arm)
            ;;
            *)
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wcast-align"
@@ -2018,16 +2051,34 @@ if test "$GNU_CXX"; then
                            ac_has_werror_return_type="no")
             CXXFLAGS="$_SAVE_CXXFLAGS"
             AC_LANG_RESTORE
         ])
     if test "$ac_has_werror_return_type" = "yes"; then
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=return-type"
     fi
 
+    AC_CACHE_CHECK(whether the compiler supports -Wtype-limits,
+                   ac_has_wtype_limits,
+        [
+            AC_LANG_SAVE
+            AC_LANG_CPLUSPLUS
+            _SAVE_CXXFLAGS="$CXXFLAGS"
+            CXXFLAGS="$CXXFLAGS -Wtype-limits"
+            AC_TRY_COMPILE([],
+                           [return(0);],
+                           ac_has_wtype_limits="yes",
+                           ac_has_wtype_limits="no")
+            CXXFLAGS="$_SAVE_CXXFLAGS"
+            AC_LANG_RESTORE
+        ])
+    if test "$ac_has_wtype_limits" = "yes"; then
+        _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wtype-limits"
+    fi
+
 else
     _DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -D_MOZILLA_CONFIG_H_ $(ACDEFINES)'
 fi
 
 dnl gcc can come with its own linker so it is better to use the pass-thru calls
 dnl MKSHLIB_FORCE_ALL is used to force the linker to include all object
 dnl files present in an archive. MKSHLIB_UNFORCE_ALL reverts the linker to
 dnl normal behavior.
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -189,16 +189,17 @@ include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
 INCLUDES	+= \
 		-I$(srcdir)/../../events/src \
 		-I$(srcdir)/../../xml/content/src \
 		-I$(srcdir)/../../../layout/xul/base/src \
 		-I$(srcdir)/../../xul/content/src \
+		-I$(srcdir)/../../xul/document/src \
 		-I$(srcdir)/../../html/content/src \
 		-I$(srcdir)/../../base/src \
 		-I$(srcdir)/../../xbl/src \
 		-I$(srcdir)/../../../layout/generic \
 		-I$(srcdir)/../../../layout/style \
 		-I$(srcdir)/../../../dom/base \
 		-I$(srcdir)/../../xml/document/src \
 		-I$(topsrcdir)/xpcom/io \
--- a/content/base/src/nsCCUncollectableMarker.cpp
+++ b/content/base/src/nsCCUncollectableMarker.cpp
@@ -52,16 +52,19 @@
 #include "nsIWindowWatcher.h"
 #include "mozilla/Services.h"
 #include "nsIXULWindow.h"
 #include "nsIAppShellService.h"
 #include "nsAppShellCID.h"
 
 static bool sInited = 0;
 PRUint32 nsCCUncollectableMarker::sGeneration = 0;
+#ifdef MOZ_XUL
+#include "nsXULPrototypeCache.h"
+#endif
 
 NS_IMPL_ISUPPORTS1(nsCCUncollectableMarker, nsIObserver)
 
 /* static */
 nsresult
 nsCCUncollectableMarker::Init()
 {
   if (sInited) {
@@ -242,11 +245,18 @@ nsCCUncollectableMarker::Observe(nsISupp
     if (hw) {
       nsCOMPtr<nsIDocShell> shell;
       hw->GetDocShell(getter_AddRefs(shell));
       nsCOMPtr<nsIDocShellTreeNode> shellTreeNode = do_QueryInterface(shell);
       MarkDocShell(shellTreeNode);
     }
   }
 
+#ifdef MOZ_XUL
+  nsXULPrototypeCache* xulCache = nsXULPrototypeCache::GetInstance();
+  if (xulCache) {
+    xulCache->MarkInCCGeneration(sGeneration);
+  }
+#endif
+
   return NS_OK;
 }
 
--- a/content/base/src/nsContentList.cpp
+++ b/content/base/src/nsContentList.cpp
@@ -42,19 +42,19 @@
  * getElementsByTagName, some properties on nsIDOMHTMLDocument, etc).
  */
 
 #include "nsContentList.h"
 #include "nsIContent.h"
 #include "nsIDOMNode.h"
 #include "nsIDocument.h"
 #include "nsGenericElement.h"
-
+#include "nsWrapperCacheInlines.h"
 #include "nsContentUtils.h"
-
+#include "nsCCUncollectableMarker.h"
 #include "nsGkAtoms.h"
 
 #include "dombindings.h"
 
 // Form related includes
 #include "nsIDOMHTMLFormElement.h"
 
 #include "pldhash.h"
@@ -75,18 +75,21 @@ nsBaseContentList::~nsBaseContentList()
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsBaseContentList)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsBaseContentList)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mElements)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsBaseContentList)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+  if (nsCCUncollectableMarker::sGeneration && tmp->IsBlack()) {
+    return NS_SUCCESS_INTERRUPTED_TRAVERSE;
+  }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_OF_NSCOMPTR(mElements)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsBaseContentList)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 #define NS_CONTENT_LIST_INTERFACES(_class)                                    \
     NS_INTERFACE_TABLE_ENTRY(_class, nsINodeList)                             \
     NS_INTERFACE_TABLE_ENTRY(_class, nsIDOMNodeList)
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -188,30 +188,31 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
 
 // for ReportToConsole
 #include "nsIStringBundle.h"
 #include "nsIScriptError.h"
 #include "nsIConsoleService.h"
 
 #include "mozAutoDocUpdate.h"
 #include "imgICache.h"
-#include "xpcprivate.h"
+#include "xpcprivate.h" // nsXPConnect
 #include "nsScriptSecurityManager.h"
 #include "nsIChannelPolicy.h"
 #include "nsChannelPolicy.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsContentDLF.h"
 #ifdef MOZ_MEDIA
 #include "nsHTMLMediaElement.h"
 #endif
 #include "nsDOMTouchEvent.h"
 #include "nsIScriptElement.h"
 #include "nsIContentViewer.h"
 #include "nsIObjectLoadingContent.h"
 
+#include "mozilla/Base64.h"
 #include "mozilla/Preferences.h"
 
 #include "nsWrapperCacheInlines.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 using namespace mozilla::widget;
 using namespace mozilla;
@@ -628,29 +629,29 @@ nsresult
 nsContentUtils::Btoa(const nsAString& aBinaryData,
                      nsAString& aAsciiBase64String)
 {
   if (!Is8bit(aBinaryData)) {
     aAsciiBase64String.Truncate();
     return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
   }
 
-  return nsXPConnect::Base64Encode(aBinaryData, aAsciiBase64String);
+  return Base64Encode(aBinaryData, aAsciiBase64String);
 }
 
 nsresult
 nsContentUtils::Atob(const nsAString& aAsciiBase64String,
                      nsAString& aBinaryData)
 {
   if (!Is8bit(aAsciiBase64String)) {
     aBinaryData.Truncate();
     return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
   }
 
-  nsresult rv = nsXPConnect::Base64Decode(aAsciiBase64String, aBinaryData);
+  nsresult rv = Base64Decode(aAsciiBase64String, aBinaryData);
   if (NS_FAILED(rv) && rv == NS_ERROR_INVALID_ARG) {
     return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
   }
   return rv;
 }
 
 bool
 nsContentUtils::IsAutocompleteEnabled(nsIDOMHTMLInputElement* aInput)
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -1203,23 +1203,16 @@ nsINode::GetContextForEventHandlers(nsre
 /* static */
 void
 nsINode::Trace(nsINode *tmp, TraceCallback cb, void *closure)
 {
   nsContentUtils::TraceWrapper(tmp, cb, closure);
 }
 
 static bool
-IsBlackNode(nsINode* aNode)
-{
-  JSObject* o = aNode->GetWrapperPreserveColor();
-  return o && !xpc_IsGrayGCThing(o);
-}
-
-static bool
 IsXBL(nsINode* aNode)
 {
   return aNode->IsElement() &&
          aNode->AsElement()->IsInNamespace(kNameSpaceID_XBL);
 }
 
 /* static */
 bool
@@ -1228,36 +1221,36 @@ nsINode::Traverse(nsINode *tmp, nsCycleC
   nsIDocument *currentDoc = tmp->GetCurrentDoc();
   if (currentDoc &&
       nsCCUncollectableMarker::InGeneration(cb, currentDoc->GetMarkedCCGeneration())) {
     return false;
   }
 
   if (nsCCUncollectableMarker::sGeneration) {
     // If we're black no need to traverse.
-    if (IsBlackNode(tmp)) {
+    if (tmp->IsBlack()) {
       return false;
     }
 
     const PtrBits problematicFlags =
       (NODE_IS_ANONYMOUS |
        NODE_IS_IN_ANONYMOUS_SUBTREE |
        NODE_IS_NATIVE_ANONYMOUS_ROOT |
        NODE_MAY_BE_IN_BINDING_MNGR |
        NODE_IS_INSERTION_PARENT);
 
     if (!tmp->HasFlag(problematicFlags) && !IsXBL(tmp)) {
       // If we're in a black document, return early.
-      if ((currentDoc && IsBlackNode(currentDoc))) {
+      if ((currentDoc && currentDoc->IsBlack())) {
         return false;
       }
       // If we're not in anonymous content and we have a black parent,
       // return early.
       nsIContent* parent = tmp->GetParent();
-      if (parent && !IsXBL(parent) && IsBlackNode(parent)) {
+      if (parent && !IsXBL(parent) && parent->IsBlack()) {
         NS_ABORT_IF_FALSE(parent->IndexOf(tmp) >= 0, "Parent doesn't own us?");
         return false;
       }
     }
   }
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(GetParent())
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -804,17 +804,17 @@ protected:
                                                 state.patternStyles[aStyle]->mForceWriteOnly,
                                                 state.patternStyles[aStyle]->mCORSUsed);
         }
 
         ExtendMode mode;
         if (state.patternStyles[aStyle]->mRepeat == nsCanvasPatternAzure::NOREPEAT) {
           mode = EXTEND_CLAMP;
         } else {
-          mode = EXTEND_WRAP;
+          mode = EXTEND_REPEAT;
         }
         mPattern = new (mSurfacePattern.addr())
           SurfacePattern(state.patternStyles[aStyle]->mSurface, mode);
       }
 
       return *mPattern;
     }
 
--- a/content/media/test/test_defaultMuted.html
+++ b/content/media/test/test_defaultMuted.html
@@ -1,55 +1,54 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>Media test: defaultMuted</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <script type="text/javascript" src="manifest.js"></script>
+  <script type="text/javascript" src="../../html/content/test/reflect.js"></script>
 </head>
 <body>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=706731">Mozilla Bug 706731</a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <video id='v1'></video><audio id='a1'></audio>
   <video id='v2' muted></video><audio id='a2' muted></audio>
 <pre id="test">
 <script class="testbody" type="text/javascript">
+    reflectBoolean({
+      element: document.createElement("video"),
+      attribute: { content: "muted", idl: "defaultMuted" },
+    });
+
+    reflectBoolean({
+      element: document.createElement("audio"),
+      attribute: { content: "muted", idl: "defaultMuted" },
+    });
+
     var v1 = document.getElementById('v1');
     var a1 = document.getElementById('a1');
     var v2 = document.getElementById('v2');
     var a2 = document.getElementById('a2');
 
-    ok(!v1.defaultMuted, "v1.defaultMuted should be false by default");
-    ok(!a1.defaultMuted, "a1.defaultMuted should be false by default");
-    ok(v2.defaultMuted, "v2.defaultMuted should be true");
-    ok(a2.defaultMuted, "a2.defaultMuted should be true");
-
+    // Check that muted state correspond to the default value.
     is(v1.muted, false, "v1.muted should be false by default");
     is(a1.muted, false, "a1.muted should be false by default");
+    is(v2.muted, true, "v2.muted should be true by default");
+    is(a2.muted, true, "a2.muted should be true by default");
 
+    // Changing defaultMuted value should not change current muted state.
     v1.defaultMuted = true;
     a1.defaultMuted = true;
-    ok(!v1.muted, "v1.muted should be false");
-    ok(!a1.muted, "a1.muted should be false");
-    ok(v1.defaultMuted, "v1.defaultMuted should be true");
-    ok(a1.defaultMuted, "a1.defaultMuted should be true");
-    ok(v1.hasAttribute("muted"), "v1.hasAttribute(\"muted\") should be true");
-    ok(a1.hasAttribute("muted"), "a1.hasAttribute(\"muted\") should be true");
-
-    is(v2.muted, true, "v2.muted should be true");
-    is(a2.muted, true, "a2.muted should be true");
-
     v2.defaultMuted = false;
     a2.defaultMuted = false;
-    ok(!v2.defaultMuted, "v2.defaultMuted should be false");
-    ok(v2.muted, "v2.muted should be true");
-    ok(!a2.defaultMuted, "a2.defaultMuted should be false");
-    ok(a2.muted, "a2.muted should be true");
-    ok(!v2.hasAttribute("muted"), "v2.hasAttribute(\"muted\") should be false");
-    ok(!a2.hasAttribute("muted"), "a2.hasAttribute(\"muted\") should be false");
+
+    is(v1.muted, false, "v1.muted should not have changed");
+    is(a1.muted, false, "a1.muted should not have changed");
+    is(v2.muted, true, "v2.muted should not have changed");
+    is(a2.muted, true, "a2.muted should not have changed");
 
     mediaTestCleanup();
 </script>
 </pre>
 </body>
 </html>
--- a/content/xbl/src/nsXBLDocumentInfo.h
+++ b/content/xbl/src/nsXBLDocumentInfo.h
@@ -77,16 +77,23 @@ public:
   
   void FlushSkinStylesheets();
 
   bool IsChrome() { return mIsChrome; }
 
   // nsIScriptGlobalObjectOwner methods
   virtual nsIScriptGlobalObject* GetScriptGlobalObject();
 
+  void MarkInCCGeneration(PRUint32 aGeneration)
+  {
+    if (mDocument) {
+      mDocument->MarkUncollectableForCCGeneration(aGeneration);
+    }
+  }
+
   static nsresult ReadPrototypeBindings(nsIURI* aURI, nsXBLDocumentInfo** aDocInfo);
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsXBLDocumentInfo,
                                                          nsIScriptGlobalObjectOwner)
 
 private:
   nsCOMPtr<nsIDocument> mDocument;
   bool mScriptAccess;
--- a/content/xslt/src/base/txExpandedNameMap.h
+++ b/content/xslt/src/base/txExpandedNameMap.h
@@ -97,28 +97,26 @@ protected:
 
         bool next()
         {
             return ++mCurrentPos < mMap.mItems.Length();
         }
 
         const txExpandedName key()
         {
-            NS_ASSERTION(mCurrentPos >= 0 &&
-                         mCurrentPos < mMap.mItems.Length(),
+            NS_ASSERTION(mCurrentPos < mMap.mItems.Length(),
                          "invalid position in txExpandedNameMap::iterator");
             return txExpandedName(mMap.mItems[mCurrentPos].mNamespaceID,
                                   mMap.mItems[mCurrentPos].mLocalName);
         }
 
     protected:
         void* itemValue()
         {
-            NS_ASSERTION(mCurrentPos >= 0 &&
-                         mCurrentPos < mMap.mItems.Length(),
+            NS_ASSERTION(mCurrentPos < mMap.mItems.Length(),
                          "invalid position in txExpandedNameMap::iterator");
             return mMap.mItems[mCurrentPos].mValue;
         }
 
     private:
         txExpandedNameMap_base& mMap;
         PRUint32 mCurrentPos;
     };
--- a/content/xul/document/src/nsXULPrototypeCache.cpp
+++ b/content/xul/document/src/nsXULPrototypeCache.cpp
@@ -691,8 +691,33 @@ nsXULPrototypeCache::BeginCaching(nsIURI
 
     // Success!  Insert this URI into the mCacheURITable
     // and commit locals to globals.
     mCacheURITable.Put(aURI, 1);
 
     gStartupCache = startupCache;
     return NS_OK;
 }
+
+static PLDHashOperator
+MarkXBLInCCGeneration(nsIURI* aKey, nsRefPtr<nsXBLDocumentInfo> &aDocInfo,
+                      void* aClosure)
+{
+    PRUint32* gen = static_cast<PRUint32*>(aClosure);
+    aDocInfo->MarkInCCGeneration(*gen);
+    return PL_DHASH_NEXT;
+}
+
+static PLDHashOperator
+MarkXULInCCGeneration(nsIURI* aKey, nsRefPtr<nsXULPrototypeDocument> &aDoc,
+                      void* aClosure)
+{
+    PRUint32* gen = static_cast<PRUint32*>(aClosure);
+    aDoc->MarkInCCGeneration(*gen);
+    return PL_DHASH_NEXT;
+}
+
+void
+nsXULPrototypeCache::MarkInCCGeneration(PRUint32 aGeneration)
+{
+    mXBLDocTable.Enumerate(MarkXBLInCCGeneration, &aGeneration);
+    mPrototypeTable.Enumerate(MarkXULInCCGeneration, &aGeneration);
+}
--- a/content/xul/document/src/nsXULPrototypeCache.h
+++ b/content/xul/document/src/nsXULPrototypeCache.h
@@ -154,16 +154,17 @@ public:
 
     static nsXULPrototypeCache* GetInstance();
 
     static void ReleaseGlobals()
     {
         NS_IF_RELEASE(sInstance);
     }
 
+    void MarkInCCGeneration(PRUint32 aGeneration);
 protected:
     friend nsresult
     NS_NewXULPrototypeCache(nsISupports* aOuter, REFNSIID aIID, void** aResult);
 
     nsXULPrototypeCache();
     virtual ~nsXULPrototypeCache();
 
     static nsXULPrototypeCache* sInstance;
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -154,17 +154,18 @@ JSClass nsXULPDGlobalObject::gSharedGlob
 
 //----------------------------------------------------------------------
 //
 // ctors, dtors, n' stuff
 //
 
 nsXULPrototypeDocument::nsXULPrototypeDocument()
     : mRoot(nsnull),
-      mLoaded(false)
+      mLoaded(false),
+      mCCGeneration(0)
 {
     ++gRefCnt;
 }
 
 
 nsresult
 nsXULPrototypeDocument::Init()
 {
@@ -190,16 +191,19 @@ nsXULPrototypeDocument::~nsXULPrototypeD
     }
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULPrototypeDocument)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULPrototypeDocument)
     tmp->mPrototypeWaiters.Clear();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULPrototypeDocument)
+    if (nsCCUncollectableMarker::InGeneration(cb, tmp->mCCGeneration)) {
+        return NS_SUCCESS_INTERRUPTED_TRAVERSE;
+    }
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mRoot,
                                                     nsXULPrototypeElement)
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mGlobalObject");
     cb.NoteXPCOMChild(static_cast<nsIScriptGlobalObject*>(tmp->mGlobalObject));
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mNodeInfoManager,
                                                     nsNodeInfoManager)
     for (PRUint32 i = 0; i < tmp->mPrototypeWaiters.Length(); ++i) {
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mPrototypeWaiters[i]");
--- a/content/xul/document/src/nsXULPrototypeDocument.h
+++ b/content/xul/document/src/nsXULPrototypeDocument.h
@@ -142,32 +142,39 @@ public:
      */
     nsresult NotifyLoadDone();
 
     nsNodeInfoManager *GetNodeInfoManager();
 
     // nsIScriptGlobalObjectOwner methods
     virtual nsIScriptGlobalObject* GetScriptGlobalObject();
 
+    void MarkInCCGeneration(PRUint32 aCCGeneration)
+    {
+        mCCGeneration = aCCGeneration;
+    }
+
     NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULPrototypeDocument,
                                              nsIScriptGlobalObjectOwner)
 
 protected:
     nsCOMPtr<nsIURI> mURI;
     nsRefPtr<nsXULPrototypeElement> mRoot;
     nsTArray<nsRefPtr<nsXULPrototypePI> > mProcessingInstructions;
     nsCOMArray<nsIURI> mStyleSheetReferences;
 
     nsRefPtr<nsXULPDGlobalObject> mGlobalObject;
 
     bool mLoaded;
     nsTArray< nsRefPtr<nsXULDocument> > mPrototypeWaiters;
 
     nsRefPtr<nsNodeInfoManager> mNodeInfoManager;
 
+    PRUint32 mCCGeneration;
+
     nsXULPrototypeDocument();
     virtual ~nsXULPrototypeDocument();
     nsresult Init();
 
     friend NS_IMETHODIMP
     NS_NewXULPrototypeDocument(nsXULPrototypeDocument** aResult);
 
     nsXULPDGlobalObject *NewXULPDGlobalObject();
--- a/docshell/test/unit/test_nsIDownloadHistory.js
+++ b/docshell/test/unit/test_nsIDownloadHistory.js
@@ -86,15 +86,18 @@ function run_test()
   try {
     Cc["@mozilla.org/browser/global-history;2"].
       getService(Ci.nsIGlobalHistory2);
   }
   catch (ex) {
     return;
   }
 
+  // Needed to properly setup and shutdown the profile.
+  do_get_profile();
+
   Services.prefs.setBoolPref("places.history.enabled", true);
 
   for (var i = 0; i < tests.length; i++)
     tests[i]();
 
   cleanup();
 }
--- a/dom/Makefile.in
+++ b/dom/Makefile.in
@@ -79,17 +79,20 @@ DIRS += \
   plugins/ipc \
   indexedDB \
   system \
   ipc \
   workers \
   $(NULL)
 
 ifdef MOZ_B2G_RIL #{
-DIRS += telephony
+DIRS += \
+  telephony \
+  wifi \
+  $(NULL)
 endif #}
 
 ifdef ENABLE_TESTS
 DIRS += tests
 ifneq (,$(filter gtk2 cocoa windows android qt os2,$(MOZ_WIDGET_TOOLKIT)))
 DIRS += plugins/test
 endif
 endif
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -1030,16 +1030,24 @@ Navigator::SizeOf() const
   // TODO: add SizeOf() to nsGeolocation, bug 674115.
   size += mGeolocation ? sizeof(*mGeolocation.get()) : 0;
   // TODO: add SizeOf() to nsDesktopNotificationCenter, bug 674116.
   size += mNotification ? sizeof(*mNotification.get()) : 0;
 
   return size;
 }
 
+void
+Navigator::SetWindow(nsPIDOMWindow *aInnerWindow)
+{
+  NS_ASSERTION(aInnerWindow->IsInnerWindow(),
+               "Navigator must get an inner window!");
+  mWindow = do_GetWeakReference(aInnerWindow);
+}
+
 } // namespace dom
 } // namespace mozilla
 
 nsresult
 NS_GetNavigatorUserAgent(nsAString& aUserAgent)
 {
   nsresult rv;
 
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -98,16 +98,21 @@ public:
   nsPIDOMWindow *GetWindow();
 
   void RefreshMIMEArray();
 
   static bool HasDesktopNotificationSupport();
 
   PRInt64 SizeOf() const;
 
+  /**
+   * For use during document.write where our inner window changes.
+   */
+  void SetWindow(nsPIDOMWindow *aInnerWindow);
+
 private:
   bool IsSmsAllowed() const;
   bool IsSmsSupported() const;
 
   nsRefPtr<nsMimeTypeArray> mMimeTypes;
   nsRefPtr<nsPluginArray> mPlugins;
   nsRefPtr<nsGeolocation> mGeolocation;
   nsRefPtr<nsDesktopNotificationCenter> mNotification;
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1674,16 +1674,35 @@ jsid nsDOMClassInfo::sWrappedJSObject_id
 jsid nsDOMClassInfo::sURL_id             = JSID_VOID;
 jsid nsDOMClassInfo::sKeyPath_id         = JSID_VOID;
 jsid nsDOMClassInfo::sAutoIncrement_id   = JSID_VOID;
 jsid nsDOMClassInfo::sUnique_id          = JSID_VOID;
 jsid nsDOMClassInfo::sMultiEntry_id      = JSID_VOID;
 jsid nsDOMClassInfo::sOnload_id          = JSID_VOID;
 jsid nsDOMClassInfo::sOnerror_id         = JSID_VOID;
 
+static const JSClass *sObjectClass = nsnull;
+
+/**
+ * Set our JSClass pointer for the Object class
+ */
+static void
+FindObjectClass(JSObject* aGlobalObject)
+{
+  NS_ASSERTION(!sObjectClass,
+               "Double set of sObjectClass");
+  JSObject *obj, *proto = aGlobalObject;
+  do {
+    obj = proto;
+    proto = js::GetObjectProto(obj);
+  } while (proto);
+
+  sObjectClass = js::GetObjectJSClass(obj);
+}
+
 static void
 PrintWarningOnConsole(JSContext *cx, const char *stringBundleProperty)
 {
   nsCOMPtr<nsIStringBundleService> stringService =
     mozilla::services::GetStringBundleService();
   if (!stringService) {
     return;
   }
@@ -4697,62 +4716,16 @@ GetExternalClassInfo(nsScriptNameSpaceMa
 static nsresult
 ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx,
                  JSObject *obj, const PRUnichar *name,
                  const nsDOMClassInfoData *ci_data,
                  const nsGlobalNameStruct *name_struct,
                  nsScriptNameSpaceManager *nameSpaceManager,
                  JSObject *dot_prototype, bool install, bool *did_resolve);
 
-static nsresult
-LookupPrototypeProto(JSContext *cx, JSObject *winobj,
-                     const nsDOMClassInfoData *ci_data,
-                     const nsGlobalNameStruct *name_struct,
-                     JSObject **aProtoProto);
-
-
-static nsGlobalWindow*
-FindUsableInnerWindow(nsIXPConnect *xpc, JSContext *cx, JSObject *global)
-{
-  // Only do this if the global object is a window.
-  // XXX Is there a better way to check this?
-  nsISupports *globalNative = xpc->GetNativeOfWrapper(cx, global);
-  nsCOMPtr<nsPIDOMWindow> piwin = do_QueryInterface(globalNative);
-  if (!piwin) {
-    return nsnull;
-  }
-
-  nsGlobalWindow *win = nsGlobalWindow::FromSupports(globalNative);
-  if (win->IsClosedOrClosing()) {
-    return nsnull;
-  }
-  
-  // If the window is in a different compartment than the global object, then
-  // it's likely that global is a sandbox object whose prototype is a window.
-  // Don't do anything in this case.
-  if (win->FastGetGlobalJSObject() &&
-      js::GetObjectCompartment(global) != js::GetObjectCompartment(win->FastGetGlobalJSObject())) {
-    return nsnull;
-  }
-
-  if (win->IsOuterWindow()) {
-    // XXXjst: Do security checks here when we remove the security
-    // checks on the inner window.
-
-    win = win->GetCurrentInnerWindowInternal();
-
-    JSObject* global;
-    if (!win || !(global = win->GetGlobalJSObject()) ||
-        win->IsClosedOrClosing()) {
-      return nsnull;
-    }
-  }
-
-  return win;
-}
 
 NS_IMETHODIMP
 nsDOMClassInfo::PostCreatePrototype(JSContext * cx, JSObject * proto)
 {
   PRUint32 flags = (mData->mScriptableFlags & DONT_ENUM_STATIC_PROPS)
                    ? 0
                    : JSPROP_ENUMERATE;
 
@@ -4761,16 +4734,29 @@ nsDOMClassInfo::PostCreatePrototype(JSCo
     count++;
   }
 
   if (!sXPConnect->DefineDOMQuickStubs(cx, proto, flags,
                                        count, mData->mInterfaces)) {
     JS_ClearPendingException(cx);
   }
 
+  // This is called before any other location that requires
+  // sObjectClass, so compute it here. We assume that nobody has had a
+  // chance to monkey around with proto's prototype chain before this.
+  if (!sObjectClass) {
+    FindObjectClass(proto);
+    NS_ASSERTION(sObjectClass && !strcmp(sObjectClass->name, "Object"),
+                 "Incorrect object class!");
+  }
+
+  NS_ASSERTION(::JS_GetPrototype(cx, proto) &&
+               JS_GET_CLASS(cx, ::JS_GetPrototype(cx, proto)) == sObjectClass,
+               "Hmm, somebody did something evil?");
+
 #ifdef DEBUG
   if (mData->mHasClassInterface && mData->mProtoChainInterface &&
       mData->mProtoChainInterface != &NS_GET_IID(nsISupports)) {
     nsCOMPtr<nsIInterfaceInfoManager>
       iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
 
     if (iim) {
       nsCOMPtr<nsIInterfaceInfo> if_info;
@@ -4788,22 +4774,48 @@ nsDOMClassInfo::PostCreatePrototype(JSCo
 #endif
 
   // Make prototype delegation work correctly. Consider if a site sets
   // HTMLElement.prototype.foopy = function () { ... } Now, calling
   // document.body.foopy() needs to ensure that looking up foopy on
   // document.body's prototype will find the right function.
   JSObject *global = ::JS_GetGlobalForObject(cx, proto);
 
-  nsGlobalWindow *win = FindUsableInnerWindow(XPConnect(), cx, global);
-  if (!win) {
+  // Only do this if the global object is a window.
+  // XXX Is there a better way to check this?
+  nsISupports *globalNative = XPConnect()->GetNativeOfWrapper(cx, global);
+  nsCOMPtr<nsPIDOMWindow> piwin = do_QueryInterface(globalNative);
+  if (!piwin) {
+    return NS_OK;
+  }
+
+  nsGlobalWindow *win = nsGlobalWindow::FromSupports(globalNative);
+  if (win->IsClosedOrClosing()) {
     return NS_OK;
   }
 
-  global = win->FastGetGlobalJSObject();
+  // If the window is in a different compartment than the global object, then
+  // it's likely that global is a sandbox object whose prototype is a window.
+  // Don't do anything in this case.
+  if (win->FastGetGlobalJSObject() &&
+      js::GetObjectCompartment(global) != js::GetObjectCompartment(win->FastGetGlobalJSObject())) {
+    return NS_OK;
+  }
+
+  if (win->IsOuterWindow()) {
+    // XXXjst: Do security checks here when we remove the security
+    // checks on the inner window.
+
+    win = win->GetCurrentInnerWindowInternal();
+
+    if (!win || !(global = win->GetGlobalJSObject()) ||
+        win->IsClosedOrClosing()) {
+      return NS_OK;
+    }
+  }
 
   // Don't overwrite a property set by content.
   JSBool found;
   if (!::JS_AlreadyHasOwnUCProperty(cx, global, reinterpret_cast<const jschar*>(mData->mNameUTF16),
                                     nsCRT::strlen(mData->mNameUTF16), &found)) {
     return NS_ERROR_FAILURE;
   }
 
@@ -4812,33 +4824,16 @@ nsDOMClassInfo::PostCreatePrototype(JSCo
   NS_ENSURE_TRUE(nameSpaceManager, NS_OK);
 
   bool unused;
   return ResolvePrototype(sXPConnect, win, cx, global, mData->mNameUTF16,
                           mData, nsnull, nameSpaceManager, proto, !found,
                           &unused);
 }
 
-NS_IMETHODIMP
-nsDOMClassInfo::PreCreatePrototype(JSContext * cx, JSObject * global,
-                                   JSObject **protoProto)
-{
-  *protoProto = nsnull;
-  
-  nsGlobalWindow *win = FindUsableInnerWindow(XPConnect(), cx, global);
-  if (!win) {
-    return NS_OK;
-  }
-
-  JSObject *winObj = win->FastGetGlobalJSObject();
-  
-  return LookupPrototypeProto(cx, winObj, mData, nsnull, protoProto);
-}
-
-
 // static
 nsIClassInfo *
 NS_GetDOMClassInfoInstance(nsDOMClassInfoID aID)
 {
   if (aID >= eDOMClassInfoIDCount) {
     NS_ERROR("Bad ID!");
 
     return nsnull;
@@ -5181,17 +5176,17 @@ nsWindowSH::InstallGlobalScopePolluter(J
   }
 
   JSObject *o = obj, *proto;
 
   // Find the place in the prototype chain where we want this global
   // scope polluter (right before Object.prototype).
 
   while ((proto = ::JS_GetPrototype(cx, o))) {
-    if (js::GetObjectClass(proto) == &js::ObjectClass) {
+    if (JS_GET_CLASS(cx, proto) == sObjectClass) {
       // Set the global scope polluters prototype to Object.prototype
       ::JS_SplicePrototype(cx, gsp, proto);
 
       break;
     }
 
     o = proto;
   }
@@ -6003,115 +5998,16 @@ GetXPCProto(nsIXPConnect *aXPConnect, JS
   if (!JS_WrapObject(cx, &proto_obj)) {
     return NS_ERROR_FAILURE;
   }
 
   NS_IF_RELEASE(*aProto);
   return aXPConnect->HoldObject(cx, proto_obj, aProto);
 }
 
-static nsresult
-LookupPrototypeProto(JSContext *cx, JSObject *winobj,
-                     const nsDOMClassInfoData *ci_data,
-                     const nsGlobalNameStruct *name_struct,
-                     JSObject **aProtoProto)
-{
-  NS_ASSERTION(ci_data ||
-               (name_struct &&
-                name_struct->mType == nsGlobalNameStruct::eTypeClassProto),
-               "Wrong type or missing ci_data!");
-
-  const nsIID *primary_iid = &NS_GET_IID(nsISupports);
-
-  if (!ci_data) {
-    primary_iid = &name_struct->mIID;
-  } else if (ci_data->mProtoChainInterface) {
-    primary_iid = ci_data->mProtoChainInterface;
-  }
-
-  if (primary_iid->Equals(NS_GET_IID(nsISupports))) {
-    *aProtoProto = nsnull;
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIInterfaceInfoManager>
-    iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
-  NS_ENSURE_TRUE(iim, NS_ERROR_NOT_AVAILABLE);
-
-  nsCOMPtr<nsIInterfaceInfo> if_info;
-  iim->GetInfoForIID(primary_iid, getter_AddRefs(if_info));
-  NS_ENSURE_TRUE(if_info, NS_ERROR_UNEXPECTED);
-
-  const nsIID *iid = nsnull;
-
-  nsCOMPtr<nsIInterfaceInfo> parent;
-  if (ci_data && !ci_data->mHasClassInterface) {
-    if_info->GetIIDShared(&iid);
-  } else {
-    if_info->GetParent(getter_AddRefs(parent));
-    NS_ENSURE_TRUE(parent, NS_ERROR_UNEXPECTED);
-
-    parent->GetIIDShared(&iid);
-  }
-
-  if (!iid || iid->Equals(NS_GET_IID(nsISupports))) {
-    *aProtoProto = nsnull;
-    return NS_OK;
-  }
-
-  const char *class_parent_name = nsnull;
-  if (ci_data && !ci_data->mHasClassInterface) {
-    // If the class doesn't have a class interface the primary
-    // interface is the interface that should be
-    // constructor.prototype.__proto__.
-
-    if_info->GetNameShared(&class_parent_name);
-  } else {
-    // If the class does have a class interface (or there's no
-    // real class for this name) then the parent of the
-    // primary interface is what we want on
-    // constructor.prototype.__proto__.
-
-    NS_ASSERTION(parent, "Whoa, this is bad, null parent here!");
-
-    parent->GetNameShared(&class_parent_name);
-  }
-
-  JSObject *protoProto = nsnull;
-
-  // Get class_parent_name here
-  if (class_parent_name) {
-    jsval val;
-
-    JSAutoEnterCompartment ac;
-    if (!ac.enter(cx, winobj)) {
-      return NS_ERROR_UNEXPECTED;
-    }
-
-    if (!::JS_LookupProperty(cx, winobj, CutPrefix(class_parent_name), &val)) {
-      return NS_ERROR_UNEXPECTED;
-    }
-
-    JSObject *tmp = JSVAL_IS_OBJECT(val) ? JSVAL_TO_OBJECT(val) : nsnull;
-
-    if (tmp) {
-      if (!::JS_LookupProperty(cx, tmp, "prototype", &val)) {
-        return NS_ERROR_UNEXPECTED;
-      }
-
-      if (JSVAL_IS_OBJECT(val)) {
-        protoProto = JSVAL_TO_OBJECT(val);
-      }
-    }
-  }
-
-  *aProtoProto = protoProto;
-  return NS_OK;
-}
-
 // Either ci_data must be non-null or name_struct must be non-null and of type
 // eTypeClassProto.
 static nsresult
 ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx,
                  JSObject *obj, const PRUnichar *name,
                  const nsDOMClassInfoData *ci_data,
                  const nsGlobalNameStruct *name_struct,
                  nsScriptNameSpaceManager *nameSpaceManager,
@@ -6147,16 +6043,20 @@ ResolvePrototype(nsIXPConnect *aXPConnec
 
   if (!ci_data) {
     primary_iid = &name_struct->mIID;
   }
   else if (ci_data->mProtoChainInterface) {
     primary_iid = ci_data->mProtoChainInterface;
   }
 
+  nsCOMPtr<nsIInterfaceInfo> if_info;
+  nsCOMPtr<nsIInterfaceInfo> parent;
+  const char *class_parent_name = nsnull;
+
   if (!primary_iid->Equals(NS_GET_IID(nsISupports))) {
     JSAutoEnterCompartment ac;
 
     if (!ac.enter(cx, class_obj)) {
       return NS_ERROR_FAILURE;
     }
 
     rv = DefineInterfaceConstants(cx, class_obj, primary_iid);
@@ -6170,36 +6070,98 @@ ResolvePrototype(nsIXPConnect *aXPConnec
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     // Special case for |IDBKeyRange| which gets funny "static" functions.
     if (primary_iid->Equals(NS_GET_IID(nsIIDBKeyRange)) &&
         !indexedDB::IDBKeyRange::DefineConstructors(cx, class_obj)) {
       return NS_ERROR_FAILURE;
     }
+
+    nsCOMPtr<nsIInterfaceInfoManager>
+      iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
+    NS_ENSURE_TRUE(iim, NS_ERROR_NOT_AVAILABLE);
+
+    iim->GetInfoForIID(primary_iid, getter_AddRefs(if_info));
+    NS_ENSURE_TRUE(if_info, NS_ERROR_UNEXPECTED);
+
+    const nsIID *iid = nsnull;
+
+    if (ci_data && !ci_data->mHasClassInterface) {
+      if_info->GetIIDShared(&iid);
+    } else {
+      if_info->GetParent(getter_AddRefs(parent));
+      NS_ENSURE_TRUE(parent, NS_ERROR_UNEXPECTED);
+
+      parent->GetIIDShared(&iid);
+    }
+
+    if (iid) {
+      if (!iid->Equals(NS_GET_IID(nsISupports))) {
+        if (ci_data && !ci_data->mHasClassInterface) {
+          // If the class doesn't have a class interface the primary
+          // interface is the interface that should be
+          // constructor.prototype.__proto__.
+
+          if_info->GetNameShared(&class_parent_name);
+        } else {
+          // If the class does have a class interface (or there's no
+          // real class for this name) then the parent of the
+          // primary interface is what we want on
+          // constructor.prototype.__proto__.
+
+          NS_ASSERTION(parent, "Whoa, this is bad, null parent here!");
+
+          parent->GetNameShared(&class_parent_name);
+        }
+      }
+    }
   }
 
   {
     JSObject *winobj = aWin->FastGetGlobalJSObject();
 
-    JSObject *proto;
-    rv = LookupPrototypeProto(cx, winobj, ci_data, name_struct, &proto);
-    NS_ENSURE_SUCCESS(rv, rv);
+    JSObject *proto = nsnull;
+
+    if (class_parent_name) {
+      jsval val;
+
+      JSAutoEnterCompartment ac;
+      if (!ac.enter(cx, winobj)) {
+        return NS_ERROR_UNEXPECTED;
+      }
+
+      if (!::JS_LookupProperty(cx, winobj, CutPrefix(class_parent_name), &val)) {
+        return NS_ERROR_UNEXPECTED;
+      }
+
+      JSObject *tmp = JSVAL_IS_OBJECT(val) ? JSVAL_TO_OBJECT(val) : nsnull;
+
+      if (tmp) {
+        if (!::JS_LookupProperty(cx, tmp, "prototype", &val)) {
+          return NS_ERROR_UNEXPECTED;
+        }
+
+        if (JSVAL_IS_OBJECT(val)) {
+          proto = JSVAL_TO_OBJECT(val);
+        }
+      }
+    }
 
     if (dot_prototype) {
       JSAutoEnterCompartment ac;
       if (!ac.enter(cx, dot_prototype)) {
         return NS_ERROR_UNEXPECTED;
       }
 
       JSObject *xpc_proto_proto = ::JS_GetPrototype(cx, dot_prototype);
 
       if (proto &&
           (!xpc_proto_proto ||
-           js::GetObjectClass(xpc_proto_proto) == &js::ObjectClass)) {
+           JS_GET_CLASS(cx, xpc_proto_proto) == sObjectClass)) {
         if (!JS_WrapObject(cx, &proto) ||
             !JS_SetPrototype(cx, dot_prototype, proto)) {
           return NS_ERROR_UNEXPECTED;
         }
       }
     } else {
       JSAutoEnterCompartment ac;
       if (!ac.enter(cx, winobj)) {
@@ -9576,17 +9538,17 @@ nsHTMLPluginObjElementSH::SetupProtoChai
   rv = wrapper->GetJSObjectPrototype(&my_proto);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Set 'this.__proto__' to pi
   if (!::JS_SetPrototype(cx, obj, pi_obj)) {
     return NS_ERROR_UNEXPECTED;
   }
 
-  if (pi_proto && js::GetObjectClass(pi_proto) != &js::ObjectClass) {
+  if (pi_proto && JS_GET_CLASS(cx, pi_proto) != sObjectClass) {
     // The plugin wrapper has a proto that's not Object.prototype, set
     // 'pi.__proto__.__proto__' to the original 'this.__proto__'
     if (pi_proto != my_proto && !::JS_SetPrototype(cx, pi_proto, my_proto)) {
       return NS_ERROR_UNEXPECTED;
     }
   } else {
     // 'pi' didn't have a prototype, or pi's proto was
     // 'Object.prototype' (i.e. pi is an NPRuntime wrapped JS object)
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1983,17 +1983,17 @@ nsGlobalWindow::SetNewDocument(nsIDocume
     // instead.
     if (!JS_TransplantObject(cx, mJSObject, mJSObject)) {
       return NS_ERROR_FAILURE;
     }
   } else {
     if (aState) {
       newInnerWindow = wsh->GetInnerWindow();
       mInnerWindowHolder = wsh->GetInnerWindowHolder();
-      
+
       NS_ASSERTION(newInnerWindow, "Got a state without inner window");
     } else if (thisChrome) {
       newInnerWindow = new nsGlobalChromeWindow(this);
       isChrome = true;
     } else if (mIsModalContentWindow) {
       newInnerWindow = new nsGlobalModalWindow(this);
     } else {
       newInnerWindow = new nsGlobalWindow(this);
@@ -2033,16 +2033,25 @@ nsGlobalWindow::SetNewDocument(nsIDocume
 
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     if (currentInner && currentInner->mJSObject) {
       bool termFuncSet = false;
 
       if (oldDoc == aDocument) {
+        // Move the navigator from the old inner window to the new one since
+        // this is a document.write. This is safe from a same-origin point of
+        // view because document.write can only be used by the same origin.
+        newInnerWindow->mNavigator = currentInner->mNavigator;
+        currentInner->mNavigator = nsnull;
+        if (newInnerWindow->mNavigator) {
+          newInnerWindow->mNavigator->SetWindow(newInnerWindow);
+        }
+
         // Suspend the current context's request before Pop() resumes the old
         // context's request.
         JSAutoSuspendRequest asr(cx);
 
         // Pop our context here so that we get the correct one for the
         // termination function.
         cxPusher.Pop();
 
--- a/dom/base/nsStructuredCloneContainer.cpp
+++ b/dom/base/nsStructuredCloneContainer.cpp
@@ -40,17 +40,20 @@
 
 #include "nsCOMPtr.h"
 #include "nsIDocument.h"
 #include "nsIJSContextStack.h"
 #include "nsIScriptContext.h"
 #include "nsIVariant.h"
 #include "nsServiceManagerUtils.h"
 #include "nsContentUtils.h"
-#include "xpcprivate.h"
+
+#include "mozilla/Base64.h"
+
+using namespace mozilla;
 
 NS_IMPL_ADDREF(nsStructuredCloneContainer)
 NS_IMPL_RELEASE(nsStructuredCloneContainer)
 
 NS_INTERFACE_MAP_BEGIN(nsStructuredCloneContainer)
   NS_INTERFACE_MAP_ENTRY(nsIStructuredCloneContainer)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
@@ -119,17 +122,17 @@ nsStructuredCloneContainer::InitFromBase
                                            PRUint32 aFormatVersion,
                                            JSContext *aCx)
 {
   NS_ENSURE_STATE(!mData);
 
   NS_ConvertUTF16toUTF8 data(aData);
 
   nsCAutoString binaryData;
-  nsresult rv = nsXPConnect::Base64Decode(data, binaryData);
+  nsresult rv = Base64Decode(data, binaryData);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Copy the string's data into our own buffer.
   mData = (PRUint64*) malloc(binaryData.Length());
   NS_ENSURE_STATE(mData);
   memcpy(mData, binaryData.get(), binaryData.Length());
 
   mSize = binaryData.Length();
@@ -166,17 +169,17 @@ nsStructuredCloneContainer::DeserializeT
 nsresult
 nsStructuredCloneContainer::GetDataAsBase64(nsAString &aOut)
 {
   NS_ENSURE_STATE(mData);
   aOut.Truncate();
 
   nsCAutoString binaryData(reinterpret_cast<char*>(mData), mSize);
   nsCAutoString base64Data;
-  nsresult rv = nsXPConnect::Base64Encode(binaryData, base64Data);
+  nsresult rv = Base64Encode(binaryData, base64Data);
   NS_ENSURE_SUCCESS(rv, rv);
 
   aOut.Assign(NS_ConvertASCIItoUTF16(base64Data));
   return NS_OK;
 }
 
 nsresult
 nsStructuredCloneContainer::GetSerializedNBytes(PRUint64 *aSize)
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -185,16 +185,21 @@ public:
    */
   virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
                                bool *triedToWrap)
   {
     *triedToWrap = false;
     return nsnull;
   }
 
+  /**
+   * Returns true if the object has a non-gray wrapper.
+   */
+  bool IsBlack();
+
 private:
   // Only meant to be called by nsContentUtils.
   void SetPreservingWrapper(bool aPreserve)
   {
     if(aPreserve) {
       mWrapperPtrBits |= WRAPPER_BIT_PRESERVED;
     }
     else {
--- a/dom/base/nsWrapperCacheInlines.h
+++ b/dom/base/nsWrapperCacheInlines.h
@@ -134,9 +134,16 @@ nsWrapperCache::ClearWrapperIfProxy()
         return;
     }
 
     RemoveExpandoObject();
 
     SetWrapperBits(NULL);
 }
 
+inline bool
+nsWrapperCache::IsBlack()
+{
+  JSObject* o = GetWrapperPreserveColor();
+  return o && !xpc_IsGrayGCThing(o);
+}
+
 #endif /* nsWrapperCache_h___ */
--- a/dom/indexedDB/test/Makefile.in
+++ b/dom/indexedDB/test/Makefile.in
@@ -119,21 +119,22 @@ TEST_FILES = \
   test_transaction_lifetimes.html \
   test_transaction_lifetimes_nested.html \
   test_transaction_ordering.html \
   test_setVersion.html \
   test_setVersion_abort.html \
   test_setVersion_events.html \
   test_setVersion_exclusion.html \
   test_unique_index_update.html \
-  test_writer_starvation.html \
   third_party_iframe1.html \
   third_party_iframe2.html \
   $(NULL)
 
+#   test_writer_starvation.html  disabled for infinite loops, bug 595368
+
 ifeq (browser,$(MOZ_BUILD_APP))
 BROWSER_TEST_FILES = \
   browser_forgetThisSite.js \
   browser_forgetThisSiteAdd.html \
   browser_forgetThisSiteGet.html \
   browserHelpers.js \
   browser_permissionsPrompt.html \
   browser_permissionsPromptAllow.js \
--- a/dom/system/b2g/Makefile.in
+++ b/dom/system/b2g/Makefile.in
@@ -61,12 +61,13 @@ endif
 XPIDLSRCS = \
   nsIAudioManager.idl \
   nsIRadioWorker.idl \
   $(NULL)
 
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/dom/base \
   -I$(topsrcdir)/dom/telephony \
+  -I$(topsrcdir)/dom/wifi \
   -I$(topsrcdir)/content/events/src \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/dom/system/b2g/RadioManager.cpp
+++ b/dom/system/b2g/RadioManager.cpp
@@ -40,31 +40,36 @@
 #include "RadioManager.h"
 #include "nsIRadioWorker.h"
 #include "nsContentUtils.h"
 #include "nsIXPConnect.h"
 #include "nsIJSContextStack.h"
 #include "nsIObserverService.h"
 #include "mozilla/dom/workers/Workers.h"
 #include "jstypedarray.h"
+
 #include "nsTelephonyWorker.h"
+#include "nsITelephone.h"
+#include "nsWifiWorker.h"
+#include "nsIWifi.h"
 
 #include "nsThreadUtils.h"
 
 #if defined(MOZ_WIDGET_GONK)
 #include <android/log.h>
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
 #else
 #define LOG(args...)  printf(args);
 #endif
 
 USING_WORKERS_NAMESPACE
 using namespace mozilla::ipc;
 
 static NS_DEFINE_CID(kTelephonyWorkerCID, NS_TELEPHONYWORKER_CID);
+static NS_DEFINE_CID(kWifiWorkerCID, NS_WIFIWORKER_CID);
 
 // Topic we listen to for shutdown.
 #define PROFILE_BEFORE_CHANGE_TOPIC "profile-before-change"
 
 USING_TELEPHONY_NAMESPACE
 
 namespace {
 
@@ -220,69 +225,41 @@ RadioManager::Init()
   if (!obs) {
     NS_WARNING("Failed to get observer service!");
     return NS_ERROR_FAILURE;
   }
 
   nsresult rv = obs->AddObserver(this, PROFILE_BEFORE_CHANGE_TOPIC, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // The telephony worker component is a hack that gives us a global object for
-  // our own functions and makes creating the worker possible.
-  nsCOMPtr<nsIRadioWorker> worker(do_CreateInstance(kTelephonyWorkerCID));
-  NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
-
-  jsval workerval;
-  rv = worker->GetWorker(&workerval);
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ASSERTION(!JSVAL_IS_PRIMITIVE(workerval), "bad worker value");
-
   JSContext *cx;
   rv = nsContentUtils::ThreadJSContextStack()->GetSafeJSContext(&cx);
   NS_ENSURE_SUCCESS(rv, rv);
   nsCxPusher pusher;
   if (!cx || !pusher.Push(cx, false)) {
     return NS_ERROR_FAILURE;
   }
 
-  JSObject *workerobj = JSVAL_TO_OBJECT(workerval);
-
-  JSAutoRequest ar(cx);
-  JSAutoEnterCompartment ac;
-  if (!ac.enter(cx, workerobj)) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
+  rv = InitTelephone(cx);
+  NS_ENSURE_SUCCESS(rv, rv);
 
-  WorkerCrossThreadDispatcher *wctd = GetWorkerCrossThreadDispatcher(cx, workerval);
-  if (!wctd) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsRefPtr<ConnectWorkerToRIL> connection = new ConnectWorkerToRIL();
-  if (!wctd->PostTask(connection)) {
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  // Now that we're set up, connect ourselves to the RIL thread.
-  mozilla::RefPtr<RILReceiver> receiver = new RILReceiver(wctd);
-  StartRil(receiver);
-
-  mTelephone = do_QueryInterface(worker);
-  NS_ENSURE_TRUE(mTelephone, NS_ERROR_FAILURE);
+  rv = InitWifi(cx);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 void
 RadioManager::Shutdown()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   StopRil();
   mTelephone = nsnull;
+  mWifi = nsnull;
 
   mShutdown = true;
 }
 
 // static
 already_AddRefed<RadioManager>
 RadioManager::FactoryCreate()
 {
@@ -311,16 +288,69 @@ RadioManager::GetTelephone()
   if (gInstance) {
     nsCOMPtr<nsITelephone> retval = gInstance->mTelephone;
     return retval.forget();
   }
 
   return nsnull;
 }
 
+nsresult
+RadioManager::InitTelephone(JSContext *cx)
+{
+  // The telephony worker component is a hack that gives us a global object for
+  // our own functions and makes creating the worker possible.
+  nsCOMPtr<nsIRadioWorker> worker(do_CreateInstance(kTelephonyWorkerCID));
+  NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
+
+  jsval workerval;
+  nsresult rv = worker->GetWorker(&workerval);
+  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ASSERTION(!JSVAL_IS_PRIMITIVE(workerval), "bad worker value");
+
+  JSObject *workerobj = JSVAL_TO_OBJECT(workerval);
+
+  JSAutoRequest ar(cx);
+  JSAutoEnterCompartment ac;
+  if (!ac.enter(cx, workerobj)) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  WorkerCrossThreadDispatcher *wctd = GetWorkerCrossThreadDispatcher(cx, workerval);
+  if (!wctd) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsRefPtr<ConnectWorkerToRIL> connection = new ConnectWorkerToRIL();
+  if (!wctd->PostTask(connection)) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  // Now that we're set up, connect ourselves to the RIL thread.
+  mozilla::RefPtr<RILReceiver> receiver = new RILReceiver(wctd);
+  StartRil(receiver);
+
+  mTelephone = do_QueryInterface(worker);
+  NS_ENSURE_TRUE(mTelephone, NS_ERROR_FAILURE);
+
+  return NS_OK;
+}
+
+nsresult
+RadioManager::InitWifi(JSContext *cx)
+{
+  nsCOMPtr<nsIRadioWorker> worker(do_CreateInstance(kWifiWorkerCID));
+  NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
+
+  mWifi = do_QueryInterface(worker);
+  NS_ENSURE_TRUE(mWifi, NS_ERROR_FAILURE);
+
+  return NS_OK;
+}
+
 
 NS_IMPL_ISUPPORTS1(RadioManager, nsIObserver)
 
 NS_IMETHODIMP
 RadioManager::Observe(nsISupports* aSubject, const char* aTopic,
                       const PRUnichar* aData)
 {
   if (!strcmp(aTopic, PROFILE_BEFORE_CHANGE_TOPIC)) {
--- a/dom/system/b2g/RadioManager.h
+++ b/dom/system/b2g/RadioManager.h
@@ -43,17 +43,16 @@
 #include "jsapi.h"
 #include "nsComponentManagerUtils.h"
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
 #include "nsServiceManagerUtils.h"
 
 #include "nsIObserver.h"
 #include "mozilla/ipc/Ril.h"
-#include "nsITelephone.h"
 
 #define TELEPHONYRADIO_CONTRACTID "@mozilla.org/telephony/radio;1"
 #define TELEPHONYRADIOINTERFACE_CONTRACTID "@mozilla.org/telephony/radio-interface;1"
 
 #define BEGIN_TELEPHONY_NAMESPACE \
   namespace mozilla { namespace dom { namespace telephony {
 #define END_TELEPHONY_NAMESPACE \
   } /* namespace telephony */ } /* namespace dom */ } /* namespace mozilla */
@@ -65,16 +64,18 @@
   {0xa5c3a6de, 0x84c4, 0x4b15, {0x86, 0x11, 0x8a, 0xeb, 0x8d, 0x97, 0xf8, 0xba}}
 
 // {a688f191-8ffc-47f3-8740-94a312cf59cb}}
 #define TELEPHONYRADIOINTERFACE_CID \
   {0xd66e7ece, 0x41b1, 0x4608, {0x82, 0x80, 0x72, 0x50, 0xa6, 0x44, 0xe6, 0x6f}}
 
 
 class nsIXPConnectJSObjectHolder;
+class nsITelephone;
+class nsIWifi;
 
 BEGIN_TELEPHONY_NAMESPACE
 
 class RadioManager : public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
@@ -87,15 +88,19 @@ public:
 
   static already_AddRefed<nsITelephone>
   GetTelephone();
 
 protected:
   RadioManager();
   ~RadioManager();
 
+  nsresult InitTelephone(JSContext *cx);
+  nsresult InitWifi(JSContext *cx);
+
   nsCOMPtr<nsITelephone> mTelephone;
+  nsCOMPtr<nsIWifi> mWifi;
   bool mShutdown;
 };
 
 END_TELEPHONY_NAMESPACE
 
 #endif // mozilla_dom_telephony_radio_h__
--- a/dom/tests/mochitest/bugs/Makefile.in
+++ b/dom/tests/mochitest/bugs/Makefile.in
@@ -147,12 +147,13 @@ include $(topsrcdir)/config/rules.mk
 		test_bug698551.html \
 		test_window_bar.html \
 		file_window_bar.html \
 		test_resize_move_windows.html \
 		test_devicemotion_multiple_listeners.html \
 		devicemotion_outer.html \
 		devicemotion_inner.html \
 		test_bug698061.html \
+		test_bug707749.html \
 		$(NULL)
 
 libs:: 	$(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/bugs/test_bug707749.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=707749
+-->
+<head>
+  <title>Test for Bug 707749</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=707749 ">Mozilla Bug 707749 </a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 707749 **/
+SimpleTest.waitForExplicitFinish();
+function loaded() {
+    $('ifr').contentDocument.open();
+    $('ifr').contentDocument.close();
+    ok(true, "Don't throw an exception from contentDocument.open()");
+    SimpleTest.finish();
+}
+
+</script>
+<iframe id="ifr" onload="loaded()" src="data:text/html,<script>navigator</script>"></iframe>
+</pre>
+</body>
+</html>
+
--- a/dom/tests/mochitest/orientation/Makefile.in
+++ b/dom/tests/mochitest/orientation/Makefile.in
@@ -40,14 +40,15 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir	= dom/tests/mochitest/orientation
 
 include $(DEPTH)/config/autoconf.mk
 
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES	= \
+		bug507902-frame.html \
 		test_bug507902.html \
 		$(NULL)
 
 libs:: 	$(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 
copy from dom/tests/mochitest/orientation/test_bug507902.html
copy to dom/tests/mochitest/orientation/bug507902-frame.html
--- a/dom/tests/mochitest/orientation/test_bug507902.html
+++ b/dom/tests/mochitest/orientation/bug507902-frame.html
@@ -1,38 +1,30 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=507902
--->
 <head>
-  <title>Test for watchPosition </title>
+  <title>Frame for watchPosition </title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=507902">Mozilla Bug 507902</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-  
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
+<script type="text/javascript">
+
+var ok = window.parent.ok;
+var SimpleTest = window.parent.SimpleTest;
 
 function boom()
 {
   window.addEventListener("unload", function(){}, false);
   window.addEventListener("devicemotion", function(){}, false);
   location = "data:text/html,2";
 
   ok(1, "leak will be at the end of mochitests. so pass.");
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 
 window.addEventListener("load", function() { setTimeout(boom, 0); }, false);
 
 </script>
-</pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/orientation/test_bug507902.html
+++ b/dom/tests/mochitest/orientation/test_bug507902.html
@@ -1,38 +1,36 @@
 <!DOCTYPE HTML>
 <html>
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=507902
 -->
 <head>
-  <title>Test for watchPosition </title>
+  <title>Test for devicemotion</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=507902">Mozilla Bug 507902</a>
 <p id="display"></p>
-<div id="content" style="display: none">
-  
+<div id="content">
+<iframe id="frame" src="bug507902-frame.html"></iframe>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 function boom()
 {
   window.addEventListener("unload", function(){}, false);
   window.addEventListener("devicemotion", function(){}, false);
   location = "data:text/html,2";
 
   ok(1, "leak will be at the end of mochitests. so pass.");
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 
-window.addEventListener("load", function() { setTimeout(boom, 0); }, false);
-
 </script>
 </pre>
 </body>
 </html>
 
new file mode 100644
--- /dev/null
+++ b/dom/wifi/Makefile.in
@@ -0,0 +1,70 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Telephony.
+#
+# The Initial Developer of the Original Code is
+#   The Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Ben Turner <bent.mozilla@gmail.com> (Original Author)
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH            = ../..
+topsrcdir        = @top_srcdir@
+srcdir           = @srcdir@
+VPATH            = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE           = dom
+LIBRARY_NAME     = domwifi_s
+XPIDL_MODULE     = dom_wifi
+LIBXUL_LIBRARY   = 1
+FORCE_STATIC_LIB = 1
+
+include $(topsrcdir)/dom/dom-config.mk
+
+XPIDLSRCS = \
+  nsIWifi.idl \
+  $(NULL)
+
+EXTRA_COMPONENTS = \
+  nsWifiWorker.js \
+  nsWifiWorker.manifest \
+  $(NULL)
+
+EXTRA_JS_MODULES = \
+  libcutils.js \
+  libhardware_legacy.js \
+  libnetutils.js \
+  network_worker.js \
+  $(NULL)
+
+include $(topsrcdir)/config/rules.mk
+
new file mode 100644
--- /dev/null
+++ b/dom/wifi/libcutils.js
@@ -0,0 +1,13 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+
+"use strict";
+
+let libcutils = (function () {
+  let library = ctypes.open("/system/lib/libcutils.so");
+
+  return {
+    property_get: library.declare("property_get", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.char.ptr, ctypes.char.ptr),
+    property_set: library.declare("property_set", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.char.ptr)
+  };
+})();
new file mode 100644
--- /dev/null
+++ b/dom/wifi/libhardware_legacy.js
@@ -0,0 +1,36 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+
+"use strict";
+
+let libhardware_legacy = (function () {
+  let library = ctypes.open("/system/lib/libhardware_legacy.so");
+
+  return {
+    // Load wifi driver, 0 on success, < 0 on failure.
+    load_driver: library.declare("wifi_load_driver", ctypes.default_abi, ctypes.int),
+
+    // Unload wifi driver, 0 on success, < 0 on failure.
+    unload_driver: library.declare("wifi_unload_driver", ctypes.default_abi, ctypes.int),
+
+    // Start supplicant, 0 on success, < 0 on failure.
+    start_supplicant: library.declare("wifi_start_supplicant", ctypes.default_abi, ctypes.int),
+
+    // Stop supplicant, 0 on success, < 0 on failure.
+    stop_supplicant: library.declare("wifi_stop_supplicant", ctypes.default_abi, ctypes.int),
+
+    // Open a connection to the supplicant, 0 on success, < 0 on failure.
+    connect_to_supplicant: library.declare("wifi_connect_to_supplicant", ctypes.default_abi, ctypes.int),
+
+    // Close connection to connection to the supplicant, 0 on success, < 0 on failure.
+    close_supplicant_connection: library.declare("wifi_close_supplicant_connection", ctypes.default_abi, ctypes.int),
+
+    // Block until a wifi event is returned, buf is the buffer, len is the max length of the buffer.
+    // Return value is number of bytes in buffer, or 0 if no event (no connection for instance), and < 0 on failure.
+    wait_for_event: library.declare("wifi_wait_for_event", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.size_t),
+
+    // Issue a command to the wifi driver. command is the command string, reply will hold the reply, reply_len contains
+    // the maximum reply length initially and is updated with the actual length. 0 is returned on success, < 0 on failure.
+    command: library.declare("wifi_command", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.char.ptr, ctypes.size_t.ptr),
+  };
+})();
new file mode 100644
--- /dev/null
+++ b/dom/wifi/libnetutils.js
@@ -0,0 +1,30 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+
+"use strict";
+
+let libnetutils = (function () {
+  let library = ctypes.open("/system/lib/libnetutils.so");
+
+  return {
+    ifc_enable: library.declare("ifc_enable", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
+    ifc_disable: library.declare("ifc_disable", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
+    ifc_add_host_route: library.declare("ifc_add_host_route", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.int),
+    ifc_remove_host_routes: library.declare("ifc_remove_host_routes", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
+    ifc_set_default_route: library.declare("ifc_set_default_route", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.int),
+    ifc_get_default_route: library.declare("ifc_get_default_route", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
+    ifc_remove_default_route: library.declare("ifc_remove_default_route", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
+    ifc_reset_connections: library.declare("ifc_reset_connections", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
+    ifc_configure: library.declare("ifc_configure", ctypes.default_abi, ctypes.int, ctypes.char.ptr,
+                                   ctypes.int, ctypes.int, ctypes.int, ctypes.int, ctypes.int),
+    dhcp_do_request: library.declare("dhcp_do_request", ctypes.default_abi, ctypes.int,
+                                     ctypes.char.ptr, ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr,
+                                     ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr),
+    dhcp_stop: library.declare("dhcp_stop", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
+    dhcp_release_lease: library.declare("dhcp_release_lease", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
+    dhcp_get_errmsg: library.declare("dhcp_get_errmsg", ctypes.default_abi, ctypes.char.ptr),
+    dhcp_do_request_renew: library.declare("dhcp_do_request_renew", ctypes.default_abi, ctypes.int,
+                                           ctypes.char.ptr, ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr,
+                                           ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr)
+  };
+})();
new file mode 100644
--- /dev/null
+++ b/dom/wifi/network_worker.js
@@ -0,0 +1,94 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+
+"use strict";
+
+importScripts("libhardware_legacy.js", "libnetutils.js", "libcutils.js");
+
+var cbuf = ctypes.char.array(4096)();
+var hwaddr = ctypes.uint8_t.array(6)();
+var len = ctypes.size_t();
+var ints = ctypes.int.array(8)();
+
+self.onmessage = function(e) {
+  var data = e.data;
+  var id = data.id;
+  var cmd = data.cmd;
+
+  switch (cmd) {
+  case "command":
+    len.value = 4096;
+    var ret = libhardware_legacy.command(data.request, cbuf, len.address());
+    dump("For command " + data.request + " ret is " + ret + "\n");
+    var reply = "";
+    if (!ret) {
+      var reply_len = len.value;
+      var str = cbuf.readString();
+      if (str[reply_len-1] == "\n")
+        --reply_len;
+      reply = str.substr(0, reply_len);
+    }
+    postMessage({ id: id, status: ret, reply: reply });
+    break;
+  case "wait_for_event":
+    var ret = libhardware_legacy.wait_for_event(cbuf, 4096);
+    var event = cbuf.readString().substr(0, ret.value);
+    postMessage({ id: id, event: event });
+    break;
+  case "ifc_enable":
+  case "ifc_disable":
+  case "ifc_remove_host_routes":
+  case "ifc_remove_default_route":
+  case "ifc_reset_connections":
+  case "dhcp_stop":
+  case "dhcp_release_lease":
+    var ret = libnetutils[cmd](data.ifname);
+    postMessage({ id: id, status: ret });
+    break;
+  case "ifc_get_default_route":
+    var route = libnetutils.ifc_get_default_route(data.ifname);
+    postMessage({ id: id, route: route });
+    break;
+  case "ifc_add_host_route":
+  case "ifc_set_default_route":
+    var ret = libnetutils[cmd](data.ifname, data.route);
+    postMessage({ id: id, status: ret });
+    break;
+  case "ifc_configure":
+    dump("WIFI: data: " + uneval(data) + "\n");
+    var ret = libnetutils.ifc_configure(data.ifname, data.ipaddr, data.mask, data.gateway, data.dns1, data.dns2);
+    postMessage({ id: id, status: ret });
+    break;
+  case "dhcp_get_errmsg":
+    var error = libnetutils.get_dhcp_get_errmsg();
+    postMessage({ id: id, error: error.readString() });
+    break;
+  case "dhcp_do_request":
+  case "dhcp_do_request_renew":
+    var ret = libnetutils[cmd](data.ifname,
+                               ints.addressOfElement(0),
+                               ints.addressOfElement(1),
+                               ints.addressOfElement(2),
+                               ints.addressOfElement(3),
+                               ints.addressOfElement(4),
+                               ints.addressOfElement(5),
+                               ints.addressOfElement(6));
+    postMessage({ id: id, status: ret, ipaddr: ints[0], gateway: ints[1], mask: ints[2],
+                  dns1: ints[3], dns2: ints[4], server: ints[5], lease: ints[6]});
+    break;
+  case "property_get":
+    var ret = libcutils.property_get(data.key, cbuf, data.defaultValue);
+    postMessage({ id: id, status: ret, value: cbuf.readString() });
+    break;
+  case "property_set":
+    var ret = libcutils.property_set(data.key, data.value);
+    postMessage({ id: id, status: ret });
+    break;
+  default:
+    var f = libhardware_legacy[cmd] || libnetutils[cmd];
+    var ret = f();
+    dump("WIFI: " + cmd + " returned: " + ret);
+    postMessage({ id: id, status: ret });
+    break;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/dom/wifi/nsIWifi.idl
@@ -0,0 +1,42 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Telephony.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Philipp von Weitershausen <philipp@weitershausen.de>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.idl"
+
+[scriptable, uuid(9DCE05BF-659C-4427-A050-0EAC3BB6C1C0)]
+interface nsIWifi : nsISupports {
+};
new file mode 100644
--- /dev/null
+++ b/dom/wifi/nsWifiWorker.h
@@ -0,0 +1,40 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Telephony.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ben Turner <bent.mozilla@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#define NS_WIFIWORKER_CID \
+{ 0xA14E8977, 0xD259, 0x433A, \
+  { 0xA8, 0x8D, 0x58, 0xDD, 0x44, 0x65, 0x7E, 0x5B } }
new file mode 100644
--- /dev/null
+++ b/dom/wifi/nsWifiWorker.js
@@ -0,0 +1,853 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Telephony.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Andreas Gal <gal@mozilla.com>
+ *   Blake Kaplan <mrbkap@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+"use strict";
+
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const DEBUG = true; // set to false to suppress debug messages
+
+const WIFIWORKER_CONTRACTID = "@mozilla.org/wifi/worker;1";
+const WIFIWORKER_CID        = Components.ID("{a14e8977-d259-433a-a88d-58dd44657e5b}");
+
+const WIFIWORKER_WORKER     = "resource://gre/modules/network_worker.js";
+
+var WifiManager = (function() {
+  var controlWorker = new ChromeWorker(WIFIWORKER_WORKER);
+  var eventWorker = new ChromeWorker(WIFIWORKER_WORKER);
+
+  // Callbacks to invoke when a reply arrives from the controlWorker.
+  var controlCallbacks = Object.create(null);
+  var idgen = 0;
+
+  function controlMessage(obj, callback) {
+    var id = idgen++;
+    obj.id = id;
+    if (callback)
+      controlCallbacks[id] = callback;
+    controlWorker.postMessage(obj);
+  }
+
+  function onerror(e) {
+    // It is very important to call preventDefault on the event here.
+    // If an exception is thrown on the worker, it bubbles out to the
+    // component that created it. If that component doesn't have an
+    // onerror handler, the worker will try to call the error reporter
+    // on the context it was created on. However, That doesn't work
+    // for component contexts and can result in crashes. This onerror
+    // handler has to make sure that it calls preventDefault on the
+    // incoming event.
+    e.preventDefault();
+
+    var worker = (this === controlWorker) ? "control" : "event";
+
+    debug("Got an error from the " + worker + " worker: " + e.filename +
+          ":" + e.lineno + ": " + e.message + "\n");
+  }
+
+  controlWorker.onerror = onerror;
+  eventWorker.onerror = onerror;
+
+  controlWorker.onmessage = function(e) {
+    var data = e.data;
+    var id = data.id;
+    var callback = controlCallbacks[id];
+    if (callback) {
+      callback(data);
+      delete controlCallbacks[id];
+    }
+  };
+
+  // Polling the status worker
+  var recvErrors = 0;
+  eventWorker.onmessage = function(e) {
+    // process the event and tell the event worker to listen for more events
+    if (handleEvent(e.data.event))
+      waitForEvent();
+  };
+
+  function waitForEvent() {
+    eventWorker.postMessage({ cmd: "wait_for_event" });
+  }
+
+  // Commands to the control worker
+
+  function voidControlMessage(cmd, callback) {
+    controlMessage({ cmd: cmd }, function (data) {
+      callback(data.status);
+    });
+  }
+
+  function loadDriver(callback) {
+    voidControlMessage("load_driver", callback);
+  }
+
+  function unloadDriver(callback) {
+    voidControlMessage("unload_driver", callback);
+  }
+
+  function startSupplicant(callback) {
+    voidControlMessage("start_supplicant", callback);
+  }
+
+  function stopSupplicant(callback) {
+    voidControlMessage("stop_supplicant", callback);
+  }
+
+  function connectToSupplicant(callback) {
+    voidControlMessage("connect_to_supplicant", callback);
+  }
+
+  function closeSupplicantConnection(callback) {
+    voidControlMessage("close_supplicant_connection", callback);
+  }
+
+  function doCommand(request, callback) {
+    controlMessage({ cmd: "command", request: request }, callback);
+  }
+
+  function doIntCommand(request, callback) {
+    doCommand(request, function(data) {
+      callback(data.status ? -1 : (data.reply|0));
+    });
+  }
+
+  function doBooleanCommand(request, expected, callback) {
+    doCommand(request, function(data) {
+      callback(data.status ? false : (data.reply == expected));
+    });
+  }
+
+  function doStringCommand(request, callback) {
+    doCommand(request, function(data) {
+      callback(data.status ? null : data.reply);
+    });
+  }
+
+  function listNetworksCommand(callback) {
+    doStringCommand("LIST_NETWORKS", callback);
+  }
+
+  function addNetworkCommand(callback) {
+    doIntCommand("ADD_NETWORK", callback);
+  }
+
+  function setNetworkVariableCommand(netId, name, value, callback) {
+    doBooleanCommand("SET_NETWORK " + netId + " " + name + " " + value, "OK", callback);
+  }
+
+  function getNetworkVariableCommand(netId, name, callback) {
+    doStringCommand("GET_NETWORK " + netId + " " + name, callback);
+  }
+
+  function removeNetworkCommand(netId, callback) {
+    doBooleanCommand("REMOVE_NETWORK " + netId, callback);
+  }
+
+  function enableNetworkCommand(netId, disableOthers, callback) {
+    doBooleanCommand((disableOthers ? "SELECT_NETWORK " : "ENABLE_NETWORK ") + netId, "OK", callback);
+  }
+
+  function disableNetworkCommand(netId, callback) {
+    doBooleanCommand("DISABLE_NETWORK " + netId, "OK", callback);
+  }
+
+  function statusCommand(callback) {
+    doStringCommand("STATUS", callback);
+  }
+
+  function pingCommand(callback) {
+    doBooleanCommand("PING", "PONG", callback);
+  }
+
+  function scanResultsCommand(callback) {
+    doStringCommand("SCAN_RESULTS", callback);
+  }
+
+  function disconnectCommand(callback) {
+    doBooleanCommand("DISCONNECT", "OK", callback);
+  }
+
+  function reconnectCommand(callback) {
+    doBooleanCommand("RECONNECT", "OK", callback);
+  }
+
+  function reassociateCommand(callback) {
+    doBooleanCommand("REASSOCIATE", "OK", callback);
+  }
+
+  var scanModeActive = false;
+
+  function doSetScanModeCommand(setActive, callback) {
+    doBooleanCommand(setActive ? "DRIVER SCAN-ACTIVE" : "DRIVER SCAN-PASSIVE", "OK", callback);
+  }
+
+  function scanCommand(forceActive, callback) {
+    if (forceActive && !scanModeActive) {
+      doSetScanModeCommand(true, function(ok) {
+        ok && doBooleanCommand("SCAN", "OK", function(ok) {
+          ok && doSetScanModeCommand(false, callback);
+        });
+      });
+      return;
+    }
+    doBooleanCommand("SCAN", "OK", callback);
+  }
+
+  function setScanModeCommand(setActive, callback) {
+    sScanModeActive = setActive;
+    doSetScanModeCommand(setActive, callback);
+  }
+
+  function startDriverCommand(callback) {
+    doBooleanCommand("DRIVER START", "OK");
+  }
+
+  function stopDriverCommand(callback) {
+    doBooleanCommand("DRIVER STOP", "OK");
+  }
+
+  function startPacketFiltering(callback) {
+    doBooleanCommand("DRIVER RXFILTER-ADD 0", "OK", function(ok) {
+      ok && doBooleanCommand("DRIVER RXFILTER-ADD 1", "OK", function(ok) {
+        ok && doBooleanCommand("DRIVER RXFILTER-ADD 3", "OK", function(ok) {
+          ok && doBooleanCommand("DRIVER RXFILTER-START", "OK", callback)
+        });
+      });
+    });
+  }
+
+  function stopPacketFiltering(callback) {
+    doBooleanCommand("DRIVER RXFILTER-STOP", "OK", function(ok) {
+      ok && doBooleanCommand("DRIVER RXFILTER-REMOVE 3", "OK", function(ok) {
+        ok && doBooleanCommand("DRIVER RXFILTER-REMOVE 1", "OK", function(ok) {
+          ok && doBooleanCommand("DRIVER RXFILTER-REMOVE 0", "OK", callback)
+        });
+      });
+    });
+  }
+
+  function doGetRssiCommand(cmd, callback) {
+    doCommand(cmd, function(data) {
+      var rssi = -200;
+
+      if (!data.status) {
+        // If we are associating, the reply is "OK".
+        var reply = data.reply;
+        if (reply != "OK") {
+          // Format is: <SSID> rssi XX". SSID can contain spaces.
+          var offset = reply.lastIndexOf("rssi ");
+          if (offset != -1)
+            rssi = reply.substr(offset + 5) | 0;
+        }
+      }
+      callback(rssi);
+    });
+  }
+
+  function getRssiCommand(callback) {
+    doGetRssiCommand("DRIVER RSSI", callback);
+  }
+
+  function getRssiApproxCommand(callback) {
+    doGetRssiCommand("DRIVER RSSI-APPROX", callback);
+  }
+
+  function getLinkSpeedCommand(callback) {
+    doStringCommand("DRIVER LINKSPEED", function(reply) {
+      if (reply)
+        reply = reply.split()[1] | 0; // Format: LinkSpeed XX
+      callback(reply);
+    });
+  }
+
+  function getMacAddressCommand(callback) {
+    doStringCommand("DRIVER MACADDR", function(reply) {
+      if (reply)
+        reply = reply.split(" ")[2]; // Format: Macaddr = XX.XX.XX.XX.XX.XX
+      callback(reply);
+    });
+  }
+
+  function setPowerModeCommand(mode, callback) {
+    doBooleanCommand("DRIVER POWERMODE " + mode, "OK", callback);
+  }
+
+  function getPowerModeCommand(callback) {
+    doStringCommand("DRIVER GETPOWER", function(reply) {
+      if (reply)
+        reply = (reply.split()[2]|0); // Format: powermode = XX
+      callback(reply);
+    });
+  }
+
+  function setNumAllowedChannelsCommand(numChannels, callback) {
+    doBooleanCommand("DRIVER SCAN-CHANNELS " + numChannels, "OK", callback);
+  }
+
+  function getNumAllowedChannelsCommand(callback) {
+    doStringCommand("DRIVER SCAN-CHANNELS", function(reply) {
+      if (reply)
+        reply = (reply.split()[2]|0); // Format: Scan-Channels = X
+      callback(reply);
+    });
+  }
+
+  function setBluetoothCoexistenceModeCommand(mode, callback) {
+    doBooleanCommand("DRIVER BTCOEXMODE " + mode, "OK", callback);
+  }
+
+  function setBluetoothCoexistenceScanModeCommand(mode, callback) {
+    doBooleanCommand("DRIVER BTCOEXSCAN-" + (mode ? "START" : "STOP"), "OK", callback);
+  }
+
+  function saveConfigCommand(callback) {
+    // Make sure we never write out a value for AP_SCAN other than 1
+    doBooleanCommand("AP_SCAN 1", "OK", function(ok) {
+      doBooleanCommand("SAVE_CONFIG", "OK", callback);
+    });
+  }
+
+  function reloadConfigCommand(callback) {
+    doBooleanCommand("RECONFIGURE", "OK", callback);
+  }
+
+  function setScanResultHandlingCommand(mode, callback) {
+    doBooleanCommand("AP_SCAN " + mode, "OK", callback);
+  }
+
+  function addToBlacklistCommand(bssid, callback) {
+    doBooleanCommand("BLACKLIST " + bssid, "OK", callback);
+  }
+
+  function clearBlacklistCommand(callback) {
+    doBooleanCommand("BLACKLIST clear", "OK", callback);
+  }
+
+  function setSuspendOptimizationsCommand(enabled, callback) {
+    doBooleanCommand("DRIVER SETSUSPENDOPT " + (enabled ? 0 : 1), "OK", callback);
+  }
+
+  function getProperty(key, defaultValue, callback) {
+    controlMessage({ cmd: "property_get", key: key, defaultValue: defaultValue }, function(data) {
+      callback(data.status < 0 ? null : data.value);
+    });
+  }
+
+  function setProperty(key, value, callback) {
+    controlMessage({ cmd: "property_set", key: key, value: value }, function(data) {
+      callback(!data.status);
+    });
+  }
+
+  function enableInterface(ifname, callback) {
+    controlMessage({ cmd: "ifc_enable", ifname: ifname }, function(data) {
+      callback(!data.status);
+    });
+  }
+
+  function disableInterface(ifname, callback) {
+    controlMessage({ cmd: "ifc_disable", ifname: ifname }, function(data) {
+      callback(!data.status);
+    });
+  }
+
+  function addHostRoute(ifname, route, callback) {
+    controlMessage({ cmd: "ifc_add_host_route", ifname: ifname, route: route }, function(data) {
+      callback(!data.status);
+    });
+  }
+
+  function removeHostRoutes(ifname, callback) {
+    controlMessage({ cmd: "ifc_remove_host_routes", ifname: ifname }, function(data) {
+      callback(!data.status);
+    });
+  }
+
+  function setDefaultRoute(ifname, route, callback) {
+    controlMessage({ cmd: "ifc_set_default_route", ifname: ifname, route: route }, function(data) {
+      callback(!data.status);
+    });
+  }
+
+  function getDefaultRoute(ifname, callback) {
+    controlMessage({ cmd: "ifc_get_default_route", ifname: ifname }, function(data) {
+      callback(!data.route);
+    });
+  }
+
+  function removeDefaultRoute(ifname, callback) {
+    controlMessage({ cmd: "ifc_remove_default_route", ifname: ifname }, function(data) {
+      callback(!data.status);
+    });
+  }
+
+  function resetConnections(ifname, callback) {
+    controlMessage({ cmd: "ifc_reset_connections", ifname: ifname }, function(data) {
+      callback(!data.status);
+    });
+  }
+
+  function runDhcp(ifname, callback) {
+    controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) {
+      callback(data.status ? null : data);
+    });
+  }
+
+  function stopDhcp(ifname, callback) {
+    controlMessage({ cmd: "dhcp_stop", ifname: ifname }, function(data) {
+      callback(!data.status);
+    });
+  }
+
+  function releaseDhcpLease(ifname, callback) {
+    controlMessage({ cmd: "dhcp_release_lease", ifname: ifname }, function(data) {
+      callback(!data.status);
+    });
+  }
+
+  function getDhcpError(callback) {
+    controlMessage({ cmd: "dhcp_get_errmsg" }, function(data) {
+      callback(data.error);
+    });
+  }
+
+  function configureInterface(ifname, ipaddr, mask, gateway, dns1, dns2, callback) {
+    controlMessage({ cmd: "ifc_configure", ifname: ifname,
+                     ipaddr: ipaddr, mask: mask, gateway: gateway,
+                     dns1: dns1, dns2: dns2}, function(data) {
+      callback(!data.status);
+    });
+  }
+
+  function runDhcpRenew(ifname, callback) {
+    controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) {
+      callback(data.status ? null : data);
+    });
+  }
+
+  var manager = {};
+
+  function notify(eventName, eventObject) {
+    var handler = manager["on" + eventName];
+    if (handler) {
+      if (!eventObject)
+        eventObject = ({});
+      handler.call(eventObject);
+    }
+  }
+
+  // try to connect to the supplicant
+  var connectTries = 0;
+  var retryTimer = null;
+  function connectCallback(ok) {
+    if (ok === 0) {
+      // tell the event worker to start waiting for events
+      retryTimer = null;
+      waitForEvent();
+      notify("supplicantconnection");
+      return;
+    }
+    if (connectTries++ < 3) {
+      // try again in 5 seconds
+      if (!retryTimer)
+        retryTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+
+      retryTimer.initWithCallback(function(timer) {
+          connectToSupplicant(connectCallback);
+        }, 5000, Ci.nsITimer.TYPE_ONE_SHOT);
+      return;
+    }
+
+    retryTimer = null;
+    notify("supplicantlost");
+  }
+
+  manager.start = function() {
+    connectToSupplicant(connectCallback);
+  }
+
+  var supplicantStatesMap = ["DISCONNECTED", "INACTIVE", "SCANNING", "ASSOCIATING",
+                             "FOUR_WAY_HANDSHAKE", "GROUP_HANDSHAKE", "COMPLETED",
+                             "DORMANT", "UNINITIALIZED"];
+  var driverEventMap = { STOPPED: "driverstopped", STARTED: "driverstarted", HANGED: "driverhung" };
+
+  // handle events sent to us by the event worker
+  function handleEvent(event) {
+    debug("Event coming in: " + event);
+    if (event.indexOf("CTRL-EVENT-") !== 0) {
+      debug("Got weird event, possibly not doing anything.");
+      if (event.indexOf("WPA:") == 0 &&
+          event.indexOf("pre-shared key may be incorrect") != -1) {
+        notify("passwordmaybeincorrect");
+      }
+      return true;
+    }
+
+    var eventData = event.substr(0, event.indexOf(" ") + 1);
+    if (eventData.indexOf("CTRL-EVENT-STATE-CHANGE") === 0) {
+      // Parse the event data
+      var fields = {};
+      var tokens = eventData.split(" ");
+      for (var n = 0; n < tokens.length; ++n) {
+        var kv = tokens[n].split("=");
+        if (kv.length === 2)
+          fields[kv[0]] = kv[1];
+      }
+      if (!("state" in fields))
+        return true;
+      fields.state = supplicantStatesMap[fields.state];
+      notify("statechange", fields);
+      return true;
+    }
+    if (eventData.indexOf("CTRL-EVENT-DRIVER-STATE") === 0) {
+      var handlerName = driverEventMap[eventData];
+      if (handlerName)
+        notify(handlerName);
+      return true;
+    }
+    if (eventData.indexOf("CTRL-EVENT-TERMINATING") === 0) {
+      // If the monitor socket is closed, we have already stopped the
+      // supplicant and we can stop waiting for more events and
+      // simply exit here (we don't have to notify).
+      if (eventData.indexOf("connection closed") !== -1)
+        return false;
+
+      // As long we haven't seen too many recv errors yet, we
+      // will keep going for a bit longer
+      if (eventData.indexOf("recv error") !== -1 && ++recvErrors < 10)
+        return true;
+
+      notify("supplicantlost");
+      return false;
+    }
+    if (eventData.indexOf("CTRL-EVENT-DISCONNECTED") === 0) {
+      notify("statechange", { state: "DISCONNECTED" });
+      return true;
+    }
+    if (eventData.indexOf("CTRL-EVENT-CONNECTED") === 0) {
+      // Format: CTRL-EVENT-CONNECTED - Connection to 00:1e:58:ec:d5:6d completed (reauth) [id=1 id_str=]
+      var bssid = eventData.split(" ")[4];
+      var id = eventData.substr(eventData.indexOf("id=")).split(" ")[0];
+      notify("statechange", { state: "CONNECTED", BSSID: bssid, id: id });
+      return true;
+    }
+    if (eventData.indexOf("CTRL-EVENT-SCAN-RESULTS") === 0) {
+      debug("Notifying of scn results available");
+      notify("scanresultsavailable");
+      return true;
+    }
+    // unknown event
+    return true;
+  }
+
+  // Initial state
+  var airplaneMode = false;
+
+  // Public interface of the wifi service
+  manager.setWifiEnabled = function(enable, callback) {
+    var targetState = enable ? "ENABLED" : "DISABLED";
+    if (enable == targetState)
+      return true;
+    if (enable && airplaneMode)
+      return false;
+    if (enable) {
+      loadDriver(function (ok) {
+        (ok === 0) ? startSupplicant(callback) : callback(-1);
+      });
+    } else {
+      stopSupplicant(function (ok) {
+        (ok === 0) ? unloadDriver(callback) : callback(-1);
+      });
+    }
+  }
+
+  manager.disconnect = disconnectCommand;
+  manager.reconnect = reconnectCommand;
+  manager.reassociate = reassociateCommand;
+
+  var networkConfigurationFields = ["ssid", "bssid", "psk", "wep_key0", "wep_key1", "wep_key2", "wep_key3",
+                                    "wep_tx_keyidx", "priority", "key_mgmt", "scan_ssid"];
+
+  manager.getNetworkConfiguration = function(config, callback) {
+    var netId = config.netId;
+    var done = 0;
+    for (var n = 0; n < networkConfigurationFields; ++n) {
+      var fieldName = networkConfigurationFields[n];
+      getNetworkVariableCommand(netId, fieldName, function(value) {
+        config[fieldName] = value;
+        if (++done == networkConfigurationFields.length)
+          callback(config);
+      });
+    }
+  }
+  manager.setNetworkConfiguration = function(config, callback) {
+    var netId = config.netId;
+    var done = 0;
+    var errors = 0;
+    for (var n = 0; n < networkConfigurationFields.length; ++n) {
+      var fieldName = networkConfigurationFields[n];
+      if (!(fieldName in config)) {
+        ++done;
+      } else {
+        setNetworkVariableCommand(netId, fieldName, config[fieldName], function(ok) {
+          if (!ok)
+            ++errors;
+          if (++done == networkConfigurationFields.length)
+            callback(errors == 0);
+        });
+      }
+    }
+    // If config didn't contain any of the fields we want, don't lose the error callback
+    if (done == networkConfigurationFields.length)
+      callback(false);
+  }
+  manager.getConfiguredNetworks = function(callback) {
+    listNetworksCommand(function (reply) {
+      var networks = {};
+      var done = 0;
+      var errors = 0;
+      var lines = reply.split("\n");
+      for (var n = 1; n < lines.length; ++n) {
+        var result = lines[n].split("\t");
+        var netId = result[0];
+        var config = networks[netId] = { netId: netId };
+        switch (result[3]) {
+        case "[CURRENT]":
+          config.status = "CURRENT";
+          break;
+        case "[DISABLED]":
+          config.status = "DISABLED";
+          break;
+        default:
+          config.status = "ENABLED";
+          break;
+        }
+        manager.getNetworkConfiguration(config, function (ok) {
+            if (!ok)
+              ++errors;
+            if (++done == lines.length - 1) {
+              if (errors) {
+                // If an error occured, delete the new netId
+                removeNetworkCommand(netId, function() {
+                  callback(null);
+                });
+              } else {
+                callback(networks);
+              }
+            }
+        });
+      }
+    });
+  }
+  manager.addNetwork = function(config, callback) {
+    addNetworkCommand(function (netId) {
+      config.netId = netId;
+      manager.setNetworkConfiguration(config, callback);
+    });
+  }
+  manager.updateNetwork = function(config, callback) {
+    manager.setNetworkConfiguration(config, callback);
+  }
+  manager.removeNetwork = function(netId, callback) {
+    removeNetworkCommand(netId, callback);
+  }
+
+  function ipToString(n) {
+    return String((n & (0xff << 24)) >> 24) + "." +
+                 ((n & (0xff << 16)) >> 16) + "." +
+                 ((n & (0xff <<  8)) >>  8) + "." +
+                 ((n & (0xff <<  0)) >>  0);
+  }
+
+  manager.enableNetwork = function(netId, disableOthers, callback) {
+    getProperty("wifi.interface", "tiwlan0", function (ifname) {
+      if (!ifname) {
+        callback(false);
+        return;
+      }
+      enableInterface(ifname, function (ok) {
+        if (!ok) {
+          callback(false);
+          return;
+        }
+        enableNetworkCommand(netId, disableOthers, function (ok) {
+          if (!ok) {
+            disableInterface(ifname, function () {
+              callback(false);
+            });
+            return;
+          }
+          runDhcp(ifname, function (data) {
+            debug("After running dhcp, got data: " + uneval(data));
+            if (!data) {
+              disableInterface(ifname, function() {
+                callback(false);
+              });
+              return;
+            }
+            setProperty("net.dns1", ipToString(data.dns1), function(ok) {
+              if (!ok) {
+                callback(false);
+                return;
+              }
+              getProperty("net.dnschange", "0", function(value) {
+                if (value === null) {
+                  callback(false);
+                  return;
+                }
+                setProperty("net.dnschange", String(Number(value) + 1), function(ok) {
+                  callback(ok);
+                });
+              });
+            });
+          });
+        });
+      });
+    });
+  }
+  manager.disableNetwork = function(netId, callback) {
+    disableNetworkCommand(netId, callback);
+  }
+  manager.getMacAddress = getMacAddressCommand;
+  manager.getScanResults = scanResultsCommand;
+  return manager;
+})();
+
+function nsWifiWorker() {
+  WifiManager.onsupplicantconnection = function() {
+    debug("Connected to supplicant");
+    WifiManager.getMacAddress(function (mac) {
+      debug("Got mac: " + mac);
+    });
+  }
+  WifiManager.onsupplicantlost = function() {
+    debug("Couldn't connect to supplicant");
+  }
+
+  var networks = Object.create(null);
+  WifiManager.onscanresultsavailable = function() {
+    debug("Scan results are available! Asking for them.");
+    if (networks["Mozilla Guest"])
+      return;
+    WifiManager.getScanResults(function(r) {
+      let lines = r.split("\n");
+      // NB: Skip the header line.
+      let added = !("Mozilla Guest" in networks);
+      for (let i = 1; i < lines.length; ++i) {
+        // bssid / frequency / signal level / flags / ssid
+        var match = /([\S]+)\s+([\S]+)\s+([\S]+)\s+(\[[\S]+\])?\s+(.*)/.exec(lines[i])
+        if (match)
+          networks[match[5]] = match[1];
+        else
+          debug("Match didn't find anything for: " + lines[i]);
+      }
+
+      if (("Mozilla Guest" in networks) && added) {
+        debug("Mozilla Guest exists in networks, trying to connect!");
+        var config = Object.create(null);
+        config["ssid"] = '"Mozilla Guest"';
+        //config["bssid"] = '"' + networks["Mozilla Guest"] + '"';
+        config["key_mgmt"] = "NONE";
+        config["scan_ssid"] = 1;
+        WifiManager.addNetwork(config, function (ok) {
+          if (ok) {
+            WifiManager.enableNetwork(config.netId, false, function (ok) {
+              if (ok)
+                debug("Enabled the network!");
+              else
+                debug("Failed to enable the network :(");
+            });
+          } else {
+            debug("Failed to add the network :(");
+          }
+        });
+      }
+    });
+  }
+
+  WifiManager.setWifiEnabled(true, function (ok) {
+      if (ok === 0)
+        WifiManager.start();
+      else
+        debug("Couldn't start Wifi");
+    });
+
+  debug("Wifi starting");
+}
+
+nsWifiWorker.prototype = {
+  classID:   WIFIWORKER_CID,
+  classInfo: XPCOMUtils.generateCI({classID: WIFIWORKER_CID,
+                                    contractID: WIFIWORKER_CONTRACTID,
+                                    classDescription: "WifiWorker",
+                                    interfaces: [Ci.nsIRadioWorker,
+                                                 Ci.nsIWifi]}),
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIRadioWorker,
+                                         Ci.nsIWifi]),
+
+  setWifiEnabled: function(enable) {
+    WifiManager.setWifiEnabled(enable, function (ok) {
+      debug(ok);
+    });
+  },
+
+  // This is a bit ugly, but works. In particular, this depends on the fact
+  // that RadioManager never actually tries to get the worker from us.
+  get worker() { throw "Not implemented"; },
+
+  shutdown: function() {
+    this.setWifiEnabled(false);
+  }
+};
+
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([nsWifiWorker]);
+
+let debug;
+if (DEBUG) {
+  debug = function (s) {
+    dump("-*- nsWifiWorker component: " + s + "\n");
+  };
+} else {
+  debug = function (s) {};
+}
new file mode 100644
--- /dev/null
+++ b/dom/wifi/nsWifiWorker.manifest
@@ -0,0 +1,1 @@
+component {a14e8977-d259-433a-a88d-58dd44657e5b} nsWifiWorker.js
--- a/dom/workers/FileReaderSync.cpp
+++ b/dom/workers/FileReaderSync.cpp
@@ -41,17 +41,16 @@
 
 #include "nsIDOMFile.h"
 
 #include "jsapi.h"
 #include "jsatom.h"
 #include "jscntxt.h"
 #include "jstypedarray.h"
 #include "nsJSUtils.h"
-#include "xpcprivate.h"
 
 #include "Exceptions.h"
 #include "File.h"
 #include "FileReaderSyncPrivate.h"
 #include "WorkerInlines.h"
 
 #define FUNCTION_FLAGS \
   JSPROP_ENUMERATE
--- a/dom/workers/Makefile.in
+++ b/dom/workers/Makefile.in
@@ -72,17 +72,16 @@ CPPSRCS = \
   XMLHttpRequest.cpp \
   XMLHttpRequestPrivate.cpp \
   $(NULL)
 
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/content/base/src \
   -I$(topsrcdir)/content/events/src \
   -I$(topsrcdir)/dom/base \
-  -I$(topsrcdir)/js/xpconnect/src \
   -I$(topsrcdir)/xpcom/build \
   $(NULL)
 
 ifdef ENABLE_TESTS
 DIRS += test
 endif
 
 include $(topsrcdir)/config/rules.mk
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -37,20 +37,21 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Util.h"
 
 #include "WorkerScope.h"
 
 #include "jsapi.h"
+#include "jsdbgapi.h"
 #include "jscntxt.h"
 
 #include "nsTraceRefcnt.h"
-#include "xpcprivate.h"
+#include "xpcpublic.h"
 
 #include "ChromeWorkerScope.h"
 #include "Events.h"
 #include "EventTarget.h"
 #include "Exceptions.h"
 #include "File.h"
 #include "FileReaderSync.h"
 #include "ListenerManager.h"
@@ -543,17 +544,17 @@ private:
     }
 
     jsval string;
     if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", &string)) {
       return false;
     }
 
     jsval result;
-    if (!nsXPConnect::Base64Decode(aCx, string, &result)) {
+    if (!xpc::Base64Decode(aCx, string, &result)) {
       return false;
     }
 
     JS_SET_RVAL(aCx, aVp, result);
     return true;
   }
 
   static JSBool
@@ -569,17 +570,17 @@ private:
     }
 
     jsval binary;
     if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", &binary)) {
       return false;
     }
 
     jsval result;
-    if (!nsXPConnect::Base64Encode(aCx, binary, &result)) {
+    if (!xpc::Base64Encode(aCx, binary, &result)) {
       return false;
     }
 
     JS_SET_RVAL(aCx, aVp, result);
     return true;
   }
 };
 
--- a/extensions/spellcheck/hunspell/src/README.hunspell
+++ b/extensions/spellcheck/hunspell/src/README.hunspell
@@ -31,17 +31,17 @@
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 ******* END LICENSE BLOCK *******
 
 Hunspell Version:   1.3.2
-Additional Patches: Bug 710967
+Additional Patches: 694002, 710967
 
 Hunspell Author: Lszl Nmeth
 MySpell Author: Kevin Hendricks & David Einstein
 
 Hunspell is a spell checker and morphological analyser library. Hunspell
 is based on OpenOffice.org's Myspell. Documentation, tests, and examples
 are available at http://hunspell.sourceforge.net.
 
--- a/extensions/spellcheck/hunspell/src/affentry.cpp
+++ b/extensions/spellcheck/hunspell/src/affentry.cpp
@@ -462,17 +462,19 @@ SfxEntry::SfxEntry(AffixMgr * pmgr, affe
   numconds = dp->numconds;   // length of the condition
   opts = dp->opts;           // cross product flag
 
   // then copy over all of the conditions
   if (opts & aeLONGCOND) {
     memcpy(c.l.conds1, dp->c.l.conds1, MAXCONDLEN_1);
     c.l.conds2 = dp->c.l.conds2;
   } else memcpy(c.conds, dp->c.conds, MAXCONDLEN);
-
+  next = NULL;
+  nextne = NULL;
+  nexteq = NULL;
   rappnd = myrevstrdup(appnd);
   morphcode = dp->morphcode;
   contclass = dp->contclass;
   contclasslen = dp->contclasslen;
 }
 
 
 SfxEntry::~SfxEntry()
--- a/extensions/spellcheck/src/mozPersonalDictionary.cpp
+++ b/extensions/spellcheck/src/mozPersonalDictionary.cpp
@@ -162,17 +162,17 @@ NS_IMETHODIMP mozPersonalDictionary::Loa
   
   return res;
 }
 
 // A little helper function to add the key to the list.
 // This is not threadsafe, and only safe if the consumer does not 
 // modify the list.
 static PLDHashOperator
-AddHostToStringArray(nsUniCharEntry *aEntry, void *aArg)
+AddHostToStringArray(nsUnicharPtrHashKey *aEntry, void *aArg)
 {
   static_cast<nsTArray<nsString>*>(aArg)->AppendElement(nsDependentString(aEntry->GetKey()));
   return PL_DHASH_NEXT;
 }
 
 /* void Save (); */
 NS_IMETHODIMP mozPersonalDictionary::Save()
 {
--- a/extensions/spellcheck/src/mozPersonalDictionary.h
+++ b/extensions/spellcheck/src/mozPersonalDictionary.h
@@ -43,70 +43,39 @@
 #include "nsVoidArray.h"
 #include "mozIPersonalDictionary.h"
 #include "nsIUnicodeEncoder.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 #include "nsTHashtable.h"
 #include "nsCRT.h"
 #include "nsCycleCollectionParticipant.h"
+#include "nsHashKeys.h"
 
 #define MOZ_PERSONALDICTIONARY_CONTRACTID "@mozilla.org/spellchecker/personaldictionary;1"
 #define MOZ_PERSONALDICTIONARY_CID         \
 { /* 7EF52EAF-B7E1-462B-87E2-5D1DBACA9048 */  \
 0X7EF52EAF, 0XB7E1, 0X462B, \
   { 0X87, 0XE2, 0X5D, 0X1D, 0XBA, 0XCA, 0X90, 0X48 } }
 
-class nsUniCharEntry : public PLDHashEntryHdr
-{
-public:
-  // Hash methods
-  typedef const PRUnichar* KeyType;
-  typedef const PRUnichar* KeyTypePointer;
-
-  nsUniCharEntry(const PRUnichar* aKey) : mKey(nsCRT::strdup(aKey)) {}
-  nsUniCharEntry(const nsUniCharEntry& toCopy)
-  { 
-    NS_NOTREACHED("ALLOW_MEMMOVE is set, so copy ctor shouldn't be called");
-  }
-
-  ~nsUniCharEntry()
-  { 
-    if (mKey)
-      nsCRT::free(mKey);
-  }
- 
-  KeyType GetKey() const { return mKey; }
-  bool KeyEquals(KeyTypePointer aKey) const { return !nsCRT::strcmp(mKey, aKey); }
-  static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
-
-  static PLDHashNumber HashKey(KeyTypePointer aKey) { return nsCRT::HashCode(aKey); }
-
-  enum { ALLOW_MEMMOVE = true };
-
-private:
-  PRUnichar *mKey;
-};
-
-
-class mozPersonalDictionary : public mozIPersonalDictionary, 
+class mozPersonalDictionary : public mozIPersonalDictionary,
                               public nsIObserver,
                               public nsSupportsWeakReference
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_MOZIPERSONALDICTIONARY
   NS_DECL_NSIOBSERVER
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(mozPersonalDictionary, mozIPersonalDictionary)
 
   mozPersonalDictionary();
   virtual ~mozPersonalDictionary();
 
   nsresult Init();
 
 protected:
   bool           mDirty;       /* has the dictionary been modified */
-  nsTHashtable<nsUniCharEntry> mDictionaryTable;
-  nsTHashtable<nsUniCharEntry> mIgnoreTable;
+  nsTHashtable<nsUnicharPtrHashKey> mDictionaryTable;
+  nsTHashtable<nsUnicharPtrHashKey> mIgnoreTable;
   nsCOMPtr<nsIUnicodeEncoder>  mEncoder; /*Encoder to use to compare with spellchecker word */
 };
 
 #endif
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -143,23 +143,29 @@ struct StrokeOptions {
   CapStyle mLineCap : 3;
 };
 
 /*
  * This structure supplies additional options for calls to DrawSurface.
  *
  * mFilter - Filter used when resampling source surface region to the
  *           destination region.
+ * aSamplingBounds - This indicates whether the implementation is allowed
+ *                   to sample pixels outside the source rectangle as
+ *                   specified in DrawSurface on the surface.
  */
 struct DrawSurfaceOptions {
-  DrawSurfaceOptions(Filter aFilter = FILTER_LINEAR)
+  DrawSurfaceOptions(Filter aFilter = FILTER_LINEAR,
+                     SamplingBounds aSamplingBounds = SAMPLING_UNBOUNDED)
     : mFilter(aFilter)
+    , mSamplingBounds(aSamplingBounds)
   { }
 
   Filter mFilter : 3;
+  SamplingBounds mSamplingBounds : 1;
 };
 
 /*
  * This class is used to store gradient stops, it can only be used with a
  * matching DrawTarget. Not adhering to this condition will make a draw call
  * fail.
  */
 class GradientStops : public RefCounted<GradientStops>
@@ -207,89 +213,109 @@ public:
  * stored in a separate object and are backend dependent. This class itself
  * may be used on the stack.
  */
 class LinearGradientPattern : public Pattern
 {
 public:
   /*
    * aBegin Start of the linear gradient
-   * aEnd End of the linear gradient
+   * aEnd End of the linear gradient - NOTE: In the case of a zero length
+   *      gradient it will act as the color of the last stop.
    * aStops GradientStops object for this gradient, this should match the
    *        backend type of the draw target this pattern will be used with.
+   * aMatrix A matrix that transforms the pattern into user space
    */
   LinearGradientPattern(const Point &aBegin,
                         const Point &aEnd,
-                        GradientStops *aStops)
+                        GradientStops *aStops,
+                        const Matrix &aMatrix = Matrix())
     : mBegin(aBegin)
     , mEnd(aEnd)
     , mStops(aStops)
+    , mMatrix(aMatrix)
   {
   }
 
   virtual PatternType GetType() const { return PATTERN_LINEAR_GRADIENT; }
 
   Point mBegin;
   Point mEnd;
   RefPtr<GradientStops> mStops;
+  Matrix mMatrix;
 };
 
 /*
  * This class is used for Radial Gradient Patterns, the gradient stops are
  * stored in a separate object and are backend dependent. This class itself
  * may be used on the stack.
  */
 class RadialGradientPattern : public Pattern
 {
 public:
   /*
    * aBegin Start of the linear gradient
    * aEnd End of the linear gradient
    * aStops GradientStops object for this gradient, this should match the
    *        backend type of the draw target this pattern will be used with.
+   * aMatrix A matrix that transforms the pattern into user space
    */
   RadialGradientPattern(const Point &aCenter1,
                         const Point &aCenter2,
                         Float aRadius1,
                         Float aRadius2,
-                        GradientStops *aStops)
+                        GradientStops *aStops,
+                        const Matrix &aMatrix = Matrix())
     : mCenter1(aCenter1)
     , mCenter2(aCenter2)
     , mRadius1(aRadius1)
     , mRadius2(aRadius2)
     , mStops(aStops)
+    , mMatrix(aMatrix)
   {
   }
 
   virtual PatternType GetType() const { return PATTERN_RADIAL_GRADIENT; }
 
   Point mCenter1;
   Point mCenter2;
   Float mRadius1;
   Float mRadius2;
   RefPtr<GradientStops> mStops;
+  Matrix mMatrix;
 };
 
 /*
  * This class is used for Surface Patterns, they wrap a surface and a
  * repetition mode for the surface. This may be used on the stack.
  */
 class SurfacePattern : public Pattern
 {
 public:
-  SurfacePattern(SourceSurface *aSourceSurface, ExtendMode aExtendMode)
+  /*
+   * aSourceSurface Surface to use for drawing
+   * aExtendMode This determines how the image is extended outside the bounds
+   *             of the image.
+   * aMatrix A matrix that transforms the pattern into user space
+   * aFilter Resampling filter used for resampling the image.
+   */
+  SurfacePattern(SourceSurface *aSourceSurface, ExtendMode aExtendMode,
+                 const Matrix &aMatrix = Matrix(), Filter aFilter = FILTER_LINEAR)
     : mSurface(aSourceSurface)
     , mExtendMode(aExtendMode)
+    , mFilter(aFilter)
+    , mMatrix(aMatrix)
   {}
 
   virtual PatternType GetType() const { return PATTERN_SURFACE; }
 
   RefPtr<SourceSurface> mSurface;
   ExtendMode mExtendMode;
   Filter mFilter;
+  Matrix mMatrix;
 };
 
 /*
  * This is the base class for source surfaces. These objects are surfaces
  * which may be used as a source in a SurfacePattern of a DrawSurface call.
  * They cannot be drawn to directly.
  */
 class SourceSurface : public RefCounted<SourceSurface>
@@ -306,24 +332,31 @@ public:
    * DataSourceSurface's data can be accessed directly.
    */
   virtual TemporaryRef<DataSourceSurface> GetDataSurface() = 0;
 };
 
 class DataSourceSurface : public SourceSurface
 {
 public:
+  virtual SurfaceType GetType() const { return SURFACE_DATA; }
   /* Get the raw bitmap data of the surface */
   virtual unsigned char *GetData() = 0;
   /*
    * Stride of the surface, distance in bytes between the start of the image
    * data belonging to row y and row y+1. This may be negative.
    */
   virtual int32_t Stride() = 0;
 
+  /*
+   * This function is called after modifying the data on the source surface
+   * directly through the data pointer.
+   */
+  virtual void MarkDirty() {}
+
   virtual TemporaryRef<DataSourceSurface> GetDataSurface() { RefPtr<DataSourceSurface> temp = this; return temp.forget(); }
 };
 
 /* This is an abstract object that accepts path segments. */
 class PathSink : public RefCounted<PathSink>
 {
 public:
   virtual ~PathSink() {}
@@ -602,37 +635,58 @@ public:
    * Fill a series of clyphs on the draw target with a certain source pattern.
    */
   virtual void FillGlyphs(ScaledFont *aFont,
                           const GlyphBuffer &aBuffer,
                           const Pattern &aPattern,
                           const DrawOptions &aOptions = DrawOptions()) = 0;
 
   /*
+   * This takes a source pattern and a mask, and composites the source pattern
+   * onto the destination surface using the alpha channel of the mask pattern
+   * as a mask for the operation.
+   *
+   * aSource Source pattern
+   * aMask Mask pattern
+   * aOptions Drawing options
+   */
+  virtual void Mask(const Pattern &aSource,
+                    const Pattern &aMask,
+                    const DrawOptions &aOptions = DrawOptions()) = 0;
+
+  /*
    * Push a clip to the DrawTarget.
    *
    * aPath The path to clip to
    */
   virtual void PushClip(const Path *aPath) = 0;
 
+  /*
+   * Push an axis-aligned rectangular clip to the DrawTarget. This rectangle
+   * is specified in user space.
+   *
+   * aRect The rect to clip to
+   */
+  virtual void PushClipRect(const Rect &aRect) = 0;
+
   /* Pop a clip from the DrawTarget. A pop without a corresponding push will
    * be ignored.
    */
   virtual void PopClip() = 0;
 
   /*
    * Create a SourceSurface optimized for use with this DrawTarget from
    * existing bitmap data in memory.
    *
    * The SourceSurface does not take ownership of aData, and may be freed at any time.
    */
   virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
-                                                            const IntSize &aSize,
-                                                            int32_t aStride,
-                                                            SurfaceFormat aFormat) const = 0;
+                                                                  const IntSize &aSize,
+                                                                  int32_t aStride,
+                                                                  SurfaceFormat aFormat) const = 0;
 
   /*
    * Create a SourceSurface optimized for use with this DrawTarget from
    * an arbitrary other SourceSurface. This may return aSourceSurface or some
    * other existing surface.
    */
   virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const = 0;
 
@@ -661,18 +715,23 @@ public:
 
   /*
    * Create a GradientStops object that holds information about a set of
    * gradient stops, this object is required for linear or radial gradient
    * patterns to represent the color stops in the gradient.
    *
    * aStops An array of gradient stops
    * aNumStops Number of stops in the array aStops
+   * aExtendNone This describes how to extend the stop color outside of the
+   *             gradient area.
    */
-  virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const = 0;
+  virtual TemporaryRef<GradientStops>
+    CreateGradientStops(GradientStop *aStops,
+                        uint32_t aNumStops,
+                        ExtendMode aExtendMode = EXTEND_CLAMP) const = 0;
 
   const Matrix &GetTransform() const { return mTransform; }
 
   /*
    * Set a transform on the surface, this transform is applied at drawing time
    * to both the mask and source of the operation.
    */
   virtual void SetTransform(const Matrix &aTransform)
@@ -690,22 +749,44 @@ protected:
   bool mTransformDirty : 1;
 
   SurfaceFormat mFormat;
 };
 
 class Factory
 {
 public:
-#ifdef USE_CAIRO
   static TemporaryRef<DrawTarget> CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface);
-#endif
+
+  static TemporaryRef<DrawTarget>
+    CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat);
+  
+  static TemporaryRef<DrawTarget>
+    CreateDrawTargetForData(BackendType aBackend, unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
+
+  static TemporaryRef<ScaledFont>
+    CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize);
 
-  static TemporaryRef<DrawTarget> CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat);
-  static TemporaryRef<ScaledFont> CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize);
+  /*
+   * This creates a simple data source surface for a certain size. It allocates
+   * new memory for the surface. This memory is freed when the surface is
+   * destroyed.
+   */
+  static TemporaryRef<DataSourceSurface>
+    CreateDataSourceSurface(const IntSize &aSize, SurfaceFormat aFormat);
+  
+  /*
+   * This creates a simple data source surface for some existing data. It will
+   * wrap this data and the data for this source surface. The caller is
+   * responsible for deallocating the memory only after destruction of the
+   * surface.
+   */
+  static TemporaryRef<DataSourceSurface>
+    CreateDataSourceSurfaceFromData(unsigned char *aData, int32_t aStride,
+                                    const IntSize &aSize, SurfaceFormat aFormat);
 
 #ifdef WIN32
   static TemporaryRef<DrawTarget> CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
   static void SetDirect3D10Device(ID3D10Device1 *aDevice);
   static ID3D10Device1 *GetDirect3D10Device();
 
 private:
   static ID3D10Device1 *mD3D10Device;
--- a/gfx/2d/DrawTargetCairo.h
+++ b/gfx/2d/DrawTargetCairo.h
@@ -101,34 +101,39 @@ public:
                     const DrawOptions &aOptions = DrawOptions())
   { return; }
 
   virtual void FillGlyphs(ScaledFont *aFont,
                           const GlyphBuffer &aBuffer,
                           const Pattern &aPattern,
                           const DrawOptions &aOptions)
   { return; }
+  virtual void Mask(const Pattern &aSource,
+                    const Pattern &aMask,
+                    const DrawOptions &aOptions = DrawOptions())
+  { return; }
 
   virtual void PushClip(const Path *aPath) { }
+  virtual void PushClipRect(const Rect &aRect) { }
   virtual void PopClip() { }
 
   virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FILL_WINDING) const { return NULL; }
 
   virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
                                                             const IntSize &aSize,
                                                             int32_t aStride,
                                                             SurfaceFormat aFormat) const;
   virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
   virtual TemporaryRef<SourceSurface>
     CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const;
   virtual TemporaryRef<DrawTarget>
     CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
   { return NULL; }
 
-  virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const
+  virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops, ExtendMode aExtendMode = EXTEND_CLAMP) const
   { return NULL; }
 
   virtual void *GetNativeSurface(NativeSurfaceType aType)
   { return NULL; }
 
   virtual void SetTransform(const Matrix& aTransform);
 
   bool Init(cairo_surface_t* aSurface);
--- a/gfx/2d/DrawTargetD2D.cpp
+++ b/gfx/2d/DrawTargetD2D.cpp
@@ -263,16 +263,18 @@ DrawTargetD2D::DrawSurface(SourceSurface
                            const DrawOptions &aOptions)
 {
   RefPtr<ID2D1Bitmap> bitmap;
 
   ID2D1RenderTarget *rt = GetRTForOperation(aOptions.mCompositionOp, ColorPattern(Color()));
   
   PrepareForDrawing(rt);
 
+  rt->SetAntialiasMode(D2DAAMode(aOptions.mAntialiasMode));
+
   Rect srcRect = aSource;
 
   switch (aSurface->GetType()) {
 
   case SURFACE_D2D1_BITMAP:
     {
       SourceSurfaceD2D *srcSurf = static_cast<SourceSurfaceD2D*>(aSurface);
       bitmap = srcSurf->GetBitmap();
@@ -748,16 +750,18 @@ void
 DrawTargetD2D::FillRect(const Rect &aRect,
                         const Pattern &aPattern,
                         const DrawOptions &aOptions)
 {
   ID2D1RenderTarget *rt = GetRTForOperation(aOptions.mCompositionOp, aPattern);
 
   PrepareForDrawing(rt);
 
+  rt->SetAntialiasMode(D2DAAMode(aOptions.mAntialiasMode));
+
   RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
 
   if (brush) {
     rt->FillRectangle(D2DRect(aRect), brush);
   }
 
   FinalizeRTForOperation(aOptions.mCompositionOp, aPattern, aRect);
 }
@@ -767,16 +771,18 @@ DrawTargetD2D::StrokeRect(const Rect &aR
                           const Pattern &aPattern,
                           const StrokeOptions &aStrokeOptions,
                           const DrawOptions &aOptions)
 {
   ID2D1RenderTarget *rt = GetRTForOperation(aOptions.mCompositionOp, aPattern);
 
   PrepareForDrawing(rt);
 
+  rt->SetAntialiasMode(D2DAAMode(aOptions.mAntialiasMode));
+
   RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
 
   RefPtr<ID2D1StrokeStyle> strokeStyle = CreateStrokeStyleForOptions(aStrokeOptions);
 
   if (brush && strokeStyle) {
     rt->DrawRectangle(D2DRect(aRect), brush, aStrokeOptions.mLineWidth, strokeStyle);
   }
 
@@ -789,16 +795,18 @@ DrawTargetD2D::StrokeLine(const Point &a
                           const Pattern &aPattern,
                           const StrokeOptions &aStrokeOptions,
                           const DrawOptions &aOptions)
 {
   ID2D1RenderTarget *rt = GetRTForOperation(aOptions.mCompositionOp, aPattern);
 
   PrepareForDrawing(rt);
 
+  rt->SetAntialiasMode(D2DAAMode(aOptions.mAntialiasMode));
+
   RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
 
   RefPtr<ID2D1StrokeStyle> strokeStyle = CreateStrokeStyleForOptions(aStrokeOptions);
 
   if (brush && strokeStyle) {
     rt->DrawLine(D2DPoint(aStart), D2DPoint(aEnd), brush, aStrokeOptions.mLineWidth, strokeStyle);
   }
 
@@ -817,16 +825,18 @@ DrawTargetD2D::Stroke(const Path *aPath,
   }
 
   const PathD2D *d2dPath = static_cast<const PathD2D*>(aPath);
 
   ID2D1RenderTarget *rt = GetRTForOperation(aOptions.mCompositionOp, aPattern);
 
   PrepareForDrawing(rt);
 
+  rt->SetAntialiasMode(D2DAAMode(aOptions.mAntialiasMode));
+
   RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
 
   RefPtr<ID2D1StrokeStyle> strokeStyle = CreateStrokeStyleForOptions(aStrokeOptions);
 
   if (brush && strokeStyle) {
     rt->DrawGeometry(d2dPath->mGeometry, brush, aStrokeOptions.mLineWidth, strokeStyle);
   }
 
@@ -844,16 +854,18 @@ DrawTargetD2D::Fill(const Path *aPath,
   }
 
   const PathD2D *d2dPath = static_cast<const PathD2D*>(aPath);
 
   ID2D1RenderTarget *rt = GetRTForOperation(aOptions.mCompositionOp, aPattern);
 
   PrepareForDrawing(rt);
 
+  rt->SetAntialiasMode(D2DAAMode(aOptions.mAntialiasMode));
+
   RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
 
   if (brush) {
     rt->FillGeometry(d2dPath->mGeometry, brush);
   }
 
   Rect bounds;
   if (aOptions.mCompositionOp != OP_OVER) {
@@ -912,16 +924,46 @@ DrawTargetD2D::FillGlyphs(ScaledFont *aF
   if (brush) {
     rt->DrawGlyphRun(D2D1::Point2F(), &glyphRun, brush);
   }
 
   FinalizeRTForOperation(aOptions.mCompositionOp, aPattern, Rect(0, 0, (Float)mSize.width, (Float)mSize.height));
 }
 
 void
+DrawTargetD2D::Mask(const Pattern &aSource,
+                    const Pattern &aMask,
+                    const DrawOptions &aOptions)
+{
+  ID2D1RenderTarget *rt = GetRTForOperation(aOptions.mCompositionOp, aSource);
+  
+  PrepareForDrawing(rt);
+
+  RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aSource, aOptions.mAlpha);
+  RefPtr<ID2D1Brush> maskBrush = CreateBrushForPattern(aMask, 1.0f);
+
+  RefPtr<ID2D1Layer> layer;
+  rt->CreateLayer(byRef(layer));
+  rt->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), NULL,
+                                      D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
+                                      D2D1::IdentityMatrix(),
+                                      1.0f, maskBrush),
+                layer);
+
+  Rect rect(0, 0, mSize.width, mSize.height);
+  Matrix mat = mTransform;
+  mat.Invert();
+  
+  rt->FillRectangle(D2DRect(mat.TransformBounds(rect)), brush);
+  rt->PopLayer();
+
+  FinalizeRTForOperation(aOptions.mCompositionOp, aSource, Rect(0, 0, (Float)mSize.width, (Float)mSize.height));
+}
+
+void
 DrawTargetD2D::PushClip(const Path *aPath)
 {
   if (aPath->GetBackendType() != BACKEND_DIRECT2D) {
     gfxDebug() << *this << ": Ignoring clipping call for incompatible path.";
     return;
   }
 
   RefPtr<PathD2D> pathD2D = static_cast<PathD2D*>(const_cast<Path*>(aPath));
@@ -953,34 +995,67 @@ DrawTargetD2D::PushClip(const Path *aPat
     mRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), pathD2D->mGeometry,
                                          D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
                                          clip.mTransform, 1.0f, NULL,
                                          options), layer);
   }
 }
 
 void
+DrawTargetD2D::PushClipRect(const Rect &aRect)
+{
+  if (!mTransform.IsRectilinear()) {
+    // Whoops, this isn't a rectangle in device space, Direct2D will not deal
+    // with this transform the way we want it to.
+    // See remarks: http://msdn.microsoft.com/en-us/library/dd316860%28VS.85%29.aspx
+
+    RefPtr<PathBuilder> pathBuilder = CreatePathBuilder();
+    pathBuilder->MoveTo(aRect.TopLeft());
+    pathBuilder->LineTo(aRect.TopRight());
+    pathBuilder->LineTo(aRect.BottomRight());
+    pathBuilder->LineTo(aRect.BottomLeft());
+    pathBuilder->Close();
+    RefPtr<Path> path = pathBuilder->Finish();
+    return PushClip(path);
+  }
+
+  PushedClip clip;
+  // Do not store the transform, just store the device space rectangle directly.
+  clip.mBounds = D2DRect(mTransform.TransformBounds(aRect));
+
+  mPushedClips.push_back(clip);
+
+  mRT->SetTransform(D2D1::IdentityMatrix());
+  if (mClipsArePushed) {
+    mRT->PushAxisAlignedClip(clip.mBounds, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
+  }
+}
+
+void
 DrawTargetD2D::PopClip()
 {
   if (mClipsArePushed) {
-    mRT->PopLayer();
+    if (mPushedClips.back().mLayer) {
+      mRT->PopLayer();
+    } else {
+      mRT->PopAxisAlignedClip();
+    }
   }
   mPushedClips.pop_back();
 }
 
 TemporaryRef<SourceSurface> 
 DrawTargetD2D::CreateSourceSurfaceFromData(unsigned char *aData,
                                            const IntSize &aSize,
                                            int32_t aStride,
                                            SurfaceFormat aFormat) const
 {
   RefPtr<SourceSurfaceD2D> newSurf = new SourceSurfaceD2D();
 
   if (!newSurf->InitFromData(aData, aSize, aStride, aFormat, mRT)) {
-    gfxDebug() << *this << ": Failure to create source surface from data. Size: " << aSize;
     return NULL;
   }
 
   return newSurf;
 }
 
 TemporaryRef<SourceSurface> 
 DrawTargetD2D::OptimizeSourceSurface(SourceSurface *aSurface) const
@@ -1044,28 +1119,32 @@ DrawTargetD2D::CreatePathBuilder(FillRul
   if (aFillRule == FILL_WINDING) {
     sink->SetFillMode(D2D1_FILL_MODE_WINDING);
   }
 
   return new PathBuilderD2D(sink, path, aFillRule);
 }
 
 TemporaryRef<GradientStops>
-DrawTargetD2D::CreateGradientStops(GradientStop *rawStops, uint32_t aNumStops) const
+DrawTargetD2D::CreateGradientStops(GradientStop *rawStops, uint32_t aNumStops, ExtendMode aExtendMode) const
 {
   D2D1_GRADIENT_STOP *stops = new D2D1_GRADIENT_STOP[aNumStops];
 
   for (uint32_t i = 0; i < aNumStops; i++) {
     stops[i].position = rawStops[i].offset;
     stops[i].color = D2DColor(rawStops[i].color);
   }
 
   RefPtr<ID2D1GradientStopCollection> stopCollection;
 
-  HRESULT hr = mRT->CreateGradientStopCollection(stops, aNumStops, byRef(stopCollection));
+  HRESULT hr =
+    mRT->CreateGradientStopCollection(stops, aNumStops,
+                                      D2D1_GAMMA_2_2, D2DExtend(aExtendMode),
+                                      byRef(stopCollection));
+  delete [] stops;
 
   if (FAILED(hr)) {
     gfxWarning() << "Failed to create GradientStopCollection. Code: " << hr;
     return NULL;
   }
 
   return new GradientStopsD2D(stopCollection);
 }
@@ -1092,30 +1171,35 @@ DrawTargetD2D::Init(const IntSize &aSize
   mFormat = aFormat;
 
   if (!Factory::GetDirect3D10Device()) {
     gfxDebug() << "Failed to Init Direct2D DrawTarget (No D3D10 Device set.)";
     return false;
   }
   mDevice = Factory::GetDirect3D10Device();
 
-  CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
+  CD3D10_TEXTURE2D_DESC desc(DXGIFormat(aFormat),
                              mSize.width,
                              mSize.height,
                              1, 1);
   desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
 
   hr = mDevice->CreateTexture2D(&desc, NULL, byRef(mTexture));
 
   if (FAILED(hr)) {
     gfxDebug() << "Failed to init Direct2D DrawTarget. Size: " << mSize << " Code: " << hr;
     return false;
   }
 
-  return InitD2DRenderTarget();
+  if (!InitD2DRenderTarget()) {
+    return false;
+  }
+
+  mRT->Clear(D2D1::ColorF(0, 0));
+  return true;
 }
 
 bool
 DrawTargetD2D::Init(ID3D10Texture2D *aTexture, SurfaceFormat aFormat)
 {
   HRESULT hr;
 
   mTexture = aTexture;
@@ -1225,49 +1309,52 @@ DrawTargetD2D::InitD2DRenderTarget()
   mRT = CreateRTForTexture(mTexture);
 
   if (!mRT) {
     return false;
   }
 
   mRT->BeginDraw();
 
-  mRT->Clear(D2D1::ColorF(0, 0));
-
   if (mFormat == FORMAT_B8G8R8X8) {
     mRT->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE);
   }
 
   return InitD3D10Data();
 }
 
 void
 DrawTargetD2D::PrepareForDrawing(ID2D1RenderTarget *aRT)
 {
   if (!mClipsArePushed || aRT == mTempRT) {
     if (mPushedClips.size()) {
       // The transform of clips is relative to the world matrix, since we use the total
       // transform for the clips, make the world matrix identity.
-      mRT->SetTransform(D2D1::IdentityMatrix());
-      mTransformDirty = true;
+      aRT->SetTransform(D2D1::IdentityMatrix());
+      if (aRT == mRT) {
+        mTransformDirty = true;
+        mClipsArePushed = true;
+      }
       for (std::vector<PushedClip>::iterator iter = mPushedClips.begin();
-           iter != mPushedClips.end(); iter++) {
+            iter != mPushedClips.end(); iter++) {
         D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
+        if (iter->mLayer) {
+          D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
 
-        if (mFormat == FORMAT_B8G8R8X8) {
-          options = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE;
+          if (mFormat == FORMAT_B8G8R8X8) {
+            options = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE;
+          }
+
+          aRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), iter->mPath->mGeometry,
+                                                D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
+                                                iter->mTransform, 1.0f, NULL,
+                                                options), iter->mLayer);
+        } else {
+          aRT->PushAxisAlignedClip(iter->mBounds, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
         }
-
-        aRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), iter->mPath->mGeometry,
-                                             D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
-                                             iter->mTransform, 1.0f, NULL,
-                                             options), iter->mLayer);
-      }
-      if (aRT == mRT) {
-        mClipsArePushed = true;
       }
     }
   }
   FlushTransformToRT();
   MarkChanged();
 
   if (aRT == mTempRT) {
     mTempRT->SetTransform(D2DMatrix(mTransform));
@@ -1416,18 +1503,22 @@ DrawTargetD2D::FinalizeRTForOperation(Co
   if (aOperator == OP_OVER && !IsPatternSupportedByD2D(aPattern)) {
     return;
   }
 
   if (!mTempRT) {
     return;
   }
 
-  for (unsigned int i = 0; i < mPushedClips.size(); i++) {
-    mTempRT->PopLayer();
+  for (int i = mPushedClips.size() - 1; i >= 0; i--) {
+    if (mPushedClips[i].mLayer) {
+      mTempRT->PopLayer();
+    } else {
+      mTempRT->PopAxisAlignedClip();
+    }
   }
 
   mRT->Flush();
   mTempRT->Flush();
 
   AutoSaveRestoreClippedOut restoreClippedOut(this);
 
   bool needsWriteBack =
@@ -1530,17 +1621,17 @@ DrawTargetD2D::CreateRTForTexture(ID3D10
     return NULL;
   }
 
   D3D10_TEXTURE2D_DESC desc;
   aTexture->GetDesc(&desc);
 
   D2D1_ALPHA_MODE alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
 
-  if (mFormat == FORMAT_B8G8R8X8) {
+  if (mFormat == FORMAT_B8G8R8X8 && aTexture == mTexture) {
     alphaMode = D2D1_ALPHA_MODE_IGNORE;
   }
 
   D2D1_RENDER_TARGET_PROPERTIES props =
     D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat(desc.Format, alphaMode));
   hr = factory()->CreateDxgiSurfaceRenderTarget(surface, props, byRef(rt));
 
   if (FAILED(hr)) {
@@ -1587,18 +1678,22 @@ DrawTargetD2D::EnsureViews()
     gfxWarning() << *this << "Failed to create rendertarget view for temp texture. Code: " << hr;
   }
 }
 
 void
 DrawTargetD2D::PopAllClips()
 {
   if (mClipsArePushed) {
-    for (unsigned int i = 0; i < mPushedClips.size(); i++) {
-      mRT->PopLayer();
+    for (int i = mPushedClips.size() - 1; i >= 0; i--) {
+      if (mPushedClips[i].mLayer) {
+        mRT->PopLayer();
+      } else {
+        mRT->PopAxisAlignedClip();
+      }
     }
   
     mClipsArePushed = false;
   }
 }
 
 TemporaryRef<ID2D1Brush>
 DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
@@ -1624,19 +1719,30 @@ DrawTargetD2D::CreateBrushForPattern(con
 
     GradientStopsD2D *stops = static_cast<GradientStopsD2D*>(pat->mStops.get());
 
     if (!stops) {
       gfxDebug() << "No stops specified for gradient pattern.";
       return NULL;
     }
 
+    if (pat->mBegin == pat->mEnd) {
+      RefPtr<ID2D1SolidColorBrush> colBrush;
+      uint32_t stopCount = stops->mStopCollection->GetGradientStopCount();
+      vector<D2D1_GRADIENT_STOP> d2dStops(stopCount);
+      stops->mStopCollection->GetGradientStops(&d2dStops.front(), stopCount);
+      mRT->CreateSolidColorBrush(d2dStops.back().color,
+                                 D2D1::BrushProperties(aAlpha),
+                                 byRef(colBrush));
+      return colBrush;
+    }
+
     mRT->CreateLinearGradientBrush(D2D1::LinearGradientBrushProperties(D2DPoint(pat->mBegin),
                                                                        D2DPoint(pat->mEnd)),
-                                   D2D1::BrushProperties(aAlpha),
+                                   D2D1::BrushProperties(aAlpha, D2DMatrix(pat->mMatrix)),
                                    stops->mStopCollection,
                                    byRef(gradBrush));
     return gradBrush;
   } else if (aPattern.GetType() == PATTERN_RADIAL_GRADIENT) {
     RefPtr<ID2D1RadialGradientBrush> gradBrush;
     const RadialGradientPattern *pat =
       static_cast<const RadialGradientPattern*>(&aPattern);
 
@@ -1647,71 +1753,66 @@ DrawTargetD2D::CreateBrushForPattern(con
       return NULL;
     }
 
     // This will not be a complex radial gradient brush.
     mRT->CreateRadialGradientBrush(
       D2D1::RadialGradientBrushProperties(D2DPoint(pat->mCenter1),
                                           D2D1::Point2F(),
                                           pat->mRadius2, pat->mRadius2),
-      D2D1::BrushProperties(aAlpha),
+      D2D1::BrushProperties(aAlpha, D2DMatrix(pat->mMatrix)),
       stops->mStopCollection,
       byRef(gradBrush));
 
     return gradBrush;
   } else if (aPattern.GetType() == PATTERN_SURFACE) {
     RefPtr<ID2D1BitmapBrush> bmBrush;
     const SurfacePattern *pat =
       static_cast<const SurfacePattern*>(&aPattern);
 
     if (!pat->mSurface) {
       gfxDebug() << "No source surface specified for surface pattern";
       return NULL;
     }
 
     RefPtr<ID2D1Bitmap> bitmap;
+
+    Matrix mat = pat->mMatrix;
     
     switch (pat->mSurface->GetType()) {
     case SURFACE_D2D1_BITMAP:
       {
         SourceSurfaceD2D *surf = static_cast<SourceSurfaceD2D*>(pat->mSurface.get());
 
         bitmap = surf->mBitmap;
 
         if (!bitmap) {
-          gfxDebug() << "Source surface used for pattern too large!";
-          return NULL;
+          bitmap = CreatePartialBitmapForSurface(surf, mat);
+
+          if (!bitmap) {
+            return NULL;
+          }
         }
       }
       break;
     case SURFACE_D2D1_DRAWTARGET:
       {
         SourceSurfaceD2DTarget *surf =
           static_cast<SourceSurfaceD2DTarget*>(pat->mSurface.get());
         bitmap = surf->GetBitmap(mRT);
         AddDependencyOnSource(surf);
       }
       break;
     }
-
-    D2D1_EXTEND_MODE extend = D2D1_EXTEND_MODE_CLAMP;
-    switch (pat->mExtendMode) {
-    case EXTEND_WRAP:
-      extend = D2D1_EXTEND_MODE_WRAP;
-      break;
-    case EXTEND_MIRROR:
-      extend = D2D1_EXTEND_MODE_MIRROR;
-      break;
-    }
-
+    
     mRT->CreateBitmapBrush(bitmap,
-                           D2D1::BitmapBrushProperties(extend,
-                                                       extend,
+                           D2D1::BitmapBrushProperties(D2DExtend(pat->mExtendMode),
+                                                       D2DExtend(pat->mExtendMode),
                                                        D2DFilter(pat->mFilter)),
-                           D2D1::BrushProperties(aAlpha),
+                           D2D1::BrushProperties(aAlpha, D2DMatrix(mat)),
                            byRef(bmBrush));
 
     return bmBrush;
   }
 
   gfxWarning() << "Invalid pattern type detected.";
   return NULL;
 }
@@ -1850,16 +1951,69 @@ DrawTargetD2D::CreateGradientTexture(con
   data.pSysMem = &textureData.front();
 
   RefPtr<ID3D10Texture1D> tex;
   mDevice->CreateTexture1D(&desc, &data, byRef(tex));
 
   return tex;
 }
 
+TemporaryRef<ID2D1Bitmap>
+DrawTargetD2D::CreatePartialBitmapForSurface(SourceSurfaceD2D *aSurface, Matrix &aMatrix)
+{
+  RefPtr<ID2D1Bitmap> bitmap;
+
+  // This is where things get complicated. The source surface was
+  // created for a surface that was too large to fit in a texture.
+  // We'll need to figure out if we can work with a partial upload
+  // or downsample in software.
+
+  Matrix transform = mTransform;
+  transform = aMatrix * transform;
+  if (!transform.Invert()) {
+    // Singular transform, nothing to be drawn.
+    return NULL;
+  }
+
+  Rect rect(0, 0, mSize.width, mSize.height);
+
+  // Calculate the rectangle of the source mapped to our surface.
+  rect = transform.TransformBounds(rect);
+  rect.RoundOut();
+
+  Rect uploadRect(0, 0, aSurface->mSize.width, aSurface->mSize.height);
+
+  // Calculate the rectangle on the source bitmap that touches our
+  // surface.
+  uploadRect = uploadRect.Intersect(rect);
+
+  if (uploadRect.width <= mRT->GetMaximumBitmapSize() &&
+      uploadRect.height <= mRT->GetMaximumBitmapSize()) {
+            
+    int Bpp = BytesPerPixel(aSurface->mFormat);
+    int stride = Bpp * aSurface->mSize.width;
+
+    // A partial upload will suffice.
+    mRT->CreateBitmap(D2D1::SizeU(uint32_t(uploadRect.width), uint32_t(uploadRect.height)),
+                      &aSurface->mRawData.front() + int(uploadRect.x) + int(uploadRect.y) * stride,
+                      stride,
+                      D2D1::BitmapProperties(D2DPixelFormat(aSurface->mFormat)),
+                      byRef(bitmap));
+
+    aMatrix.Translate(-uploadRect.x, -uploadRect.y);
+
+    return bitmap;
+  } else {
+    // XXX - FIX ME!!
+    MOZ_ASSERT(false);
+    gfxDebug() << "Source surface used for pattern too large!";
+    return NULL;
+  }
+}
+
 void
 DrawTargetD2D::SetupEffectForRadialGradient(const RadialGradientPattern *aPattern)
 {
   mPrivateData->mEffect->GetTechniqueByName("SampleRadialGradient")->GetPassByIndex(0)->Apply(0);
   mPrivateData->mEffect->GetVariableByName("MaskTexCoords")->AsVector()->
     SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
 
   float dimensions[] = { float(mSize.width), float(mSize.height), 0, 0 };
@@ -1902,23 +2056,36 @@ DrawTargetD2D::SetupEffectForRadialGradi
                       invTransform._21, invTransform._22, 0, 0,
                       invTransform._31, invTransform._32, 1.0f, 0,
                       0, 0, 0, 1.0f };
 
   mPrivateData->mEffect->GetVariableByName("DeviceSpaceToUserSpace")->
     AsMatrix()->SetMatrix(matrix);
 
   float A = dc.x * dc.x + dc.y * dc.y - dr * dr;
+
+  uint32_t offset = 0;
+  switch (stops->mStopCollection->GetExtendMode()) {
+  case D2D1_EXTEND_MODE_WRAP:
+    offset = 1;
+    break;
+  case D2D1_EXTEND_MODE_MIRROR:
+    offset = 2;
+    break;
+  default:
+    gfxWarning() << "This shouldn't happen! Invalid extend mode for gradient stops.";
+  }
+
   if (A == 0) {
     mPrivateData->mEffect->GetTechniqueByName("SampleRadialGradient")->
-      GetPassByIndex(1)->Apply(0);
+      GetPassByIndex(offset * 2 + 1)->Apply(0);
   } else {
     mPrivateData->mEffect->GetVariableByName("A")->AsScalar()->SetFloat(A);
     mPrivateData->mEffect->GetTechniqueByName("SampleRadialGradient")->
-      GetPassByIndex(0)->Apply(0);
+      GetPassByIndex(offset * 2)->Apply(0);
   }
 }
 
 ID2D1Factory*
 DrawTargetD2D::factory()
 {
   if (mFactory) {
     return mFactory;
@@ -1931,17 +2098,17 @@ DrawTargetD2D::factory()
 
   if (!createD2DFactory) {
     gfxWarning() << "Failed to locate D2D1CreateFactory function.";
     return NULL;
   }
 
   D2D1_FACTORY_OPTIONS options;
 #ifdef _DEBUG
-  options.debugLevel = D2D1_DEBUG_LEVEL_NONE;
+  options.debugLevel = D2D1_DEBUG_LEVEL_WARNING;
 #else
   options.debugLevel = D2D1_DEBUG_LEVEL_NONE;
 #endif
 
   HRESULT hr = createD2DFactory(D2D1_FACTORY_TYPE_MULTI_THREADED,
                                 __uuidof(ID2D1Factory),
                                 &options,
                                 (void**)&mFactory);
--- a/gfx/2d/DrawTargetD2D.h
+++ b/gfx/2d/DrawTargetD2D.h
@@ -51,16 +51,17 @@
 #else
 #include <unordered_set>
 #endif
 
 namespace mozilla {
 namespace gfx {
 
 class SourceSurfaceD2DTarget;
+class SourceSurfaceD2D;
 class GradientStopsD2D;
 
 struct PrivateD3D10DataD2D
 {
   RefPtr<ID3D10Effect> mEffect;
   RefPtr<ID3D10InputLayout> mInputLayout;
   RefPtr<ID3D10Buffer> mVB;
   RefPtr<ID3D10BlendState> mBlendStates[OP_COUNT];
@@ -112,34 +113,41 @@ public:
                       const DrawOptions &aOptions = DrawOptions());
   virtual void Fill(const Path *aPath,
                     const Pattern &aPattern,
                     const DrawOptions &aOptions = DrawOptions());
   virtual void FillGlyphs(ScaledFont *aFont,
                           const GlyphBuffer &aBuffer,
                           const Pattern &aPattern,
                           const DrawOptions &aOptions = DrawOptions());
+  virtual void Mask(const Pattern &aSource,
+                    const Pattern &aMask,
+                    const DrawOptions &aOptions = DrawOptions());
   virtual void PushClip(const Path *aPath);
+  virtual void PushClipRect(const Rect &aRect);
   virtual void PopClip();
 
   virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
                                                             const IntSize &aSize,
                                                             int32_t aStride,
                                                             SurfaceFormat aFormat) const;
   virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
 
   virtual TemporaryRef<SourceSurface>
     CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const;
   
   virtual TemporaryRef<DrawTarget>
     CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const;
 
   virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FILL_WINDING) const;
 
-  virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const;
+  virtual TemporaryRef<GradientStops>
+    CreateGradientStops(GradientStop *aStops,
+                        uint32_t aNumStops,
+                        ExtendMode aExtendMode = EXTEND_CLAMP) const;
 
   virtual void *GetNativeSurface(NativeSurfaceType aType);
 
   bool Init(const IntSize &aSize, SurfaceFormat aFormat);
   bool Init(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
   bool InitD3D10Data();
 
   static ID2D1Factory *factory();
@@ -181,16 +189,21 @@ private:
 
   TemporaryRef<ID2D1RenderTarget> CreateRTForTexture(ID3D10Texture2D *aTexture);
   TemporaryRef<ID2D1Geometry> GetClippedGeometry();
 
   TemporaryRef<ID2D1Brush> CreateBrushForPattern(const Pattern &aPattern, Float aAlpha = 1.0f);
 
   TemporaryRef<ID3D10Texture1D> CreateGradientTexture(const GradientStopsD2D *aStops);
 
+  // This creates a partially uploaded bitmap for a SourceSurfaceD2D that is
+  // too big to fit in a bitmap. It adjusts the passed Matrix to accomodate the
+  // partial upload.
+  TemporaryRef<ID2D1Bitmap> CreatePartialBitmapForSurface(SourceSurfaceD2D *aSurface, Matrix &aMatrix);
+
   void SetupEffectForRadialGradient(const RadialGradientPattern *aPattern);
 
   static const uint32_t test = 4;
 
   IntSize mSize;
 
   RefPtr<ID3D10Device1> mDevice;
   RefPtr<ID3D10Texture2D> mTexture;
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -194,19 +194,19 @@ DrawTargetSkia::Snapshot()
 
 SkShader::TileMode
 ExtendModeToTileMode(ExtendMode aMode)
 {
   switch (aMode)
   {
     case EXTEND_CLAMP:
       return SkShader::kClamp_TileMode;
-    case EXTEND_WRAP:
+    case EXTEND_REPEAT:
       return SkShader::kRepeat_TileMode;
-    case EXTEND_MIRROR:
+    case EXTEND_REFLECT:
       return SkShader::kMirror_TileMode;
   }
   return SkShader::kClamp_TileMode;
 }
 
 struct AutoPaintSetup {
   AutoPaintSetup(SkCanvas *aCanvas, const DrawOptions& aOptions, const Pattern& aPattern)
     : mNeedsRestore(false), mAlpha(1.0)
@@ -666,17 +666,17 @@ DrawTargetSkia::PushClip(const Path *aPa
 
 void
 DrawTargetSkia::PopClip()
 {
   mCanvas->restore();
 }
 
 TemporaryRef<GradientStops>
-DrawTargetSkia::CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const
+DrawTargetSkia::CreateGradientStops(GradientStop *aStops, uint32_t aNumStops, ExtendMode aExtendMode) const
 {
   std::vector<GradientStop> stops;
   stops.resize(aNumStops);
   for (uint32_t i = 0; i < aNumStops; i++) {
     stops[i] = aStops[i];
   }
   std::stable_sort(stops.begin(), stops.end());
   
--- a/gfx/2d/DrawTargetSkia.h
+++ b/gfx/2d/DrawTargetSkia.h
@@ -94,29 +94,34 @@ public:
                       const DrawOptions &aOptions = DrawOptions());
   virtual void Fill(const Path *aPath,
                     const Pattern &aPattern,
                     const DrawOptions &aOptions = DrawOptions());
   virtual void FillGlyphs(ScaledFont *aFont,
                           const GlyphBuffer &aBuffer,
                           const Pattern &aPattern,
                           const DrawOptions &aOptions = DrawOptions());
+  virtual void Mask(const Pattern &aSource,
+                    const Pattern &aMask,
+                    const DrawOptions &aOptions = DrawOptions())
+  { return; }
   virtual void PushClip(const Path *aPath);
+  virtual void PushClipRect(const Rect &aRect) { }
   virtual void PopClip();
   virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
                                                             const IntSize &aSize,
                                                             int32_t aStride,
                                                             SurfaceFormat aFormat) const;
   virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
   virtual TemporaryRef<SourceSurface>
     CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const;
   virtual TemporaryRef<DrawTarget>
     CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const;
   virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FILL_WINDING) const;
-  virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const;
+  virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops, ExtendMode aExtendMode = EXTEND_CLAMP) const;
   virtual void SetTransform(const Matrix &aTransform);
 
   bool Init(const IntSize &aSize, SurfaceFormat aFormat);
   
   operator std::string() const {
     std::stringstream stream;
     stream << "DrawTargetSkia(" << this << ")";
     return stream.str();
--- a/gfx/2d/HelpersD2D.h
+++ b/gfx/2d/HelpersD2D.h
@@ -54,31 +54,46 @@ static inline D2D1_SIZE_U D2DIntSize(con
   return D2D1::SizeU(aSize.width, aSize.height);
 }
 
 static inline D2D1_RECT_F D2DRect(const Rect &aRect)
 {
   return D2D1::RectF(aRect.x, aRect.y, aRect.XMost(), aRect.YMost());
 }
 
+static inline D2D1_EXTEND_MODE D2DExtend(ExtendMode aExtendMode)
+{
+  D2D1_EXTEND_MODE extend = D2D1_EXTEND_MODE_CLAMP;
+  switch (aExtendMode) {
+  case EXTEND_REPEAT:
+    extend = D2D1_EXTEND_MODE_WRAP;
+    break;
+  case EXTEND_REFLECT:
+    extend = D2D1_EXTEND_MODE_MIRROR;
+    break;
+  }
+
+  return extend;
+}
+
 static inline D2D1_BITMAP_INTERPOLATION_MODE D2DFilter(const Filter &aFilter)
 {
   switch (aFilter) {
   case FILTER_POINT:
     return D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
   }
 
   return D2D1_BITMAP_INTERPOLATION_MODE_LINEAR;
 }
 
-static inline D2D1_ANTIALIAS_MODE D2DAAMode(const AntialiasMode &aMode)
+static inline D2D1_ANTIALIAS_MODE D2DAAMode(AntialiasMode aMode)
 {
   switch (aMode) {
   case AA_NONE:
-    D2D1_ANTIALIAS_MODE_ALIASED;
+    return D2D1_ANTIALIAS_MODE_ALIASED;
   }
 
   return D2D1_ANTIALIAS_MODE_PER_PRIMITIVE;
 }
 
 static inline D2D1_MATRIX_3X2_F D2DMatrix(const Matrix &aTransform)
 {
   return D2D1::Matrix3x2F(aTransform._11, aTransform._12,
@@ -136,16 +151,21 @@ static inline D2D1_ALPHA_MODE AlphaMode(
   switch (aFormat) {
   case FORMAT_B8G8R8X8:
     return D2D1_ALPHA_MODE_IGNORE;
   }
 
   return D2D1_ALPHA_MODE_PREMULTIPLIED;
 }
 
+static inline D2D1_PIXEL_FORMAT D2DPixelFormat(SurfaceFormat aFormat)
+{
+  return D2D1::PixelFormat(DXGIFormat(aFormat), AlphaMode(aFormat));
+}
+
 static inline int BytesPerPixel(SurfaceFormat aFormat)
 {
   switch (aFormat) {
   case FORMAT_A8:
     return 1;
   default:
     return 4;
   }
--- a/gfx/2d/Matrix.h
+++ b/gfx/2d/Matrix.h
@@ -138,14 +138,32 @@ public:
     resultMatrix._12 = this->_11 * aMatrix._12 + this->_12 * aMatrix._22;
     resultMatrix._21 = this->_21 * aMatrix._11 + this->_22 * aMatrix._21;
     resultMatrix._22 = this->_21 * aMatrix._12 + this->_22 * aMatrix._22;
     resultMatrix._31 = this->_31 * aMatrix._11 + this->_32 * aMatrix._21 + aMatrix._31;
     resultMatrix._32 = this->_31 * aMatrix._12 + this->_32 * aMatrix._22 + aMatrix._32;
 
     return resultMatrix;
   }
+
+  /* Returns true if the matrix is a rectilinear transformation (i.e.
+   * grid-aligned rectangles are transformed to grid-aligned rectangles)
+   */
+  bool IsRectilinear() {
+    if (FuzzyEqual(_12, 0) && FuzzyEqual(_21, 0)) {
+      return true;
+    } else if (FuzzyEqual(_22, 0) && FuzzyEqual(_11, 0)) {
+      return true;
+    }
+
+    return false;
+  }
+private:
+  static bool FuzzyEqual(Float aV1, Float aV2) {
+    // XXX - Check if fabs does the smart thing and just negates the sign bit.
+    return fabs(aV2 - aV1) < 1e-6;
+  }
 };
 
 }
 }
 
 #endif /* MOZILLA_GFX_MATRIX_H_ */
--- a/gfx/2d/ShadersD2D.fx
+++ b/gfx/2d/ShadersD2D.fx
@@ -55,16 +55,30 @@ Texture2D mask;
 
 sampler sSampler = sampler_state {
     Filter = MIN_MAG_MIP_LINEAR;
     Texture = tex;
     AddressU = Clamp;
     AddressV = Clamp;
 };
 
+sampler sWrapSampler = sampler_state {
+    Filter = MIN_MAG_MIP_LINEAR;
+    Texture = tex;
+    AddressU = Wrap;
+    AddressV = Wrap;
+};
+
+sampler sMirrorSampler = sampler_state {
+    Filter = MIN_MAG_MIP_LINEAR;
+    Texture = tex;
+    AddressU = Mirror;
+    AddressV = Mirror;
+};
+
 sampler sMaskSampler = sampler_state {
     Filter = MIN_MAG_MIP_LINEAR;
     Texture = mask;
     AddressU = Clamp;
     AddressV = Clamp;
 };
 
 sampler sShadowSampler = sampler_state {
@@ -137,17 +151,17 @@ float4 SampleTexturePS( VS_OUTPUT In) : 
     return tex.Sample(sSampler, In.TexCoord);
 };
 
 float4 SampleMaskTexturePS( VS_OUTPUT In) : SV_Target
 {
     return tex.Sample(sSampler, In.TexCoord) * mask.Sample(sMaskSampler, In.MaskTexCoord).a;
 };
 
-float4 SampleRadialGradientPS( VS_RADIAL_OUTPUT In) : SV_Target
+float4 SampleRadialGradientPS(VS_RADIAL_OUTPUT In, uniform sampler aSampler) : SV_Target
 {
     // Radial gradient painting is defined as the set of circles whose centers
     // are described by C(t) = (C2 - C1) * t + C1; with radii
     // R(t) = (R2 - R1) * t + R1; for R(t) > 0. This shader solves the
     // quadratic equation that arises when calculating t for pixel (x, y).
     //
     // A more extensive derrivation can be found in the pixman radial gradient
     // code.
@@ -173,25 +187,25 @@ float4 SampleRadialGradientPS( VS_RADIAL
     float2 isValid = step(float2(-radius1, -radius1), t * diff.z);
 
     if (max(isValid.x, isValid.y) <= 0) {
       return float4(0, 0, 0, 0);
     }
 
     float upper_t = lerp(t.y, t.x, isValid.x);
 
-    float4 output = tex.Sample(sSampler, float2(upper_t, 0.5));
+    float4 output = tex.Sample(aSampler, float2(upper_t, 0.5));
     // Premultiply
     output.rgb *= output.a;
     // Multiply the output color by the input mask for the operation.
     output *= mask.Sample(sMaskSampler, In.MaskTexCoord).a;
     return output;
 };
 
-float4 SampleRadialGradientA0PS( VS_RADIAL_OUTPUT In) : SV_Target
+float4 SampleRadialGradientA0PS( VS_RADIAL_OUTPUT In, uniform sampler aSampler ) : SV_Target
 {
     // This simpler shader is used for the degenerate case where A is 0,
     // i.e. we're actually solving a linear equation.
 
     float2 p = In.PixelCoord;
     float3 dp = float3(p - center1, radius1);
 
     // dpx * dcx + dpy * dcy + r * dr
@@ -200,17 +214,17 @@ float4 SampleRadialGradientA0PS( VS_RADI
     float C = pow(dp.x, 2) + pow(dp.y, 2) - pow(radius1, 2);
 
     float t = 0.5 * C / B;
 
     if (-radius1 >= t * diff.z) {
       return float4(0, 0, 0, 0);
     }
 
-    float4 output = tex.Sample(sSampler, float2(t, 0.5));
+    float4 output = tex.Sample(aSampler, float2(t, 0.5));
     // Premultiply
     output.rgb *= output.a;
     // Multiply the output color by the input mask for the operation.
     output *= mask.Sample(sMaskSampler, In.MaskTexCoord).a;
     return output;
 };
 
 float4 SampleShadowHPS( VS_OUTPUT In) : SV_Target
@@ -272,29 +286,57 @@ technique10 SampleTexture
         SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
         SetGeometryShader(NULL);
         SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTexturePS()));
     }
 }
 
 technique10 SampleRadialGradient
 {
-    pass P0
+    pass APos
+    {
+        SetRasterizerState(TextureRast);
+        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
+        SetGeometryShader(NULL);
+        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientPS( sSampler )));
+    }
+    pass A0
+    {
+        SetRasterizerState(TextureRast);
+        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
+        SetGeometryShader(NULL);
+        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientA0PS( sSampler )));
+    }
+    pass APosWrap
     {
         SetRasterizerState(TextureRast);
         SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
         SetGeometryShader(NULL);
-        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientPS()));
+        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientPS( sWrapSampler )));
     }
-    pass P1
+    pass A0Wrap
     {
         SetRasterizerState(TextureRast);
         SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
         SetGeometryShader(NULL);
-        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientA0PS()));
+        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientA0PS( sWrapSampler )));
+    }
+    pass APosMirror
+    {
+        SetRasterizerState(TextureRast);
+        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
+        SetGeometryShader(NULL);
+        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientPS( sMirrorSampler )));
+    }
+    pass A0Mirror
+    {
+        SetRasterizerState(TextureRast);
+        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
+        SetGeometryShader(NULL);
+        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientA0PS( sMirrorSampler )));
     }
 }
 
 technique10 SampleMaskedTexture
 {
     pass P0
     {
         SetRasterizerState(TextureRast);
--- a/gfx/2d/ShadersD2D.h
+++ b/gfx/2d/ShadersD2D.h
@@ -27,27 +27,41 @@ cbuffer cb2
     float3  diff;                       // Offset:   64, size:   12
     float2  center1;                    // Offset:   80, size:    8
     float   A;                          // Offset:   88, size:    4
     float   radius1;                    // Offset:   92, size:    4
     float   sq_radius1;                 // Offset:   96, size:    4
 }
 
 //
-// 8 local object(s)
+// 10 local object(s)
 //
 Texture2D tex;
 Texture2D mask;
 SamplerState sSampler
 {
     Filter   = uint(MIN_MAG_MIP_LINEAR /* 21 */);
     Texture  = tex;
     AddressU = uint(CLAMP /* 3 */);
     AddressV = uint(CLAMP /* 3 */);
 };
+SamplerState sWrapSampler
+{
+    Filter   = uint(MIN_MAG_MIP_LINEAR /* 21 */);
+    Texture  = tex;
+    AddressU = uint(WRAP /* 1 */);
+    AddressV = uint(WRAP /* 1 */);
+};
+SamplerState sMirrorSampler
+{
+    Filter   = uint(MIN_MAG_MIP_LINEAR /* 21 */);
+    Texture  = tex;
+    AddressU = uint(MIRROR /* 2 */);
+    AddressV = uint(MIRROR /* 2 */);
+};
 SamplerState sMaskSampler
 {
     Filter   = uint(MIN_MAG_MIP_LINEAR /* 21 */);
     Texture  = mask;
     AddressU = uint(CLAMP /* 3 */);
     AddressV = uint(CLAMP /* 3 */);
 };
 SamplerState sShadowSampler
@@ -227,17 +241,17 @@ technique10 SampleTexture
                     
         };
     }
 
 }
 
 technique10 SampleRadialGradient
 {
-    pass P0
+    pass APos
     {
         RasterizerState = TextureRast;
         VertexShader = asm {
             //
             // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
             //
             //
             // Buffer Definitions: 
@@ -495,17 +509,17 @@ technique10 SampleRadialGradient
             sample r0.xyzw, v1.xyxx, t1.xyzw, s1
             mul o0.xyzw, r0.wwww, r2.xyzw
             ret 
             // Approximately 33 instruction slots used
                     
         };
     }
 
-    pass P1
+    pass A0
     {
         RasterizerState = TextureRast;
         VertexShader = asm {
             //
             // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
             //
             //
             // Buffer Definitions: 
@@ -738,16 +752,1038 @@ technique10 SampleRadialGradient
             sample r0.xyzw, v1.xyxx, t1.xyzw, s1
             mul o0.xyzw, r0.wwww, r1.xyzw
             ret 
             // Approximately 19 instruction slots used
                     
         };
     }
 
+    pass APosWrap
+    {
+        RasterizerState = TextureRast;
+        VertexShader = asm {
+            //
+            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+            //
+            //
+            // Buffer Definitions: 
+            //
+            // cbuffer cb0
+            // {
+            //
+            //   float4 QuadDesc;                   // Offset:    0 Size:    16
+            //   float4 TexCoords;                  // Offset:   16 Size:    16 [unused]
+            //   float4 MaskTexCoords;              // Offset:   32 Size:    16
+            //
+            // }
+            //
+            // cbuffer cb2
+            // {
+            //
+            //   float3x3 DeviceSpaceToUserSpace;   // Offset:    0 Size:    44
+            //   float2 dimensions;                 // Offset:   48 Size:     8
+            //   float3 diff;                       // Offset:   64 Size:    12 [unused]
+            //   float2 center1;                    // Offset:   80 Size:     8 [unused]
+            //   float A;                           // Offset:   88 Size:     4 [unused]
+            //   float radius1;                     // Offset:   92 Size:     4 [unused]
+            //   float sq_radius1;                  // Offset:   96 Size:     4 [unused]
+            //
+            // }
+            //
+            //
+            // Resource Bindings:
+            //
+            // Name                                 Type  Format         Dim Slot Elements
+            // ------------------------------ ---------- ------- ----------- ---- --------
+            // cb0                               cbuffer      NA          NA    0        1
+            // cb2                               cbuffer      NA          NA    1        1
+            //
+            //
+            //
+            // Input signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // POSITION                 0   xyz         0     NONE  float   xy  
+            //
+            //
+            // Output signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Position              0   xyzw        0      POS  float   xyzw
+            // TEXCOORD                 0   xy          1     NONE  float   xy  
+            // TEXCOORD                 1     zw        1     NONE  float     zw
+            //
+            //
+            // Constant buffer to DX9 shader constant mappings:
+            //
+            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
+            // ---------- ------- --------- --------- ----------------------
+            // c1         cb0             0         1  ( FLT, FLT, FLT, FLT)
+            // c2         cb0             2         1  ( FLT, FLT, FLT, FLT)
+            // c3         cb1             0         2  ( FLT, FLT, FLT, FLT)
+            // c5         cb1             3         1  ( FLT, FLT, FLT, FLT)
+            //
+            //
+            // Runtime generated constant mappings:
+            //
+            // Target Reg                               Constant Description
+            // ---------- --------------------------------------------------
+            // c0                              Vertex Shader position offset
+            //
+            //
+            // Level9 shader bytecode:
+            //
+                vs_2_x
+                def c6, 1, 0.5, 0, 0
+                dcl_texcoord v0
+                mad oT0.xy, v0, c2.zwzw, c2
+                mad r0.xy, v0, c1.zwzw, c1
+                add r0.z, r0.x, c6.x
+                mul r0.z, r0.z, c5.x
+                mul r1.x, r0.z, c6.y
+                add r0.z, -r0.y, c6.x
+                add oPos.xy, r0, c0
+                mul r0.x, r0.z, c5.y
+                mul r1.y, r0.x, c6.y
+                mov r1.z, c6.x
+                dp3 oT0.w, r1, c3
+                dp3 oT0.z, r1, c4
+                mov oPos.zw, c6.xyzx
+            
+            // approximately 13 instruction slots used
+            vs_4_0
+            dcl_constantbuffer cb0[3], immediateIndexed
+            dcl_constantbuffer cb1[4], immediateIndexed
+            dcl_input v0.xy
+            dcl_output_siv o0.xyzw, position
+            dcl_output o1.xy
+            dcl_output o1.zw
+            dcl_temps 2
+            mov o0.zw, l(0,0,0,1.000000)
+            mad r0.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx
+            mov o0.xy, r0.xyxx
+            add r0.x, r0.x, l(1.000000)
+            add r0.y, -r0.y, l(1.000000)
+            mul r0.xy, r0.xyxx, cb1[3].xyxx
+            mul r1.xy, r0.xyxx, l(0.500000, 0.500000, 0.000000, 0.000000)
+            mov r1.z, l(1.000000)
+            dp3 o1.z, r1.xyzx, cb1[0].xyzx
+            dp3 o1.w, r1.xyzx, cb1[1].xyzx
+            mad o1.xy, v0.xyxx, cb0[2].zwzz, cb0[2].xyxx
+            ret 
+            // Approximately 12 instruction slots used
+                    
+        };
+        GeometryShader = NULL;
+        PixelShader = asm {
+            //
+            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+            //
+            //
+            // Buffer Definitions: 
+            //
+            // cbuffer cb2
+            // {
+            //
+            //   float3x3 DeviceSpaceToUserSpace;   // Offset:    0 Size:    44 [unused]
+            //   float2 dimensions;                 // Offset:   48 Size:     8 [unused]
+            //   float3 diff;                       // Offset:   64 Size:    12
+            //   float2 center1;                    // Offset:   80 Size:     8
+            //   float A;                           // Offset:   88 Size:     4
+            //   float radius1;                     // Offset:   92 Size:     4
+            //   float sq_radius1;                  // Offset:   96 Size:     4
+            //
+            // }
+            //
+            //
+            // Resource Bindings:
+            //
+            // Name                                 Type  Format         Dim Slot Elements
+            // ------------------------------ ---------- ------- ----------- ---- --------
+            // sWrapSampler                      sampler      NA          NA    0        1
+            // sMaskSampler                      sampler      NA          NA    1        1
+            // tex                               texture  float4          2d    0        1
+            // mask                              texture  float4          2d    1        1
+            // cb2                               cbuffer      NA          NA    0        1
+            //
+            //
+            //
+            // Input signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Position              0   xyzw        0      POS  float       
+            // TEXCOORD                 0   xy          1     NONE  float   xy  
+            // TEXCOORD                 1     zw        1     NONE  float     zw
+            //
+            //
+            // Output signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Target                0   xyzw        0   TARGET  float   xyzw
+            //
+            //
+            // Constant buffer to DX9 shader constant mappings:
+            //
+            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
+            // ---------- ------- --------- --------- ----------------------
+            // c0         cb0             4         3  ( FLT, FLT, FLT, FLT)
+            //
+            //
+            // Sampler/Resource to DX9 shader sampler mappings:
+            //
+            // Target Sampler Source Sampler  Source Resource
+            // -------------- --------------- ----------------
+            // s0             s0              t0               
+            // s1             s1              t1               
+            //
+            //
+            // Level9 shader bytecode:
+            //
+                ps_2_x
+                def c3, 0.5, 0, 0, 0
+                def c4, 1, -1, 0, -0
+                dcl t0
+                dcl_2d s0
+                dcl_2d s1
+                add r0.xy, t0.wzzw, -c1
+                dp2add r0.w, r0, r0, -c2.x
+                mul r0.w, r0.w, c1.z
+                mov r0.z, c1.w
+                dp3 r0.x, r0, c0
+                mad r0.y, r0.x, r0.x, -r0.w
+                abs r0.z, r0.y
+                rsq r0.z, r0.z
+                rcp r1.x, r0.z
+                mov r1.yz, -r1.x
+                add r0.xzw, r0.x, r1.xyyz
+                rcp r1.x, c1.z
+                mul r0.xzw, r0, r1.x
+                mov r1.w, c1.w
+                mad r1.xyz, r0.xzww, c0.z, r1.w
+                cmp r2.x, r1.x, r0.x, r0.w
+                cmp r0.xzw, r1.xyyz, c4.xyxy, c4.zyzw
+                mov r2.y, c3.x
+                texld r1, t0, s1
+                texld r2, r2, s0
+                mul r2.xyz, r2.w, r2
+                mul r1, r1.w, r2
+                add r0.w, r0.w, r0.x
+                cmp r0.x, r0.w, r0.x, r0.z
+                cmp r1, -r0.x, c4.z, r1
+                cmp r0, r0.y, r1, c4.z
+                mov oC0, r0
+            
+            // approximately 28 instruction slots used (2 texture, 26 arithmetic)
+            ps_4_0
+            dcl_constantbuffer cb0[7], immediateIndexed
+            dcl_sampler s0, mode_default
+            dcl_sampler s1, mode_default
+            dcl_resource_texture2d (float,float,float,float) t0
+            dcl_resource_texture2d (float,float,float,float) t1
+            dcl_input_ps linear v1.xy
+            dcl_input_ps linear v1.zw
+            dcl_output o0.xyzw
+            dcl_temps 3
+            add r0.xy, v1.zwzz, -cb0[5].xyxx
+            mov r0.z, cb0[5].w
+            dp3 r0.z, r0.xyzx, cb0[4].xyzx
+            dp2 r0.x, r0.xyxx, r0.xyxx
+            add r0.x, r0.x, -cb0[6].x
+            mul r0.x, r0.x, cb0[5].z
+            mad r0.x, r0.z, r0.z, -r0.x
+            lt r0.y, r0.x, l(0.000000)
+            sqrt r1.x, |r0.x|
+            mov r1.y, -r1.x
+            add r0.xz, r0.zzzz, r1.xxyx
+            div r0.xz, r0.xxzx, cb0[5].zzzz
+            mul r1.xy, r0.xzxx, cb0[4].zzzz
+            ge r1.xy, r1.xyxx, -cb0[5].wwww
+            and r1.xy, r1.xyxx, l(0x3f800000, 0x3f800000, 0, 0)
+            add r0.x, -r0.z, r0.x
+            mad r2.x, r1.x, r0.x, r0.z
+            mov r2.y, l(0.500000)
+            sample r2.xyzw, r2.xyxx, t0.xyzw, s0
+            if_nz r0.y
+              mov o0.xyzw, l(0,0,0,0)
+              ret 
+            endif 
+            max r0.x, r1.y, r1.x
+            ge r0.x, l(0.000000), r0.x
+            if_nz r0.x
+              mov o0.xyzw, l(0,0,0,0)
+              ret 
+            endif 
+            mul r2.xyz, r2.wwww, r2.xyzx
+            sample r0.xyzw, v1.xyxx, t1.xyzw, s1
+            mul o0.xyzw, r0.wwww, r2.xyzw
+            ret 
+            // Approximately 33 instruction slots used
+                    
+        };
+    }
+
+    pass A0Wrap
+    {
+        RasterizerState = TextureRast;
+        VertexShader = asm {
+            //
+            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+            //
+            //
+            // Buffer Definitions: 
+            //
+            // cbuffer cb0
+            // {
+            //
+            //   float4 QuadDesc;                   // Offset:    0 Size:    16
+            //   float4 TexCoords;                  // Offset:   16 Size:    16 [unused]
+            //   float4 MaskTexCoords;              // Offset:   32 Size:    16
+            //
+            // }
+            //
+            // cbuffer cb2
+            // {
+            //
+            //   float3x3 DeviceSpaceToUserSpace;   // Offset:    0 Size:    44
+            //   float2 dimensions;                 // Offset:   48 Size:     8
+            //   float3 diff;                       // Offset:   64 Size:    12 [unused]
+            //   float2 center1;                    // Offset:   80 Size:     8 [unused]
+            //   float A;                           // Offset:   88 Size:     4 [unused]
+            //   float radius1;                     // Offset:   92 Size:     4 [unused]
+            //   float sq_radius1;                  // Offset:   96 Size:     4 [unused]
+            //
+            // }
+            //
+            //
+            // Resource Bindings:
+            //
+            // Name                                 Type  Format         Dim Slot Elements
+            // ------------------------------ ---------- ------- ----------- ---- --------
+            // cb0                               cbuffer      NA          NA    0        1
+            // cb2                               cbuffer      NA          NA    1        1
+            //
+            //
+            //
+            // Input signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // POSITION                 0   xyz         0     NONE  float   xy  
+            //
+            //
+            // Output signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Position              0   xyzw        0      POS  float   xyzw
+            // TEXCOORD                 0   xy          1     NONE  float   xy  
+            // TEXCOORD                 1     zw        1     NONE  float     zw
+            //
+            //
+            // Constant buffer to DX9 shader constant mappings:
+            //
+            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
+            // ---------- ------- --------- --------- ----------------------
+            // c1         cb0             0         1  ( FLT, FLT, FLT, FLT)
+            // c2         cb0             2         1  ( FLT, FLT, FLT, FLT)
+            // c3         cb1             0         2  ( FLT, FLT, FLT, FLT)
+            // c5         cb1             3         1  ( FLT, FLT, FLT, FLT)
+            //
+            //
+            // Runtime generated constant mappings:
+            //
+            // Target Reg                               Constant Description
+            // ---------- --------------------------------------------------
+            // c0                              Vertex Shader position offset
+            //
+            //
+            // Level9 shader bytecode:
+            //
+                vs_2_x
+                def c6, 1, 0.5, 0, 0
+                dcl_texcoord v0
+                mad oT0.xy, v0, c2.zwzw, c2
+                mad r0.xy, v0, c1.zwzw, c1
+                add r0.z, r0.x, c6.x
+                mul r0.z, r0.z, c5.x
+                mul r1.x, r0.z, c6.y
+                add r0.z, -r0.y, c6.x
+                add oPos.xy, r0, c0
+                mul r0.x, r0.z, c5.y
+                mul r1.y, r0.x, c6.y
+                mov r1.z, c6.x
+                dp3 oT0.w, r1, c3
+                dp3 oT0.z, r1, c4
+                mov oPos.zw, c6.xyzx
+            
+            // approximately 13 instruction slots used
+            vs_4_0
+            dcl_constantbuffer cb0[3], immediateIndexed
+            dcl_constantbuffer cb1[4], immediateIndexed
+            dcl_input v0.xy
+            dcl_output_siv o0.xyzw, position
+            dcl_output o1.xy
+            dcl_output o1.zw
+            dcl_temps 2
+            mov o0.zw, l(0,0,0,1.000000)
+            mad r0.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx
+            mov o0.xy, r0.xyxx
+            add r0.x, r0.x, l(1.000000)
+            add r0.y, -r0.y, l(1.000000)
+            mul r0.xy, r0.xyxx, cb1[3].xyxx
+            mul r1.xy, r0.xyxx, l(0.500000, 0.500000, 0.000000, 0.000000)
+            mov r1.z, l(1.000000)
+            dp3 o1.z, r1.xyzx, cb1[0].xyzx
+            dp3 o1.w, r1.xyzx, cb1[1].xyzx
+            mad o1.xy, v0.xyxx, cb0[2].zwzz, cb0[2].xyxx
+            ret 
+            // Approximately 12 instruction slots used
+                    
+        };
+        GeometryShader = NULL;
+        PixelShader = asm {
+            //
+            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+            //
+            //
+            // Buffer Definitions: 
+            //
+            // cbuffer cb2
+            // {
+            //
+            //   float3x3 DeviceSpaceToUserSpace;   // Offset:    0 Size:    44 [unused]
+            //   float2 dimensions;                 // Offset:   48 Size:     8 [unused]
+            //   float3 diff;                       // Offset:   64 Size:    12
+            //   float2 center1;                    // Offset:   80 Size:     8
+            //   float A;                           // Offset:   88 Size:     4 [unused]
+            //   float radius1;                     // Offset:   92 Size:     4
+            //   float sq_radius1;                  // Offset:   96 Size:     4 [unused]
+            //
+            // }
+            //
+            //
+            // Resource Bindings:
+            //
+            // Name                                 Type  Format         Dim Slot Elements
+            // ------------------------------ ---------- ------- ----------- ---- --------
+            // sWrapSampler                      sampler      NA          NA    0        1
+            // sMaskSampler                      sampler      NA          NA    1        1
+            // tex                               texture  float4          2d    0        1
+            // mask                              texture  float4          2d    1        1
+            // cb2                               cbuffer      NA          NA    0        1
+            //
+            //
+            //
+            // Input signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Position              0   xyzw        0      POS  float       
+            // TEXCOORD                 0   xy          1     NONE  float   xy  
+            // TEXCOORD                 1     zw        1     NONE  float     zw
+            //
+            //
+            // Output signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Target                0   xyzw        0   TARGET  float   xyzw
+            //
+            //
+            // Constant buffer to DX9 shader constant mappings:
+            //
+            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
+            // ---------- ------- --------- --------- ----------------------
+            // c0         cb0             4         2  ( FLT, FLT, FLT, FLT)
+            //
+            //
+            // Sampler/Resource to DX9 shader sampler mappings:
+            //
+            // Target Sampler Source Sampler  Source Resource
+            // -------------- --------------- ----------------
+            // s0             s0              t0               
+            // s1             s1              t1               
+            //
+            //
+            // Level9 shader bytecode:
+            //
+                ps_2_x
+                def c2, 0.5, 0, 0, 0
+                dcl t0
+                dcl_2d s0
+                dcl_2d s1
+                mul r0.w, c1.w, c1.w
+                add r0.xy, t0.wzzw, -c1
+                dp2add r0.w, r0, r0, -r0.w
+                mul r0.w, r0.w, c2.x
+                mov r0.z, c1.w
+                dp3 r0.x, r0, c0
+                rcp r0.x, r0.x
+                mul r0.x, r0.x, r0.w
+                mov r0.y, c2.x
+                texld r1, t0, s1
+                texld r2, r0, s0
+                mov r0.w, c1.w
+                mad r0.x, r0.x, -c0.z, -r0.w
+                mul r2.xyz, r2.w, r2
+                mul r1, r1.w, r2
+                cmp r0, r0.x, c2.y, r1
+                mov oC0, r0
+            
+            // approximately 18 instruction slots used (2 texture, 16 arithmetic)
+            ps_4_0
+            dcl_constantbuffer cb0[6], immediateIndexed
+            dcl_sampler s0, mode_default
+            dcl_sampler s1, mode_default
+            dcl_resource_texture2d (float,float,float,float) t0
+            dcl_resource_texture2d (float,float,float,float) t1
+            dcl_input_ps linear v1.xy
+            dcl_input_ps linear v1.zw
+            dcl_output o0.xyzw
+            dcl_temps 2
+            add r0.xy, v1.zwzz, -cb0[5].xyxx
+            mov r0.z, cb0[5].w
+            dp3 r0.z, r0.xyzx, cb0[4].xyzx
+            dp2 r0.x, r0.xyxx, r0.xyxx
+            mad r0.x, -cb0[5].w, cb0[5].w, r0.x
+            mul r0.x, r0.x, l(0.500000)
+            div r0.x, r0.x, r0.z
+            mul r0.z, r0.x, cb0[4].z
+            ge r0.z, -cb0[5].w, r0.z
+            mov r0.y, l(0.500000)
+            sample r1.xyzw, r0.xyxx, t0.xyzw, s0
+            if_nz r0.z
+              mov o0.xyzw, l(0,0,0,0)
+              ret 
+            endif 
+            mul r1.xyz, r1.wwww, r1.xyzx
+            sample r0.xyzw, v1.xyxx, t1.xyzw, s1
+            mul o0.xyzw, r0.wwww, r1.xyzw
+            ret 
+            // Approximately 19 instruction slots used
+                    
+        };
+    }
+
+    pass APosMirror
+    {
+        RasterizerState = TextureRast;
+        VertexShader = asm {
+            //
+            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+            //
+            //
+            // Buffer Definitions: 
+            //
+            // cbuffer cb0
+            // {
+            //
+            //   float4 QuadDesc;                   // Offset:    0 Size:    16
+            //   float4 TexCoords;                  // Offset:   16 Size:    16 [unused]
+            //   float4 MaskTexCoords;              // Offset:   32 Size:    16
+            //
+            // }
+            //
+            // cbuffer cb2
+            // {
+            //
+            //   float3x3 DeviceSpaceToUserSpace;   // Offset:    0 Size:    44
+            //   float2 dimensions;                 // Offset:   48 Size:     8
+            //   float3 diff;                       // Offset:   64 Size:    12 [unused]
+            //   float2 center1;                    // Offset:   80 Size:     8 [unused]
+            //   float A;                           // Offset:   88 Size:     4 [unused]
+            //   float radius1;                     // Offset:   92 Size:     4 [unused]
+            //   float sq_radius1;                  // Offset:   96 Size:     4 [unused]
+            //
+            // }
+            //
+            //
+            // Resource Bindings:
+            //
+            // Name                                 Type  Format         Dim Slot Elements
+            // ------------------------------ ---------- ------- ----------- ---- --------
+            // cb0                               cbuffer      NA          NA    0        1
+            // cb2                               cbuffer      NA          NA    1        1
+            //
+            //
+            //
+            // Input signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // POSITION                 0   xyz         0     NONE  float   xy  
+            //
+            //
+            // Output signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Position              0   xyzw        0      POS  float   xyzw
+            // TEXCOORD                 0   xy          1     NONE  float   xy  
+            // TEXCOORD                 1     zw        1     NONE  float     zw
+            //
+            //
+            // Constant buffer to DX9 shader constant mappings:
+            //
+            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
+            // ---------- ------- --------- --------- ----------------------
+            // c1         cb0             0         1  ( FLT, FLT, FLT, FLT)
+            // c2         cb0             2         1  ( FLT, FLT, FLT, FLT)
+            // c3         cb1             0         2  ( FLT, FLT, FLT, FLT)
+            // c5         cb1             3         1  ( FLT, FLT, FLT, FLT)
+            //
+            //
+            // Runtime generated constant mappings:
+            //
+            // Target Reg                               Constant Description
+            // ---------- --------------------------------------------------
+            // c0                              Vertex Shader position offset
+            //
+            //
+            // Level9 shader bytecode:
+            //
+                vs_2_x
+                def c6, 1, 0.5, 0, 0
+                dcl_texcoord v0
+                mad oT0.xy, v0, c2.zwzw, c2
+                mad r0.xy, v0, c1.zwzw, c1
+                add r0.z, r0.x, c6.x
+                mul r0.z, r0.z, c5.x
+                mul r1.x, r0.z, c6.y
+                add r0.z, -r0.y, c6.x
+                add oPos.xy, r0, c0
+                mul r0.x, r0.z, c5.y
+                mul r1.y, r0.x, c6.y
+                mov r1.z, c6.x
+                dp3 oT0.w, r1, c3
+                dp3 oT0.z, r1, c4
+                mov oPos.zw, c6.xyzx
+            
+            // approximately 13 instruction slots used
+            vs_4_0
+            dcl_constantbuffer cb0[3], immediateIndexed
+            dcl_constantbuffer cb1[4], immediateIndexed
+            dcl_input v0.xy
+            dcl_output_siv o0.xyzw, position
+            dcl_output o1.xy
+            dcl_output o1.zw
+            dcl_temps 2
+            mov o0.zw, l(0,0,0,1.000000)
+            mad r0.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx
+            mov o0.xy, r0.xyxx
+            add r0.x, r0.x, l(1.000000)
+            add r0.y, -r0.y, l(1.000000)
+            mul r0.xy, r0.xyxx, cb1[3].xyxx
+            mul r1.xy, r0.xyxx, l(0.500000, 0.500000, 0.000000, 0.000000)
+            mov r1.z, l(1.000000)
+            dp3 o1.z, r1.xyzx, cb1[0].xyzx
+            dp3 o1.w, r1.xyzx, cb1[1].xyzx
+            mad o1.xy, v0.xyxx, cb0[2].zwzz, cb0[2].xyxx
+            ret 
+            // Approximately 12 instruction slots used
+                    
+        };
+        GeometryShader = NULL;
+        PixelShader = asm {
+            //
+            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+            //
+            //
+            // Buffer Definitions: 
+            //
+            // cbuffer cb2
+            // {
+            //
+            //   float3x3 DeviceSpaceToUserSpace;   // Offset:    0 Size:    44 [unused]
+            //   float2 dimensions;                 // Offset:   48 Size:     8 [unused]
+            //   float3 diff;                       // Offset:   64 Size:    12
+            //   float2 center1;                    // Offset:   80 Size:     8
+            //   float A;                           // Offset:   88 Size:     4
+            //   float radius1;                     // Offset:   92 Size:     4
+            //   float sq_radius1;                  // Offset:   96 Size:     4
+            //
+            // }
+            //
+            //
+            // Resource Bindings:
+            //
+            // Name                                 Type  Format         Dim Slot Elements
+            // ------------------------------ ---------- ------- ----------- ---- --------
+            // sMirrorSampler                    sampler      NA          NA    0        1
+            // sMaskSampler                      sampler      NA          NA    1        1
+            // tex                               texture  float4          2d    0        1
+            // mask                              texture  float4          2d    1        1
+            // cb2                               cbuffer      NA          NA    0        1
+            //
+            //
+            //
+            // Input signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Position              0   xyzw        0      POS  float       
+            // TEXCOORD                 0   xy          1     NONE  float   xy  
+            // TEXCOORD                 1     zw        1     NONE  float     zw
+            //
+            //
+            // Output signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Target                0   xyzw        0   TARGET  float   xyzw
+            //
+            //
+            // Constant buffer to DX9 shader constant mappings:
+            //
+            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
+            // ---------- ------- --------- --------- ----------------------
+            // c0         cb0             4         3  ( FLT, FLT, FLT, FLT)
+            //
+            //
+            // Sampler/Resource to DX9 shader sampler mappings:
+            //
+            // Target Sampler Source Sampler  Source Resource
+            // -------------- --------------- ----------------
+            // s0             s0              t0               
+            // s1             s1              t1               
+            //
+            //
+            // Level9 shader bytecode:
+            //
+                ps_2_x
+                def c3, 0.5, 0, 0, 0
+                def c4, 1, -1, 0, -0
+                dcl t0
+                dcl_2d s0
+                dcl_2d s1
+                add r0.xy, t0.wzzw, -c1
+                dp2add r0.w, r0, r0, -c2.x
+                mul r0.w, r0.w, c1.z
+                mov r0.z, c1.w
+                dp3 r0.x, r0, c0
+                mad r0.y, r0.x, r0.x, -r0.w
+                abs r0.z, r0.y
+                rsq r0.z, r0.z
+                rcp r1.x, r0.z
+                mov r1.yz, -r1.x
+                add r0.xzw, r0.x, r1.xyyz
+                rcp r1.x, c1.z
+                mul r0.xzw, r0, r1.x
+                mov r1.w, c1.w
+                mad r1.xyz, r0.xzww, c0.z, r1.w
+                cmp r2.x, r1.x, r0.x, r0.w
+                cmp r0.xzw, r1.xyyz, c4.xyxy, c4.zyzw
+                mov r2.y, c3.x
+                texld r1, t0, s1
+                texld r2, r2, s0
+                mul r2.xyz, r2.w, r2
+                mul r1, r1.w, r2
+                add r0.w, r0.w, r0.x
+                cmp r0.x, r0.w, r0.x, r0.z
+                cmp r1, -r0.x, c4.z, r1
+                cmp r0, r0.y, r1, c4.z
+                mov oC0, r0
+            
+            // approximately 28 instruction slots used (2 texture, 26 arithmetic)
+            ps_4_0
+            dcl_constantbuffer cb0[7], immediateIndexed
+            dcl_sampler s0, mode_default
+            dcl_sampler s1, mode_default
+            dcl_resource_texture2d (float,float,float,float) t0
+            dcl_resource_texture2d (float,float,float,float) t1
+            dcl_input_ps linear v1.xy
+            dcl_input_ps linear v1.zw
+            dcl_output o0.xyzw
+            dcl_temps 3
+            add r0.xy, v1.zwzz, -cb0[5].xyxx
+            mov r0.z, cb0[5].w
+            dp3 r0.z, r0.xyzx, cb0[4].xyzx
+            dp2 r0.x, r0.xyxx, r0.xyxx
+            add r0.x, r0.x, -cb0[6].x
+            mul r0.x, r0.x, cb0[5].z
+            mad r0.x, r0.z, r0.z, -r0.x
+            lt r0.y, r0.x, l(0.000000)
+            sqrt r1.x, |r0.x|
+            mov r1.y, -r1.x
+            add r0.xz, r0.zzzz, r1.xxyx
+            div r0.xz, r0.xxzx, cb0[5].zzzz
+            mul r1.xy, r0.xzxx, cb0[4].zzzz
+            ge r1.xy, r1.xyxx, -cb0[5].wwww
+            and r1.xy, r1.xyxx, l(0x3f800000, 0x3f800000, 0, 0)
+            add r0.x, -r0.z, r0.x
+            mad r2.x, r1.x, r0.x, r0.z
+            mov r2.y, l(0.500000)
+            sample r2.xyzw, r2.xyxx, t0.xyzw, s0
+            if_nz r0.y
+              mov o0.xyzw, l(0,0,0,0)
+              ret 
+            endif 
+            max r0.x, r1.y, r1.x
+            ge r0.x, l(0.000000), r0.x
+            if_nz r0.x
+              mov o0.xyzw, l(0,0,0,0)
+              ret 
+            endif 
+            mul r2.xyz, r2.wwww, r2.xyzx
+            sample r0.xyzw, v1.xyxx, t1.xyzw, s1
+            mul o0.xyzw, r0.wwww, r2.xyzw
+            ret 
+            // Approximately 33 instruction slots used
+                    
+        };
+    }
+
+    pass A0Mirror
+    {
+        RasterizerState = TextureRast;
+        VertexShader = asm {
+            //
+            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+            //
+            //
+            // Buffer Definitions: 
+            //
+            // cbuffer cb0
+            // {
+            //
+            //   float4 QuadDesc;                   // Offset:    0 Size:    16
+            //   float4 TexCoords;                  // Offset:   16 Size:    16 [unused]
+            //   float4 MaskTexCoords;              // Offset:   32 Size:    16
+            //
+            // }
+            //
+            // cbuffer cb2
+            // {
+            //
+            //   float3x3 DeviceSpaceToUserSpace;   // Offset:    0 Size:    44
+            //   float2 dimensions;                 // Offset:   48 Size:     8
+            //   float3 diff;                       // Offset:   64 Size:    12 [unused]
+            //   float2 center1;                    // Offset:   80 Size:     8 [unused]
+            //   float A;                           // Offset:   88 Size:     4 [unused]
+            //   float radius1;                     // Offset:   92 Size:     4 [unused]
+            //   float sq_radius1;                  // Offset:   96 Size:     4 [unused]
+            //
+            // }
+            //
+            //
+            // Resource Bindings:
+            //
+            // Name                                 Type  Format         Dim Slot Elements
+            // ------------------------------ ---------- ------- ----------- ---- --------
+            // cb0                               cbuffer      NA          NA    0        1
+            // cb2                               cbuffer      NA          NA    1        1
+            //
+            //
+            //
+            // Input signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // POSITION                 0   xyz         0     NONE  float   xy  
+            //
+            //
+            // Output signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Position              0   xyzw        0      POS  float   xyzw
+            // TEXCOORD                 0   xy          1     NONE  float   xy  
+            // TEXCOORD                 1     zw        1     NONE  float     zw
+            //
+            //
+            // Constant buffer to DX9 shader constant mappings:
+            //
+            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
+            // ---------- ------- --------- --------- ----------------------
+            // c1         cb0             0         1  ( FLT, FLT, FLT, FLT)
+            // c2         cb0             2         1  ( FLT, FLT, FLT, FLT)
+            // c3         cb1             0         2  ( FLT, FLT, FLT, FLT)
+            // c5         cb1             3         1  ( FLT, FLT, FLT, FLT)
+            //
+            //
+            // Runtime generated constant mappings:
+            //
+            // Target Reg                               Constant Description
+            // ---------- --------------------------------------------------
+            // c0                              Vertex Shader position offset
+            //
+            //
+            // Level9 shader bytecode:
+            //
+                vs_2_x
+                def c6, 1, 0.5, 0, 0
+                dcl_texcoord v0
+                mad oT0.xy, v0, c2.zwzw, c2
+                mad r0.xy, v0, c1.zwzw, c1
+                add r0.z, r0.x, c6.x
+                mul r0.z, r0.z, c5.x
+                mul r1.x, r0.z, c6.y
+                add r0.z, -r0.y, c6.x
+                add oPos.xy, r0, c0
+                mul r0.x, r0.z, c5.y
+                mul r1.y, r0.x, c6.y
+                mov r1.z, c6.x
+                dp3 oT0.w, r1, c3
+                dp3 oT0.z, r1, c4
+                mov oPos.zw, c6.xyzx
+            
+            // approximately 13 instruction slots used
+            vs_4_0
+            dcl_constantbuffer cb0[3], immediateIndexed
+            dcl_constantbuffer cb1[4], immediateIndexed
+            dcl_input v0.xy
+            dcl_output_siv o0.xyzw, position
+            dcl_output o1.xy
+            dcl_output o1.zw
+            dcl_temps 2
+            mov o0.zw, l(0,0,0,1.000000)
+            mad r0.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx
+            mov o0.xy, r0.xyxx
+            add r0.x, r0.x, l(1.000000)
+            add r0.y, -r0.y, l(1.000000)
+            mul r0.xy, r0.xyxx, cb1[3].xyxx
+            mul r1.xy, r0.xyxx, l(0.500000, 0.500000, 0.000000, 0.000000)
+            mov r1.z, l(1.000000)
+            dp3 o1.z, r1.xyzx, cb1[0].xyzx
+            dp3 o1.w, r1.xyzx, cb1[1].xyzx
+            mad o1.xy, v0.xyxx, cb0[2].zwzz, cb0[2].xyxx
+            ret 
+            // Approximately 12 instruction slots used
+                    
+        };
+        GeometryShader = NULL;
+        PixelShader = asm {
+            //
+            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+            //
+            //
+            // Buffer Definitions: 
+            //
+            // cbuffer cb2
+            // {
+            //
+            //   float3x3 DeviceSpaceToUserSpace;   // Offset:    0 Size:    44 [unused]
+            //   float2 dimensions;                 // Offset:   48 Size:     8 [unused]
+            //   float3 diff;                       // Offset:   64 Size:    12
+            //   float2 center1;                    // Offset:   80 Size:     8
+            //   float A;                           // Offset:   88 Size:     4 [unused]
+            //   float radius1;                     // Offset:   92 Size:     4
+            //   float sq_radius1;                  // Offset:   96 Size:     4 [unused]
+            //
+            // }
+            //
+            //
+            // Resource Bindings:
+            //
+            // Name                                 Type  Format         Dim Slot Elements
+            // ------------------------------ ---------- ------- ----------- ---- --------
+            // sMirrorSampler                    sampler      NA          NA    0        1
+            // sMaskSampler                      sampler      NA          NA    1        1
+            // tex                               texture  float4          2d    0        1
+            // mask                              texture  float4          2d    1        1
+            // cb2                               cbuffer      NA          NA    0        1
+            //
+            //
+            //
+            // Input signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Position              0   xyzw        0      POS  float       
+            // TEXCOORD                 0   xy          1     NONE  float   xy  
+            // TEXCOORD                 1     zw        1     NONE  float     zw
+            //
+            //
+            // Output signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Target                0   xyzw        0   TARGET  float   xyzw
+            //
+            //
+            // Constant buffer to DX9 shader constant mappings:
+            //
+            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
+            // ---------- ------- --------- --------- ----------------------
+            // c0         cb0             4         2  ( FLT, FLT, FLT, FLT)
+            //
+            //
+            // Sampler/Resource to DX9 shader sampler mappings:
+            //
+            // Target Sampler Source Sampler  Source Resource
+            // -------------- --------------- ----------------
+            // s0             s0              t0               
+            // s1             s1              t1               
+            //
+            //
+            // Level9 shader bytecode:
+            //
+                ps_2_x
+                def c2, 0.5, 0, 0, 0
+                dcl t0
+                dcl_2d s0
+                dcl_2d s1
+                mul r0.w, c1.w, c1.w
+                add r0.xy, t0.wzzw, -c1
+                dp2add r0.w, r0, r0, -r0.w
+                mul r0.w, r0.w, c2.x
+                mov r0.z, c1.w
+                dp3 r0.x, r0, c0
+                rcp r0.x, r0.x
+                mul r0.x, r0.x, r0.w
+                mov r0.y, c2.x
+                texld r1, t0, s1
+                texld r2, r0, s0
+                mov r0.w, c1.w
+                mad r0.x, r0.x, -c0.z, -r0.w
+                mul r2.xyz, r2.w, r2
+                mul r1, r1.w, r2
+                cmp r0, r0.x, c2.y, r1
+                mov oC0, r0
+            
+            // approximately 18 instruction slots used (2 texture, 16 arithmetic)
+            ps_4_0
+            dcl_constantbuffer cb0[6], immediateIndexed
+            dcl_sampler s0, mode_default
+            dcl_sampler s1, mode_default
+            dcl_resource_texture2d (float,float,float,float) t0
+            dcl_resource_texture2d (float,float,float,float) t1
+            dcl_input_ps linear v1.xy
+            dcl_input_ps linear v1.zw
+            dcl_output o0.xyzw
+            dcl_temps 2
+            add r0.xy, v1.zwzz, -cb0[5].xyxx
+            mov r0.z, cb0[5].w
+            dp3 r0.z, r0.xyzx, cb0[4].xyzx
+            dp2 r0.x, r0.xyxx, r0.xyxx
+            mad r0.x, -cb0[5].w, cb0[5].w, r0.x
+            mul r0.x, r0.x, l(0.500000)
+            div r0.x, r0.x, r0.z
+            mul r0.z, r0.x, cb0[4].z
+            ge r0.z, -cb0[5].w, r0.z
+            mov r0.y, l(0.500000)
+            sample r1.xyzw, r0.xyxx, t0.xyzw, s0
+            if_nz r0.z
+              mov o0.xyzw, l(0,0,0,0)
+              ret 
+            endif 
+            mul r1.xyz, r1.wwww, r1.xyzx
+            sample r0.xyzw, v1.xyxx, t1.xyzw, s1
+            mul o0.xyzw, r0.wwww, r1.xyzw
+            ret 
+            // Approximately 19 instruction slots used
+                    
+        };
+    }
+
 }
 
 technique10 SampleMaskedTexture
 {
     pass P0
     {
         RasterizerState = TextureRast;
         VertexShader = asm {
@@ -1616,36 +2652,36 @@ technique10 SampleTextureWithShadow
     }
 
 }
 
 #endif
 
 const BYTE d2deffect[] =
 {
-     68,  88,  66,  67, 109, 248, 
-     87, 153, 208, 172, 175,  58, 
-    169, 190, 216,  26, 197,   8, 
-    157,  19,   1,   0,   0,   0, 
-      1, 102,   0,   0,   1,   0, 
+     68,  88,  66,  67,  89, 219, 
+    143,  13, 125, 145, 119,   9, 
+    237,  27, 203,  21,   5, 113, 
+    148,  91,   1,   0,   0,   0, 
+     89, 168,   0,   0,   1,   0, 
       0,   0,  36,   0,   0,   0, 
-     70,  88,  49,  48, 213, 101, 
+     70,  88,  49,  48,  45, 168, 
       0,   0,   1,  16, 255, 254, 
       3,   0,   0,   0,  14,   0, 
-      0,   0,   8,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0, 157,  94, 
+      0,   0,  10,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,  21, 159, 
       0,   0,   0,   0,   0,   0, 
       2,   0,   0,   0,   0,   0, 
       0,   0,   2,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  14,   0, 
-      0,   0,  14,   0,   0,   0, 
+      1,   0,   0,   0,   5,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  22,   0, 
+      0,   0,  22,   0,   0,   0, 
       0,   0,   0,   0,  99,  98, 
      48,   0, 102, 108, 111,  97, 
     116,  52,   0,   8,   0,   0, 
       0,   1,   0,   0,   0,   0, 
       0,   0,   0,  16,   0,   0, 
       0,  16,   0,   0,   0,  16, 
       0,   0,   0,  10,  33,   0, 
       0,  81, 117,  97, 100,  68, 
@@ -1720,236 +2756,683 @@ const BYTE d2deffect[] =
       0,   0,   0, 115,  83,  97, 
     109, 112, 108, 101, 114,   0, 
       1,   0,   0,   0,   2,   0, 
       0,   0,  21,   0,   0,   0, 
       1,   0,   0,   0,   2,   0, 
       0,   0,   3,   0,   0,   0, 
       1,   0,   0,   0,   2,   0, 
       0,   0,   3,   0,   0,   0, 
-    115,  77,  97, 115, 107,  83, 
+    115,  87, 114,  97, 112,  83, 
      97, 109, 112, 108, 101, 114, 
       0,   1,   0,   0,   0,   2, 
       0,   0,   0,  21,   0,   0, 
       0,   1,   0,   0,   0,   2, 
-      0,   0,   0,   3,   0,   0, 
+      0,   0,   0,   1,   0,   0, 
       0,   1,   0,   0,   0,   2, 
-      0,   0,   0,   3,   0,   0, 
-      0, 115,  83, 104,  97, 100, 
-    111, 119,  83,  97, 109, 112, 
+      0,   0,   0,   1,   0,   0, 
+      0, 115,  77, 105, 114, 114, 
+    111, 114,  83,  97, 109, 112, 
     108, 101, 114,   0,   1,   0, 
       0,   0,   2,   0,   0,   0, 
      21,   0,   0,   0,   1,   0, 
       0,   0,   2,   0,   0,   0, 
-      4,   0,   0,   0,   1,   0, 
+      2,   0,   0,   0,   1,   0, 
       0,   0,   2,   0,   0,   0, 
-      4,   0,   0,   0,   4,   0, 
+      2,   0,   0,   0, 115,  77, 
+     97, 115, 107,  83,  97, 109, 
+    112, 108, 101, 114,   0,   1, 
+      0,   0,   0,   2,   0,   0, 
+      0,  21,   0,   0,   0,   1, 
+      0,   0,   0,   2,   0,   0, 
+      0,   3,   0,   0,   0,   1, 
+      0,   0,   0,   2,   0,   0, 
+      0,   3,   0,   0,   0, 115, 
+     83, 104,  97, 100, 111, 119, 
+     83,  97, 109, 112, 108, 101, 
+    114,   0,   1,   0,   0,   0, 
+      2,   0,   0,   0,  21,   0, 
+      0,   0,   1,   0,   0,   0, 
+      2,   0,   0,   0,   4,   0, 
+      0,   0,   1,   0,   0,   0, 
+      2,   0,   0,   0,   4,   0, 
+      0,   0,   4,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,  82,  97, 
-    115, 116, 101, 114, 105, 122, 
-    101, 114,  83, 116,  97, 116, 
-    101,   0, 128,   2,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   4,   0,   0,   0, 
-     84, 101, 120, 116, 117, 114, 
-    101,  82,  97, 115, 116,   0, 
-      1,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-     66, 108, 101, 110, 100,  83, 
-    116,  97, 116, 101,   0, 208, 
-      2,   0,   0,   2,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   2, 
-      0,   0,   0,  83, 104,  97, 
-    100, 111, 119,  66, 108, 101, 
-    110, 100,  72,   0,   1,   0, 
+      0,   0,  82,  97, 115, 116, 
+    101, 114, 105, 122, 101, 114, 
+     83, 116,  97, 116, 101,   0, 
+    228,   2,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,  84, 101, 
+    120, 116, 117, 114, 101,  82, 
+     97, 115, 116,   0,   1,   0, 
       0,   0,   2,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-     15,   0,   0,   0,  83, 104, 
-     97, 100, 111, 119,  66, 108, 
-    101, 110, 100,  86,   0,   1, 
-      0,   0,   0,   2,   0,   0, 
-      0,   1,   0,   0,   0,   1, 
-      0,   0,   0,   2,   0,   0, 
-      0,   2,   0,   0,   0,   1, 
-      0,   0,   0,   2,   0,   0, 
-      0,   6,   0,   0,   0,   1, 
-      0,   0,   0,   2,   0,   0, 
-      0,   1,   0,   0,   0,   1, 
-      0,   0,   0,   2,   0,   0, 
-      0,   2,   0,   0,   0,   1, 
-      0,   0,   0,   2,   0,   0, 
-      0,   6,   0,   0,   0,   1, 
+      0,   0,   2,   0,   0,   0, 
+      1,   0,   0,   0,  66, 108, 
+    101, 110, 100,  83, 116,  97, 
+    116, 101,   0,  52,   3,   0, 
+      0,   2,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
       0,   0,   0,   2,   0,   0, 
-      0,   1,   0,   0,   0,   1, 
-      0,   0,   0,   3,   0,   0, 
-      0,  15,   0,   0,   0,  83, 
-     97, 109, 112, 108, 101,  84, 
-    101, 120, 116, 117, 114, 101, 
-      0,  80,  48,   0,  36,   4, 
-      0,   0,  68,  88,  66,  67, 
-    116, 139,  68,  62,  73, 113, 
-     92,   4,  72,  76, 225, 161, 
-     30, 132, 222, 233,   1,   0, 
-      0,   0,  36,   4,   0,   0, 
-      6,   0,   0,   0,  56,   0, 
-      0,   0, 248,   0,   0,   0, 
-    244,   1,   0,   0, 112,   2, 
-      0,   0, 128,   3,   0,   0, 
-    180,   3,   0,   0,  65, 111, 
-    110,  57, 184,   0,   0,   0, 
-    184,   0,   0,   0,   0,   2, 
-    254, 255, 132,   0,   0,   0, 
-     52,   0,   0,   0,   1,   0, 
-     36,   0,   0,   0,  48,   0, 
+      0,  83, 104,  97, 100, 111, 
+    119,  66, 108, 101, 110, 100, 
+     72,   0,   1,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,  15,   0, 
+      0,   0,  83, 104,  97, 100, 
+    111, 119,  66, 108, 101, 110, 
+    100,  86,   0,   1,   0,   0, 
+      0,   2,   0,   0,   0,   1, 
+      0,   0,   0,   1,   0,   0, 
+      0,   2,   0,   0,   0,   2, 
+      0,   0,   0,   1,   0,   0, 
+      0,   2,   0,   0,   0,   6, 
+      0,   0,   0,   1,   0,   0, 
+      0,   2,   0,   0,   0,   1, 
+      0,   0,   0,   1,   0,   0, 
+      0,   2,   0,   0,   0,   2, 
+      0,   0,   0,   1,   0,   0, 
+      0,   2,   0,   0,   0,   6, 
+      0,   0,   0,   1,   0,   0, 
+      0,   2,   0,   0,   0,   1, 
+      0,   0,   0,   1,   0,   0, 
+      0,   3,   0,   0,   0,  15, 
+      0,   0,   0,  83,  97, 109, 
+    112, 108, 101,  84, 101, 120, 
+    116, 117, 114, 101,   0,  80, 
+     48,   0,  36,   4,   0,   0, 
+     68,  88,  66,  67, 116, 139, 
+     68,  62,  73, 113,  92,   4, 
+     72,  76, 225, 161,  30, 132, 
+    222, 233,   1,   0,   0,   0, 
+     36,   4,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+    248,   0,   0,   0, 244,   1, 
+      0,   0, 112,   2,   0,   0, 
+    128,   3,   0,   0, 180,   3, 
+      0,   0,  65, 111, 110,  57, 
+    184,   0,   0,   0, 184,   0, 
+      0,   0,   0,   2, 254, 255, 
+    132,   0,   0,   0,  52,   0, 
+      0,   0,   1,   0,  36,   0, 
       0,   0,  48,   0,   0,   0, 
-     36,   0,   1,   0,  48,   0, 
-      0,   0,   0,   0,   3,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   2, 
-    254, 255,  81,   0,   0,   5, 
-      4,   0,  15, 160,   0,   0, 
+     48,   0,   0,   0,  36,   0, 
+      1,   0,  48,   0,   0,   0, 
+      0,   0,   3,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   2, 254, 255, 
+     81,   0,   0,   5,   4,   0, 
+     15, 160,   0,   0,   0,   0, 
+      0,   0, 128,  63,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     31,   0,   0,   2,   5,   0, 
+      0, 128,   0,   0,  15, 144, 
+      4,   0,   0,   4,   0,   0, 
+      3, 224,   0,   0, 228, 144, 
+      2,   0, 238, 160,   2,   0, 
+    228, 160,   4,   0,   0,   4, 
+      0,   0,  12, 224,   0,   0, 
+     20, 144,   3,   0, 180, 160, 
+      3,   0,  20, 160,   4,   0, 
+      0,   4,   0,   0,   3, 128, 
+      0,   0, 228, 144,   1,   0, 
+    238, 160,   1,   0, 228, 160, 
+      2,   0,   0,   3,   0,   0, 
+      3, 192,   0,   0, 228, 128, 
+      0,   0, 228, 160,   1,   0, 
+      0,   2,   0,   0,  12, 192, 
+      4,   0,  68, 160, 255, 255, 
+      0,   0,  83,  72,  68,  82, 
+    244,   0,   0,   0,  64,   0, 
+      1,   0,  61,   0,   0,   0, 
+     89,   0,   0,   4,  70, 142, 
+     32,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,  95,   0, 
+      0,   3,  50,  16,  16,   0, 
+      0,   0,   0,   0, 103,   0, 
+      0,   4, 242,  32,  16,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0, 101,   0,   0,   3, 
+     50,  32,  16,   0,   1,   0, 
+      0,   0, 101,   0,   0,   3, 
+    194,  32,  16,   0,   1,   0, 
+      0,   0,  50,   0,   0,  11, 
+     50,  32,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      0,   0,   0,   0, 230, 138, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  70, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   8, 194,  32,  16,   0, 
+      0,   0,   0,   0,   2,  64, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0, 128,  63, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  31,   0,   0,   2, 
-      5,   0,   0, 128,   0,   0, 
-     15, 144,   4,   0,   0,   4, 
-      0,   0,   3, 224,   0,   0, 
-    228, 144,   2,   0, 238, 160, 
-      2,   0, 228, 160,   4,   0, 
-      0,   4,   0,   0,  12, 224, 
-      0,   0,  20, 144,   3,   0, 
-    180, 160,   3,   0,  20, 160, 
+     50,   0,   0,  11,  50,  32, 
+     16,   0,   1,   0,   0,   0, 
+     70,  16,  16,   0,   0,   0, 
+      0,   0, 230, 138,  32,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  70, 128,  32,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  50,   0,   0,  11, 
+    194,  32,  16,   0,   1,   0, 
+      0,   0,   6,  20,  16,   0, 
+      0,   0,   0,   0, 166, 142, 
+     32,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   6, 132, 
+     32,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   5,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     82,  68,  69,  70,   8,   1, 
+      0,   0,   1,   0,   0,   0, 
+     64,   0,   0,   0,   1,   0, 
+      0,   0,  28,   0,   0,   0, 
+      0,   4, 254, 255,   0,   1, 
+      0,   0, 212,   0,   0,   0, 
+     60,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,  99,  98,  48,   0, 
+     60,   0,   0,   0,   3,   0, 
+      0,   0,  88,   0,   0,   0, 
+     48,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    160,   0,   0,   0,   0,   0, 
+      0,   0,  16,   0,   0,   0, 
+      2,   0,   0,   0, 172,   0, 
+      0,   0,   0,   0,   0,   0, 
+    188,   0,   0,   0,  16,   0, 
+      0,   0,  16,   0,   0,   0, 
+      2,   0,   0,   0, 172,   0, 
+      0,   0,   0,   0,   0,   0, 
+    198,   0,   0,   0,  32,   0, 
+      0,   0,  16,   0,   0,   0, 
+      2,   0,   0,   0, 172,   0, 
+      0,   0,   0,   0,   0,   0, 
+     81, 117,  97, 100,  68, 101, 
+    115,  99,   0, 171, 171, 171, 
+      1,   0,   3,   0,   1,   0, 
+      4,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  84, 101, 
+    120,  67, 111, 111, 114, 100, 
+    115,   0,  77,  97, 115, 107, 
+     84, 101, 120,  67, 111, 111, 
+    114, 100, 115,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  57,  46,  50, 
+     57,  46,  57,  53,  50,  46, 
+     51,  49,  49,  49,   0, 171, 
+    171, 171,  73,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,   7,   3,   0,   0, 
+     80,  79,  83,  73,  84,  73, 
+     79,  78,   0, 171, 171, 171, 
+     79,  83,  71,  78, 104,   0, 
+      0,   0,   3,   0,   0,   0, 
+      8,   0,   0,   0,  80,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  92,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,  12,   0,   0,  92,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+     12,   3,   0,   0,  83,  86, 
+     95,  80, 111, 115, 105, 116, 
+    105, 111, 110,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171, 171, 171, 254,   3, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+    212,   2,   0,   0,  68,  88, 
+     66,  67,  22, 206,  82, 103, 
+    196, 235,  84, 233, 156,  39, 
+    210, 152,  32, 145, 169, 162, 
+      1,   0,   0,   0, 212,   2, 
+      0,   0,   6,   0,   0,   0, 
+     56,   0,   0,   0, 164,   0, 
+      0,   0,  16,   1,   0,   0, 
+    140,   1,   0,   0,  48,   2, 
+      0,   0, 160,   2,   0,   0, 
+     65, 111, 110,  57, 100,   0, 
+      0,   0, 100,   0,   0,   0, 
+      0,   2, 255, 255,  60,   0, 
+      0,   0,  40,   0,   0,   0, 
+      0,   0,  40,   0,   0,   0, 
+     40,   0,   0,   0,  40,   0, 
+      1,   0,  36,   0,   0,   0, 
+     40,   0,   0,   0,   0,   0, 
+      1,   2, 255, 255,  31,   0, 
+      0,   2,   0,   0,   0, 128, 
+      0,   0,  15, 176,  31,   0, 
+      0,   2,   0,   0,   0, 144, 
+      0,   8,  15, 160,  66,   0, 
+      0,   3,   0,   0,  15, 128, 
+      0,   0, 228, 176,   0,   8, 
+    228, 160,   1,   0,   0,   2, 
+      0,   8,  15, 128,   0,   0, 
+    228, 128, 255, 255,   0,   0, 
+     83,  72,  68,  82, 100,   0, 
+      0,   0,  64,   0,   0,   0, 
+     25,   0,   0,   0,  90,   0, 
+      0,   3,   0,  96,  16,   0, 
+      0,   0,   0,   0,  88,  24, 
+      0,   4,   0, 112,  16,   0, 
+      0,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+     50,  16,  16,   0,   1,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,  69,   0,   0,   9, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  82,  68, 
+     69,  70, 156,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    105,   0,   0,   0,  92,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+    101,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      4,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  12,   0, 
+      0,   0, 115,  83,  97, 109, 
+    112, 108, 101, 114,   0, 116, 
+    101, 120,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  57,  46,  50,  57, 
+     46,  57,  53,  50,  46,  51, 
+     49,  49,  49,   0, 171, 171, 
+     73,  83,  71,  78, 104,   0, 
+      0,   0,   3,   0,   0,   0, 
+      8,   0,   0,   0,  80,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  92,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   3,   0,   0,  92,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+     12,   0,   0,   0,  83,  86, 
+     95,  80, 111, 115, 105, 116, 
+    105, 111, 110,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     97, 114, 103, 101, 116,   0, 
+    171, 171,  58,   8,   0,   0, 
+      0,   0,   0,   0,  83,  97, 
+    109, 112, 108, 101,  82,  97, 
+    100, 105,  97, 108,  71, 114, 
+     97, 100, 105, 101, 110, 116, 
+      0,  65,  80, 111, 115,   0, 
+      4,   7,   0,   0,  68,  88, 
+     66,  67, 171,   7,  14, 215, 
+    173,  41,  24, 247, 237,   1, 
+     38,  39, 209, 221, 241, 232, 
+      1,   0,   0,   0,   4,   7, 
+      0,   0,   6,   0,   0,   0, 
+     56,   0,   0,   0, 148,   1, 
+      0,   0, 104,   3,   0,   0, 
+    228,   3,   0,   0,  96,   6, 
+      0,   0, 148,   6,   0,   0, 
+     65, 111, 110,  57,  84,   1, 
+      0,   0,  84,   1,   0,   0, 
+      0,   2, 254, 255, 252,   0, 
+      0,   0,  88,   0,   0,   0, 
+      4,   0,  36,   0,   0,   0, 
+     84,   0,   0,   0,  84,   0, 
+      0,   0,  36,   0,   1,   0, 
+     84,   0,   0,   0,   0,   0, 
+      1,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      1,   0,   2,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      2,   0,   3,   0,   0,   0, 
+      0,   0,   1,   0,   3,   0, 
+      1,   0,   5,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   2, 254, 255,  81,   0, 
+      0,   5,   6,   0,  15, 160, 
+      0,   0, 128,  63,   0,   0, 
+      0,  63,   0,   0,   0,   0, 
+      0,   0,   0,   0,  31,   0, 
+      0,   2,   5,   0,   0, 128, 
+      0,   0,  15, 144,   4,   0, 
+      0,   4,   0,   0,   3, 224, 
+      0,   0, 228, 144,   2,   0, 
+    238, 160,   2,   0, 228, 160, 
       4,   0,   0,   4,   0,   0, 
       3, 128,   0,   0, 228, 144, 
       1,   0, 238, 160,   1,   0, 
     228, 160,   2,   0,   0,   3, 
-      0,   0,   3, 192,   0,   0, 
-    228, 128,   0,   0, 228, 160, 
-      1,   0,   0,   2,   0,   0, 
-     12, 192,   4,   0,  68, 160, 
-    255, 255,   0,   0,  83,  72, 
-     68,  82, 244,   0,   0,   0, 
-     64,   0,   1,   0,  61,   0, 
+      0,   0,   4, 128,   0,   0, 
+      0, 128,   6,   0,   0, 160, 
+      5,   0,   0,   3,   0,   0, 
+      4, 128,   0,   0, 170, 128, 
+      5,   0,   0, 160,   5,   0, 
+      0,   3,   1,   0,   1, 128, 
+      0,   0, 170, 128,   6,   0, 
+     85, 160,   2,   0,   0,   3, 
+      0,   0,   4, 128,   0,   0, 
+     85, 129,   6,   0,   0, 160, 
+      2,   0,   0,   3,   0,   0, 
+      3, 192,   0,   0, 228, 128, 
+      0,   0, 228, 160,   5,   0, 
+      0,   3,   0,   0,   1, 128, 
+      0,   0, 170, 128,   5,   0, 
+     85, 160,   5,   0,   0,   3, 
+      1,   0,   2, 128,   0,   0, 
+      0, 128,   6,   0,  85, 160, 
+      1,   0,   0,   2,   1,   0, 
+      4, 128,   6,   0,   0, 160, 
+      8,   0,   0,   3,   0,   0, 
+      8, 224,   1,   0, 228, 128, 
+      3,   0, 228, 160,   8,   0, 
+      0,   3,   0,   0,   4, 224, 
+      1,   0, 228, 128,   4,   0, 
+    228, 160,   1,   0,   0,   2, 
+      0,   0,  12, 192,   6,   0, 
+     36, 160, 255, 255,   0,   0, 
+     83,  72,  68,  82, 204,   1, 
+      0,   0,  64,   0,   1,   0, 
+    115,   0,   0,   0,  89,   0, 
+      0,   4,  70, 142,  32,   0, 
+      0,   0,   0,   0,   3,   0, 
       0,   0,  89,   0,   0,   4, 
-     70, 142,  32,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
+     70, 142,  32,   0,   1,   0, 
+      0,   0,   4,   0,   0,   0, 
      95,   0,   0,   3,  50,  16, 
      16,   0,   0,   0,   0,   0, 
     103,   0,   0,   4, 242,  32, 
      16,   0,   0,   0,   0,   0, 
       1,   0,   0,   0, 101,   0, 
       0,   3,  50,  32,  16,   0, 
       1,   0,   0,   0, 101,   0, 
       0,   3, 194,  32,  16,   0, 
-      1,   0,   0,   0,  50,   0, 
-      0,  11,  50,  32,  16,   0, 
-      0,   0,   0,   0,  70,  16, 
-     16,   0,   0,   0,   0,   0, 
-    230, 138,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     70, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0, 104,   0, 
+      0,   2,   2,   0,   0,   0, 
      54,   0,   0,   8, 194,  32, 
      16,   0,   0,   0,   0,   0, 
       2,  64,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
     128,  63,  50,   0,   0,  11, 
-     50,  32,  16,   0,   1,   0, 
+     50,   0,  16,   0,   0,   0, 
       0,   0,  70,  16,  16,   0, 
       0,   0,   0,   0, 230, 138, 
      32,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,  70, 128, 
+      0,   0,   0,   0,  70, 128, 
      32,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,  50,   0, 
-      0,  11, 194,  32,  16,   0, 
-      1,   0,   0,   0,   6,  20, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5,  50,  32,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+      0,   0,   0,   7,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0, 128,  63,   0,   0, 
+      0,   8,  34,   0,  16,   0, 
+      0,   0,   0,   0,  26,   0, 
+     16, 128,  65,   0,   0,   0, 
+      0,   0,   0,   0,   1,  64, 
+      0,   0,   0,   0, 128,  63, 
+     56,   0,   0,   8,  50,   0, 
      16,   0,   0,   0,   0,   0, 
-    166, 142,  32,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      6, 132,  32,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  70, 128,  32,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,  56,   0,   0,  10, 
+     50,   0,  16,   0,   1,   0, 
+      0,   0,  70,   0,  16,   0, 
+      0,   0,   0,   0,   2,  64, 
+      0,   0,   0,   0,   0,  63, 
+      0,   0,   0,  63,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5,  66,   0, 
+     16,   0,   1,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+    128,  63,  16,   0,   0,   8, 
+     66,  32,  16,   0,   1,   0, 
+      0,   0,  70,   2,  16,   0, 
+      1,   0,   0,   0,  70, 130, 
+     32,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,  16,   0, 
+      0,   8, 130,  32,  16,   0, 
+      1,   0,   0,   0,  70,   2, 
+     16,   0,   1,   0,   0,   0, 
+     70, 130,  32,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+     50,   0,   0,  11,  50,  32, 
+     16,   0,   1,   0,   0,   0, 
+     70,  16,  16,   0,   0,   0, 
+      0,   0, 230, 138,  32,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,  70, 128,  32,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,  12,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   4,   0,   0,   0, 
+      6,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  82,  68, 
+     69,  70, 116,   2,   0,   0, 
+      2,   0,   0,   0, 100,   0, 
       0,   0,   2,   0,   0,   0, 
-     62,   0,   0,   1,  83,  84, 
-     65,  84, 116,   0,   0,   0, 
-      5,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      4,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    254, 255,   0,   1,   0,   0, 
+     67,   2,   0,   0,  92,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  82,  68,  69,  70, 
-      8,   1,   0,   0,   1,   0, 
-      0,   0,  64,   0,   0,   0, 
-      1,   0,   0,   0,  28,   0, 
-      0,   0,   0,   4, 254, 255, 
-      0,   1,   0,   0, 212,   0, 
-      0,   0,  60,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
+     96,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,  99,  98, 
-     48,   0,  60,   0,   0,   0, 
-      3,   0,   0,   0,  88,   0, 
-      0,   0,  48,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0, 160,   0,   0,   0, 
-      0,   0,   0,   0,  16,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,  99,  98,  48,   0, 
+     99,  98,  50,   0,  92,   0, 
+      0,   0,   3,   0,   0,   0, 
+    148,   0,   0,   0,  48,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  96,   0, 
+      0,   0,   7,   0,   0,   0, 
+     16,   1,   0,   0, 112,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 220,   0, 
+      0,   0,   0,   0,   0,   0, 
+     16,   0,   0,   0,   2,   0, 
+      0,   0, 232,   0,   0,   0, 
+      0,   0,   0,   0, 248,   0, 
+      0,   0,  16,   0,   0,   0, 
+     16,   0,   0,   0,   0,   0, 
+      0,   0, 232,   0,   0,   0, 
+      0,   0,   0,   0,   2,   1, 
+      0,   0,  32,   0,   0,   0, 
+     16,   0,   0,   0,   2,   0, 
+      0,   0, 232,   0,   0,   0, 
+      0,   0,   0,   0,  81, 117, 
+     97, 100,  68, 101, 115,  99, 
+      0, 171, 171, 171,   1,   0, 
+      3,   0,   1,   0,   4,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  84, 101, 120,  67, 
+    111, 111, 114, 100, 115,   0, 
+     77,  97, 115, 107,  84, 101, 
+    120,  67, 111, 111, 114, 100, 
+    115,   0, 184,   1,   0,   0, 
+      0,   0,   0,   0,  44,   0, 
       0,   0,   2,   0,   0,   0, 
-    172,   0,   0,   0,   0,   0, 
-      0,   0, 188,   0,   0,   0, 
-     16,   0,   0,   0,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-    172,   0,   0,   0,   0,   0, 
-      0,   0, 198,   0,   0,   0, 
-     32,   0,   0,   0,  16,   0, 
+    208,   1,   0,   0,   0,   0, 
+      0,   0, 224,   1,   0,   0, 
+     48,   0,   0,   0,   8,   0, 
       0,   0,   2,   0,   0,   0, 
-    172,   0,   0,   0,   0,   0, 
-      0,   0,  81, 117,  97, 100, 
-     68, 101, 115,  99,   0, 171, 
-    171, 171,   1,   0,   3,   0, 
-      1,   0,   4,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     84, 101, 120,  67, 111, 111, 
-    114, 100, 115,   0,  77,  97, 
-    115, 107,  84, 101, 120,  67, 
-    111, 111, 114, 100, 115,   0, 
-     77, 105,  99, 114, 111, 115, 
-    111, 102, 116,  32,  40,  82, 
-     41,  32,  72,  76,  83,  76, 
-     32,  83, 104,  97, 100, 101, 
-    114,  32,  67, 111, 109, 112, 
-    105, 108, 101, 114,  32,  57, 
-     46,  50,  57,  46,  57,  53, 
-     50,  46,  51,  49,  49,  49, 
-      0, 171, 171, 171,  73,  83, 
+    236,   1,   0,   0,   0,   0, 
+      0,   0, 252,   1,   0,   0, 
+     64,   0,   0,   0,  12,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   2,   0,   0,   0,   0, 
+      0,   0,  20,   2,   0,   0, 
+     80,   0,   0,   0,   8,   0, 
+      0,   0,   0,   0,   0,   0, 
+    236,   1,   0,   0,   0,   0, 
+      0,   0,  28,   2,   0,   0, 
+     88,   0,   0,   0,   4,   0, 
+      0,   0,   0,   0,   0,   0, 
+     32,   2,   0,   0,   0,   0, 
+      0,   0,  48,   2,   0,   0, 
+     92,   0,   0,   0,   4,   0, 
+      0,   0,   0,   0,   0,   0, 
+     32,   2,   0,   0,   0,   0, 
+      0,   0,  56,   2,   0,   0, 
+     96,   0,   0,   0,   4,   0, 
+      0,   0,   0,   0,   0,   0, 
+     32,   2,   0,   0,   0,   0, 
+      0,   0,  68, 101, 118, 105, 
+     99, 101,  83, 112,  97,  99, 
+    101,  84, 111,  85, 115, 101, 
+    114,  83, 112,  97,  99, 101, 
+      0, 171,   3,   0,   3,   0, 
+      3,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    100, 105, 109, 101, 110, 115, 
+    105, 111, 110, 115,   0, 171, 
+      1,   0,   3,   0,   1,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 100, 105, 
+    102, 102,   0, 171, 171, 171, 
+      1,   0,   3,   0,   1,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  99, 101, 
+    110, 116, 101, 114,  49,   0, 
+     65,   0, 171, 171,   0,   0, 
+      3,   0,   1,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 114,  97, 100, 105, 
+    117, 115,  49,   0, 115, 113, 
+     95, 114,  97, 100, 105, 117, 
+    115,  49,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  57,  46,  50,  57, 
+     46,  57,  53,  50,  46,  51, 
+     49,  49,  49,   0,  73,  83, 
      71,  78,  44,   0,   0,   0, 
       1,   0,   0,   0,   8,   0, 
       0,   0,  32,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,   7,   3, 
       0,   0,  80,  79,  83,  73, 
      84,  73,  79,  78,   0, 171, 
@@ -1967,146 +3450,443 @@ const BYTE d2deffect[] =
      92,   0,   0,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       3,   0,   0,   0,   1,   0, 
       0,   0,  12,   3,   0,   0, 
      83,  86,  95,  80, 111, 115, 
     105, 116, 105, 111, 110,   0, 
      84,  69,  88,  67,  79,  79, 
      82,  68,   0, 171, 171, 171, 
-    154,   3,   0,   0,   0,   0, 
+     52,  11,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       2,   0,   0,   0,   0,   0, 
-      0,   0, 212,   2,   0,   0, 
-     68,  88,  66,  67,  22, 206, 
-     82, 103, 196, 235,  84, 233, 
-    156,  39, 210, 152,  32, 145, 
-    169, 162,   1,   0,   0,   0, 
-    212,   2,   0,   0,   6,   0, 
+      0,   0, 220,   9,   0,   0, 
+     68,  88,  66,  67,  75, 110, 
+    115, 165, 159, 108, 132, 208, 
+    154,  90, 141,  18, 236, 102, 
+     72, 112,   1,   0,   0,   0, 
+    220,   9,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
-    164,   0,   0,   0,  16,   1, 
-      0,   0, 140,   1,   0,   0, 
-     48,   2,   0,   0, 160,   2, 
+    128,   2,   0,   0,  88,   6, 
+      0,   0, 212,   6,   0,   0, 
+     56,   9,   0,   0, 168,   9, 
       0,   0,  65, 111, 110,  57, 
-    100,   0,   0,   0, 100,   0, 
+     64,   2,   0,   0,  64,   2, 
       0,   0,   0,   2, 255, 255, 
-     60,   0,   0,   0,  40,   0, 
-      0,   0,   0,   0,  40,   0, 
-      0,   0,  40,   0,   0,   0, 
-     40,   0,   1,   0,  36,   0, 
-      0,   0,  40,   0,   0,   0, 
-      0,   0,   1,   2, 255, 255, 
-     31,   0,   0,   2,   0,   0, 
-      0, 128,   0,   0,  15, 176, 
-     31,   0,   0,   2,   0,   0, 
-      0, 144,   0,   8,  15, 160, 
-     66,   0,   0,   3,   0,   0, 
-     15, 128,   0,   0, 228, 176, 
-      0,   8, 228, 160,   1,   0, 
-      0,   2,   0,   8,  15, 128, 
-      0,   0, 228, 128, 255, 255, 
-      0,   0,  83,  72,  68,  82, 
-    100,   0,   0,   0,  64,   0, 
-      0,   0,  25,   0,   0,   0, 
+      8,   2,   0,   0,  56,   0, 
+      0,   0,   1,   0,  44,   0, 
+      0,   0,  56,   0,   0,   0, 
+     56,   0,   2,   0,  36,   0, 
+      0,   0,  56,   0,   0,   0, 
+      0,   0,   1,   1,   1,   0, 
+      0,   0,   4,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   2, 255, 255,  81,   0, 
+      0,   5,   3,   0,  15, 160, 
+      0,   0,   0,  63,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  81,   0, 
+      0,   5,   4,   0,  15, 160, 
+      0,   0, 128,  63,   0,   0, 
+    128, 191,   0,   0,   0,   0, 
+      0,   0,   0, 128,  31,   0, 
+      0,   2,   0,   0,   0, 128, 
+      0,   0,  15, 176,  31,   0, 
+      0,   2,   0,   0,   0, 144, 
+      0,   8,  15, 160,  31,   0, 
+      0,   2,   0,   0,   0, 144, 
+      1,   8,  15, 160,   2,   0, 
+      0,   3,   0,   0,   3, 128, 
+      0,   0, 235, 176,   1,   0, 
+    228, 161,  90,   0,   0,   4, 
+      0,   0,   8, 128,   0,   0, 
+    228, 128,   0,   0, 228, 128, 
+      2,   0,   0, 161,   5,   0, 
+      0,   3,   0,   0,   8, 128, 
+      0,   0, 255, 128,   1,   0, 
+    170, 160,   1,   0,   0,   2, 
+      0,   0,   4, 128,   1,   0, 
+    255, 160,   8,   0,   0,   3, 
+      0,   0,   1, 128,   0,   0, 
+    228, 128,   0,   0, 228, 160, 
+      4,   0,   0,   4,   0,   0, 
+      2, 128,   0,   0,   0, 128, 
+      0,   0,   0, 128,   0,   0, 
+    255, 129,  35,   0,   0,   2, 
+      0,   0,   4, 128,   0,   0, 
+     85, 128,   7,   0,   0,   2, 
+      0,   0,   4, 128,   0,   0, 
+    170, 128,   6,   0,   0,   2, 
+      1,   0,   1, 128,   0,   0, 
+    170, 128,   1,   0,   0,   2, 
+      1,   0,   6, 128,   1,   0, 
+      0, 129,   2,   0,   0,   3, 
+      0,   0,  13, 128,   0,   0, 
+      0, 128,   1,   0, 148, 128, 
+      6,   0,   0,   2,   1,   0, 
+      1, 128,   1,   0, 170, 160, 
+      5,   0,   0,   3,   0,   0, 
+     13, 128,   0,   0, 228, 128, 
+      1,   0,   0, 128,   1,   0, 
+      0,   2,   1,   0,   8, 128, 
+      1,   0, 255, 160,   4,   0, 
+      0,   4,   1,   0,   7, 128, 
+      0,   0, 248, 128,   0,   0, 
+    170, 160,   1,   0, 255, 128, 
+     88,   0,   0,   4,   2,   0, 
+      1, 128,   1,   0,   0, 128, 
+      0,   0,   0, 128,   0,   0, 
+    255, 128,  88,   0,   0,   4, 
+      0,   0,  13, 128,   1,   0, 
+    148, 128,   4,   0,  68, 160, 
+      4,   0, 230, 160,   1,   0, 
+      0,   2,   2,   0,   2, 128, 
+      3,   0,   0, 160,  66,   0, 
+      0,   3,   1,   0,  15, 128, 
+      0,   0, 228, 176,   1,   8, 
+    228, 160,  66,   0,   0,   3, 
+      2,   0,  15, 128,   2,   0, 
+    228, 128,   0,   8, 228, 160, 
+      5,   0,   0,   3,   2,   0, 
+      7, 128,   2,   0, 255, 128, 
+      2,   0, 228, 128,   5,   0, 
+      0,   3,   1,   0,  15, 128, 
+      1,   0, 255, 128,   2,   0, 
+    228, 128,   2,   0,   0,   3, 
+      0,   0,   8, 128,   0,   0, 
+    255, 128,   0,   0,   0, 128, 
+     88,   0,   0,   4,   0,   0, 
+      1, 128,   0,   0, 255, 128, 
+      0,   0,   0, 128,   0,   0, 
+    170, 128,  88,   0,   0,   4, 
+      1,   0,  15, 128,   0,   0, 
+      0, 129,   4,   0, 170, 160, 
+      1,   0, 228, 128,  88,   0, 
+      0,   4,   0,   0,  15, 128, 
+      0,   0,  85, 128,   1,   0, 
+    228, 128,   4,   0, 170, 160, 
+      1,   0,   0,   2,   0,   8, 
+     15, 128,   0,   0, 228, 128, 
+    255, 255,   0,   0,  83,  72, 
+     68,  82, 208,   3,   0,   0, 
+     64,   0,   0,   0, 244,   0, 
+      0,   0,  89,   0,   0,   4, 
+     70, 142,  32,   0,   0,   0, 
+      0,   0,   7,   0,   0,   0, 
      90,   0,   0,   3,   0,  96, 
      16,   0,   0,   0,   0,   0, 
+     90,   0,   0,   3,   0,  96, 
+     16,   0,   1,   0,   0,   0, 
      88,  24,   0,   4,   0, 112, 
      16,   0,   0,   0,   0,   0, 
-     85,  85,   0,   0,  98,  16, 
-      0,   3,  50,  16,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0,  69,   0, 
-      0,   9, 242,  32,  16,   0, 
-      0,   0,   0,   0,  70,  16, 
+     85,  85,   0,   0,  88,  24, 
+      0,   4,   0, 112,  16,   0, 
+      1,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+     50,  16,  16,   0,   1,   0, 
+      0,   0,  98,  16,   0,   3, 
+    194,  16,  16,   0,   1,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0, 104,   0,   0,   2, 
+      3,   0,   0,   0,   0,   0, 
+      0,   9,  50,   0,  16,   0, 
+      0,   0,   0,   0, 230,  26, 
+     16,   0,   1,   0,   0,   0, 
+     70, 128,  32, 128,  65,   0, 
+      0,   0,   0,   0,   0,   0, 
+      5,   0,   0,   0,  54,   0, 
+      0,   6,  66,   0,  16,   0, 
+      0,   0,   0,   0,  58, 128, 
+     32,   0,   0,   0,   0,   0, 
+      5,   0,   0,   0,  16,   0, 
+      0,   8,  66,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     70, 130,  32,   0,   0,   0, 
+      0,   0,   4,   0,   0,   0, 
+     15,   0,   0,   7,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,   0,  16,   0,   0,   0, 
+      0,   0,  70,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   9,  18,   0,  16,   0, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     10, 128,  32, 128,  65,   0, 
+      0,   0,   0,   0,   0,   0, 
+      6,   0,   0,   0,  56,   0, 
+      0,   8,  18,   0,  16,   0, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     42, 128,  32,   0,   0,   0, 
+      0,   0,   5,   0,   0,   0, 
+     50,   0,   0,  10,  18,   0, 
+     16,   0,   0,   0,   0,   0, 
+     42,   0,  16,   0,   0,   0, 
+      0,   0,  42,   0,  16,   0, 
+      0,   0,   0,   0,  10,   0, 
+     16, 128,  65,   0,   0,   0, 
+      0,   0,   0,   0,  49,   0, 
+      0,   7,  34,   0,  16,   0, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+      0,   0,  75,   0,   0,   6, 
+     18,   0,  16,   0,   1,   0, 
+      0,   0,  10,   0,  16, 128, 
+    129,   0,   0,   0,   0,   0, 
+      0,   0,  54,   0,   0,   6, 
+     34,   0,  16,   0,   1,   0, 
+      0,   0,  10,   0,  16, 128, 
+     65,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   7, 
+     82,   0,  16,   0,   0,   0, 
+      0,   0, 166,  10,  16,   0, 
+      0,   0,   0,   0,   6,   1, 
+     16,   0,   1,   0,   0,   0, 
+     14,   0,   0,   8,  82,   0, 
+     16,   0,   0,   0,   0,   0, 
+      6,   2,  16,   0,   0,   0, 
+      0,   0, 166, 138,  32,   0, 
+      0,   0,   0,   0,   5,   0, 
+      0,   0,  56,   0,   0,   8, 
+     50,   0,  16,   0,   1,   0, 
+      0,   0, 134,   0,  16,   0, 
+      0,   0,   0,   0, 166, 138, 
+     32,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,  29,   0, 
+      0,   9,  50,   0,  16,   0, 
+      1,   0,   0,   0,  70,   0, 
+     16,   0,   1,   0,   0,   0, 
+    246, 143,  32, 128,  65,   0, 
+      0,   0,   0,   0,   0,   0, 
+      5,   0,   0,   0,   1,   0, 
+      0,  10,  50,   0,  16,   0, 
+      1,   0,   0,   0,  70,   0, 
      16,   0,   1,   0,   0,   0, 
-     70, 126,  16,   0,   0,   0, 
-      0,   0,   0,  96,  16,   0, 
-      0,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
+      2,  64,   0,   0,   0,   0, 
+    128,  63,   0,   0, 128,  63, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   8, 
+     18,   0,  16,   0,   0,   0, 
+      0,   0,  42,   0,  16, 128, 
+     65,   0,   0,   0,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  50,   0, 
+      0,   9,  18,   0,  16,   0, 
+      2,   0,   0,   0,  10,   0, 
+     16,   0,   1,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
+      0,   0,  42,   0,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5,  34,   0,  16,   0, 
+      2,   0,   0,   0,   1,  64, 
+      0,   0,   0,   0,   0,  63, 
+     69,   0,   0,   9, 242,   0, 
+     16,   0,   2,   0,   0,   0, 
+     70,   0,  16,   0,   2,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,   0,  96, 
+     16,   0,   0,   0,   0,   0, 
+     31,   0,   4,   3,  26,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  62,   0,   0,   1, 
+     21,   0,   0,   1,  52,   0, 
+      0,   7,  18,   0,  16,   0, 
+      0,   0,   0,   0,  26,   0, 
+     16,   0,   1,   0,   0,   0, 
+     10,   0,  16,   0,   1,   0, 
+      0,   0,  29,   0,   0,   7, 
+     18,   0,  16,   0,   0,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     31,   0,   4,   3,  10,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   8, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  62,   0,   0,   1, 
+     21,   0,   0,   1,  56,   0, 
+      0,   7, 114,   0,  16,   0, 
+      2,   0,   0,   0, 246,  15, 
+     16,   0,   2,   0,   0,   0, 
+     70,   2,  16,   0,   2,   0, 
+      0,   0,  69,   0,   0,   9, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  70, 126, 
+     16,   0,   1,   0,   0,   0, 
+      0,  96,  16,   0,   1,   0, 
+      0,   0,  56,   0,   0,   7, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0, 246,  15,  16,   0, 
+      0,   0,   0,   0,  70,  14, 
+     16,   0,   2,   0,   0,   0, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+     33,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,  17,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   5,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  82,  68,  69,  70, 
+     92,   2,   0,   0,   1,   0, 
+      0,   0, 224,   0,   0,   0, 
+      5,   0,   0,   0,  28,   0, 
+      0,   0,   0,   4, 255, 255, 
+      0,   1,   0,   0,  43,   2, 
+      0,   0, 188,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     82,  68,  69,  70, 156,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,  28,   0,   0,   0, 
-      0,   4, 255, 255,   0,   1, 
-      0,   0, 105,   0,   0,   0, 
-     92,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0, 101,   0,   0,   0, 
+      0,   0,   0,   0, 197,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+    210,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      4,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  12,   0, 
+      0,   0, 214,   0,   0,   0, 
       2,   0,   0,   0,   5,   0, 
       0,   0,   4,   0,   0,   0, 
-    255, 255, 255, 255,   0,   0, 
+    255, 255, 255, 255,   1,   0, 
       0,   0,   1,   0,   0,   0, 
-     12,   0,   0,   0, 115,  83, 
-     97, 109, 112, 108, 101, 114, 
-      0, 116, 101, 120,   0,  77, 
-    105,  99, 114, 111, 115, 111, 
-    102, 116,  32,  40,  82,  41, 
-     32,  72,  76,  83,  76,  32, 
-     83, 104,  97, 100, 101, 114, 
-     32,  67, 111, 109, 112, 105, 
-    108, 101, 114,  32,  57,  46, 
-     50,  57,  46,  57,  53,  50, 
-     46,  51,  49,  49,  49,   0, 
-    171, 171,  73,  83,  71,  78, 
+     12,   0,   0,   0, 219,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+    115,  83,  97, 109, 112, 108, 
+    101, 114,   0, 115,  77,  97, 
+    115, 107,  83,  97, 109, 112, 
+    108, 101, 114,   0, 116, 101, 
+    120,   0, 109,  97, 115, 107, 
+      0,  99,  98,  50,   0, 171, 
+    219,   0,   0,   0,   7,   0, 
+      0,   0, 248,   0,   0,   0, 
+    112,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    160,   1,   0,   0,   0,   0, 
+      0,   0,  44,   0,   0,   0, 
+      0,   0,   0,   0, 184,   1, 
+      0,   0,   0,   0,   0,   0, 
+    200,   1,   0,   0,  48,   0, 
+      0,   0,   8,   0,   0,   0, 
+      0,   0,   0,   0, 212,   1, 
+      0,   0,   0,   0,   0,   0, 
+    228,   1,   0,   0,  64,   0, 
+      0,   0,  12,   0,   0,   0, 
+      2,   0,   0,   0, 236,   1, 
+      0,   0,   0,   0,   0,   0, 
+    252,   1,   0,   0,  80,   0, 
+      0,   0,   8,   0,   0,   0, 
+      2,   0,   0,   0, 212,   1, 
+      0,   0,   0,   0,   0,   0, 
+      4,   2,   0,   0,  88,   0, 
+      0,   0,   4,   0,   0,   0, 
+      2,   0,   0,   0,   8,   2, 
+      0,   0,   0,   0,   0,   0, 
+     24,   2,   0,   0,  92,   0, 
+      0,   0,   4,   0,   0,   0, 
+      2,   0,   0,   0,   8,   2, 
+      0,   0,   0,   0,   0,   0, 
+     32,   2,   0,   0,  96,   0, 
+      0,   0,   4,   0,   0,   0, 
+      2,   0,   0,   0,   8,   2, 
+      0,   0,   0,   0,   0,   0, 
+     68, 101, 118, 105,  99, 101, 
+     83, 112,  97,  99, 101,  84, 
+    111,  85, 115, 101, 114,  83, 
+    112,  97,  99, 101,   0, 171, 
+      3,   0,   3,   0,   3,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 100, 105, 
+    109, 101, 110, 115, 105, 111, 
+    110, 115,   0, 171,   1,   0, 
+      3,   0,   1,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 100, 105, 102, 102, 
+      0, 171, 171, 171,   1,   0, 
+      3,   0,   1,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  99, 101, 110, 116, 
+    101, 114,  49,   0,  65,   0, 
+    171, 171,   0,   0,   3,   0, 
+      1,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    114,  97, 100, 105, 117, 115, 
+     49,   0, 115, 113,  95, 114, 
+     97, 100, 105, 117, 115,  49, 
+      0,  77, 105,  99, 114, 111, 
+    115, 111, 102, 116,  32,  40, 
+     82,  41,  32,  72,  76,  83, 
+     76,  32,  83, 104,  97, 100, 
+    101, 114,  32,  67, 111, 109, 
+    112, 105, 108, 101, 114,  32, 
+     57,  46,  50,  57,  46,  57, 
+     53,  50,  46,  51,  49,  49, 
+     49,   0,  73,  83,  71,  78, 
     104,   0,   0,   0,   3,   0, 
       0,   0,   8,   0,   0,   0, 
      80,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       3,   0,   0,   0,   0,   0, 
       0,   0,  15,   0,   0,   0, 
      92,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       3,   0,   0,   0,   1,   0, 
       0,   0,   3,   3,   0,   0, 
      92,   0,   0,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       3,   0,   0,   0,   1,   0, 
-      0,   0,  12,   0,   0,   0, 
+      0,   0,  12,  12,   0,   0, 
      83,  86,  95,  80, 111, 115, 
     105, 116, 105, 111, 110,   0, 
      84,  69,  88,  67,  79,  79, 
      82,  68,   0, 171, 171, 171, 
      79,  83,  71,  78,  44,   0, 
       0,   0,   1,   0,   0,   0, 
       8,   0,   0,   0,  32,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  83,  86, 
      95,  84,  97, 114, 103, 101, 
-    116,   0, 171, 171, 214,   7, 
-      0,   0,   0,   0,   0,   0, 
-     83,  97, 109, 112, 108, 101, 
-     82,  97, 100, 105,  97, 108, 
-     71, 114,  97, 100, 105, 101, 
-    110, 116,   0,   4,   7,   0, 
+    116,   0, 171, 171,  80,  18, 
+      0,   0,   0,   0,   0,   0, 
+     65,  48,   0,   4,   7,   0, 
       0,  68,  88,  66,  67, 171, 
       7,  14, 215, 173,  41,  24, 
     247, 237,   1,  38,  39, 209, 
     221, 241, 232,   1,   0,   0, 
       0,   4,   7,   0,   0,   6, 
       0,   0,   0,  56,   0,   0, 
       0, 148,   1,   0,   0, 104, 
       3,   0,   0, 228,   3,   0, 
@@ -2396,382 +4176,1322 @@ const BYTE d2deffect[] =
      12,   0,   0,  92,   0,   0, 
       0,   1,   0,   0,   0,   0, 
       0,   0,   0,   3,   0,   0, 
       0,   1,   0,   0,   0,  12, 
       3,   0,   0,  83,  86,  95, 
      80, 111, 115, 105, 116, 105, 
     111, 110,   0,  84,  69,  88, 
      67,  79,  79,  82,  68,   0, 
-    171, 171, 171, 203,  10,   0, 
+    171, 171, 171,  59,  28,   0, 
       0,   0,   0,   0,   0,   1, 
       0,   0,   0,   2,   0,   0, 
-      0,   0,   0,   0,   0, 220, 
-      9,   0,   0,  68,  88,  66, 
-     67,  75, 110, 115, 165, 159, 
-    108, 132, 208, 154,  90, 141, 
-     18, 236, 102,  72, 112,   1, 
-      0,   0,   0, 220,   9,   0, 
+      0,   0,   0,   0,   0, 188, 
+      7,   0,   0,  68,  88,  66, 
+     67, 158, 207, 216, 153, 107, 
+    204, 140, 217, 118, 241, 126, 
+    175, 204, 121,  49,  49,   1, 
+      0,   0,   0, 188,   7,   0, 
       0,   6,   0,   0,   0,  56, 
-      0,   0,   0, 128,   2,   0, 
-      0,  88,   6,   0,   0, 212, 
-      6,   0,   0,  56,   9,   0, 
-      0, 168,   9,   0,   0,  65, 
-    111, 110,  57,  64,   2,   0, 
-      0,  64,   2,   0,   0,   0, 
-      2, 255, 255,   8,   2,   0, 
+      0,   0,   0, 196,   1,   0, 
+      0,  56,   4,   0,   0, 180, 
+      4,   0,   0,  24,   7,   0, 
+      0, 136,   7,   0,   0,  65, 
+    111, 110,  57, 132,   1,   0, 
+      0, 132,   1,   0,   0,   0, 
+      2, 255, 255,  76,   1,   0, 
       0,  56,   0,   0,   0,   1, 
       0,  44,   0,   0,   0,  56, 
       0,   0,   0,  56,   0,   2, 
       0,  36,   0,   0,   0,  56, 
       0,   0,   0,   0,   0,   1, 
       1,   1,   0,   0,   0,   4, 
-      0,   3,   0,   0,   0,   0, 
+      0,   2,   0,   0,   0,   0, 
       0,   0,   0,   1,   2, 255, 
-    255,  81,   0,   0,   5,   3, 
+    255,  81,   0,   0,   5,   2, 
       0,  15, 160,   0,   0,   0, 
      63,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      0,  81,   0,   0,   5,   4, 
-      0,  15, 160,   0,   0, 128, 
-     63,   0,   0, 128, 191,   0, 
-      0,   0,   0,   0,   0,   0, 
-    128,  31,   0,   0,   2,   0, 
+      0,  31,   0,   0,   2,   0, 
       0,   0, 128,   0,   0,  15, 
     176,  31,   0,   0,   2,   0, 
       0,   0, 144,   0,   8,  15, 
     160,  31,   0,   0,   2,   0, 
       0,   0, 144,   1,   8,  15, 
-    160,   2,   0,   0,   3,   0, 
-      0,   3, 128,   0,   0, 235, 
-    176,   1,   0, 228, 161,  90, 
-      0,   0,   4,   0,   0,   8, 
-    128,   0,   0, 228, 128,   0, 
-      0, 228, 128,   2,   0,   0, 
-    161,   5,   0,   0,   3,   0, 
-      0,   8, 128,   0,   0, 255, 
-    128,   1,   0, 170, 160,   1, 
-      0,   0,   2,   0,   0,   4, 
-    128,   1,   0, 255, 160,   8, 
-      0,   0,   3,   0,   0,   1, 
-    128,   0,   0, 228, 128,   0, 
-      0, 228, 160,   4,   0,   0, 
-      4,   0,   0,   2, 128,   0, 
-      0,   0, 128,   0,   0,   0, 
-    128,   0,   0, 255, 129,  35, 
-      0,   0,   2,   0,   0,   4, 
-    128,   0,   0,  85, 128,   7, 
-      0,   0,   2,   0,   0,   4, 
-    128,   0,   0, 170, 128,   6, 
-      0,   0,   2,   1,   0,   1, 
-    128,   0,   0, 170, 128,   1, 
-      0,   0,   2,   1,   0,   6, 
-    128,   1,   0,   0, 129,   2, 
-      0,   0,   3,   0,   0,  13, 
-    128,   0,   0,   0, 128,   1, 
-      0, 148, 128,   6,   0,   0, 
-      2,   1,   0,   1, 128,   1, 
-      0, 170, 160,   5,   0,   0, 
-      3,   0,   0,  13, 128,   0, 
-      0, 228, 128,   1,   0,   0, 
-    128,   1,   0,   0,   2,   1, 
+    160,   5,   0,   0,   3,   0, 
       0,   8, 128,   1,   0, 255, 
-    160,   4,   0,   0,   4,   1, 
-      0,   7, 128,   0,   0, 248, 
-    128,   0,   0, 170, 160,   1, 
-      0, 255, 128,  88,   0,   0, 
-      4,   2,   0,   1, 128,   1, 
-      0,   0, 128,   0,   0,   0, 
-    128,   0,   0, 255, 128,  88, 
-      0,   0,   4,   0,   0,  13, 
-    128,   1,   0, 148, 128,   4, 
-      0,  68, 160,   4,   0, 230, 
-    160,   1,   0,   0,   2,   2, 
-      0,   2, 128,   3,   0,   0, 
-    160,  66,   0,   0,   3,   1, 
-      0,  15, 128,   0,   0, 228, 
-    176,   1,   8, 228, 160,  66, 
-      0,   0,   3,   2,   0,  15, 
-    128,   2,   0, 228, 128,   0, 
-      8, 228, 160,   5,   0,   0, 
+    160,   1,   0, 255, 160,   2, 
+      0,   0,   3,   0,   0,   3, 
+    128,   0,   0, 235, 176,   1, 
+      0, 228, 161,  90,   0,   0, 
+      4,   0,   0,   8, 128,   0, 
+      0, 228, 128,   0,   0, 228, 
+    128,   0,   0, 255, 129,   5, 
+      0,   0,   3,   0,   0,   8, 
+    128,   0,   0, 255, 128,   2, 
+      0,   0, 160,   1,   0,   0, 
+      2,   0,   0,   4, 128,   1, 
+      0, 255, 160,   8,   0,   0, 
+      3,   0,   0,   1, 128,   0, 
+      0, 228, 128,   0,   0, 228, 
+    160,   6,   0,   0,   2,   0, 
+      0,   1, 128,   0,   0,   0, 
+    128,   5,   0,   0,   3,   0, 
+      0,   1, 128,   0,   0,   0, 
+    128,   0,   0, 255, 128,   1, 
+      0,   0,   2,   0,   0,   2, 
+    128,   2,   0,   0, 160,  66, 
+      0,   0,   3,   1,   0,  15, 
+    128,   0,   0, 228, 176,   1, 
+      8, 228, 160,  66,   0,   0, 
+      3,   2,   0,  15, 128,   0, 
+      0, 228, 128,   0,   8, 228, 
+    160,   1,   0,   0,   2,   0, 
+      0,   8, 128,   1,   0, 255, 
+    160,   4,   0,   0,   4,   0, 
+      0,   1, 128,   0,   0,   0, 
+    128,   0,   0, 170, 161,   0, 
+      0, 255, 129,   5,   0,   0, 
       3,   2,   0,   7, 128,   2, 
       0, 255, 128,   2,   0, 228, 
     128,   5,   0,   0,   3,   1, 
       0,  15, 128,   1,   0, 255, 
-    128,   2,   0, 228, 128,   2, 
-      0,   0,   3,   0,   0,   8, 
-    128,   0,   0, 255, 128,   0, 
-      0,   0, 128,  88,   0,   0, 
-      4,   0,   0,   1, 128,   0, 
-      0, 255, 128,   0,   0,   0, 
-    128,   0,   0, 170, 128,  88, 
-      0,   0,   4,   1,   0,  15, 
-    128,   0,   0,   0, 129,   4, 
-      0, 170, 160,   1,   0, 228, 
-    128,  88,   0,   0,   4,   0, 
-      0,  15, 128,   0,   0,  85, 
-    128,   1,   0, 228, 128,   4, 
-      0, 170, 160,   1,   0,   0, 
-      2,   0,   8,  15, 128,   0, 
-      0, 228, 128, 255, 255,   0, 
-      0,  83,  72,  68,  82, 208, 
-      3,   0,   0,  64,   0,   0, 
-      0, 244,   0,   0,   0,  89, 
-      0,   0,   4,  70, 142,  32, 
-      0,   0,   0,   0,   0,   7, 
-      0,   0,   0,  90,   0,   0, 
-      3,   0,  96,  16,   0,   0, 
-      0,   0,   0,  90,   0,   0, 
-      3,   0,  96,  16,   0,   1, 
-      0,   0,   0,  88,  24,   0, 
-      4,   0, 112,  16,   0,   0, 
-      0,   0,   0,  85,  85,   0, 
+    128,   2,   0, 228, 128,  88, 
+      0,   0,   4,   0,   0,  15, 
+    128,   0,   0,   0, 128,   2, 
+      0,  85, 160,   1,   0, 228, 
+    128,   1,   0,   0,   2,   0, 
+      8,  15, 128,   0,   0, 228, 
+    128, 255, 255,   0,   0,  83, 
+     72,  68,  82, 108,   2,   0, 
+      0,  64,   0,   0,   0, 155, 
+      0,   0,   0,  89,   0,   0, 
+      4,  70, 142,  32,   0,   0, 
+      0,   0,   0,   6,   0,   0, 
+      0,  90,   0,   0,   3,   0, 
+     96,  16,   0,   0,   0,   0, 
+      0,  90,   0,   0,   3,   0, 
+     96,  16,   0,   1,   0,   0, 
       0,  88,  24,   0,   4,   0, 
-    112,  16,   0,   1,   0,   0, 
-      0,  85,  85,   0,   0,  98, 
-     16,   0,   3,  50,  16,  16, 
-      0,   1,   0,   0,   0,  98, 
-     16,   0,   3, 194,  16,  16, 
-      0,   1,   0,   0,   0, 101, 
-      0,   0,   3, 242,  32,  16, 
-      0,   0,   0,   0,   0, 104, 
-      0,   0,   2,   3,   0,   0, 
-      0,   0,   0,   0,   9,  50, 
-      0,  16,   0,   0,   0,   0, 
-      0, 230,  26,  16,   0,   1, 
-      0,   0,   0,  70, 128,  32, 
-    128,  65,   0,   0,   0,   0, 
-      0,   0,   0,   5,   0,   0, 
-      0,  54,   0,   0,   6,  66, 
+    112,  16,   0,   0,   0,   0, 
+      0,  85,  85,   0,   0,  88, 
+     24,   0,   4,   0, 112,  16, 
+      0,   1,   0,   0,   0,  85, 
+     85,   0,   0,  98,  16,   0, 
+      3,  50,  16,  16,   0,   1, 
+      0,   0,   0,  98,  16,   0, 
+      3, 194,  16,  16,   0,   1, 
+      0,   0,   0, 101,   0,   0, 
+      3, 242,  32,  16,   0,   0, 
+      0,   0,   0, 104,   0,   0, 
+      2,   2,   0,   0,   0,   0, 
+      0,   0,   9,  50,   0,  16, 
+      0,   0,   0,   0,   0, 230, 
+     26,  16,   0,   1,   0,   0, 
+      0,  70, 128,  32, 128,  65, 
+      0,   0,   0,   0,   0,   0, 
+      0,   5,   0,   0,   0,  54, 
+      0,   0,   6,  66,   0,  16, 
+      0,   0,   0,   0,   0,  58, 
+    128,  32,   0,   0,   0,   0, 
+      0,   5,   0,   0,   0,  16, 
+      0,   0,   8,  66,   0,  16, 
+      0,   0,   0,   0,   0,  70, 
+      2,  16,   0,   0,   0,   0, 
+      0,  70, 130,  32,   0,   0, 
+      0,   0,   0,   4,   0,   0, 
+      0,  15,   0,   0,   7,  18, 
       0,  16,   0,   0,   0,   0, 
-      0,  58, 128,  32,   0,   0, 
-      0,   0,   0,   5,   0,   0, 
-      0,  16,   0,   0,   8,  66, 
-      0,  16,   0,   0,   0,   0, 
-      0,  70,   2,  16,   0,   0, 
-      0,   0,   0,  70, 130,  32, 
-      0,   0,   0,   0,   0,   4, 
-      0,   0,   0,  15,   0,   0, 
-      7,  18,   0,  16,   0,   0, 
+      0,  70,   0,  16,   0,   0, 
       0,   0,   0,  70,   0,  16, 
-      0,   0,   0,   0,   0,  70, 
-      0,  16,   0,   0,   0,   0, 
-      0,   0,   0,   0,   9,  18, 
+      0,   0,   0,   0,   0,  50, 
+      0,   0,  12,  18,   0,  16, 
+      0,   0,   0,   0,   0,  58,