Merge last PGO-green changeset of mozilla-inbound to mozilla-central
authorEd Morley <bmo@edmorley.co.uk>
Sat, 11 Feb 2012 01:49:07 +0000
changeset 86641 d71dab82fff4325584406ae0ffac3ba89a73f13e
parent 86605 c8aee2ac4eba4263ffa214a251432d7a0bb29643 (current diff)
parent 86640 80910c61fba9ddede17045274ce9917b218a43c4 (diff)
child 86642 7d80f315802f8ede2799940d9510d32f3eaa0d2c
child 86649 34d07393a751b78d3719fc3473e1d0e323d3d7c0
child 105821 caa3dbc75fa73f1ec96b9b7aeb02ec1332391c5a
push id22035
push userbmo@edmorley.co.uk
push dateSat, 11 Feb 2012 01:49:34 +0000
treeherdermozilla-central@d71dab82fff4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone13.0a1
first release with
nightly linux32
d71dab82fff4 / 13.0a1 / 20120211031145 / files
nightly linux64
d71dab82fff4 / 13.0a1 / 20120211031145 / files
nightly mac
d71dab82fff4 / 13.0a1 / 20120211031145 / files
nightly win32
d71dab82fff4 / 13.0a1 / 20120211031145 / files
nightly win64
d71dab82fff4 / 13.0a1 / 20120211031145 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge last PGO-green changeset of mozilla-inbound to mozilla-central
--- a/accessible/src/base/nsARIAMap.cpp
+++ b/accessible/src/base/nsARIAMap.cpp
@@ -230,18 +230,17 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] 
   },
   {
     "list",
     roles::LIST,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
-    states::READONLY,
-    eARIAMultiSelectable
+    states::READONLY
   },
   {
     "listbox",
     roles::LISTBOX,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
@@ -251,19 +250,17 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] 
   },
   {
     "listitem",
     roles::LISTITEM,
     kUseMapRole,
     eNoValue,
     eNoAction, // XXX: should depend on state, parent accessible
     eNoLiveAttr,
-    states::READONLY,
-    eARIASelectable,
-    eARIACheckedMixed
+    states::READONLY
   },
   {
     "log",
     roles::NOTHING,
     kUseNativeRole,
     eNoValue,
     eNoAction,
     ePoliteLiveAttr,
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -157,22 +157,16 @@ public:
    *
    * Accessible hierarchy may be complex for single DOM node, in this case
    * these accessibles share the same DOM node. The primary accessible "owns"
    * that DOM node in terms it gets stored in the accessible to node map.
    */
   virtual bool IsPrimaryForNode() const;
 
   /**
-   * Return the string bundle
-   */
-  static nsIStringBundle* GetStringBundle()
-    { return gStringBundle; }
-
-  /**
    * Interface methods on nsIAccessible shared with ISimpleDOM.
    */
   void Language(nsAString& aLocale);
   void ScrollTo(PRUint32 aType);
 
 protected:
     nsPresContext* GetPresContext();
 
--- a/accessible/tests/mochitest/focus/test_takeFocus.html
+++ b/accessible/tests/mochitest/focus/test_takeFocus.html
@@ -91,19 +91,19 @@
   </pre>
 
   <span id="aria-link" role="link" tabindex="0">link</span>
   <span id="aria-link2" role="link" tabindex="0">link</span>
 
   <a id="link" href="">link</span>
 
   <div role="listbox" aria-activedescendant="item1" id="container" tabindex="1">
-    <div role="listitem" id="item1">item1</div>
-    <div role="listitem" id="item2">item2</div>
-    <div role="listitem" id="item3">item3</div>
+    <div role="option" id="item1">item1</div>
+    <div role="option" id="item2">item2</div>
+    <div role="option" id="item3">item3</div>
   </div>
 
   <embed id="plugin" type="application/x-test" width="200" height="200" wmode="window"></embed>
 
   <select id="listbox" size="5">
     <option id="lb_item1">item1</option>
     <option id="lb_item2">item2</option>
   </select>
--- a/accessible/tests/mochitest/selectable/test_aria.html
+++ b/accessible/tests/mochitest/selectable/test_aria.html
@@ -32,35 +32,16 @@
 
       acc.clearSelection();
       testSelectableSelection(acc, []);
     }
 
     function doTest()
     {
       //////////////////////////////////////////////////////////////////////////
-      // role="list"
-
-      var id = "list1";
-      ok(isAccessible(id, [nsIAccessibleSelectable]),
-         "No selectable accessible for " + id);
-
-      testSelectableSelection(id, [ ]);
-
-      var select = getAccessible(id, [nsIAccessibleSelectable]);
-      select.addChildToSelection(0);
-      testSelectableSelection(id, [ ]);
-      select.removeChildFromSelection(0);
-      testSelectableSelection(id, [ ]);
-      select.selectAllSelection();
-      testSelectableSelection(id, [ ]);
-      select.clearSelection();
-      testSelectableSelection(id, [ ]);
-
-      //////////////////////////////////////////////////////////////////////////
       // role="listbox"
 
       id = "listbox1";
       ok(isAccessible(id, [nsIAccessibleSelectable]),
          "No selectable accessible for " + id);
 
       testSelectableSelection(id, [ ]);
 
@@ -77,17 +58,17 @@
       select.addChildToSelection(0);
       testSelectableSelection(id, [ "listbox2_item1" ]);
       select.removeChildFromSelection(0);
       testSelectableSelection(id, [ ]);
       select.selectAllSelection();
       testSelectableSelection(id, [ "listbox2_item1", "listbox2_item2" ]);
       select.clearSelection();
       testSelectableSelection(id, [ ]);
-
+      
       //////////////////////////////////////////////////////////////////////////
       // role="grid"
 
       id = "grid1";
       ok(isAccessible(id, [nsIAccessibleSelectable]),
          "No selectable accessible for " + id);
 
       testSelectableSelection(id, [ ]);
@@ -147,29 +128,24 @@
      title="add pseudo SelectAccessible interface">
     Mozilla Bug 590176
   </a><br>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
-  <div role="list" id="list1">
-    <div role="listitem">item1</div>
-    <div role="listitem">item2</div>
-  </div>
-
   <div role="listbox" id="listbox1">
-    <div role="listitem">item1</div>
-    <div role="listitem">item2</div>
+    <div role="option">item1</div>
+    <div role="option">item2</div>
   </div>
 
   <div role="listbox" id="listbox2" aria-multiselectable="true">
-    <div role="listitem" id="listbox2_item1">item1</div>
-    <div role="listitem" id="listbox2_item2">item2</div>
+    <div role="option" id="listbox2_item1">item1</div>
+    <div role="option" id="listbox2_item2">item2</div>
   </div>
 
   <div role="grid" id="grid1">
     <div role="row">
       <span role="gridcell">cell</span>
       <span role="gridcell">cell</span>
     </div>
     <div role="row">
--- a/accessible/tests/mochitest/test_aria_token_attrs.html
+++ b/accessible/tests/mochitest/test_aria_token_attrs.html
@@ -84,22 +84,22 @@ https://bugzilla.mozilla.org/show_bug.cg
 
       // test (listbox) multiselectable states
       testStates("listbox_multiselectable_true", STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
       testStates("listbox_multiselectable_false", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
       testStates("listbox_multiselectable_empty", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
       testStates("listbox_multiselectable_undefined", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
       testStates("listbox_multiselectable_absent", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
 
-      // test (listitem) checkable and checked states
-      testStates("listitem_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
-      testStates("listitem_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
-      testStates("listitem_checked_empty", 0 , 0, STATE_CHECKABLE | STATE_CHECKED);
-      testStates("listitem_checked_undefined", 0, 0, STATE_CHECKABLE | STATE_CHECKED);
-      testStates("listitem_checked_absent", 0, 0, STATE_CHECKABLE | STATE_CHECKED);
+      // test (option) checkable and checked states
+      testStates("option_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
+      testStates("option_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
+      testStates("option_checked_empty", 0 , 0, STATE_CHECKABLE | STATE_CHECKED);
+      testStates("option_checked_undefined", 0, 0, STATE_CHECKABLE | STATE_CHECKED);
+      testStates("option_checked_absent", 0, 0, STATE_CHECKABLE | STATE_CHECKED);
 
       // test (menuitem) checkable and checked states
       testStates("menuitem_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
       testStates("menuitem_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
       testStates("menuitem_checked_empty", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
       testStates("menuitem_checked_undefined", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
       testStates("menuitem_checked_absent", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
 
@@ -234,29 +234,29 @@ https://bugzilla.mozilla.org/show_bug.cg
 
   <div id="checkbox_disabled_true" role="checkbox" aria-disabled="true" tabindex="0">This checkbox has aria-disabled="true" and should get STATE_DISABLED.</div>
   <div id="checkbox_disabled_false" role="checkbox" aria-disabled="false">This checkbox has aria-disabled="false" and should <emph>not</emph> get STATE_DISABLED.</div>
   <div id="checkbox_disabled_empty" role="checkbox" aria-disabled="">This checkbox has aria-disabled="" and should <emph>not</emph> get STATE_DISABLED.</div>
   <div id="checkbox_disabled_undefined" role="checkbox" aria-disabled="undefined">This checkbox has aria-disabled="undefined" and should <emph>not</emph> get STATE_DISABLED.</div>
   <div id="checkbox_disabled_absent" role="checkbox">This checkbox has <emph>no</emph> aria-disabled attribute and should <emph>not</emph> get STATE_DISABLED.</div>
 
   <div id="listbox_multiselectable_true" role="listbox" aria-multiselectable="true">
-    <div id="listitem_checked_true" role="listitem" aria-checked="true">item</div>
+    <div id="option_checked_true" role="option" aria-checked="true">item</div>
   </div>
   <div id="listbox_multiselectable_false" role="listbox" aria-multiselectable="false">
-    <div id="listitem_checked_false" role="listitem" aria-checked="false">item</div>
+    <div id="option_checked_false" role="option" aria-checked="false">item</div>
   </div>
   <div id="listbox_multiselectable_empty" role="listbox" aria-multiselectable="">
-    <div id="listitem_checked_empty" role="listitem" aria-checked="">item</div>
+    <div id="option_checked_empty" role="option" aria-checked="">item</div>
   </div>
   <div id="listbox_multiselectable_undefined" role="listbox" aria-multiselectable="undefined">
-    <div id="listitem_checked_undefined" role="listitem" aria-checked="undefined">item</div>
+    <div id="option_checked_undefined" role="option" aria-checked="undefined">item</div>
   </div>
   <div id="listbox_multiselectable_absent" role="listbox">
-    <div id="listitem_checked_absent" role="listitem">item</div>
+    <div id="option_checked_absent" role="option">item</div>
   </div>
 
   <div role="menu">
     <div id="menuitem_checked_true" role="menuitem" aria-checked="true">This menuitem has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_checked.</div>
     <div id="menuitem_checked_false" role="menuitem" aria-checked="false">This menuitem has aria-checked="false" and should get STATE_CHECKABLE.</div>
     <div id="menuitem_checked_empty" role="menuitem" aria-checked="">This menuitem has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
     <div id="menuitem_checked_undefined" role="menuitem" aria-checked="undefined">This menuitem has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
     <div id="menuitem_checked_absent" role="menuitem">This menuitem has <emph>no</emph> aria-checked attribute and should <emph>not</emph> get STATE_CHECKABLE.</div>
--- a/allmakefiles.sh
+++ b/allmakefiles.sh
@@ -63,16 +63,17 @@ build/pgo/Makefile
 build/pgo/blueprint/Makefile
 build/pgo/js-input/Makefile
 config/Makefile
 config/autoconf.mk
 config/nspr/Makefile
 config/doxygen.cfg
 config/expandlibs_config.py
 config/tests/src-simple/Makefile
+mfbt/Makefile
 probes/Makefile
 extensions/Makefile
 "
 
 if [ ! "$LIBXUL_SDK" ]; then
   add_makefiles "
     memory/mozalloc/Makefile
     mozglue/Makefile
@@ -120,28 +121,34 @@ if [ "$COMPILER_DEPEND" = "" -a "$MOZ_NA
     config/mkdepend/Makefile
   "
 fi
 
 if [ "$ENABLE_TESTS" ]; then
   add_makefiles "
     build/autoconf/test/Makefile
   "
+  if [ ! "$LIBXUL_SDK" ]; then 
+    add_makefiles "
+      mozglue/tests/Makefile
+    "
+  fi
   if [ "$_MSC_VER" -a "$OS_TEST" != "x86_64" ]; then
     add_makefiles "
       build/win32/vmwarerecordinghelper/Makefile
     "
   fi
   if [ "$OS_ARCH" != "WINNT" -a "$OS_ARCH" != "OS2" ]; then 
     add_makefiles "
       build/unix/test/Makefile
     "
   fi
   if [ "$MOZ_WIDGET_TOOLKIT" = "android" ]; then
     add_makefiles "
+      build/mobile/robocop/Makefile
       build/mobile/sutagent/android/Makefile
       build/mobile/sutagent/android/fencp/Makefile
       build/mobile/sutagent/android/ffxcp/Makefile
       build/mobile/sutagent/android/watcher/Makefile
     "
   fi
 fi
 
--- a/b2g/makefiles.sh
+++ b/b2g/makefiles.sh
@@ -30,26 +30,18 @@
 # 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 *****
 
 add_makefiles "
-netwerk/locales/Makefile
-dom/locales/Makefile
-toolkit/locales/Makefile
-security/manager/locales/Makefile
 b2g/app/Makefile
 $MOZ_BRANDING_DIRECTORY/Makefile
+$MOZ_BRANDING_DIRECTORY/content/Makefile
+$MOZ_BRANDING_DIRECTORY/locales/Makefile
 b2g/chrome/Makefile
 b2g/components/Makefile
 b2g/installer/Makefile
 b2g/locales/Makefile
 b2g/Makefile
 "
-
-if test -n "$MOZ_UPDATE_PACKAGING"; then
-   add_makefiles "
-     tools/update-packaging/Makefile
-   "
-fi
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -5860,93 +5860,91 @@ function hrefAndLinkNodeForClickEvent(ev
  *        The click event.
  * @param isPanelClick
  *        Whether the event comes from a web panel.
  * @note default event is prevented if the click is handled.
  */
 function contentAreaClick(event, isPanelClick)
 {
   if (!event.isTrusted || event.defaultPrevented || event.button == 2)
-    return true;
+    return;
 
   let [href, linkNode] = hrefAndLinkNodeForClickEvent(event);
   if (!href) {
     // Not a link, handle middle mouse navigation.
     if (event.button == 1 &&
         gPrefService.getBoolPref("middlemouse.contentLoadURL") &&
         !gPrefService.getBoolPref("general.autoScroll")) {
       middleMousePaste(event);
       event.preventDefault();
     }
-    return true;
+    return;
   }
 
   // This code only applies if we have a linkNode (i.e. clicks on real anchor
   // elements, as opposed to XLink).
   if (linkNode && event.button == 0 &&
       !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
     // A Web panel's links should target the main content area.  Do this
     // if no modifier keys are down and if there's no target or the target
     // equals _main (the IE convention) or _content (the Mozilla convention).
     let target = linkNode.target;
     let mainTarget = !target || target == "_content" || target  == "_main";
     if (isPanelClick && mainTarget) {
       // javascript and data links should be executed in the current browser.
       if (linkNode.getAttribute("onclick") ||
           href.substr(0, 11) === "javascript:" ||
           href.substr(0, 5) === "data:")
-        return true;
+        return;
 
       try {
         urlSecurityCheck(href, linkNode.ownerDocument.nodePrincipal);
       }
       catch(ex) {
         // Prevent loading unsecure destinations.
         event.preventDefault();
-        return true;
+        return;
       }
 
       let postData = {};
       let url = getShortcutOrURI(href, postData);
       if (!url)
-        return true;
+        return;
       loadURI(url, null, postData.value, false);
       event.preventDefault();
-      return true;
+      return;
     }
 
     if (linkNode.getAttribute("rel") == "sidebar") {
       // This is the Opera convention for a special link that, when clicked,
       // allows to add a sidebar panel.  The link's title attribute contains
       // the title that should be used for the sidebar panel.
       PlacesUIUtils.showBookmarkDialog({ action: "add"
                                        , type: "bookmark"
                                        , uri: makeURI(href)
                                        , title: linkNode.getAttribute("title")
                                        , loadBookmarkInSidebar: true
                                        , hiddenRows: [ "description"
                                                      , "location"
                                                      , "keyword" ]
                                        }, window);
       event.preventDefault();
-      return true;
+      return;
     }
   }
 
   handleLinkClick(event, href, linkNode);
 
   // Mark the page as a user followed link.  This is done so that history can
   // distinguish automatic embed visits from user activated ones.  For example
   // pages loaded in frames are embed visits and lost with the session, while
   // visits across frames should be preserved.
   try {
     PlacesUIUtils.markPageAsFollowedLink(href);
   } catch (ex) { /* Skip invalid URIs. */ }
-
-  return true;
 }
 
 /**
  * Handles clicks on links.
  *
  * @return true if the click event was handled, false otherwise.
  */
 function handleLinkClick(event, href, linkNode) {
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -961,17 +961,17 @@
 
     <splitter id="sidebar-splitter" class="chromeclass-extrachrome" hidden="true"/>
     <vbox id="appcontent" flex="1">
       <tabbrowser id="content" disablehistory="true"
                   flex="1" contenttooltip="aHTMLTooltip"
                   tabcontainer="tabbrowser-tabs"
                   contentcontextmenu="contentAreaContextMenu"
                   autocompletepopup="PopupAutoComplete"
-                  onclick="return contentAreaClick(event, false);"/>
+                  onclick="contentAreaClick(event, false);"/>
       <statuspanel id="statusbar-display" inactive="true"/>
     </vbox>
     <splitter id="devtools-side-splitter" hidden="true"/>
     <vbox id="devtools-sidebar-box" hidden="true"
           style="min-width: 18em; width: 22em; max-width: 42em;" persist="width">
       <toolbar id="devtools-sidebar-toolbar"
                class="devtools-toolbar"
                nowindowdrag="true"/>
--- a/browser/base/content/test/browser_contentAreaClick.js
+++ b/browser/base/content/test/browser_contentAreaClick.js
@@ -227,17 +227,17 @@ function test() {
 // Click handler used to steal click events.
 let gClickHandler = {
   handleEvent: function (event) {
     let linkId = event.target.id || event.target.localName;
     is(event.type, "click",
        gCurrentTest.desc + ":Handler received a click event on " + linkId);
 
     let isPanelClick = linkId == "panellink";
-    let returnValue = gTestWin.contentAreaClick(event, isPanelClick);
+    gTestWin.contentAreaClick(event, isPanelClick);
     let prevent = event.defaultPrevented;
     is(prevent, gCurrentTest.preventDefault,
        gCurrentTest.desc + ": event.defaultPrevented is correct (" + prevent + ")")
 
     // Check that all required methods have been called.
     gCurrentTest.expectedInvokedMethods.forEach(function(aExpectedMethodName) {
       isnot(gInvokedMethods.indexOf(aExpectedMethodName), -1,
             gCurrentTest.desc + ":" + aExpectedMethodName + " was invoked");
--- a/browser/base/content/web-panels.xul
+++ b/browser/base/content/web-panels.xul
@@ -93,10 +93,10 @@
                               gContextMenu = null;">
 #include browser-context.inc
     </menupopup>
   </popupset>
 
   <commandset id="editMenuCommands"/> 
   <browser id="web-panels-browser" persist="cachedurl" type="content" flex="1"
            context="contentAreaContextMenu" tooltip="aHTMLTooltip"
-           onclick="return window.parent.contentAreaClick(event, true);"/>
+           onclick="window.parent.contentAreaClick(event, true);"/>
 </page>
--- a/browser/makefiles.sh
+++ b/browser/makefiles.sh
@@ -62,24 +62,26 @@ browser/components/privatebrowsing/src/M
 browser/components/search/Makefile
 browser/components/sessionstore/Makefile
 browser/components/sessionstore/src/Makefile
 browser/components/sidebar/Makefile
 browser/components/shell/Makefile
 browser/components/shell/public/Makefile
 browser/components/shell/src/Makefile
 browser/components/tabview/Makefile
+browser/components/thumbnails/Makefile
 browser/devtools/Makefile
 browser/devtools/debugger/Makefile
 browser/devtools/highlighter/Makefile
 browser/devtools/scratchpad/Makefile
 browser/devtools/shared/Makefile
 browser/devtools/sourceeditor/Makefile
 browser/devtools/styleeditor/Makefile
 browser/devtools/styleinspector/Makefile
+browser/devtools/tilt/Makefile
 browser/devtools/webconsole/Makefile
 browser/fuel/Makefile
 browser/fuel/public/Makefile
 browser/fuel/src/Makefile
 browser/installer/Makefile
 browser/locales/Makefile
 browser/modules/Makefile
 browser/themes/Makefile
@@ -117,38 +119,41 @@ else
     browser/themes/winstripe/Makefile
     browser/themes/winstripe/communicator/Makefile
   "
 fi
 
 if [ "$ENABLE_TESTS" ]; then
   add_makefiles "
     browser/base/content/test/Makefile
+    browser/base/content/test/newtab/Makefile
     browser/components/certerror/test/Makefile
     browser/components/dirprovider/tests/Makefile
     browser/components/preferences/tests/Makefile
     browser/components/search/test/Makefile
     browser/components/sessionstore/test/Makefile
     browser/components/shell/test/Makefile
     browser/components/feeds/test/Makefile
     browser/components/feeds/test/chrome/Makefile
     browser/components/places/tests/Makefile
     browser/components/places/tests/chrome/Makefile
     browser/components/places/tests/browser/Makefile
     browser/components/privatebrowsing/test/Makefile
     browser/components/privatebrowsing/test/browser/Makefile
     browser/components/tabview/test/Makefile
     browser/components/test/Makefile
+    browser/components/thumbnails/test/Makefile
     browser/devtools/debugger/test/Makefile
     browser/devtools/highlighter/test/Makefile
     browser/devtools/scratchpad/test/Makefile
     browser/devtools/shared/test/Makefile
     browser/devtools/sourceeditor/test/Makefile
     browser/devtools/styleeditor/test/Makefile
     browser/devtools/styleinspector/test/Makefile
+    browser/devtools/tilt/test/Makefile
     browser/devtools/webconsole/test/Makefile
     browser/fuel/test/Makefile
     browser/modules/test/Makefile
   "
   if [ "$MOZ_SAFE_BROWSING" ]; then
     add_makefiles "
       browser/components/safebrowsing/content/test/Makefile
     "
--- a/build/win32/Makefile.in
+++ b/build/win32/Makefile.in
@@ -39,28 +39,28 @@ DEPTH = ../..
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 NO_PROFILE_GUIDED_OPTIMIZE = 1
 
-ifdef ENABLE_TESTS
-
 ifdef _MSC_VER
 ifneq ($(OS_TEST),x86_64)
-DIRS += vmwarerecordinghelper
+TEST_DIRS += vmwarerecordinghelper
 endif
 endif
 
-DIRS += \
+TEST_DIRS += \
   crashinjectdll \
   $(NULL)
 
+ifdef ENABLE_TESTS
+
 PROGRAM = crashinject$(BIN_SUFFIX)
 USE_STATIC_LIBS = 1
 CPPSRCS = crashinject.cpp
 
 endif # ENABLE_TESTS
 
 MOZ_GLUE_LDFLAGS =
 
--- a/configure.in
+++ b/configure.in
@@ -5476,17 +5476,17 @@ dnl ====================================
 dnl = Disable WebSMS backend
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(websms-backend,
 [  --disable-websms-backend
                            Disable WebSMS backend],
     MOZ_WEBSMS_BACKEND=,
     MOZ_WEBSMS_BACKEND=1)
 
-if test $MOZ_WEBSMS_BACKEND -eq 1; then
+if test -n "$MOZ_WEBSMS_BACKEND"; then
     AC_DEFINE(MOZ_WEBSMS_BACKEND)
 fi
 
 dnl ========================================================
 dnl = Build Personal Security Manager
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(crypto,
 [  --disable-crypto        Disable crypto support (Personal Security Manager)],
@@ -9058,24 +9058,24 @@ if test -z "$MOZ_NATIVE_NSPR"; then
         ac_configure_args="$ac_configure_args --disable-optimize"
     fi
     if test -n "$HAVE_64BIT_OS"; then
         ac_configure_args="$ac_configure_args --enable-64bit"
     fi
     if test -n "$USE_ARM_KUSER"; then
         ac_configure_args="$ac_configure_args --with-arm-kuser"
     fi
-    if test -n "$MOZ_LINKER" -a -z "$MOZ_OLD_LINKER" -a $ac_cv_func_dladdr = no ; then
+    if test -n "$MOZ_LINKER" -a -z "$MOZ_OLD_LINKER" -a "$ac_cv_func_dladdr" = no ; then
       # dladdr is supported by the new linker, even when the system linker doesn't
       # support it. Trick nspr into using dladdr when it's not supported.
       _SAVE_CPPFLAGS="$CPPFLAGS"
       export CPPFLAGS="-include $_topsrcdir/mozglue/linker/dladdr.h $CPPFLAGS"
     fi
     AC_OUTPUT_SUBDIRS(nsprpub)
-    if test -n "$MOZ_LINKER" -a -z "$MOZ_OLD_LINKER" -a $ac_cv_func_dladdr = no; then
+    if test -n "$MOZ_LINKER" -a -z "$MOZ_OLD_LINKER" -a "$ac_cv_func_dladdr" = no; then
       unset CPPFLAGS
       CPPFLAGS="$_SAVE_CFLAGS"
     fi
     ac_configure_args="$_SUBDIR_CONFIG_ARGS"
 fi
 
 if test -z "$MOZ_NATIVE_NSPR"; then
     # Hack to deal with the fact that we use NSPR_CFLAGS everywhere
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -479,26 +479,28 @@ IsSupportedImage(const nsCString& aMimeT
     return false;
   }
 
   bool supported;
   nsresult rv = loader->SupportImageWithMimeType(aMimeType.get(), &supported);
   return NS_SUCCEEDED(rv) && supported;
 }
 
-static bool
-IsSupportedPlugin(const nsCString& aMIMEType, bool aShouldPlay)
+nsresult nsObjectLoadingContent::IsPluginEnabledForType(const nsCString& aMIMEType)
 {
+  if (!mShouldPlay) {
+    return NS_ERROR_PLUGIN_CLICKTOPLAY;
+  }
+
   nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
   nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
   if (!pluginHost) {
     return false;
   }
-  nsresult rv = pluginHost->IsPluginEnabledForType(aMIMEType.get(), aShouldPlay);
-  return NS_SUCCEEDED(rv);
+  return pluginHost->IsPluginEnabledForType(aMIMEType.get());
 }
 
 static void
 GetExtensionFromURI(nsIURI* uri, nsCString& ext)
 {
   nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
   if (url) {
     url->GetFileExtension(ext);
@@ -512,35 +514,37 @@ GetExtensionFromURI(nsIURI* uri, nsCStri
     }
   }
 }
 
 /**
  * Checks whether a plugin exists and is enabled for the extension
  * in the given URI. The MIME type is returned in the mimeType out parameter.
  */
-static bool
-IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType, bool aShouldPlay)
+bool nsObjectLoadingContent::IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType)
 {
+  if (!mShouldPlay) {
+    return false;
+  }
+
   nsCAutoString ext;
   GetExtensionFromURI(uri, ext);
 
   if (ext.IsEmpty()) {
     return false;
   }
 
   nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
   nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
   if (!pluginHost) {
     return false;
   }
 
   const char* typeFromExt;
-  if (NS_SUCCEEDED(pluginHost->IsPluginEnabledForExtension(ext.get(), typeFromExt,
-                                                           aShouldPlay))) {
+  if (NS_SUCCEEDED(pluginHost->IsPluginEnabledForExtension(ext.get(), typeFromExt))) {
     mimeType = typeFromExt;
     return true;
   }
   return false;
 }
 
 nsObjectLoadingContent::nsObjectLoadingContent()
   : mPendingInstantiateEvent(nsnull)
@@ -563,16 +567,20 @@ nsObjectLoadingContent::~nsObjectLoading
   if (mFrameLoader) {
     mFrameLoader->Destroy();
   }
 }
 
 nsresult
 nsObjectLoadingContent::InstantiatePluginInstance(const char* aMimeType, nsIURI* aURI)
 {
+  if (!mShouldPlay) {
+    return NS_ERROR_PLUGIN_CLICKTOPLAY;
+  }
+
   // Don't do anything if we already have an active instance.
   if (mInstanceOwner) {
     return NS_OK;
   }
 
   // Don't allow re-entry into initialization code.
   if (mInstantiating) {
     return NS_OK;
@@ -581,21 +589,16 @@ nsObjectLoadingContent::InstantiatePlugi
   AutoSetInstantiatingToFalse autoInstantiating(this);
 
   // Instantiating an instance can result in script execution, which
   // can destroy this DOM object. Don't allow that for the scope
   // of this method.
   nsCOMPtr<nsIObjectLoadingContent> kungFuDeathGrip = this;
   nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
 
-  nsCString typeToUse(aMimeType);
-  if (typeToUse.IsEmpty() && aURI) {
-    IsPluginEnabledByExtension(aURI, typeToUse, mShouldPlay);
-  }
-
   nsCOMPtr<nsIURI> baseURI;
   if (!aURI) {
     // We need some URI. If we have nothing else, use the base URI.
     // XXX(biesi): The code used to do this. Not sure why this is correct...
     GetObjectBaseURI(thisContent, getter_AddRefs(baseURI));
     aURI = baseURI;
   }
 
@@ -725,20 +728,20 @@ nsObjectLoadingContent::OnStartRequest(n
   // We want to use the channel type unless one of the following is true:
   //
   // 1) The channel type is application/octet-stream and we have a
   //    type hint and the type hint is not a document type.
   // 2) Our type hint is a type that we support with a plugin.
   if ((channelType.EqualsASCII(APPLICATION_OCTET_STREAM) && 
        !mContentType.IsEmpty() &&
        GetTypeOfContent(mContentType) != eType_Document) ||
-      // Need to check IsSupportedPlugin() in addition to GetTypeOfContent()
+      // Need to check IsPluginEnabledForType() in addition to GetTypeOfContent()
       // because otherwise the default plug-in's catch-all behavior would
       // confuse things.
-      (IsSupportedPlugin(mContentType, mShouldPlay) && 
+      (NS_SUCCEEDED(IsPluginEnabledForType(mContentType)) && 
        GetTypeOfContent(mContentType) == eType_Plugin)) {
     // Set the type we'll use for dispatch on the channel.  Otherwise we could
     // end up trying to dispatch to a nsFrameLoader, which will complain that
     // it couldn't find a way to handle application/octet-stream
     nsCAutoString typeHint, dummy;
     NS_ParseContentType(mContentType, typeHint, dummy);
     if (!typeHint.IsEmpty()) {
       chan->SetContentType(typeHint);
@@ -747,17 +750,17 @@ nsObjectLoadingContent::OnStartRequest(n
     mContentType = channelType;
   }
 
   nsCOMPtr<nsIURI> uri;
   chan->GetURI(getter_AddRefs(uri));
 
   if (mContentType.EqualsASCII(APPLICATION_OCTET_STREAM)) {
     nsCAutoString extType;
-    if (IsPluginEnabledByExtension(uri, extType, mShouldPlay)) {
+    if (IsPluginEnabledByExtension(uri, extType)) {
       mContentType = extType;
       chan->SetContentType(extType);
     }
   }
 
   // Now find out what type the content is
   // UnloadContent will set our type to null; need to be sure to only set it to
   // the real value on success
@@ -1292,18 +1295,18 @@ nsObjectLoadingContent::LoadObject(nsIUR
   // change the order of the declarations!
   AutoFallback fallback(this, &rv);
 
   PRUint32 caps = GetCapabilities();
   LOG(("OBJLC [%p]: Capabilities: %04x\n", this, caps));
 
   nsCAutoString overrideType;
   if ((caps & eOverrideServerType) &&
-      ((!aTypeHint.IsEmpty() && IsSupportedPlugin(aTypeHint, mShouldPlay)) ||
-       (aURI && IsPluginEnabledByExtension(aURI, overrideType, mShouldPlay)))) {
+      ((!aTypeHint.IsEmpty() && NS_SUCCEEDED(IsPluginEnabledForType(aTypeHint))) ||
+       (aURI && IsPluginEnabledByExtension(aURI, overrideType)))) {
     ObjectType newType;
     if (overrideType.IsEmpty()) {
       newType = GetTypeOfContent(aTypeHint);
     } else {
       mContentType = overrideType;
       newType = eType_Plugin;
     }
 
@@ -1429,17 +1432,17 @@ nsObjectLoadingContent::LoadObject(nsIUR
 
   // E.g. mms://
   if (!CanHandleURI(aURI)) {
     if (aTypeHint.IsEmpty()) {
       rv = NS_ERROR_NOT_AVAILABLE;
       return NS_OK;
     }
 
-    if (IsSupportedPlugin(aTypeHint, mShouldPlay)) {
+    if (NS_SUCCEEDED(IsPluginEnabledForType(aTypeHint))) {
       mType = eType_Plugin;
     } else {
       rv = NS_ERROR_NOT_AVAILABLE;
       // No plugin to load, notify of the failure.
       UpdateFallbackState(thisContent, fallback, aTypeHint);
     }
 
     return NS_OK;
@@ -1739,49 +1742,43 @@ nsObjectLoadingContent::GetTypeOfContent
 
   bool isSVG = aMIMEType.LowerCaseEqualsLiteral("image/svg+xml");
   bool supportedSVG = isSVG && (caps & eSupportSVG);
   if (((caps & eSupportDocuments) || supportedSVG) &&
       IsSupportedDocument(aMIMEType)) {
     return eType_Document;
   }
 
-  if ((caps & eSupportPlugins) && IsSupportedPlugin(aMIMEType, mShouldPlay)) {
+  if ((caps & eSupportPlugins) && NS_SUCCEEDED(IsPluginEnabledForType(aMIMEType))) {
     return eType_Plugin;
   }
 
   return eType_Null;
 }
 
 nsresult
 nsObjectLoadingContent::TypeForClassID(const nsAString& aClassID,
                                        nsACString& aType)
 {
-  nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
-  nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
-  if (!pluginHost) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
   if (StringBeginsWith(aClassID, NS_LITERAL_STRING("java:"))) {
     // Supported if we have a java plugin
     aType.AssignLiteral("application/x-java-vm");
-    nsresult rv = pluginHost->IsPluginEnabledForType("application/x-java-vm");
+    nsresult rv = IsPluginEnabledForType(NS_LITERAL_CSTRING("application/x-java-vm"));
     return NS_SUCCEEDED(rv) ? NS_OK : NS_ERROR_NOT_AVAILABLE;
   }
 
   // If it starts with "clsid:", this is ActiveX content
   if (StringBeginsWith(aClassID, NS_LITERAL_STRING("clsid:"), nsCaseInsensitiveStringComparator())) {
     // Check if we have a plugin for that
 
-    if (NS_SUCCEEDED(pluginHost->IsPluginEnabledForType("application/x-oleobject"))) {
+    if (NS_SUCCEEDED(IsPluginEnabledForType(NS_LITERAL_CSTRING("application/x-oleobject")))) {
       aType.AssignLiteral("application/x-oleobject");
       return NS_OK;
     }
-    if (NS_SUCCEEDED(pluginHost->IsPluginEnabledForType("application/oleobject"))) {
+    if (NS_SUCCEEDED(IsPluginEnabledForType(NS_LITERAL_CSTRING("application/oleobject")))) {
       aType.AssignLiteral("application/oleobject");
       return NS_OK;
     }
   }
 
   return NS_ERROR_NOT_AVAILABLE;
 }
 
@@ -1827,17 +1824,17 @@ nsObjectLoadingContent::HandleBeingBlock
     if (aRetval == nsIContentPolicy::REJECT_TYPE) {
       mUserDisabled = true;
     } else if (aRetval == nsIContentPolicy::REJECT_SERVER) {
       mSuppressed = true;
     }
   }
 }
 
-/* static */ PluginSupportState
+PluginSupportState
 nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
                                               const nsCString& aContentType)
 {
   if (!aContent->IsHTML()) {
     return ePluginOtherState;
   }
 
   if (aContent->Tag() == nsGkAtoms::embed ||
@@ -1861,26 +1858,20 @@ nsObjectLoadingContent::GetPluginSupport
         nsStyleUtil::IsSignificantChild(child, true, false);
     }
   }
 
   return hasAlternateContent ? ePluginOtherState :
     GetPluginDisabledState(aContentType);
 }
 
-/* static */ PluginSupportState
+PluginSupportState
 nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
 {
-  nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
-  nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
-  if (!pluginHost) {
-    return ePluginUnsupported;
-  }
-
-  nsresult rv = pluginHost->IsPluginEnabledForType(aContentType.get());
+  nsresult rv = IsPluginEnabledForType(aContentType);
   if (rv == NS_ERROR_PLUGIN_DISABLED)
     return ePluginDisabled;
   if (rv == NS_ERROR_PLUGIN_CLICKTOPLAY)
     return ePluginClickToPlay;
   if (rv == NS_ERROR_PLUGIN_BLOCKLISTED)
     return ePluginBlocklisted;
   return ePluginUnsupported;
 }
@@ -2112,11 +2103,12 @@ nsObjectLoadingContent::NotifyContentObj
 }
 
 NS_IMETHODIMP
 nsObjectLoadingContent::PlayPlugin()
 {
   if (!nsContentUtils::IsCallerChrome())
     return NS_OK;
 
+  mSrcStreamLoadInitiated = false;
   mShouldPlay = true;
   return LoadObject(mURI, true, mContentType, true);
 }
--- a/content/base/src/nsObjectLoadingContent.h
+++ b/content/base/src/nsObjectLoadingContent.h
@@ -323,38 +323,36 @@ class nsObjectLoadingContent : public ns
 
     /**
      * Get the plugin support state for the given content node and MIME type.
      * This is used for purposes of determining whether to fire PluginNotFound
      * events etc.  aContentType is the MIME type we ended up with.
      *
      * This should only be called if the type of this content is eType_Null.
      */
-    static PluginSupportState
-      GetPluginSupportState(nsIContent* aContent,
-                            const nsCString& aContentType);
+    PluginSupportState GetPluginSupportState(nsIContent* aContent, const nsCString& aContentType);
 
     /**
      * If the plugin for aContentType is disabled, return ePluginDisabled.
      * Otherwise (including if there is no plugin for aContentType at all),
      * return ePluginUnsupported.
      *
      * This should only be called if the type of this content is eType_Null.
      */
-    static PluginSupportState
-      GetPluginDisabledState(const nsCString& aContentType);
+    PluginSupportState GetPluginDisabledState(const nsCString& aContentType);
 
     /**
      * When there is no usable plugin available this will send UI events and
      * update the AutoFallback object appropriate to the reason for there being
      * no plugin available.
      */
-    static void
-      UpdateFallbackState(nsIContent* aContent, AutoFallback& fallback,
-                          const nsCString& aTypeHint);
+    void UpdateFallbackState(nsIContent* aContent, AutoFallback& fallback, const nsCString& aTypeHint);
+
+    nsresult IsPluginEnabledForType(const nsCString& aMIMEType);
+    bool IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType);
 
     /**
      * The final listener to ship the data to (imagelib, uriloader, etc)
      */
     nsCOMPtr<nsIStreamListener> mFinalListener;
 
     /**
      * Frame loader, for content documents we load.
--- a/content/svg/content/test/test_bounds.html
+++ b/content/svg/content/test/test_bounds.html
@@ -30,110 +30,104 @@ function Rect(left, top, width, height)
 Rect.prototype.roundOut = function()
 {
   this.width = Math.ceil(this.left + this.width) - Math.floor(this.left);
   this.height = Math.ceil(this.top + this.height) - Math.floor(this.top);
   this.left = Math.floor(this.left);
   this.top = Math.floor(this.top);
 }
 
-var delta = 1;
-
-function isApproximately(a, b, message)
+function isWithAbsTolerance(a, b, tolerance, message)
 {
-  ok(delta >= Math.abs(a - b), message + " - got " + a + ", expected " + b + " ± " + delta);
+  ok(tolerance >= Math.abs(a - b), message + " - got " + a + ", expected " + b + " ± " + tolerance);
 }
 
 function runTest()
 {
   var doc = $("svg").contentWindow.document;
 
   var text1 = doc.getElementById("text1");
 
   var text1Bounds = text1.getBoundingClientRect();
   var text2Bounds = doc.getElementById("text2").getBoundingClientRect();
   var text3Bounds = doc.getElementById("text3").getBoundingClientRect();
 
   var sin45 = Math.sin(Math.PI / 4);
 
-  isApproximately(text1Bounds.left, 24, "text1.getBoundingClientRect().left");
+  isWithAbsTolerance(text1Bounds.left, 24, 1, "text1.getBoundingClientRect().left");
 
   is(text2Bounds.left, text1Bounds.left + 100, "text2.getBoundingClientRect().left");
   is(text2Bounds.top, text1Bounds.top, "text2.getBoundingClientRect().top");
   is(text2Bounds.width, text1Bounds.width, "text2.getBoundingClientRect().width");
   is(text2Bounds.height, text1Bounds.height, "text2.getBoundingClientRect().height");
 
   var r = (text1Bounds.width + text1Bounds.height) * sin45;
-  isApproximately(text3Bounds.width, Math.ceil(r), "text3.getBoundingClientRect().width");
-  isApproximately(text3Bounds.height, Math.ceil(r), "text3.getBoundingClientRect().height");
+  isWithAbsTolerance(text3Bounds.width, Math.ceil(r), 1, "text3.getBoundingClientRect().width");
+  isWithAbsTolerance(text3Bounds.height, Math.ceil(r), 1, "text3.getBoundingClientRect().height");
 
   var rect1Bounds = doc.getElementById("rect1").getBoundingClientRect();
   var rect2Bounds = doc.getElementById("rect2").getBoundingClientRect();
   var rect3Bounds = doc.getElementById("rect3").getBoundingClientRect();
   var rect4Bounds = doc.getElementById("rect4").getBoundingClientRect();
 
   is(rect1Bounds.left, 50, "rect1.getBoundingClientRect().left");
   is(rect1Bounds.top, 50, "rect1.getBoundingClientRect().top");
   is(rect1Bounds.width, 50, "rect1.getBoundingClientRect().width");
   is(rect1Bounds.height, 50, "rect1.getBoundingClientRect().height");
 
   rect = new Rect(175 - 50 * sin45, 75 - 50 * sin45, 50 * sin45 * 2, 50 * sin45 * 2);
-  rect.roundOut();
-  is(rect2Bounds.left, rect.left, "rect2.getBoundingClientRect().left");
-  is(rect2Bounds.top, rect.top, "rect2.getBoundingClientRect().top");
-  is(rect2Bounds.width, rect.width, "rect2.getBoundingClientRect().width");
-  is(rect2Bounds.height, rect.height, "rect2.getBoundingClientRect().height");
+  isWithAbsTolerance(rect2Bounds.left, rect.left, 0.1, "rect2.getBoundingClientRect().left");
+  isWithAbsTolerance(rect2Bounds.top, rect.top, 0.1, "rect2.getBoundingClientRect().top");
+  isWithAbsTolerance(rect2Bounds.width, rect.width, 0.1, "rect2.getBoundingClientRect().width");
+  isWithAbsTolerance(rect2Bounds.height, rect.height, 0.1, "rect2.getBoundingClientRect().height");
 
   is(rect3Bounds.left, 50, "rect3.getBoundingClientRect().left");
   is(rect3Bounds.top, 160, "rect3.getBoundingClientRect().top");
   is(rect3Bounds.width, 100, "rect3.getBoundingClientRect().width");
   is(rect3Bounds.height, 100, "rect3.getBoundingClientRect().height");
 
   rect = new Rect(350 - 100 * sin45, 150 - 100 * sin45, 100 * sin45 * 2, 100 * sin45 * 2);
-  rect.roundOut();
-  is(rect4Bounds.left, rect.left, "rect4.getBoundingClientRect().left");
-  is(rect4Bounds.top, rect.top, "rect4.getBoundingClientRect().top");
-  is(rect4Bounds.width, rect.width, "rect4.getBoundingClientRect().width");
-  is(rect4Bounds.height, rect.height, "rect4.getBoundingClientRect().height");
+  isWithAbsTolerance(rect4Bounds.left, rect.left, 0.1, "rect4.getBoundingClientRect().left");
+  isWithAbsTolerance(rect4Bounds.top, rect.top, 0.1, "rect4.getBoundingClientRect().top");
+  isWithAbsTolerance(rect4Bounds.width, rect.width, 0.1, "rect4.getBoundingClientRect().width");
+  isWithAbsTolerance(rect4Bounds.height, rect.height, 0.1, "rect4.getBoundingClientRect().height");
 
   var rect1aBounds = doc.getElementById("rect1a").getBoundingClientRect();
   var rect2aBounds = doc.getElementById("rect2a").getBoundingClientRect();
   var rect3aBounds = doc.getElementById("rect3a").getBoundingClientRect();
   var rect4aBounds = doc.getElementById("rect4a").getBoundingClientRect();
 
   is(rect1aBounds.left, 48, "rect1a.getBoundingClientRect().left");
   is(rect1aBounds.top, 48, "rect1a.getBoundingClientRect().top");
   is(rect1aBounds.width, 54, "rect1a.getBoundingClientRect().width");
   is(rect1aBounds.height, 54, "rect1a.getBoundingClientRect().height");
 
   rect = new Rect(175 - 54 * sin45, 75 - 54 * sin45, 54 * sin45 * 2, 54 * sin45 * 2);
-  rect.roundOut();
-  is(rect2aBounds.left, rect.left, "rect2a.getBoundingClientRect().left");
-  is(rect2aBounds.top, rect.top, "rect2a.getBoundingClientRect().top");
-  is(rect2aBounds.width, rect.width, "rect2a.getBoundingClientRect().width");
-  is(rect2aBounds.height, rect.height, "rect2a.getBoundingClientRect().height");
+  isWithAbsTolerance(rect2aBounds.left, rect.left, 0.1, "rect2a.getBoundingClientRect().left");
+  isWithAbsTolerance(rect2aBounds.top, rect.top, 0.1, "rect2a.getBoundingClientRect().top");
+  isWithAbsTolerance(rect2aBounds.width, rect.width, 0.1, "rect2a.getBoundingClientRect().width");
+  isWithAbsTolerance(rect2aBounds.height, rect.height, 0.1, "rect2a.getBoundingClientRect().height");
 
   is(rect3aBounds.left, 46, "rect3a.getBoundingClientRect().left");
   is(rect3aBounds.top, 156, "rect3a.getBoundingClientRect().top");
   is(rect3aBounds.width, 108, "rect3a.getBoundingClientRect().width");
   is(rect3aBounds.height, 108, "rect3a.getBoundingClientRect().height");
 
   rect = new Rect(350 - 108 * sin45, 150 - 108 * sin45, 108 * sin45 * 2, 108 * sin45 * 2);
-  rect.roundOut();
-  is(rect4aBounds.left, rect.left, "rect4a.getBoundingClientRect().left");
-  is(rect4aBounds.top, rect.top, "rect4a.getBoundingClientRect().top");
-  is(rect4aBounds.width, rect.width, "rect4a.getBoundingClientRect().width");
-  is(rect4aBounds.height, rect.height, "rect4a.getBoundingClientRect().height");
+  isWithAbsTolerance(rect4aBounds.left, rect.left, 0.1, "rect4a.getBoundingClientRect().left");
+  isWithAbsTolerance(rect4aBounds.top, rect.top, 0.1, "rect4a.getBoundingClientRect().top");
+  isWithAbsTolerance(rect4aBounds.width, rect.width, 0.1, "rect4a.getBoundingClientRect().width");
+  isWithAbsTolerance(rect4aBounds.height, rect.height, 0.1, "rect4a.getBoundingClientRect().height");
 
   var text1a = doc.getElementById("text1a");
 
   var text1aBounds = text1a.getBoundingClientRect();
   var text2aBounds = doc.getElementById("text2a").getBoundingClientRect();
 
-  isApproximately(text1aBounds.left, 82, "text1a.getBoundingClientRect().left");
+  isWithAbsTolerance(text1aBounds.left, 82, 1, "text1a.getBoundingClientRect().left");
   is(text1aBounds.width, text1Bounds.width + 4, "text1a.getBoundingClientRect().width");
 
   is(text2aBounds.left, text1aBounds.left + 100 - 3, "text2a.getBoundingClientRect().left");
   is(text2aBounds.width, text1aBounds.width + 6, "text2a.getBoundingClientRect().width");
 
   SimpleTest.finish();
 }
 
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -1363,42 +1363,34 @@ nsPluginHost::TrySetUpPluginInstance(con
 #endif
 
   return rv;
 }
 
 nsresult
 nsPluginHost::IsPluginEnabledForType(const char* aMimeType)
 {
-  // If plugins.click_to_play is false, plugins should always play
-  return IsPluginEnabledForType(aMimeType,
-                                !Preferences::GetBool("plugins.click_to_play", false));
-}
-
-nsresult
-nsPluginHost::IsPluginEnabledForType(const char* aMimeType, bool aShouldPlay)
-{
   nsPluginTag *plugin = FindPluginForType(aMimeType, true);
   if (plugin)
-    return aShouldPlay ? NS_OK : NS_ERROR_PLUGIN_CLICKTOPLAY;
+    return NS_OK;
 
   // Pass false as the second arg so we can return NS_ERROR_PLUGIN_DISABLED
   // for disabled plug-ins.
   plugin = FindPluginForType(aMimeType, false);
   if (!plugin)
     return NS_ERROR_FAILURE;
 
   if (!plugin->IsEnabled()) {
     if (plugin->HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED))
       return NS_ERROR_PLUGIN_BLOCKLISTED;
     else
       return NS_ERROR_PLUGIN_DISABLED;
   }
 
-  return aShouldPlay ? NS_OK : NS_ERROR_PLUGIN_CLICKTOPLAY;
+  return NS_OK;
 }
 
 // check comma delimitered extensions
 static int CompareExtensions(const char *aExtensionList, const char *aExtension)
 {
   if (!aExtensionList || !aExtension)
     return -1;
 
@@ -1417,31 +1409,22 @@ static int CompareExtensions(const char 
     pComma = strchr(pExt, ',');
   }
 
   // the last one
   return PL_strcasecmp(pExt, aExtension);
 }
 
 nsresult
-nsPluginHost::IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType)
-{
-  // If plugins.click_to_play is false, plugins should always play
-  return IsPluginEnabledForExtension(aExtension, aMimeType,
-                                     !Preferences::GetBool("plugins.click_to_play", false));
-}
-
-nsresult
 nsPluginHost::IsPluginEnabledForExtension(const char* aExtension,
-                                          const char* &aMimeType,
-                                          bool aShouldPlay)
+                                          const char* &aMimeType)
 {
   nsPluginTag *plugin = FindPluginEnabledForExtension(aExtension, aMimeType);
   if (plugin)
-    return aShouldPlay ? NS_OK : NS_ERROR_PLUGIN_CLICKTOPLAY;
+    return NS_OK;
 
   return NS_ERROR_FAILURE;
 }
 
 class DOMMimeTypeImpl : public nsIDOMMimeType {
 public:
   NS_DECL_ISUPPORTS
 
--- a/dom/plugins/base/nsPluginHost.h
+++ b/dom/plugins/base/nsPluginHost.h
@@ -115,21 +115,18 @@ public:
   nsresult LoadPlugins();
   nsresult InstantiatePluginForChannel(nsIChannel* aChannel,
                                        nsObjectLoadingContent* aContent,
                                        nsIStreamListener** aListener);
   nsresult SetUpPluginInstance(const char *aMimeType,
                                nsIURI *aURL,
                                nsIPluginInstanceOwner *aOwner);
   nsresult IsPluginEnabledForType(const char* aMimeType);
-  nsresult IsPluginEnabledForType(const char* aMimeType,
-                                  bool aShouldPlay);
   nsresult IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType);
-  nsresult IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType,
-                                       bool aShouldPlay);
+
   nsresult GetPluginCount(PRUint32* aPluginCount);
   nsresult GetPlugins(PRUint32 aPluginCount, nsIDOMPlugin** aPluginArray);
 
   nsresult GetURL(nsISupports* pluginInst,
                   const char* url,
                   const char* target,
                   nsIPluginStreamListener* streamListener,
                   const char* altHost,
--- a/dom/sms/Makefile.in
+++ b/dom/sms/Makefile.in
@@ -40,14 +40,14 @@ srcdir           = @srcdir@
 VPATH            = @srcdir@
 
 relativesrcdir   = dom/sms
 
 include $(DEPTH)/config/autoconf.mk
 
 PARALLEL_DIRS = interfaces src
 
+TEST_DIRS += tests
 ifdef ENABLE_TESTS
-DIRS += tests
 XPCSHELL_TESTS = tests
 endif
 
 include $(topsrcdir)/config/rules.mk
--- a/dom/wifi/nsWifiWorker.js
+++ b/dom/wifi/nsWifiWorker.js
@@ -488,16 +488,17 @@ var WifiManager = (function() {
       debug("Unable to get wpa supplicant's status");
       return;
     }
 
     var lines = status.split("\n");
     for (let i = 0; i < lines.length; ++i) {
       let [key, value] = lines[i].split("=");
       if (key === "wpa_state") {
+        notify("statechange", { state: value });
         if (value === "COMPLETED")
           onconnected();
       }
     }
   }
 
   // try to connect to the supplicant
   var connectTries = 0;
@@ -559,37 +560,38 @@ var WifiManager = (function() {
             });
           });
         });
       });
     });
   }
 
   var supplicantStatesMap = ["DISCONNECTED", "INACTIVE", "SCANNING", "ASSOCIATING",
-                             "FOUR_WAY_HANDSHAKE", "GROUP_HANDSHAKE", "COMPLETED",
-                             "DORMANT", "UNINITIALIZED"];
+                             "ASSOCIATED", "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);
+    var space = event.indexOf(" ");
+    var eventData = event.substr(0, space + 1);
     if (eventData.indexOf("CTRL-EVENT-STATE-CHANGE") === 0) {
       // Parse the event data
       var fields = {};
-      var tokens = eventData.split(" ");
+      var tokens = event.substr(space + 1).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];
@@ -625,17 +627,17 @@ var WifiManager = (function() {
       // 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 });
       onconnected();
       return true;
     }
     if (eventData.indexOf("CTRL-EVENT-SCAN-RESULTS") === 0) {
-      debug("Notifying of scn results available");
+      debug("Notifying of scan results available");
       notify("scanresultsavailable");
       return true;
     }
     // unknown event
     return true;
   }
 
   // Initial state
@@ -799,27 +801,68 @@ function nsWifiWorker() {
     WifiManager.getMacAddress(function (mac) {
       debug("Got mac: " + mac);
     });
   }
   WifiManager.onsupplicantlost = function() {
     debug("Couldn't connect to supplicant");
   }
 
+  var state;
+  WifiManager.onstatechange = function() {
+    debug("State change: " + state + " -> " + this.state);
+    if (state === "SCANNING" && this.state === "INACTIVE") {
+      // We're not trying to connect so try to find an open Mozilla network.
+      // TODO Remove me in favor of UI and a way to select a network.
+
+      debug("Haven't connected to a network, trying a default (for now)");
+      var name = "Mozilla";
+      var net = networks[name];
+      if (net && (net[1] && net[1] !== "[IBSS]")) {
+        debug("Network Mozilla exists, but is encrypted");
+        net = null;
+      }
+      if (!net) {
+        name = "Mozilla Guest";
+        net = networks[name];
+        if (!net || (net[1] && net[1] !== "[IBSS]")) {
+          debug("Network Mozilla Guest doesn't exist or is encrypted");
+          return;
+        }
+      }
+
+      var config = Object.create(null);
+      config["ssid"] = '"' + name + '"';
+      config["key_mgmt"] = "NONE";
+      WifiManager.addNetwork(config, function(ok) {
+        if (!ok) {
+          debug("Unable to add the network!");
+          return;
+        }
+
+        WifiManager.enableNetwork(config.netId, false, function(ok) {
+          debug((ok ? "Successfully enabled " : "Didn't enable ") + name);
+        });
+      });
+    }
+
+    state = this.state;
+  }
+
   var networks = Object.create(null);
   WifiManager.onscanresultsavailable = function() {
     debug("Scan results are available! Asking for them.");
     WifiManager.getScanResults(function(r) {
       let lines = r.split("\n");
       // NB: Skip the header line.
       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];
+          networks[match[5]] = [match[1], match[4]];
         else
           debug("Match didn't find anything for: " + lines[i]);
       }
     });
   }
 
   WifiManager.setWifiEnabled(true, function (ok) {
       if (ok === 0)
--- a/embedding/Makefile.in
+++ b/embedding/Makefile.in
@@ -43,19 +43,19 @@ VPATH		= @srcdir@
 relativesrcdir = embedding
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE       = embed
 
 DIRS = base components browser
 
+TEST_DIRS += test
 ifdef ENABLE_TESTS
 XPCSHELL_TESTS = tests/unit
-DIRS += test
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),android)
 ifneq (,$(filter mobile/xul b2g,$(MOZ_BUILD_APP)))
 DIRS += android
 endif
 endif
 
--- a/embedding/android/GeckoAppShell.java
+++ b/embedding/android/GeckoAppShell.java
@@ -598,16 +598,21 @@ public class GeckoAppShell
         if (newEnd < 0)
             GeckoApp.surfaceView.inputConnection.notifySelectionChange(
                 imm, start, end);
         else
             GeckoApp.surfaceView.inputConnection.notifyTextChange(
                 imm, text, start, end, newEnd);
     }
 
+    public static void notifyScreenShot(ByteBuffer data, int tabId, int width, int height) {
+        // this stub is never called in XUL Fennec, but we need it so that the JNI code
+        // shared between XUL and Native Fennec doesn't die.
+    }
+
     private static CountDownLatch sGeckoPendingAcks = null;
 
     // Block the current thread until the Gecko event loop is caught up
     synchronized public static void geckoEventSync() {
         sGeckoPendingAcks = new CountDownLatch(1);
         GeckoAppShell.sendEventToGecko(
             new GeckoEvent(GeckoEvent.GECKO_EVENT_SYNC));
         while (sGeckoPendingAcks.getCount() != 0) {
--- a/ipc/chromium/src/base/file_util_linux.cc
+++ b/ipc/chromium/src/base/file_util_linux.cc
@@ -1,15 +1,18 @@
 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include "base/file_util.h"
 
 #include <fcntl.h>
+#if defined(ANDROID) || defined(OS_POSIX)
+#include <unistd.h>
+#endif
 
 #include <string>
 #include <vector>
 
 #include "base/eintr_wrapper.h"
 #include "base/file_path.h"
 #include "base/string_util.h"
 
--- a/ipc/chromium/src/base/message_pump_libevent.cc
+++ b/ipc/chromium/src/base/message_pump_libevent.cc
@@ -1,16 +1,19 @@
 // Copyright (c) 2008 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include "base/message_pump_libevent.h"
 
 #include <errno.h>
 #include <fcntl.h>
+#if defined(ANDROID) || defined(OS_POSIX)
+#include <unistd.h>
+#endif
 
 #include "eintr_wrapper.h"
 #include "base/logging.h"
 #include "base/scoped_nsautorelease_pool.h"
 #include "base/scoped_ptr.h"
 #include "base/time.h"
 #include "third_party/libevent/event.h"
 
--- a/ipc/chromium/src/base/time_posix.cc
+++ b/ipc/chromium/src/base/time_posix.cc
@@ -8,16 +8,19 @@
 #include <mach/mach_time.h>
 #endif
 #include <sys/time.h>
 #ifdef ANDROID
 #include <time64.h>
 #else
 #include <time.h>
 #endif
+#if defined(ANDROID) || defined(OS_POSIX)
+#include <unistd.h>
+#endif
 
 #include <limits>
 
 #include "base/basictypes.h"
 #include "base/logging.h"
 
 namespace base {
 
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1213,16 +1213,19 @@ nsLayoutUtils::MatrixTransformPoint(cons
 }
 
 gfx3DMatrix
 nsLayoutUtils::GetTransformToAncestor(nsIFrame *aFrame, nsIFrame *aAncestor)
 {
   nsIFrame* parent;
   gfx3DMatrix ctm = aFrame->GetTransformMatrix(aAncestor, &parent);
   while (parent && parent != aAncestor) {
+    if (!parent->Preserves3DChildren()) {
+      ctm.ProjectTo2D();
+    }
     ctm = ctm * parent->GetTransformMatrix(aAncestor, &parent);
   }
   return ctm;
 }
 
 static gfxPoint
 TransformGfxPointFromAncestor(nsIFrame *aFrame,
                               const gfxPoint &aPoint,
--- a/layout/base/tests/Makefile.in
+++ b/layout/base/tests/Makefile.in
@@ -178,16 +178,17 @@ DEFINES += -D_IMPL_NS_LAYOUT
 		bug583889_inner1.html \
 		bug583889_inner2.html \
 		test_bug582771.html \
 		test_bug603550.html \
 		test_bug629838.html \
 		test_bug646757.html \
 		test_bug718809.html \
 		test_font_inflation_reftests.html \
+		test_bug725426.html \
 		$(NULL)
 
 # Tests for bugs 441782, 467672 and 570378 don't pass reliably on Windows, because of bug 469208
 ifeq (,$(filter windows,$(MOZ_WIDGET_TOOLKIT)))
 # THESE TESTS (BELOW) DO NOT RUN ON WINDOWS
 _TEST_FILES += \
 		bidi_numeral_test.js \
 		$(NULL)
--- a/layout/base/tests/test_bug435293-scale.html
+++ b/layout/base/tests/test_bug435293-scale.html
@@ -65,37 +65,37 @@ https://bugzilla.mozilla.org/show_bug.cg
 </div>
 
 <pre id="test">
 <script type="application/javascript">
 runtests();
 
 function runtests() {
   var style = window.getComputedStyle(document.getElementById("test1"), "");
-  is(style.getPropertyValue("-moz-transform"), "matrix(0.5, 0, 0, 1, 0px, 0px)",
+  is(style.getPropertyValue("-moz-transform"), "matrix(0.5, 0, 0, 1, 0, 0)",
      "Scalex proper matrix is applied");
 
   style = window.getComputedStyle(document.getElementById("test2"), "");
-  is(style.getPropertyValue("-moz-transform"), "matrix(1, 0, 0, 0.5, 0px, 0px)",
+  is(style.getPropertyValue("-moz-transform"), "matrix(1, 0, 0, 0.5, 0, 0)",
      "Scaley proper matrix is applied");
 
   style = window.getComputedStyle(document.getElementById("test3"), "");
-  is(style.getPropertyValue("-moz-transform"), "matrix(0.5, 0, 0, 0.5, 0px, 0px)",
+  is(style.getPropertyValue("-moz-transform"), "matrix(0.5, 0, 0, 0.5, 0, 0)",
      "Scale proper matrix is applied");
 
   style = window.getComputedStyle(document.getElementById("test4"), "");
   is(style.getPropertyValue("-moz-transform"), "none",
      "Three dimensional scale should be ignored");
 
   style = window.getComputedStyle(document.getElementById("test5"), "");
   is(style.getPropertyValue("-moz-transform"), "none",
      "Percent values in scale should be ignored");
 
   style = window.getComputedStyle(document.getElementById("test6"), "");
-  is(style.getPropertyValue("-moz-transform"), "matrix(640000, 0, 0, 1e-19, 0px, 0px)",
+  is(style.getPropertyValue("-moz-transform"), "matrix(640000, 0, 0, 1e-19, 0, 0)",
      "Ensure wacky values are accepted");
 
   style = window.getComputedStyle(document.getElementById("test7"), "");
   is(style.getPropertyValue("-moz-transform"), "none",
      "No unit values allowed in scale");
 }
 </script>
 </pre>
--- a/layout/base/tests/test_bug435293-skew.html
+++ b/layout/base/tests/test_bug435293-skew.html
@@ -86,84 +86,84 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 <pre id="test">
 <script type="application/javascript">
 runtests();
 
 function runtests() {
   // For test 1 we need to handle the contingency that different systems may
   // round differently.  We will parse out the values and compare them
-  // individually.  The matrix should be: matrix(1, 0, 0.57735, 1, 0px, 0px)
+  // individually.  The matrix should be: matrix(1, 0, 0.57735, 1, 0, 0)
   var style = window.getComputedStyle(document.getElementById("test1"), "");
   var tformStyle = style.getPropertyValue("-moz-transform");
   var tformValues = tformStyle.substring(tformStyle.indexOf('(') + 1,
                                          tformStyle.indexOf(')')).split(',');
   is((+tformValues[0]), 1, "Test1: skewx: param 0 is 1");
   is((+tformValues[1]), 0, "Test1: skewx: param 1 is 0");
   ok(verifyRounded(tformValues[2], 0.57735), "Test1: skewx: Rounded param 2 is in bounds");
   is((+tformValues[3]), 1, "Test1: skewx: param 3 is 1");
-  is(tformValues[4].trim(), "0px", "Test1: skewx: param 4 is 0px");
-  is(tformValues[5].trim(), "0px", "Test1: skewx: param 5 is 0px");
+  is((+tformValues[4]), 0, "Test1: skewx: param 4 is 0");
+  is((+tformValues[5]), 0, "Test1: skewx: param 5 is 0");
 
   // Again, handle rounding for test 2, proper matrix should be:
-  // matrix(1, 1.73205, 0, 1, 0px, 0px)
+  // matrix(1, 1.73205, 0, 1, 0, 0)
   style = window.getComputedStyle(document.getElementById("test2"), "");
   tformStyle = style.getPropertyValue("-moz-transform");
   tformValues = tformStyle.substring(tformStyle.indexOf('(') + 1,
                                      tformStyle.indexOf(')')).split(',');
   is((+tformValues[0]), 1, "Test2: skewy: param 0 is 1");
   ok(verifyRounded(tformValues[1], 1.73205), "Test2: skewy: Rounded param 1 is in bounds");
   is((+tformValues[2]), 0, "Test2: skewy: param 2 is 0");
   is((+tformValues[3]), 1, "Test2: skewy: param 3 is 1");
-  is(tformValues[4].trim(), "0px", "Test2: skewy: param 4 is 0px");
-  is(tformValues[5].trim(), "0px", "Test2: skewy: param 5 is 0px");
+  is((+tformValues[4]), 0, "Test2: skewy: param 4 is 0");
+  is((+tformValues[5]), 0, "Test2: skewy: param 5 is 0");
 
   style = window.getComputedStyle(document.getElementById("test3"), "");
-  is(style.getPropertyValue("-moz-transform"), "matrix(1, 1, 1, 1, 0px, 0px)",
+  is(style.getPropertyValue("-moz-transform"), "matrix(1, 1, 1, 1, 0, 0)",
      "Test3: Skew proper matrix is applied");
 
   style = window.getComputedStyle(document.getElementById("test4"), "");
-  is(style.getPropertyValue("-moz-transform"), "matrix(1, 1, 0, 1, 0px, 0px)",
+  is(style.getPropertyValue("-moz-transform"), "matrix(1, 1, 0, 1, 0, 0)",
      "Test4: Skew angle wrap: proper matrix is applied");
 
   style = window.getComputedStyle(document.getElementById("test5"), "");
-  is(style.getPropertyValue("-moz-transform"), "matrix(1, -1, 1, 1, 0px, 0px)",
+  is(style.getPropertyValue("-moz-transform"), "matrix(1, -1, 1, 1, 0, 0)",
      "Test5: Skew mixing deg and grad");
 
   style = window.getComputedStyle(document.getElementById("test6"), "");
   is(style.getPropertyValue("-moz-transform"), "none",
      "Test6: Skew with invalid units");
 
   style = window.getComputedStyle(document.getElementById("test7"), "");
   is(style.getPropertyValue("-moz-transform"), "none",
      "Test7: Skew with more invalid units");
 
   // Test 8: skew with negative degrees, here again we must handle rounding.
-  // The matrix should be: matrix(1, 3.73206, -1, 1, 0px, 0px)
+  // The matrix should be: matrix(1, 3.73206, -1, 1, 0, 0)
   style = window.getComputedStyle(document.getElementById("test8"), "");
   tformStyle = style.getPropertyValue("-moz-transform");
   tformValues = tformStyle.substring(tformStyle.indexOf('(') + 1,
                                      tformStyle.indexOf(')')).split(',');
   is(tformValues[0], 1, "Test8: Test skew with negative degrees-param 0 is 1");
   ok(verifyRounded(tformValues[1], 3.73206), "Test8: Rounded param 1 is in bounds");
   is((+tformValues[2]), -1, "Test8: param 2 is -1");
   is((+tformValues[3]), 1, "Test8: param 3 is 1");
-  is(tformValues[4].trim(), "0px", "Test8: param 4 is 0px");
-  is(tformValues[5].trim(), "0px", "Test8: param 5 is 0px");
+  is((+tformValues[4]), 0, "Test8: param 4 is 0");
+  is((+tformValues[5]), 0, "Test8: param 5 is 0");
 
   style = window.getComputedStyle(document.getElementById("test9"), "");
   is(style.getPropertyValue("-moz-transform"), "none",
      "Test9: Skew in 3d should be ignored");
 
   style = window.getComputedStyle(document.getElementById("test10"), "");
-  is(style.getPropertyValue("-moz-transform"), "matrix(1, -10000, 1, 1, 0px, 0px)",
+  is(style.getPropertyValue("-moz-transform"), "matrix(1, -10000, 1, 1, 0, 0)",
      "Test10: Skew with nearly infinite numbers");
 
   style = window.getComputedStyle(document.getElementById("test11"), "");
-  is(style.getPropertyValue("-moz-transform"), "matrix(1, -10000, 10000, 1, 0px, 0px)",
+  is(style.getPropertyValue("-moz-transform"), "matrix(1, -10000, 10000, 1, 0, 0)",
      "Test11: Skew with more infinite numbers");
 }
 
 // Verifies that aVal is +/- 0.00001 of aTrueVal
 // Returns true if so, false if not
 function verifyRounded(aVal, aTrueVal) {
   return (Math.abs(aVal - aTrueVal).toFixed(5) <= 0.00001);
 }
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/test_bug725426.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=725426
+-->
+<title>Test for bug 725426</title>
+<script src=/tests/SimpleTest/SimpleTest.js></script>
+<link rel=stylesheet href=/tests/SimpleTest/test.css>
+<body style=margin:0>
+<div style="-moz-transform: perspective(200px)">
+<div style="-moz-transform: translatez(-100px);
+width:100px;height:100px;background:blue">
+</div></div>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=725426">
+Mozilla Bug 725426</a>
+<pre id=test>
+<script class=testbody>
+var rect = document.querySelector("div>div").getBoundingClientRect();
+is(rect.top, 0, "Incorrect bounding rect top");
+is(rect.right, 100, "Incorrect bounding rect top");
+is(rect.bottom, 100, "Incorrect bounding rect top");
+is(rect.left, 0, "Incorrect bounding rect top");
+</script>
+</pre>
--- a/layout/build/nsContentDLF.cpp
+++ b/layout/build/nsContentDLF.cpp
@@ -305,17 +305,17 @@ nsContentDLF::CreateInstance(const char*
                           aChannel, aLoadGroup,
                           aContainer, kImageDocumentCID,
                           aDocListener, aDocViewer);
   }
 
   nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
   nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
   if(pluginHost &&
-     NS_SUCCEEDED(pluginHost->IsPluginEnabledForType(aContentType, true))) {
+     NS_SUCCEEDED(pluginHost->IsPluginEnabledForType(aContentType))) {
     return CreateDocument(aCommand,
                           aChannel, aLoadGroup,
                           aContainer, kPluginDocumentCID,
                           aDocListener, aDocViewer);
   }
 
   // If we get here, then we weren't able to create anything. Sorry!
   return NS_ERROR_FAILURE;
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -1078,17 +1078,21 @@ nsColumnSetFrame::Reflow(nsPresContext* 
       aReflowState.availableHeight == NS_UNCONSTRAINEDSIZE) {
     // In this situation, we might be lying about our reflow status, because
     // our last kid (the one that got interrupted) was incomplete.  Fix that.
     aStatus = NS_FRAME_COMPLETE;
   }
   
   CheckInvalidateSizeChange(aDesiredSize);
 
-  FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
+  // XXXjwir3: This call should be replaced with FinishWithAbsoluteFrames
+  //           when bug 724978 is fixed and nsColumnSetFrame is a full absolute
+  //           container.
+  FinishAndStoreOverflow(&aDesiredSize);
+
   aDesiredSize.mCarriedOutBottomMargin = carriedOutBottomMargin;
 
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
 
   NS_ASSERTION(NS_FRAME_IS_FULLY_COMPLETE(aStatus) ||
                aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE,
                "Column set should be complete if the available height is unconstrained");
 
--- a/layout/reftests/abs-pos/reftest.list
+++ b/layout/reftests/abs-pos/reftest.list
@@ -8,11 +8,13 @@ fails-if(/^Windows\x20NT\x206\.1/.test(h
 == continuation-positioned-inline-1.html continuation-positioned-inline-ref.html
 == continuation-positioned-inline-2.html continuation-positioned-inline-ref.html
 == scrollframe-1.html scrollframe-1-ref.html
 == scrollframe-2.html scrollframe-2-ref.html
 == select-1.html select-1-ref.html
 == select-1-dynamic.html select-1-ref.html
 == select-2.html select-2-ref.html
 == select-3.html select-3-ref.html
-== multi-column-1.html multi-column-1-ref.html
+
+# Fails due to bug 724978. Should be re-enabled once this is fixed.
+fails == multi-column-1.html multi-column-1-ref.html
 == button-1.html button-1-ref.html
 == button-2.html button-2-ref.html
--- a/layout/reftests/backgrounds/vector/empty/reftest.list
+++ b/layout/reftests/backgrounds/vector/empty/reftest.list
@@ -1,22 +1,23 @@
 == tall--contain--height.html ref-tall-empty.html
 == tall--contain--width.html ref-tall-empty.html
 == wide--contain--height.html ref-wide-empty.html
 == wide--contain--width.html ref-wide-empty.html
 
-# Either OS X 32-bit or 10.5, judging from imprecise Tinderbox results, renders
-# these tests as empty boxes, not filled boxes.  We don't really care about this
+# We don't really care about the failures for this
 # extreme edge case (the test exists more to test for safety against division by
 # zero), so there is no bug has been filed to fix it, although a patch would
 # probably be accepted.
-random-if(cocoaWidget) == tall--cover--height.html ref-tall-lime.html
-random-if(cocoaWidget) == tall--cover--width.html ref-tall-lime.html
-random-if(cocoaWidget) == wide--cover--height.html ref-wide-lime.html
-random-if(cocoaWidget) == wide--cover--width.html ref-wide-lime.html
+# They're still marked as failing though, rather than 'load', since
+# we want to know if they start working when we upgrade to Azure.
+fails == tall--cover--height.html ref-tall-lime.html
+fails == tall--cover--width.html ref-tall-lime.html
+fails == wide--cover--height.html ref-wide-lime.html
+fails == wide--cover--width.html ref-wide-lime.html
 
 == zero-height-ratio-contain.html ref-tall-empty.html
 == zero-height-ratio-cover.html ref-tall-empty.html
 == zero-height-ratio-auto-auto.html ref-tall-empty.html
 == zero-height-ratio-auto-5px.html ref-tall-empty.html
 == zero-height-ratio-5px-auto.html ref-tall-empty.html
 == zero-width-ratio-contain.html ref-tall-empty.html
 == zero-width-ratio-cover.html ref-tall-empty.html
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -678,21 +678,23 @@ fails-if(Android) != 376532-3.html 37653
 == 378935-1.html 378935-1-ref.html
 == 378937-1.html 378937-1-ref.html
 == 379178-xhtml.xhtml 379178-xhtml-ref.xhtml
 == 379178-html.html 379178-html-ref.html
 == 379178-svg.svg 379178-svg-ref.svg
 == 379316-1.html 379316-1-ref.html
 fails-if(Android) random-if(cocoaWidget) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 379316-2.html 379316-2-ref.html # bug 379786
 == 379328-1.html 379328-1-ref.html
-== 379349-1a.xhtml 379349-1-ref.xhtml
-== 379349-1b.xhtml 379349-1-ref.xhtml
-== 379349-1c.xhtml 379349-1-ref.xhtml
-== 379349-2a.xhtml 379349-2-ref.xhtml
-== 379349-2b.xhtml 379349-2-ref.xhtml
+# The next set of reftests all fail until bug 724978 has been fixed, and the
+# overflow container ability of nsColumnSetFrame is restored.
+fails == 379349-1a.xhtml 379349-1-ref.xhtml
+fails == 379349-1b.xhtml 379349-1-ref.xhtml
+fails == 379349-1c.xhtml 379349-1-ref.xhtml
+fails == 379349-2a.xhtml 379349-2-ref.xhtml
+fails == 379349-2b.xhtml 379349-2-ref.xhtml
 == 379349-3a.xhtml 379349-3-ref.xhtml
 == 379349-3b.xhtml 379349-3-ref.xhtml
 == 379361-1.html 379361-1-ref.html
 == 379361-2.html 379361-2-ref.html
 == 379361-3.html 379361-3-ref.html
 == 379461-1.xhtml 379461-1.html
 == 379461-2.xhtml 379461-2.html
 == 379461-3-container-xhtml.html 379461-3-container-html.html
copy from layout/reftests/transform/abspos-1a.html
copy to layout/reftests/transform/abspos-1f.html
--- a/layout/reftests/transform/abspos-1a.html
+++ b/layout/reftests/transform/abspos-1f.html
@@ -1,12 +1,12 @@
 <html>
 <head>
 </head>
 <body>
-  <div style="width: 100px; height: 200px; -moz-transform: translate(50px, 50px); background-color: gold;">
+  <div style="width: 100px; height: 200px; -moz-transform: translate(50px, 50px); background-color: gold; display: table">
     A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
     <div style="background-color: navy; color: gold; width: 200px; height: 100px; position: absolute; left: 50px; top: 100px;">
       0 1 2 3 4 5 6 7 8 9
     </div>
   </div>
 </body>
 </html>
copy from layout/reftests/transform/abspos-1b.html
copy to layout/reftests/transform/abspos-1g.html
--- a/layout/reftests/transform/abspos-1b.html
+++ b/layout/reftests/transform/abspos-1g.html
@@ -1,12 +1,12 @@
 <html>
 <head>
 </head>
 <body>
-  <div style="width: 100px; height: 200px; -moz-transform: translate(50px, 50px) ;background-color: gold;">
+  <div style="width: 100px; height: 200px; -moz-transform: translate(50px, 50px) ;background-color: gold;display: inline-table">
     A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
     <div style="background-color: navy; color: gold; width: 200px; height: 100px; position: fixed; left: 50px; top: 100px;">
       0 1 2 3 4 5 6 7 8 9
     </div>
   </div>
 </body>
 </html>
--- a/layout/reftests/transform/reftest.list
+++ b/layout/reftests/transform/reftest.list
@@ -61,16 +61,18 @@ random == rotate-1f.html rotate-1-ref.ht
 == percent-1f.html percent-1-ref.html
 == percent-1g.html percent-1-ref.html
 # Transformed elements are abs-pos and fixed-pos containing blocks.
 == abspos-1a.html abspos-1-ref.html
 == abspos-1b.html abspos-1-ref.html
 == abspos-1c.html abspos-1-ref.html
 == abspos-1d.html abspos-1-ref.html
 != abspos-1e.html abspos-1-ref.html
+== abspos-1f.html abspos-1-ref.html
+== abspos-1g.html abspos-1-ref.html
 # Origin can use "top" "right" etc.
 == origin-name-1a.html origin-name-1-ref.html
 == origin-name-1b.html origin-name-1-ref.html
 == origin-name-2a.html origin-name-2-ref.html
 == origin-name-2b.html origin-name-2-ref.html
 == origin-name-2c.html origin-name-2-ref.html
 == origin-name-3a.html origin-name-3-ref.html
 == origin-name-3b.html origin-name-3-ref.html
@@ -105,8 +107,14 @@ fails-if(Android) == stresstest-1.html s
 # Some simple checks that it obeys selector operations
 == descendant-1.html descendant-1-ref.html
 == propagate-inherit-boolean.html propagate-inherit-boolean-ref.html
 # Ensure you can't move outside an iframe
 == iframe-1.html iframe-1-ref.html
 # Bugs
 == 601894-1.html 601894-ref.html
 == 601894-2.html 601894-ref.html
+# Bug 722777
+== table-1a.html table-1-ref.html
+== table-1b.html table-1-ref.html
+== table-1c.html table-1-ref.html
+== table-2a.html table-2-ref.html
+== table-2b.html table-2-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/transform/table-1-ref.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<div style="-moz-transform:translate(200px) rotate(180deg);-moz-transform-origin:left">
+<table>
+<caption>Hello</caption>
+<tr><td>there!
+</table>
+</div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/transform/table-1a.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<table style="-moz-transform:translate(200px) rotate(180deg);-moz-transform-origin:left">
+<caption>Hello</caption>
+<tr><td>there!
+</table>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/transform/table-1b.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<table style="display:inline-table;-moz-transform:translate(200px) rotate(180deg);-moz-transform-origin:left">
+<caption>Hello</caption>
+<tr><td>there!
+</table>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/transform/table-1c.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<div style="-moz-transform:translateX(200px) rotate(180deg) translateY(-100%);-moz-transform-origin:left">
+<table style="-moz-transform:translateY(100%)">
+<caption>Hello</caption>
+<tr><td>there!
+</table>
+</div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/transform/table-2-ref.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<div style="-moz-transform:translate(200px) rotate(180deg);-moz-transform-origin:left">
+<table>
+<caption style=caption-side:bottom>there!</caption>
+<tr><td>Hello
+</table>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/transform/table-2a.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<table style="-moz-transform:translate(200px) rotate(180deg);-moz-transform-origin:left">
+<caption style=caption-side:bottom>there!</caption>
+<tr><td>Hello
+</table>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/transform/table-2b.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<table style="display:inline-table;-moz-transform:translate(200px) rotate(180deg);-moz-transform-origin:left">
+<caption style=caption-side:bottom>there!</caption>
+<tr><td>Hello
+</table>
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -1103,23 +1103,22 @@ nsComputedDOMStyle::DoGetMozTransform()
     resultString.AppendFloat(matrix._32);
     resultString.Append(NS_LITERAL_STRING(", "));
     resultString.AppendFloat(matrix._33);
     resultString.Append(NS_LITERAL_STRING(", "));
     resultString.AppendFloat(matrix._34);
     resultString.Append(NS_LITERAL_STRING(", "));
   }
   resultString.AppendFloat(matrix._41);
-  resultString.Append(NS_LITERAL_STRING("px, "));
+  resultString.Append(NS_LITERAL_STRING(", "));
   resultString.AppendFloat(matrix._42);
-  resultString.Append(NS_LITERAL_STRING("px"));
   if (is3D) {
     resultString.Append(NS_LITERAL_STRING(", "));
     resultString.AppendFloat(matrix._43);
-    resultString.Append(NS_LITERAL_STRING("px, "));
+    resultString.Append(NS_LITERAL_STRING(", "));
     resultString.AppendFloat(matrix._44);
   }
   resultString.Append(NS_LITERAL_STRING(")"));
 
   /* Create a value to hold our result. */
   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
 
   val->SetString(resultString);
--- a/layout/style/test/test_transitions_per_property.html
+++ b/layout/style/test/test_transitions_per_property.html
@@ -1310,110 +1310,110 @@ function test_transform_transition(prop)
     { start: 'none', end: 'rotatex(720deg)',
       expected_uncomputed: 'rotatex(180deg)',
       expected: c('rotatex(180deg)'),
       requires_3d: true },
 
     // translate
     { start: 'translate(20px)', end: 'none',
       expected_uncomputed: 'translate(15px)',
-      expected: 'matrix(1, 0, 0, 1, 15px, 0px)' },
+      expected: 'matrix(1, 0, 0, 1, 15, 0)' },
     { start: 'translate(20px, 12px)', end: 'none',
       expected_uncomputed: 'translate(15px, 9px)',
-      expected: 'matrix(1, 0, 0, 1, 15px, 9px)' },
+      expected: 'matrix(1, 0, 0, 1, 15, 9)' },
     { start: 'translateX(-20px)', end: 'none',
       expected_uncomputed: 'translateX(-15px)',
-      expected: 'matrix(1, 0, 0, 1, -15px, 0px)' },
+      expected: 'matrix(1, 0, 0, 1, -15, 0)' },
     { start: 'translateY(-40px)', end: 'none',
       expected_uncomputed: 'translateY(-30px)',
-      expected: 'matrix(1, 0, 0, 1, 0px, -30px)' },
+      expected: 'matrix(1, 0, 0, 1, 0, -30)' },
     { start: 'translateZ(40px)', end: 'none',
       expected_uncomputed: 'translateZ(30px)',
-      expected: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0px, 0px, 30px, 1)',
+      expected: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 30, 1)',
       requires_3d: true },
     { start: 'none', end: 'translate3D(40px, 60px, -40px)',
       expected_uncomputed: 'translate3D(10px, 15px, -10px)',
-      expected: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 10px, 15px, -10px, 1)',
+      expected: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 10, 15, -10, 1)',
       requires_3d: true },
     // percentages are relative to 300px (width) and 50px (height)
     // per the prerequisites in property_database.js
     { start: 'translate(20%)', end: 'none',
       expected_uncomputed: 'translate(15%)',
-      expected: 'matrix(1, 0, 0, 1, 45px, 0px)',
+      expected: 'matrix(1, 0, 0, 1, 45, 0)',
       round_error_ok: true },
     { start: 'translate(20%, 12%)', end: 'none',
       expected_uncomputed: 'translate(15%, 9%)',
-      expected: 'matrix(1, 0, 0, 1, 45px, 4.5px)',
+      expected: 'matrix(1, 0, 0, 1, 45, 4.5)',
       round_error_ok: true },
     { start: 'translateX(-20%)', end: 'none',
       expected_uncomputed: 'translateX(-15%)',
-      expected: 'matrix(1, 0, 0, 1, -45px, 0px)',
+      expected: 'matrix(1, 0, 0, 1, -45, 0)',
       round_error_ok: true },
     { start: 'translateY(-40%)', end: 'none',
       expected_uncomputed: 'translateY(-30%)',
-      expected: 'matrix(1, 0, 0, 1, 0px, -15px)',
+      expected: 'matrix(1, 0, 0, 1, 0, -15)',
       round_error_ok: true },
     { start: 'none', end: 'rotate(90deg) translate(20%, 20%) rotate(-90deg)',
       expected_uncomputed: 'rotate(22.5deg) translate(5%, 5%) rotate(-22.5deg)',
       round_error_ok: true },
     { start: 'none', end: 'rotate(-90deg) translate(20%, 20%) rotate(90deg)',
       expected_uncomputed: 'rotate(-22.5deg) translate(5%, 5%) rotate(22.5deg)',
       round_error_ok: true },
     // test percent translation using matrix decomposition
     { start: 'rotate(45deg) rotate(-45deg)',
       end: 'rotate(90deg) translate(20%, 20%) rotate(-90deg)',
-      expected: 'matrix(1, 0, 0, 1, -2.5px, 15px)',
+      expected: 'matrix(1, 0, 0, 1, -2.5, 15)',
       round_error_ok: true },
     { start: 'rotate(45deg) rotate(-45deg)',
       end: 'rotate(-90deg) translate(20%, 20%) rotate(90deg)',
-      expected: 'matrix(1, 0, 0, 1, 2.5px, -15px)',
+      expected: 'matrix(1, 0, 0, 1, 2.5, -15)',
       round_error_ok: true },
     // test calc() in translate
     // Note that font-size: is 20px, and that percentages are relative
     // to 300px (width) and 50px (height) per the prerequisites in
     // property_database.js
     { start: 'translateX(20%)', /* 60px */
       end: 'translateX(-moz-calc(10% + 1em))', /* 30px + 20px = 50px */
       expected_uncomputed: 'translateX(-moz-calc(17.5% + 0.25em))',
-      expected: 'matrix(1, 0, 0, 1, 57.5px, 0px)' },
+      expected: 'matrix(1, 0, 0, 1, 57.5, 0)' },
     { start: 'translate(-moz-calc(0.75 * 3em + 1.5 * 10%), -moz-calc(0.5 * 5em + 0.5 * 8%))', /* 90px, 52px */
       end: 'rotate(90deg) translateY(20%) rotate(90deg) translateY(-moz-calc(10% + 0.5em)) rotate(180deg)', /* -10px, -15px */
-      expected: 'matrix(1, 0, 0, 1, 65px, 35.25px)' },
+      expected: 'matrix(1, 0, 0, 1, 65, 35.25)' },
 
     // scale
     { start: 'scale(2)', end: 'none',
       expected_uncomputed: 'scale(1.75)',
-      expected: 'matrix(1.75, 0, 0, 1.75, 0px, 0px)' },
+      expected: 'matrix(1.75, 0, 0, 1.75, 0, 0)' },
     { start: 'none', end: 'scale(0.4)',
       expected_uncomputed: 'scale(0.85)',
-      expected: 'matrix(0.85, 0, 0, 0.85, 0px, 0px)',
+      expected: 'matrix(0.85, 0, 0, 0.85, 0, 0)',
       round_error_ok: true },
     { start: 'scale(2)', end: 'scale(-2)',
       expected_uncomputed: 'scale(1)',
-      expected: 'matrix(1, 0, 0, 1, 0px, 0px)' },
+      expected: 'matrix(1, 0, 0, 1, 0, 0)' },
     { start: 'scale(2)', end: 'scale(-6)',
       expected_uncomputed: 'scale(0)',
-      expected: 'matrix(0, 0, 0, 0, 0px, 0px)' },
+      expected: 'matrix(0, 0, 0, 0, 0, 0)' },
     { start: 'scale(2, 0.4)', end: 'none',
       expected_uncomputed: 'scale(1.75, 0.55)',
-      expected: 'matrix(1.75, 0, 0, 0.55, 0px, 0px)',
+      expected: 'matrix(1.75, 0, 0, 0.55, 0, 0)',
       round_error_ok: true },
     { start: 'scaleX(3)', end: 'none',
       expected_uncomputed: 'scaleX(2.5)',
-      expected: 'matrix(2.5, 0, 0, 1, 0px, 0px)' },
+      expected: 'matrix(2.5, 0, 0, 1, 0, 0)' },
     { start: 'scaleY(5)', end: 'none',
       expected_uncomputed: 'scaleY(4)',
-      expected: 'matrix(1, 0, 0, 4, 0px, 0px)' },
+      expected: 'matrix(1, 0, 0, 4, 0, 0)' },
     { start: 'scaleZ(5)', end: 'none',
       expected_uncomputed: 'scaleZ(4)',
-      expected: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 4, 0, 0px, 0px, 0px, 1)',
+      expected: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 1)',
       requires_3d: true },
     { start: 'none', end: 'scale3D(5, 5, 5)',
       expected_uncomputed: 'scale3D(2, 2, 2)',
-      expected: 'matrix3d(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0px, 0px, 0px, 1)',
+      expected: 'matrix3d(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1)',
       requires_3d: true },
 
     // skew
     { start: 'skewX(45deg)', end: 'none',
       expected_uncomputed: 'skewX(33.75deg)' },
     { start: 'skewY(45deg)', end: 'none',
       expected_uncomputed: 'skewY(33.75deg)' },
     { start: 'skew(45deg)', end: 'none',
@@ -1423,25 +1423,25 @@ function test_transform_transition(prop)
     { start: 'skewX(45deg)', end: 'skewX(-45deg)',
       expected_uncomputed: 'skewX(22.5deg)' },
     { start: 'skewX(0)', end: 'skewX(-45deg)',
       expected_uncomputed: 'skewX(-11.25deg)' },
     { start: 'skewY(45deg)', end: 'skewY(-45deg)',
       expected_uncomputed: 'skewY(22.5deg)' },
 
     // matrix : skewX
-    { start: 'matrix(1, 0, 3, 1, 0px, 0px)', end: 'none',
-      expected: 'matrix(1, 0, ' + 3 * 0.75 + ', 1, 0px, 0px)',
+    { start: 'matrix(1, 0, 3, 1, 0, 0)', end: 'none',
+      expected: 'matrix(1, 0, ' + 3 * 0.75 + ', 1, 0, 0)',
       round_error_ok: true },
     { start: 'skewX(0)', end: 'skewX(-45deg) translate(0)',
-      expected: 'matrix(1, 0, -0.25, 1, 0px, 0px)',
+      expected: 'matrix(1, 0, -0.25, 1, 0, 0)',
       round_error_ok: true },
     // matrix : rotate
-    { start: 'rotate(-30deg)', end: 'matrix(0, 1, -1, 0, 0px, 0px)',
-      expected: 'matrix(1, 0, 0, 1, 0px, 0px)',
+    { start: 'rotate(-30deg)', end: 'matrix(0, 1, -1, 0, 0, 0)',
+      expected: 'matrix(1, 0, 0, 1, 0, 0)',
       round_error_ok: true },
     { start: 'rotate(-30deg) translateX(0)',
       end: 'translateX(0) rotate(-90deg)',
       expected: c('rotate(-45deg)'),
       round_error_ok: true },
     // matrix decomposition of skewY
     { start: 'skewY(60deg)', end: 'skewY(-60deg) translateX(0)',
       /* rotate(30deg) skewX(60deg)/2 scale(2, 0.5) */
@@ -1451,27 +1451,27 @@ function test_transform_transition(prop)
     // matrix decomposition
 
     // Four pairs of the same matrix expressed different ways.
     { start: 'matrix(-1, 0, 0, -1, 0pt, 0pt)', /* rotate(180deg) */
       end: 'matrix(1, 0, 0, 1, 0, 0)',
       expected: c('rotate(135deg)') },
     { start: 'scale(-1)', end: 'none',
       expected_uncomputed: 'scale(-0.5)',
-      expected: 'matrix(-0.5, 0, 0, -0.5, 0px, 0px)' },
+      expected: 'matrix(-0.5, 0, 0, -0.5, 0, 0)' },
     { start: 'rotate(180deg)', end: 'none',
       expected_uncomputed: 'rotate(135deg)' },
     { start: 'rotate(-180deg)', end: 'none',
       expected_uncomputed: 'rotate(-135deg)',
       expected: c('rotate(225deg)') },
 
     // matrix followed by scale
     { start: 'matrix(2, 0, 0, 2, 10px, 20px) scale(2)',
       end: 'none',
-      expected: 'matrix(3.0625, 0, 0, 3.0625, 7.5px, 15px)' },
+      expected: 'matrix(3.0625, 0, 0, 3.0625, 7.5, 15)' },
 
     // ... and a bunch of similar possibilities.  The spec isn't settled
     // here; there are multiple options.  See:
     // http://lists.w3.org/Archives/Public/www-style/2010Jun/0602.html
     { start: 'matrix(-1, 0, 0, 1, 0pt, 0pt)', /* scaleX(-1) */
       end: 'matrix(1, 0, 0, 1, 0, 0)',
       expected: c('scaleX(-0.5)') },
 
@@ -1500,75 +1500,75 @@ function test_transform_transition(prop)
     // the animations in
     // http://dbaron.org/css/test/2010/transition-negative-determinant
     // don't flip when they finish, and then wrote tests corresponding
     // to the current code's behavior.
     // ... start with four with positive determinants
     { start: 'none',
       end: 'matrix(1, 0, 1.5, 1, 0pt, 0pt)',
       /* skewX(atan(1.5)) */
-      expected: 'matrix(1, 0, ' + 1.5 * 0.25 + ', 1, 0px, 0px)',
+      expected: 'matrix(1, 0, ' + 1.5 * 0.25 + ', 1, 0, 0)',
       round_error_ok: true },       
     { start: 'none',
       end: 'matrix(-1, 0, 2, -1, 0pt, 0pt)',
               /* rotate(180deg) skewX(atan(-2)) */
-      expected: c('rotate(45deg) matrix(1, 0, ' + -2 * 0.25 + ', 1, 0px, 0px)'),
+      expected: c('rotate(45deg) matrix(1, 0, ' + -2 * 0.25 + ', 1, 0, 0)'),
       round_error_ok: true },
     { start: 'none',
       end: 'matrix(0, -1, 1, -3, 0pt, 0pt)',
               /* rotate(-90deg) skewX(atan(3)) */
-      expected: c('rotate(-22.5deg) matrix(1, 0, ' + 3 * 0.25 + ', 1, 0px, 0px)'),
+      expected: c('rotate(-22.5deg) matrix(1, 0, ' + 3 * 0.25 + ', 1, 0, 0)'),
       round_error_ok: true },
     { start: 'none',
       end: 'matrix(0, 1, -1, 4, 0pt, 0pt)',
               /* rotate(90deg) skewX(atan(4)) */
-      expected: c('rotate(22.5deg) matrix(1, 0, ' + 4 * 0.25 + ', 1, 0px, 0px)'),
+      expected: c('rotate(22.5deg) matrix(1, 0, ' + 4 * 0.25 + ', 1, 0, 0)'),
       round_error_ok: true },
     // and then four with negative determinants
     { start: 'none',
       end: 'matrix(1, 0, 1, -1, 0pt, 0pt)',
               /* rotate(-180deg) skewX(atan(-1)) scaleX(-1) */
-      expected: c('rotate(-45deg) matrix(1, 0, ' + -1 * 0.25 + ', 1, 0px, 0px) scaleX(0.5)'),
+      expected: c('rotate(-45deg) matrix(1, 0, ' + -1 * 0.25 + ', 1, 0, 0) scaleX(0.5)'),
       round_error_ok: true },
     { start: 'none',
       end: 'matrix(-1, 0, -1, 1, 0pt, 0pt)',
               /* skewX(atan(-1)) scaleX(-1) */
-      expected: c('matrix(1, 0, ' + -1 * 0.25 + ', 1, 0px, 0px) scaleX(0.5)') },
+      expected: c('matrix(1, 0, ' + -1 * 0.25 + ', 1, 0, 0) scaleX(0.5)') },
     { start: 'none',
       end: 'matrix(0, 1, 1, -2, 0pt, 0pt)',
               /* rotate(-90deg) skewX(atan(2)) scaleX(-1) */
-      expected: c('rotate(-22.5deg) matrix(1, 0, ' + 2 * 0.25 + ', 1, 0px, 0px) scaleX(0.5)'),
+      expected: c('rotate(-22.5deg) matrix(1, 0, ' + 2 * 0.25 + ', 1, 0, 0) scaleX(0.5)'),
       round_error_ok: true },
     { start: 'none',
       end: 'matrix(0, -1, -1, 0.5, 0pt, 0pt)',
               /* rotate(90deg) skewX(atan(0.5)) scaleX(-1) */
-      expected: c('rotate(22.5deg) matrix(1, 0, ' + 0.5 * 0.25 + ', 1, 0px, 0px) scaleX(0.5)'),
+      expected: c('rotate(22.5deg) matrix(1, 0, ' + 0.5 * 0.25 + ', 1, 0, 0) scaleX(0.5)'),
       round_error_ok: true },
 
     // lists vs. matrix decomposition
     { start: 'translate(10px) skewY(45deg)',
       end: 'translate(30px) skewY(-45deg)',
       expected_uncomputed: 'translate(15px) skewY(22.5deg)' },
     { start: 'skewY(45deg) rotate(90deg)',
       end: 'skewY(-45deg) rotate(90deg)',
       expected_uncomputed: 'skewY(22.5deg) rotate(90deg)' },
     { start: 'skewY(45deg) rotate(90deg) translate(0)',
       end: 'skewY(-45deg) rotate(90deg)',
-      expected: 'matrix(0, 1, -1, -0.5, 0px, 0px)',
+      expected: 'matrix(0, 1, -1, -0.5, 0, 0)',
       round_error_ok: true },
     { start: 'skewX(45deg) rotate(90deg)',
       end: 'skewX(-45deg) rotate(90deg)',
       expected_uncomputed: 'skewX(22.5deg) rotate(90deg)' },
     { start: 'skewX(-60deg) rotate(90deg) translate(0)',
       end: 'skewX(60deg) rotate(90deg)',
       expected: c('rotate(120deg) skewX(' + Math.atan(Math.tan(Math.PI * 60/180) / 2) + 'rad) scale(2, 0.5)'),
       round_error_ok: true },
   ];
 
-  var matrix_re = /^matrix\(([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^,]*)px, ([^,]*)px\)$/;
+  var matrix_re = /^matrix\(([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^,]*)\)$/;
   for (var i in tests) {
     var test = tests[i];
     if (!("expected" in test)) {
       var v = test.expected_uncomputed;
       if (v.match(matrix_re) && !test.force_compute) {
         test.expected = v;
       } else {
         test.expected = c(v);
--- a/layout/style/ua.css
+++ b/layout/style/ua.css
@@ -69,16 +69,19 @@
   right: inherit;
   bottom: inherit;
   left: inherit;
   z-index: inherit;
   page-break-before: inherit;
   page-break-after: inherit;
   vertical-align: inherit; /* needed for inline-table */
   line-height: inherit; /* needed for vertical-align on inline-table */
+  /* Bug 722777 */
+  -moz-transform: inherit;
+  -moz-transform-origin: inherit;
 }
 
 *|*::-moz-table-row {
   display: table-row !important;
 }
 
 /* The ::-moz-table-column pseudo-element is for extra columns at the end 
    of a table. */
--- a/layout/svg/base/src/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/base/src/nsSVGForeignObjectFrame.cpp
@@ -224,20 +224,39 @@ nsSVGForeignObjectFrame::PaintSVG(nsSVGR
 
   nsRenderingContext *ctx = aContext->GetRenderingContext(this);
 
   if (!ctx || matrixForChildren.IsSingular()) {
     NS_WARNING("Can't render foreignObject element!");
     return NS_ERROR_FAILURE;
   }
 
+  nsRect kidDirtyRect = kid->GetVisualOverflowRect();
+
   /* Check if we need to draw anything. */
   if (aDirtyRect) {
-    PRInt32 appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel();
-    if (!mRect.ToOutsidePixels(appUnitsPerDevPx).Intersects(*aDirtyRect))
+    // Transform the dirty rect into app units in our userspace.
+    gfxMatrix invmatrix = matrix;
+    invmatrix.Invert();
+    NS_ASSERTION(!invmatrix.IsSingular(),
+                 "inverse of non-singular matrix should be non-singular");
+
+    gfxRect transDirtyRect = gfxRect(aDirtyRect->x, aDirtyRect->y,
+                                     aDirtyRect->width, aDirtyRect->height);
+    transDirtyRect = invmatrix.TransformBounds(transDirtyRect);
+
+    kidDirtyRect.IntersectRect(kidDirtyRect,
+      nsLayoutUtils::RoundGfxRectToAppRect(transDirtyRect,
+                       PresContext()->AppUnitsPerCSSPixel()));
+
+    // XXX after bug 614732 is fixed, we will compare mRect with aDirtyRect,
+    // not with kidDirtyRect. I.e.
+    // PRInt32 appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel();
+    // mRect.ToOutsidePixels(appUnitsPerDevPx).Intersects(*aDirtyRect)
+    if (kidDirtyRect.IsEmpty())
       return NS_OK;
   }
 
   gfxContext *gfx = aContext->GetGfxContext();
 
   gfx->Save();
 
   if (GetStyleDisplay()->IsScrollableOverflow()) {
@@ -253,31 +272,16 @@ nsSVGForeignObjectFrame::PaintSVG(nsSVGR
   gfx->Multiply(matrixForChildren);
 
   // Transform the dirty rect into the rectangle containing the
   // transformed dirty rect.
   gfxMatrix invmatrix = matrix.Invert();
   NS_ASSERTION(!invmatrix.IsSingular(),
                "inverse of non-singular matrix should be non-singular");
 
-  nsRect kidDirtyRect = kid->GetVisualOverflowRect();
-  if (aDirtyRect) {
-    gfxRect transDirtyRect = gfxRect(aDirtyRect->x, aDirtyRect->y,
-                                     aDirtyRect->width, aDirtyRect->height);
-    transDirtyRect = invmatrix.TransformBounds(transDirtyRect);
-
-    transDirtyRect.Scale(nsPresContext::AppUnitsPerCSSPixel());
-    nsPoint tl(NSToCoordFloor(transDirtyRect.X()),
-               NSToCoordFloor(transDirtyRect.Y()));
-    nsPoint br(NSToCoordCeil(transDirtyRect.XMost()),
-               NSToCoordCeil(transDirtyRect.YMost()));
-    kidDirtyRect.IntersectRect(kidDirtyRect,
-                               nsRect(tl.x, tl.y, br.x - tl.x, br.y - tl.y));
-  }
-
   PRUint32 flags = nsLayoutUtils::PAINT_IN_TRANSFORM;
   if (aContext->IsPaintingToWindow()) {
     flags |= nsLayoutUtils::PAINT_TO_WINDOW;
   }
   nsresult rv = nsLayoutUtils::PaintFrame(ctx, kid, nsRegion(kidDirtyRect),
                                           NS_RGBA(0,0,0,0), flags);
 
   gfx->Restore();
@@ -339,17 +343,19 @@ nsSVGForeignObjectFrame::GetFrameForPoin
     return frame;
 
   return nsnull;
 }
 
 NS_IMETHODIMP_(nsRect)
 nsSVGForeignObjectFrame::GetCoveredRegion()
 {
-  return mRect;
+  // See bug 614732 comment 32:
+  //return nsSVGUtils::TransformFrameRectToOuterSVG(mRect, GetCanvasTM(), PresContext());
+  return mCoveredRegion;
 }
 
 NS_IMETHODIMP
 nsSVGForeignObjectFrame::UpdateCoveredRegion()
 {
   if (GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)
     return NS_ERROR_FAILURE;
 
@@ -357,18 +363,21 @@ nsSVGForeignObjectFrame::UpdateCoveredRe
   static_cast<nsSVGForeignObjectElement*>(mContent)->
     GetAnimatedLengthValues(&x, &y, &w, &h, nsnull);
 
   // If mRect's width or height are negative, reflow blows up! We must clamp!
   if (w < 0.0f) w = 0.0f;
   if (h < 0.0f) h = 0.0f;
 
   // GetCanvasTM includes the x,y translation
-  mRect = ToCanvasBounds(gfxRect(0.0, 0.0, w, h), GetCanvasTM(), PresContext());
-  
+  mRect = nsLayoutUtils::RoundGfxRectToAppRect(
+                           gfxRect(0.0, 0.0, w, h),
+                           PresContext()->AppUnitsPerDevPixel());
+  mCoveredRegion = ToCanvasBounds(gfxRect(0.0, 0.0, w, h), GetCanvasTM(), PresContext());
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSVGForeignObjectFrame::InitialUpdate()
 {
   NS_ASSERTION(GetStateBits() & NS_FRAME_FIRST_REFLOW,
                "Yikes! We've been called already! Hopefully we weren't called "
@@ -640,29 +649,28 @@ nsSVGForeignObjectFrame::DoReflow()
 
 void
 nsSVGForeignObjectFrame::InvalidateDirtyRect(nsSVGOuterSVGFrame* aOuter,
     const nsRect& aRect, PRUint32 aFlags)
 {
   if (aRect.IsEmpty())
     return;
 
+  // Don't invalidate areas outside our bounds:
+  nsRect rect = aRect.Intersect(mRect);
+  if (rect.IsEmpty())
+    return;
+
   // The areas dirtied by children are in app units, relative to this frame.
-  // We need to convert the rect to userspace to use IntersectRect.
+  // We need to convert the rect from app units in our userspace to app units
+  // relative to our nsSVGOuterSVGFrame's content rect.
 
   gfxRect r(aRect.x, aRect.y, aRect.width, aRect.height);
   r.Scale(1.0 / nsPresContext::AppUnitsPerCSSPixel());
-
-  nsRect rect = ToCanvasBounds(r, GetCanvasTM(), PresContext());
-
-  // Don't invalidate areas outside our bounds:
-  rect.IntersectRect(rect, mRect);
-  if (rect.IsEmpty())
-    return;
-
+  rect = ToCanvasBounds(r, GetCanvasTM(), PresContext());
   rect = nsSVGUtils::FindFilterInvalidation(this, rect);
   aOuter->InvalidateWithFlags(rect, aFlags);
 }
 
 void
 nsSVGForeignObjectFrame::FlushDirtyRegion(PRUint32 aFlags)
 {
   if ((mSameDocDirtyRegion.IsEmpty() && mSubDocDirtyRegion.IsEmpty()) ||
--- a/layout/svg/base/src/nsSVGForeignObjectFrame.h
+++ b/layout/svg/base/src/nsSVGForeignObjectFrame.h
@@ -161,12 +161,14 @@ protected:
   nsAutoPtr<gfxMatrix> mCanvasTM;
 
   // Areas dirtied by changes to decendents that are in our document
   nsRegion mSameDocDirtyRegion;
 
   // Areas dirtied by changes to sub-documents embedded by our decendents
   nsRegion mSubDocDirtyRegion;
 
+  nsRect mCoveredRegion;
+
   bool mInReflow;
 };
 
 #endif
--- a/layout/svg/base/src/nsSVGGeometryFrame.h
+++ b/layout/svg/base/src/nsSVGGeometryFrame.h
@@ -119,13 +119,15 @@ protected:
    * Returns the given 'fill-opacity' or 'stroke-opacity' value multiplied by
    * the value of the 'opacity' property if it's possible to avoid the expense
    * of creating and compositing an offscreen surface for 'opacity' by
    * combining 'opacity' with the 'fill-opacity'/'stroke-opacity'. If not, the
    * given 'fill-opacity'/'stroke-opacity' is returned unmodified.
    */
   float MaybeOptimizeOpacity(float aFillOrStrokeOpacity);
 
+  nsRect mCoveredRegion;
+
 private:
   bool GetStrokeDashData(FallibleTArray<gfxFloat>& dashes, gfxFloat *dashOffset);
 };
 
 #endif // __NS_SVGGEOMETRYFRAME_H__
--- a/layout/svg/base/src/nsSVGGlyphFrame.cpp
+++ b/layout/svg/base/src/nsSVGGlyphFrame.cpp
@@ -435,31 +435,29 @@ nsSVGGlyphFrame::GetFrameForPoint(const 
     return this;
 
   return nsnull;
 }
 
 NS_IMETHODIMP_(nsRect)
 nsSVGGlyphFrame::GetCoveredRegion()
 {
-  return mRect;
+  // See bug 614732 comment 32:
+  //return nsSVGUtils::TransformFrameRectToOuterSVG(mRect, GetCanvasTM(), PresContext());
+  return mCoveredRegion;
 }
 
 NS_IMETHODIMP
 nsSVGGlyphFrame::UpdateCoveredRegion()
 {
   mRect.SetEmpty();
 
-  gfxMatrix matrix = GetCanvasTM();
-  if (matrix.IsSingular()) {
-    return NS_ERROR_FAILURE;
-  }
-
+  // XXX here we have tmpCtx use its default identity matrix, but does this
+  // function call anything that will call GetCanvasTM and break things?
   nsRefPtr<gfxContext> tmpCtx = MakeTmpCtx();
-  tmpCtx->Multiply(matrix);
 
   bool hasStroke = HasStroke();
   if (hasStroke) {
     SetupCairoStrokeGeometry(tmpCtx);
   } else if (GetStyleSVG()->mFill.mType == eStyleSVGPaintType_None) {
     return NS_OK;
   }
 
@@ -482,23 +480,29 @@ nsSVGGlyphFrame::UpdateCoveredRegion()
   //
   // Another thing to be aware of is that under AddBoundingBoxesToPath the
   // gfxContext has SetLineWidth() called on it, so if we want to ask the
   // gfxContext for *stroke* extents, we'll neet to wrap the
   // AddBoundingBoxesToPath() call with CurrentLineWidth()/SetLineWidth()
   // calls to record and then reset the stroke width.
   gfxRect extent = tmpCtx->GetUserPathExtent();
   if (hasStroke) {
-    extent = nsSVGUtils::PathExtentsToMaxStrokeExtents(extent, this);
+    extent =
+      nsSVGUtils::PathExtentsToMaxStrokeExtents(extent, this, gfxMatrix());
   }
 
   if (!extent.IsEmpty()) {
-    mRect = nsSVGUtils::ToAppPixelRect(PresContext(), extent);
+    mRect = nsLayoutUtils::RoundGfxRectToAppRect(extent, 
+              PresContext()->AppUnitsPerDevPixel());
   }
 
+  // See bug 614732 comment 32.
+  mCoveredRegion = nsSVGUtils::TransformFrameRectToOuterSVG(
+    mRect, GetCanvasTM(), PresContext());
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSVGGlyphFrame::InitialUpdate()
 {
   NS_ASSERTION(GetStateBits() & NS_FRAME_FIRST_REFLOW,
                "Yikes! We've been called already! Hopefully we weren't called "
@@ -615,17 +619,19 @@ nsSVGGlyphFrame::GetBBoxContribution(con
        GetStyleSVG()->mFill.mType != eStyleSVGPaintType_None)) {
     bbox = pathExtents;
   }
 
   // Account for stroke:
   if ((aFlags & nsSVGUtils::eBBoxIncludeStroke) != 0 &&
       ((aFlags & nsSVGUtils::eBBoxIgnoreStrokeIfNone) == 0 || HasStroke())) {
     bbox =
-      bbox.Union(nsSVGUtils::PathExtentsToMaxStrokeExtents(pathExtents, this));
+      bbox.Union(nsSVGUtils::PathExtentsToMaxStrokeExtents(pathExtents,
+                                                           this,
+                                                           aToBBoxUserspace));
   }
 
   return bbox;
 }
 
 //----------------------------------------------------------------------
 // nsSVGGeometryFrame methods:
 
--- a/layout/svg/base/src/nsSVGImageFrame.cpp
+++ b/layout/svg/base/src/nsSVGImageFrame.cpp
@@ -360,17 +360,19 @@ nsSVGImageFrame::PaintSVG(nsSVGRenderSta
       ctx->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
     }
 
     nscoord appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel();
     nsRect dirtyRect; // only used if aDirtyRect is non-null
     if (aDirtyRect) {
       dirtyRect = aDirtyRect->ToAppUnits(appUnitsPerDevPx);
       // Adjust dirtyRect to match our local coordinate system.
-      dirtyRect.MoveBy(-mRect.TopLeft());
+      nsRect rootRect =
+        nsSVGUtils::TransformFrameRectToOuterSVG(mRect, GetCanvasTM(), PresContext());
+      dirtyRect.MoveBy(-rootRect.TopLeft());
     }
 
     // XXXbholley - I don't think huge images in SVGs are common enough to
     // warrant worrying about the responsiveness impact of doing synchronous
     // decodes. The extra code complexity of determinining when we want to
     // force sync probably just isn't worth it, so always pass FLAG_SYNC_DECODE
     PRUint32 drawFlags = imgIContainer::FLAG_SYNC_DECODE;
 
@@ -478,25 +480,30 @@ nsSVGImageFrame::GetType() const
 
 NS_IMETHODIMP
 nsSVGImageFrame::UpdateCoveredRegion()
 {
   mRect.SetEmpty();
 
   gfxContext context(gfxPlatform::GetPlatform()->ScreenReferenceSurface());
 
-  GeneratePath(&context);
-  context.IdentityMatrix();
+  gfxMatrix identity;
+  GeneratePath(&context, &identity);
 
   gfxRect extent = context.GetUserPathExtent();
 
   if (!extent.IsEmpty()) {
-    mRect = nsSVGUtils::ToAppPixelRect(PresContext(), extent);
+    mRect = nsLayoutUtils::RoundGfxRectToAppRect(extent, 
+              PresContext()->AppUnitsPerDevPixel());
   }
 
+  // See bug 614732 comment 32.
+  mCoveredRegion = nsSVGUtils::TransformFrameRectToOuterSVG(
+    mRect, GetCanvasTM(), PresContext());
+
   return NS_OK;
 }
 
 PRUint16
 nsSVGImageFrame::GetHitTestFlags()
 {
   PRUint16 flags = 0;
 
--- a/layout/svg/base/src/nsSVGPathGeometryFrame.cpp
+++ b/layout/svg/base/src/nsSVGPathGeometryFrame.cpp
@@ -154,18 +154,26 @@ NS_IMETHODIMP_(nsIFrame*)
 nsSVGPathGeometryFrame::GetFrameForPoint(const nsPoint &aPoint)
 {
   PRUint16 fillRule, hitTestFlags;
   if (GetStateBits() & NS_STATE_SVG_CLIPPATH_CHILD) {
     hitTestFlags = SVG_HIT_TEST_FILL;
     fillRule = GetClipRule();
   } else {
     hitTestFlags = GetHitTestFlags();
+    // XXX once bug 614732 is fixed, aPoint won't need any conversion in order
+    // to compare it with mRect.
+    gfxMatrix canvasTM = GetCanvasTM();
+    if (canvasTM.IsSingular()) {
+      return nsnull;
+    }
+    nsPoint point =
+      nsSVGUtils::TransformOuterSVGPointToChildFrame(aPoint, canvasTM, PresContext());
     if (!hitTestFlags || ((hitTestFlags & SVG_HIT_TEST_CHECK_MRECT) &&
-                          !mRect.Contains(aPoint)))
+                          !mRect.Contains(point)))
       return nsnull;
     fillRule = GetStyleSVG()->mFillRule;
   }
 
   bool isHit = false;
 
   nsRefPtr<gfxContext> context =
     new gfxContext(gfxPlatform::GetPlatform()->ScreenReferenceSurface());
@@ -191,27 +199,35 @@ nsSVGPathGeometryFrame::GetFrameForPoint
     return this;
 
   return nsnull;
 }
 
 NS_IMETHODIMP_(nsRect)
 nsSVGPathGeometryFrame::GetCoveredRegion()
 {
-  return mRect;
+  // See bug 614732 comment 32:
+  //return nsSVGUtils::TransformFrameRectToOuterSVG(mRect, GetCanvasTM(), PresContext());
+  return mCoveredRegion;
 }
 
 NS_IMETHODIMP
 nsSVGPathGeometryFrame::UpdateCoveredRegion()
 {
-  gfxRect extent = GetBBoxContribution(GetCanvasTM(),
+  gfxRect extent = GetBBoxContribution(gfxMatrix(),
     nsSVGUtils::eBBoxIncludeFill | nsSVGUtils::eBBoxIgnoreFillIfNone |
     nsSVGUtils::eBBoxIncludeStroke | nsSVGUtils::eBBoxIgnoreStrokeIfNone |
     nsSVGUtils::eBBoxIncludeMarkers);
-  mRect = nsSVGUtils::ToAppPixelRect(PresContext(), extent);
+  mRect = nsLayoutUtils::RoundGfxRectToAppRect(extent,
+            PresContext()->AppUnitsPerDevPixel());
+
+  // See bug 614732 comment 32.
+  mCoveredRegion = nsSVGUtils::TransformFrameRectToOuterSVG(
+    mRect, GetCanvasTM(), PresContext());
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSVGPathGeometryFrame::InitialUpdate()
 {
   NS_ASSERTION(GetStateBits() & NS_FRAME_FIRST_REFLOW,
                "Yikes! We've been called already! Hopefully we weren't called "
@@ -302,17 +318,19 @@ nsSVGPathGeometryFrame::GetBBoxContribut
       // though, because if pathExtents is empty, its position will not have
       // been set. Happily we can use context->GetUserStrokeExtent() to find
       // the center point of the extents even though it gets the extents wrong.
       SetupCairoStrokeGeometry(context);
       pathExtents.MoveTo(context->GetUserStrokeExtent().Center());
       pathExtents.SizeTo(0, 0);
     }
     bbox =
-      bbox.Union(nsSVGUtils::PathExtentsToMaxStrokeExtents(pathExtents, this));
+      bbox.Union(nsSVGUtils::PathExtentsToMaxStrokeExtents(pathExtents,
+                                                           this,
+                                                           aToBBoxUserspace));
   }
 
   // Account for markers:
   if ((aFlags & nsSVGUtils::eBBoxIncludeMarkers) != 0 &&
       static_cast<nsSVGPathGeometryElement*>(mContent)->IsMarkable()) {
 
     float strokeWidth = GetStrokeWidth();
     MarkerProperties properties = GetMarkerProperties(this);
--- a/layout/svg/base/src/nsSVGUtils.cpp
+++ b/layout/svg/base/src/nsSVGUtils.cpp
@@ -1005,18 +1005,20 @@ nsSVGUtils::PaintFrameWithEffects(nsSVGR
    * true for path geometry and glyphs, so basically we're traversing
    * all containers and we can only skip leaves here.
    */
   if (aDirtyRect && svgChildFrame->HasValidCoveredRect()) {
     if (filterFrame) {
       if (!aDirtyRect->Intersects(filterFrame->GetFilterBBox(aFrame, nsnull)))
         return;
     } else {
+      nsRect leafBounds = nsSVGUtils::TransformFrameRectToOuterSVG(
+        aFrame->GetRect(), GetCanvasTM(aFrame), aFrame->PresContext());
       nsRect rect = aDirtyRect->ToAppUnits(aFrame->PresContext()->AppUnitsPerDevPixel());
-      if (!rect.Intersects(aFrame->GetRect()))
+      if (!rect.Intersects(leafBounds))
         return;
     }
   }
 
   /* SVG defines the following rendering model:
    *
    *  1. Render fill
    *  2. Render stroke
@@ -1173,32 +1175,43 @@ nsSVGUtils::GetCoveredRegion(const nsFra
       nsRect childRect = child->GetCoveredRegion();
       rect.UnionRect(rect, childRect);
     }
   }
 
   return rect;
 }
 
-nsRect
-nsSVGUtils::ToAppPixelRect(nsPresContext *aPresContext,
-                           double xmin, double ymin,
-                           double xmax, double ymax)
+nsPoint
+nsSVGUtils::TransformOuterSVGPointToChildFrame(nsPoint aPoint,
+                                               const gfxMatrix& aFrameToCanvasTM,
+                                               nsPresContext* aPresContext)
 {
-  return ToAppPixelRect(aPresContext,
-                        gfxRect(xmin, ymin, xmax - xmin, ymax - ymin));
+  gfxMatrix devToUser = aFrameToCanvasTM;
+  devToUser.Invert();
+  NS_ABORT_IF_FALSE(!devToUser.IsSingular(), "should not get here");
+  gfxPoint devPt = gfxPoint(aPoint.x, aPoint.y) /
+    aPresContext->AppUnitsPerDevPixel();
+  gfxPoint userPt = devToUser.Transform(devPt).Round();
+  gfxPoint appPt = userPt * aPresContext->AppUnitsPerCSSPixel();
+  userPt.x = clamped(appPt.x, gfxFloat(nscoord_MIN), gfxFloat(nscoord_MAX));
+  userPt.y = clamped(appPt.y, gfxFloat(nscoord_MIN), gfxFloat(nscoord_MAX));
+  // now guaranteed to be safe:
+  return nsPoint(nscoord(userPt.x), nscoord(userPt.y));
 }
 
 nsRect
-nsSVGUtils::ToAppPixelRect(nsPresContext *aPresContext, const gfxRect& rect)
+nsSVGUtils::TransformFrameRectToOuterSVG(const nsRect& aRect,
+                                         const gfxMatrix& aMatrix,
+                                         nsPresContext* aPresContext)
 {
-  return nsRect(aPresContext->DevPixelsToAppUnits(NSToIntFloor(rect.X())),
-                aPresContext->DevPixelsToAppUnits(NSToIntFloor(rect.Y())),
-                aPresContext->DevPixelsToAppUnits(NSToIntCeil(rect.XMost()) - NSToIntFloor(rect.X())),
-                aPresContext->DevPixelsToAppUnits(NSToIntCeil(rect.YMost()) - NSToIntFloor(rect.Y())));
+  gfxRect r(aRect.x, aRect.y, aRect.width, aRect.height);
+  r.Scale(1.0 / nsPresContext::AppUnitsPerCSSPixel());
+  return nsLayoutUtils::RoundGfxRectToAppRect(
+    aMatrix.TransformBounds(r), aPresContext->AppUnitsPerDevPixel());
 }
 
 gfxIntSize
 nsSVGUtils::ConvertToSurfaceSize(const gfxSize& aSize,
                                  bool *aResultOverflows)
 {
   gfxIntSize surfaceSize(ClampToInt(ceil(aSize.width)), ClampToInt(ceil(aSize.height)));
 
@@ -1490,41 +1503,42 @@ nsSVGUtils::WritePPM(const char *fname, 
   fclose(f);
 }
 #endif
 
 // The logic here comes from _cairo_stroke_style_max_distance_from_path
 static gfxRect
 PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
                               nsSVGGeometryFrame* aFrame,
-                              double styleExpansionFactor)
+                              double styleExpansionFactor,
+                              const gfxMatrix& aMatrix)
 {
   double style_expansion =
     styleExpansionFactor * aFrame->GetStrokeWidth();
 
-  gfxMatrix ctm = aFrame->GetCanvasTM();
-
-  double dx = style_expansion * (fabs(ctm.xx) + fabs(ctm.xy));
-  double dy = style_expansion * (fabs(ctm.yy) + fabs(ctm.yx));
+  double dx = style_expansion * (fabs(aMatrix.xx) + fabs(aMatrix.xy));
+  double dy = style_expansion * (fabs(aMatrix.yy) + fabs(aMatrix.yx));
 
   gfxRect strokeExtents = aPathExtents;
   strokeExtents.Inflate(dx, dy);
   return strokeExtents;
 }
 
 /*static*/ gfxRect
 nsSVGUtils::PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
-                                          nsSVGGeometryFrame* aFrame)
+                                          nsSVGGeometryFrame* aFrame,
+                                          const gfxMatrix& aMatrix)
 {
-  return ::PathExtentsToMaxStrokeExtents(aPathExtents, aFrame, 0.5);
+  return ::PathExtentsToMaxStrokeExtents(aPathExtents, aFrame, 0.5, aMatrix);
 }
 
 /*static*/ gfxRect
 nsSVGUtils::PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
-                                          nsSVGPathGeometryFrame* aFrame)
+                                          nsSVGPathGeometryFrame* aFrame,
+                                          const gfxMatrix& aMatrix)
 {
   double styleExpansionFactor = 0.5;
 
   if (static_cast<nsSVGPathGeometryElement*>(aFrame->GetContent())->IsMarkable()) {
     const nsStyleSVG* style = aFrame->GetStyleSVG();
 
     if (style->mStrokeLinecap == NS_STYLE_STROKE_LINECAP_SQUARE) {
       styleExpansionFactor = M_SQRT1_2;
@@ -1534,17 +1548,18 @@ nsSVGUtils::PathExtentsToMaxStrokeExtent
         styleExpansionFactor < style->mStrokeMiterlimit &&
         aFrame->GetContent()->Tag() != nsGkAtoms::line) {
       styleExpansionFactor = style->mStrokeMiterlimit;
     }
   }
 
   return ::PathExtentsToMaxStrokeExtents(aPathExtents,
                                          aFrame,
-                                         styleExpansionFactor);
+                                         styleExpansionFactor,
+                                         aMatrix);
 }
 
 // ----------------------------------------------------------------------
 
 nsSVGRenderState::nsSVGRenderState(nsRenderingContext *aContext) :
   mRenderMode(NORMAL), mRenderingContext(aContext), mPaintingToWindow(false)
 {
   mGfxContext = aContext->ThebesContext();
--- a/layout/svg/base/src/nsSVGUtils.h
+++ b/layout/svg/base/src/nsSVGUtils.h
@@ -442,24 +442,29 @@ public:
   NotifyRedrawUnsuspended(nsIFrame *aFrame);
 
   /*
    * Get frame's covered region by walking the children and doing union.
    */
   static nsRect
   GetCoveredRegion(const nsFrameList &aFrames);
 
-  /*
-   * Convert a rect from device pixel units to app pixel units by inflation.
-   */
+  // Converts aPoint from an app unit point in outer-<svg> content rect space
+  // to an app unit point in a frame's SVG userspace. 
+  // This is a temporary helper we should no longer need after bug 614732 is
+  // fixed.
+  static nsPoint
+  TransformOuterSVGPointToChildFrame(nsPoint aPoint,
+                                     const gfxMatrix& aFrameToCanvasTM,
+                                     nsPresContext* aPresContext);
+
   static nsRect
-  ToAppPixelRect(nsPresContext *aPresContext,
-                 double xmin, double ymin, double xmax, double ymax);
-  static nsRect
-  ToAppPixelRect(nsPresContext *aPresContext, const gfxRect& rect);
+  TransformFrameRectToOuterSVG(const nsRect& aRect,
+                               const gfxMatrix& aMatrix,
+                               nsPresContext* aPresContext);
 
   /*
    * Convert a surface size to an integer for use by thebes
    * possibly making it smaller in the process so the surface does not
    * use excessive memory.
    *
    * @param aSize the desired surface size
    * @param aResultOverflows true if the desired surface size is too big
@@ -576,19 +581,21 @@ public:
    * tightest extents that we can guarantee fully enclose the inked stroke
    * without doing the calculations for the actual tight extents. We exploit
    * the fact that cairo does have an API for getting the tight device space
    * fill/path extents.
    *
    * This should die once bug 478152 is fixed.
    */
   static gfxRect PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
-                                               nsSVGGeometryFrame* aFrame);
+                                               nsSVGGeometryFrame* aFrame,
+                                               const gfxMatrix& aMatrix);
   static gfxRect PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
-                                               nsSVGPathGeometryFrame* aFrame);
+                                               nsSVGPathGeometryFrame* aFrame,
+                                               const gfxMatrix& aMatrix);
 
   /**
    * Convert a floating-point value to a 32-bit integer value, clamping to
    * the range of valid integers.
    */
   static PRInt32 ClampToInt(double aVal)
   {
     return NS_lround(NS_MAX(double(PR_INT32_MIN),
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -208,16 +208,20 @@ nsTableFrame::Init(nsIContent*      aCon
 
   // Let the base class do its processing
   nsresult rv = nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
 
   // see if border collapse is on, if so set it
   const nsStyleTableBorder* tableStyle = GetStyleTableBorder();
   bool borderCollapse = (NS_STYLE_BORDER_COLLAPSE == tableStyle->mBorderCollapse);
   SetBorderCollapse(borderCollapse);
+
+  // Transforms need to affect the outer frame, not the inner frame (bug 722777)
+  mState &= ~NS_FRAME_MAY_BE_TRANSFORMED;
+
   // Create the cell map if this frame is the first-in-flow.
   if (!aPrevInFlow) {
     mCellMap = new nsTableCellMap(*this, borderCollapse);
     if (!mCellMap)
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   if (aPrevInFlow) {
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -452,18 +452,18 @@ abstract public class GeckoApp
             bookmark.setChecked(false);
             bookmark.setIcon(R.drawable.ic_menu_bookmark_add);
         }
 
         forward.setEnabled(tab.canDoForward());
 
         // Disable share menuitem for about:, chrome: and file: URIs
         String scheme = Uri.parse(tab.getURL()).getScheme();
-        boolean enabled = !(scheme.equals("about") || scheme.equals("chrome") ||
-                            scheme.equals("file"));
+        boolean enabled = scheme != null && !(scheme.equals("about") || scheme.equals("chrome") ||
+                                              scheme.equals("file"));
         share.setEnabled(enabled);
 
         // Disable save as PDF for about:home and xul pages
         saveAsPDF.setEnabled(!(tab.getURL().equals("about:home") ||
                                tab.getContentType().equals("application/vnd.mozilla.xul+xml")));
 
         // DownloadManager support is tied to level 12 and higher
         if (Build.VERSION.SDK_INT < 12)
@@ -617,31 +617,37 @@ abstract public class GeckoApp
                 message.put("tabID", tab.getId());
 
                 JSONObject source = new JSONObject();
                 source.put("width", sw);
                 source.put("height", sh);
                 message.put("source", source);
 
                 JSONObject destination = new JSONObject();
-                source.put("width", dw);
-                source.put("height", dh);
+                destination.put("width", dw);
+                destination.put("height", dh);
                 message.put("destination", destination);
 
                 String json = message.toString();
                 GeckoAppShell.sendEventToGecko(new GeckoEvent("Tab:Screenshot", json));
             } catch(JSONException jsonEx) {
                 Log.w(LOGTAG, "Constructing the JSON data for Tab:Screenshot event failed", jsonEx);
             }
         }
     }
     
     void processThumbnail(Tab thumbnailTab, Bitmap bitmap, byte[] compressed) {
-        if (Tabs.getInstance().isSelectedTab(thumbnailTab))
+        if (Tabs.getInstance().isSelectedTab(thumbnailTab)) {
+            if (compressed == null) {
+                ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                bitmap.compress(Bitmap.CompressFormat.PNG, 0, bos);
+                compressed = bos.toByteArray();
+            }
             mLastScreen = compressed;
+        }
         if (thumbnailTab.getURL().equals("about:home")) {
             thumbnailTab.updateThumbnail(null);
             return;
         }
         try {
             if (bitmap == null)
                 bitmap = BitmapFactory.decodeByteArray(compressed, 0, compressed.length);
             thumbnailTab.updateThumbnail(bitmap);
@@ -2317,31 +2323,31 @@ abstract public class GeckoApp
         } catch (Exception e) {
             Log.i(LOGTAG, "error reading update status", e);
         }
         return status;
     }
 
     private void checkMigrateProfile() {
         File profileDir = getProfileDir();
+        long currentTime = SystemClock.uptimeMillis();
+
         if (profileDir != null) {
-            long currentTime = SystemClock.uptimeMillis();
             Log.i(LOGTAG, "checking profile migration in: " + profileDir.getAbsolutePath());
             final GeckoApp app = GeckoApp.mAppContext;
             final SetupScreen setupScreen = new SetupScreen(app);
             // don't show unless we take a while
             setupScreen.showDelayed(mMainHandler);
-            GeckoAppShell.ensureSQLiteLibsLoaded(app.getApplication().getPackageResourcePath());
             ProfileMigrator profileMigrator =
                 new ProfileMigrator(app.getContentResolver(), profileDir);
             profileMigrator.launch();
             setupScreen.dismiss();
-            long timeDiff = SystemClock.uptimeMillis() - currentTime;
-            Log.i(LOGTAG, "Profile migration took " + timeDiff + " ms");
         }
+        long timeDiff = SystemClock.uptimeMillis() - currentTime;
+        Log.i(LOGTAG, "Profile migration took " + timeDiff + " ms");
     }
 
     private SynchronousQueue<String> mFilePickerResult = new SynchronousQueue<String>();
     public String showFilePicker(String aMimeType) {
         Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
         intent.addCategory(Intent.CATEGORY_OPENABLE);
         intent.setType(aMimeType);
         GeckoApp.this.
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -553,16 +553,27 @@ public class GeckoAppShell
             mInputConnection.notifyIMEEnabled(state, typeHint, actionHint, landscapeFS);
     }
 
     public static void notifyIMEChange(String text, int start, int end, int newEnd) {
         if (mInputConnection != null)
             mInputConnection.notifyIMEChange(text, start, end, newEnd);
     }
 
+    public static void notifyScreenShot(ByteBuffer data, int tabId, int width, int height) {
+        final Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
+        b.copyPixelsFromBuffer(data);
+        final Tab tab = Tabs.getInstance().getTab(tabId);
+        getHandler().post(new Runnable() {
+            public void run() {
+                GeckoApp.mAppContext.processThumbnail(tab, b, null);
+            }
+        });
+    }
+
     private static CountDownLatch sGeckoPendingAcks = null;
 
     // Block the current thread until the Gecko event loop is caught up
     synchronized public static void geckoEventSync() {
         sGeckoPendingAcks = new CountDownLatch(1);
         GeckoAppShell.sendEventToGecko(
             new GeckoEvent(GeckoEvent.GECKO_EVENT_SYNC));
         while (sGeckoPendingAcks.getCount() != 0) {
--- a/mobile/android/base/ProfileMigrator.java
+++ b/mobile/android/base/ProfileMigrator.java
@@ -275,16 +275,17 @@ public class ProfileMigrator {
             if (!dbFile.exists()) {
                 Log.i(LOGTAG, "No database");
                 return;
             }
             File dbFileWal = new File(dbPathWal);
             File dbFileShm = new File(dbPathShm);
 
             SQLiteBridge db = null;
+            GeckoAppShell.ensureSQLiteLibsLoaded(GeckoApp.mAppContext.getApplication().getPackageResourcePath());
             try {
                 db = new SQLiteBridge(dbPath);
                 migrateBookmarks(db);
                 migrateHistory(db);
                 db.close();
 
                 // Clean up
                 dbFile.delete();
--- a/mobile/android/base/Tabs.java
+++ b/mobile/android/base/Tabs.java
@@ -63,17 +63,16 @@ public class Tabs implements GeckoEventL
         GeckoAppShell.registerGeckoEventListener("SessionHistory:New", this);
         GeckoAppShell.registerGeckoEventListener("SessionHistory:Back", this);
         GeckoAppShell.registerGeckoEventListener("SessionHistory:Forward", this);
         GeckoAppShell.registerGeckoEventListener("SessionHistory:Goto", this);
         GeckoAppShell.registerGeckoEventListener("SessionHistory:Purge", this);
         GeckoAppShell.registerGeckoEventListener("Tab:Added", this);
         GeckoAppShell.registerGeckoEventListener("Tab:Close", this);
         GeckoAppShell.registerGeckoEventListener("Tab:Select", this);
-        GeckoAppShell.registerGeckoEventListener("Tab:ScreenshotData", this);
         GeckoAppShell.registerGeckoEventListener("Session:RestoreBegin", this);
         GeckoAppShell.registerGeckoEventListener("Session:RestoreEnd", this);
     }
 
     public int getCount() {
         return tabs.size();
     }
 
@@ -283,23 +282,16 @@ public class Tabs implements GeckoEventL
                     selectTab(tab.getId());
                 if (message.getBoolean("delayLoad"))
                     tab.setHasLoaded(false);
             } else if (event.equals("Tab:Close")) {
                 Tab tab = getTab(message.getInt("tabID"));
                 closeTab(tab);
             } else if (event.equals("Tab:Select")) {
                 selectTab(message.getInt("tabID"));
-            } else if (event.equals("Tab:ScreenshotData")) {
-                Tab tab = getTab(message.getInt("tabID"));
-                String data = message.getString("data");
-                if (data.length() < 22)
-                    return;
-                byte[] compressed = GeckoAppShell.decodeBase64(data.substring(22), GeckoAppShell.BASE64_DEFAULT);
-                GeckoApp.mAppContext.processThumbnail(tab, null, compressed);
             } else if (event.equals("Session:RestoreBegin")) {
                 mRestoringSession = true;
             } else if (event.equals("Session:RestoreEnd")) {
                 mRestoringSession = false;
                 GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
                     public void run() {
                         GeckoApp.mBrowserToolbar.updateTabCount(getCount());
                     }
--- a/mobile/android/base/tests/BaseTest.java.in
+++ b/mobile/android/base/tests/BaseTest.java.in
@@ -99,18 +99,16 @@ abstract class BaseTest extends Activity
     }
 
     protected final Activity clickOnAwesomeBar() {
         Element awesomebar = mDriver.findElement(mActivity, "awesome_bar");
         return getActivityFromClick(awesomebar);
     }
 
     protected final void enterUrl(String url) {
-        mActions.expectGeckoEvent("Gecko:Ready").blockForEvent();
-
         Activity awesomeBarActivity = clickOnAwesomeBar();
         Element urlbar = mDriver.findElement(awesomeBarActivity, "awesomebar_text");
         mActions.sendKeys(url);
         mAsserter.is(urlbar.getText(), url, "Awesomebar URL typed properly");
     }
 
     protected final void hitEnterAndWait() {
         Actions.EventExpecter contentEventExpecter = mActions.expectGeckoEvent("DOMContentLoaded");
--- a/mobile/android/base/tests/testAwesomebar.java.in
+++ b/mobile/android/base/tests/testAwesomebar.java.in
@@ -2,16 +2,18 @@
 package @ANDROID_PACKAGE_NAME@.tests;
 
 import @ANDROID_PACKAGE_NAME@.*;
 
 public class testAwesomebar extends BaseTest {
     public void testAwesomebar() {
         setTestType("mochitest");
 
+        mActions.expectGeckoEvent("Gecko:Ready").blockForEvent();
+
         String url = getAbsoluteUrl("/robocop/robocop_blank_01.html");
         loadUrl(url);
 
         mDriver.setupScrollHandling();
         // Calculate where we should be dragging.
         int midX = mDriver.getGeckoLeft() + mDriver.getGeckoWidth()/2;
         int midY = mDriver.getGeckoTop() + mDriver.getGeckoHeight()/2;
         int endY = mDriver.getGeckoTop() + mDriver.getGeckoHeight()/10;
--- a/mobile/android/base/tests/testAxisLocking.java.in
+++ b/mobile/android/base/tests/testAxisLocking.java.in
@@ -14,16 +14,18 @@ import android.app.Instrumentation;
  */
 public class testAxisLocking extends PixelTest {
     public void testAxisLocking() {
         setTestType("mochitest");
         String url = getAbsoluteUrl("/robocop/robocop_boxes.html");
 
         MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mDriver.getGeckoLeft(), mDriver.getGeckoTop());
 
+        mActions.expectGeckoEvent("Gecko:Ready").blockForEvent();
+
         // load page and check we're at 0,0
         loadAndVerifyBoxes(url);
 
         // drag page upwards by 100 pixels with a slight angle. verify that
         // axis locking prevents any horizontal scrolling
         Actions.RepeatedEventExpecter paintExpecter = mActions.expectPaint();
         meh.dragSync(20, 150, 10, 50);
         int[][] painted = waitForPaint(paintExpecter);
--- a/mobile/android/base/tests/testBookmark.java.in
+++ b/mobile/android/base/tests/testBookmark.java.in
@@ -7,16 +7,19 @@ import android.widget.TextView;
 import android.os.SystemClock;
 import java.util.ArrayList;
 
 public class testBookmark extends BaseTest {
     private static final long MAX_WAIT_MS = 10 * 1000; 
 
     public void testBookmark() {
         setTestType("mochitest");
+
+        mActions.expectGeckoEvent("Gecko:Ready").blockForEvent();
+
         String url = getAbsoluteUrl("/robocop/robocop_blank_02.html");
         enterUrl(url);
 
         //Click the top item in the awesome list.
         mActions.sendSpecialKey(Actions.SpecialKey.DOWN);
         hitEnterAndWait();
 
         //Click the top item in the bookmark list.
--- a/mobile/android/base/tests/testCheck.java.in
+++ b/mobile/android/base/tests/testCheck.java.in
@@ -10,16 +10,19 @@ public class testCheck extends PixelTest
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
     }
 
     public void testCheck() {
         setTestType("talos");
         String url = getAbsoluteUrl("/startup_test/fennecmark/wikipedia.html");
+
+        mActions.expectGeckoEvent("Gecko:Ready").blockForEvent();
+
         loadAndPaint(url);
 
         mDriver.setupScrollHandling();
 
         // Setup scrolling coordinates.
         int midX = mDriver.getGeckoLeft() + mDriver.getGeckoWidth()/2;
         int midY = mDriver.getGeckoTop() + mDriver.getGeckoHeight()/2;
         int endY = mDriver.getGeckoTop() + mDriver.getGeckoHeight()/6;
--- a/mobile/android/base/tests/testFlingCorrectness.java.in
+++ b/mobile/android/base/tests/testFlingCorrectness.java.in
@@ -12,16 +12,18 @@ import android.app.Instrumentation;
  */
 public class testFlingCorrectness extends PixelTest {
     public void testFlingCorrectness() {
         setTestType("mochitest");
         String url = getAbsoluteUrl("/robocop/robocop_boxes.html");
 
         MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mDriver.getGeckoLeft(), mDriver.getGeckoTop());
 
+        mActions.expectGeckoEvent("Gecko:Ready").blockForEvent();
+
         // load page and check we're at 0,0
         loadAndVerifyBoxes(url);
 
         // drag page upwards by 200 pixels (use two drags instead of one in case
         // the screen size is small)
         Actions.RepeatedEventExpecter paintExpecter = mActions.expectPaint();
         meh.dragSync(10, 150, 10, 50);
         meh.dragSync(10, 150, 10, 50);
--- a/mobile/android/base/tests/testLoad.java.in
+++ b/mobile/android/base/tests/testLoad.java.in
@@ -9,13 +9,15 @@ import @ANDROID_PACKAGE_NAME@.*;
  * - verifies it rendered properly
  * - verifies the displayed url is correct
  */
 public class testLoad extends PixelTest {
     public void testLoad() {
         setTestType("mochitest");
         String url = getAbsoluteUrl("/robocop/robocop_boxes.html");
 
+        mActions.expectGeckoEvent("Gecko:Ready").blockForEvent();
+
         loadAndVerifyBoxes(url);
 
         verifyUrl(url);
     }
 }
--- a/mobile/android/base/tests/testOverscroll.java.in
+++ b/mobile/android/base/tests/testOverscroll.java.in
@@ -12,16 +12,18 @@ import android.app.Instrumentation;
  */
 public class testOverscroll extends PixelTest {
     public void testOverscroll() {
         setTestType("mochitest");
         String url = getAbsoluteUrl("/robocop/robocop_boxes.html");
 
         MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mDriver.getGeckoLeft(), mDriver.getGeckoTop());
 
+        mActions.expectGeckoEvent("Gecko:Ready").blockForEvent();
+
         // load page and check we're at 0,0
         loadAndVerifyBoxes(url);
 
         // drag page downwards by 100 pixels so that it goes into overscroll.
         // wait for it to bounce back and check we're at the right spot.
         // the screen size is small). Note that since we only go into overscroll
         // and back this should NOT trigger a gecko-paint
         Actions.RepeatedEventExpecter paintExpecter = mActions.expectPaint();
--- a/mobile/android/base/tests/testPan.java.in
+++ b/mobile/android/base/tests/testPan.java.in
@@ -9,16 +9,18 @@ import @ANDROID_PACKAGE_NAME@.*;
  * that fennec draws at.
  */
 public class testPan extends PixelTest {
 
     public void testPan() {
         setTestType("talos");
         String url = getAbsoluteUrl("/startup_test/fennecmark/wikipedia.html");
 
+        mActions.expectGeckoEvent("Gecko:Ready").blockForEvent();
+
         loadAndPaint(url);
 
         mDriver.setupScrollHandling();
 
         // Setup scrolling coordinates.
         int midX = mDriver.getGeckoLeft() + mDriver.getGeckoWidth()/2;
         int midY = mDriver.getGeckoTop() + mDriver.getGeckoHeight()/2;
         int endY = mDriver.getGeckoTop() + mDriver.getGeckoHeight()/10;
--- a/mobile/android/base/tests/testPanCorrectness.java.in
+++ b/mobile/android/base/tests/testPanCorrectness.java.in
@@ -12,16 +12,18 @@ import android.app.Instrumentation;
  */
 public class testPanCorrectness extends PixelTest {
     public void testPanCorrectness() {
         setTestType("mochitest");
         String url = getAbsoluteUrl("/robocop/robocop_boxes.html");
 
         MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mDriver.getGeckoLeft(), mDriver.getGeckoTop());
 
+        mActions.expectGeckoEvent("Gecko:Ready").blockForEvent();
+
         // load page and check we're at 0,0
         loadAndVerifyBoxes(url);
 
         // drag page upwards by 100 pixels
         Actions.RepeatedEventExpecter paintExpecter = mActions.expectPaint();
         meh.dragSync(10, 150, 10, 50);
         int[][] painted = waitForPaint(paintExpecter);
         checkScrollWithBoxes(painted, 0, 100);
--- a/mobile/android/base/tests/test_bug720538.java.in
+++ b/mobile/android/base/tests/test_bug720538.java.in
@@ -4,16 +4,18 @@ package @ANDROID_PACKAGE_NAME@.tests;
 import @ANDROID_PACKAGE_NAME@.*;
 import android.app.Instrumentation;
 
 public class test_bug720538 extends PixelTest {
     public void test_bug720538() {
         setTestType("mochitest");
         String url = getAbsoluteUrl("/robocop/test_bug720538.html");
 
+        mActions.expectGeckoEvent("Gecko:Ready").blockForEvent();
+
         /*
          * for this test, we load the associated test_bug720538.html file. this file has two
          * iframes (painted completely blue - #0000FF) and the rest of the page is the background
          * color, which is #008000 green. When we first render the page there is an iframe in
          * the top-left corner, and when we double-tap on it it should zoom to fill the visible
          * view area leaving a little bit of space on either side. We can test for this by checking
          * a few pixels to ensure that there is some background visible on either side of the iframe.
          * Finally, when we double-tap on it to zoom out again, we need to check that the bottom of
--- a/mobile/android/chrome/content/aboutAddons.xhtml
+++ b/mobile/android/chrome/content/aboutAddons.xhtml
@@ -135,22 +135,24 @@
                     .getInterface(Ci.nsIDOMWindow)
                     .QueryInterface(Ci.nsIDOMChromeWindow);
       }
       return gChromeWin;
     }
 
     function init() {
       window.addEventListener("popstate", onPopState, false);
+      Services.obs.addObserver(Addons, "browser-search-engine-modified", false);
 
       AddonManager.addInstallListener(Addons);
       Addons.getAddons();
     }
 
     function uninit() {
+      Services.obs.removeObserver(Addons, "browser-search-engine-modified");
       AddonManager.removeInstallListener(Addons);
     }
 
     function openLink(aElement) {
       try {
         let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
         let url = formatter.formatURLPref(aElement.getAttribute("pref"));
         let BrowserApp = getChromeWin().BrowserApp;
@@ -485,18 +487,18 @@
 
         let listItem = this._getElementForAddon(detailItem.addon.id);
 
         if (detailItem.addon.type == "search") {
           // Make sure the engine isn't hidden before removing it, to make sure it's
           // visible if the user later re-adds it (works around bug 341833)
           detailItem.addon.engine.hidden = false;
           Services.search.removeEngine(detailItem.addon.engine);
-          // the search-engine-modified observer in browser.js will take care of
-          // updating the list
+          // the search-engine-modified observer will take care of updating the list
+          history.back();
         } else {
           detailItem.addon.uninstall();
           let opType = this._getOpTypeForOperations(detailItem.addon.pendingOperations);
 
           if (detailItem.addon.pendingOperations & AddonManager.PENDING_UNINSTALL) {
             this.showRestart();
 
             // A disabled addon doesn't need a restart so it has no pending ops and
@@ -549,16 +551,28 @@
           element = this._createItemForAddon(aAddon);
           list.insertBefore(element, list.firstElementChild);
         }
 
         if (needsRestart)
           element.setAttribute("opType", "needs-restart");
       },
 
+      observe: function observe(aSubject, aTopic, aData) {
+        if (aTopic == "browser-search-engine-modified") {
+          switch (aData) {
+            case "engine-added":
+            case "engine-removed":
+            case "engine-changed":
+              this.getAddons();
+              break;
+          }
+        }
+      },
+
       onInstallFailed: function(aInstall) {
       },
 
       onDownloadProgress: function xpidm_onDownloadProgress(aInstall) {
       },
 
       onDownloadFailed: function(aInstall) {
       },
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -348,39 +348,53 @@ var BrowserApp = {
       gecko: {
         "type": "Checkerboard:Toggle",
         "value": Services.prefs.getBoolPref("gfx.show_checkerboard_pattern")
       }
     });
   },
 
   _showTelemetryPrompt: function _showTelemetryPrompt() {
-    let telemetryPrompted = false;
+    const PREF_TELEMETRY_PROMPTED = "toolkit.telemetry.prompted";
+    const PREF_TELEMETRY_ENABLED = "toolkit.telemetry.enabled";
+    const PREF_TELEMETRY_REJECTED = "toolkit.telemetry.rejected";
+
+    // This is used to reprompt users when privacy message changes
+    const TELEMETRY_PROMPT_REV = 2;
+
+    let telemetryPrompted = null;
     try {
-      telemetryPrompted = Services.prefs.getBoolPref("toolkit.telemetry.prompted");
+      telemetryPrompted = Services.prefs.getIntPref(PREF_TELEMETRY_PROMPTED);
     } catch (e) { /* Optional */ }
-    if (telemetryPrompted)
+
+    // If the user has seen the latest telemetry prompt, do not prompt again
+    // else clear old prefs and reprompt
+    if (telemetryPrompted === TELEMETRY_PROMPT_REV)
       return;
 
+    Services.prefs.clearUserPref(PREF_TELEMETRY_PROMPTED);
+    Services.prefs.clearUserPref(PREF_TELEMETRY_ENABLED);
+  
     let buttons = [
       {
         label: Strings.browser.GetStringFromName("telemetry.optin.yes"),
         callback: function () {
-          Services.prefs.setBoolPref("toolkit.telemetry.prompted", true);
-          Services.prefs.setBoolPref("toolkit.telemetry.enabled", true);
+          Services.prefs.setIntPref(PREF_TELEMETRY_PROMPTED, TELEMETRY_PROMPT_REV);
+          Services.prefs.setBoolPref(PREF_TELEMETRY_ENABLED, true);
         }
       },
       {
         label: Strings.browser.GetStringFromName("telemetry.optin.no"),
         callback: function () {
-          Services.prefs.setBoolPref("toolkit.telemetry.prompted", true);
-          Services.prefs.setBoolPref("toolkit.telemetry.enabled", false);
+          Services.prefs.setIntPref(PREF_TELEMETRY_PROMPTED, TELEMETRY_PROMPT_REV);
+          Services.prefs.setBoolPref(PREF_TELEMETRY_REJECTED, true);
         }
       }
     ];
+
     let brandShortName = Strings.brand.GetStringFromName("brandShortName");
     let message = Strings.browser.formatStringFromName("telemetry.optin.message", [brandShortName], 1);
     NativeWindow.doorhanger.show(message, "telemetry-optin", buttons);
   },
 
   shutdown: function shutdown() {
     NativeWindow.uninit();
     FormAssistant.uninit();
@@ -1360,17 +1374,17 @@ nsBrowserAccess.prototype = {
           aWhere = Services.prefs.getIntPref("browser.link.open_newwindow");
       }
     }
 
     let newTab = (aWhere == Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW || aWhere == Ci.nsIBrowserDOMWindow.OPEN_NEWTAB);
 
     let parentId = -1;
     if (newTab && !isExternal) {
-      let parent = BrowserApp.getTabForBrowser(BrowserApp.getBrowserForWindow(aOpener));
+      let parent = BrowserApp.getTabForBrowser(BrowserApp.getBrowserForWindow(aOpener.top));
       if (parent)
         parentId = parent.id;
     }
 
     let browser;
     if (newTab) {
       let tab = BrowserApp.addTab("about:blank", { external: isExternal, parentId: parentId, selected: true });
       browser = tab.browser;
@@ -1596,34 +1610,17 @@ Tab.prototype = {
     if (transformChanged)
       this.updateTransform();
   },
 
   screenshot: function(aSrc, aDst) {
       if (!this.browser || !this.browser.contentWindow)
         return;
 
-      let canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
-      canvas.setAttribute("width", aDst.width);  
-      canvas.setAttribute("height", aDst.height);
-      canvas.setAttribute("moz-opaque", "true");
-
-      let ctx = canvas.getContext("2d");
-      let flags = ctx.DRAWWINDOW_DO_NOT_FLUSH;
-      ctx.drawWindow(this.browser.contentWindow, 0, 0, aSrc.width, aSrc.height, "#fff", flags);
-      let message = {
-        gecko: {
-          type: "Tab:ScreenshotData",
-          tabID: this.id,
-          width: aDst.width,
-          height: aDst.height,
-          data: canvas.toDataURL()
-        }
-      };
-      sendMessageToJava(message);
+      getBridge().takeScreenshot(this.browser.contentWindow, 0, 0, aSrc.width, aSrc.height, aDst.width, aDst.height, this.id);
       Services.tm.mainThread.dispatch(function() {
 	  BrowserApp.doNextScreenshot()
       }, Ci.nsIThread.DISPATCH_NORMAL);
   },
 
   updateTransform: function() {
     let hasZoom = (Math.abs(this._viewport.zoom - 1.0) >= 1e-6);
     let x = this._viewport.offsetX + Math.round(-this.viewportExcess.x * this._viewport.zoom);
@@ -2902,78 +2899,71 @@ var FormAssistant = {
       aElement.dispatchEvent(evt);
     }, 0);
   },
 
   _isSelectElement: function(aElement) {
     return (aElement instanceof HTMLSelectElement);
   },
 
-  _isOptionElement: function(aElement) {
-    return aElement instanceof HTMLOptionElement;
-  },
-
-  _isOptionGroupElement: function(aElement) {
-    return aElement instanceof HTMLOptGroupElement;
-  },
-
   getListForElement: function(aElement) {
     let result = {
       type: "Prompt:Show",
       multiple: aElement.multiple,
       selected: [],
       listitems: []
     };
 
     if (aElement.multiple) {
       result.buttons = [
         { label: Strings.browser.GetStringFromName("selectHelper.closeMultipleSelectDialog") },
       ];
     }
 
-    this.forOptions(aElement, function(aNode, aIndex) {
+    this.forOptions(aElement, function(aNode, aIndex, aIsGroup, aInGroup) {
       let item = {
         label: aNode.text || aNode.label,
-        isGroup: this._isOptionGroupElement(aNode),
-        inGroup: this._isOptionGroupElement(aNode.parentNode),
+        isGroup: aIsGroup,
+        inGroup: aInGroup,
         disabled: aNode.disabled,
         id: aIndex
       }
-      if (item.inGroup)
+      if (aInGroup)
         item.disabled = item.disabled || aNode.parentNode.disabled;
 
       result.listitems[aIndex] = item;
       result.selected[aIndex] = aNode.selected;
     });
     return result;
   },
 
   forOptions: function(aElement, aFunction) {
     let optionIndex = 0;
     let children = aElement.children;
+    let numChildren = children.length;
     // if there are no children in this select, we add a dummy row so that at least something appears
-    if (children.length == 0)
+    if (numChildren == 0)
       aFunction.call(this, {label:""}, optionIndex);
-    for (let i = 0; i < children.length; i++) {
+    for (let i = 0; i < numChildren; i++) {
       let child = children[i];
-      if (this._isOptionGroupElement(child)) {
-        aFunction.call(this, child, optionIndex);
+      if (child instanceof HTMLOptionElement) {
+        // This is a regular choice under no group.
+        aFunction.call(this, child, optionIndex, false, false);
+        optionIndex++;
+      } else if (child instanceof HTMLOptGroupElement) {
+        aFunction.call(this, child, optionIndex, true, false);
         optionIndex++;
 
         let subchildren = child.children;
-        for (let j = 0; j < subchildren.length; j++) {
+        let numSubchildren = subchildren.length;
+        for (let j = 0; j < numSubchildren; j++) {
           let subchild = subchildren[j];
-          aFunction.call(this, subchild, optionIndex);
+          aFunction.call(this, subchild, optionIndex, false, true);
           optionIndex++;
         }
-
-      } else if (this._isOptionElement(child)) {
-        // This is a regular choice under no group.
-        aFunction.call(this, child, optionIndex);
-        optionIndex++;
       }
     }
   }
 }
 
 var XPInstallObserver = {
   init: function xpi_init() {
     Services.obs.addObserver(XPInstallObserver, "addon-install-blocked", false);
@@ -4160,12 +4150,11 @@ var CharacterEncoding = {
     });
   },
 
   setEncoding: function setEncoding(aEncoding) {
     let browser = BrowserApp.selectedBrowser;
     let docCharset = browser.docShell.QueryInterface(Ci.nsIDocCharset);
     docCharset.charset = aEncoding;
     browser.reload(Ci.nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE);
-  },
-
+  }
 };
 
--- a/mobile/android/makefiles.sh
+++ b/mobile/android/makefiles.sh
@@ -31,35 +31,36 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 add_makefiles "
-netwerk/locales/Makefile
-dom/locales/Makefile
-toolkit/locales/Makefile
-security/manager/locales/Makefile
+mobile/locales/Makefile
+mobile/android/Makefile
 mobile/android/app/Makefile
 mobile/android/app/profile/extensions/Makefile
 mobile/android/base/Makefile
 mobile/android/base/locales/Makefile
-mobile/locales/Makefile
 $MOZ_BRANDING_DIRECTORY/Makefile
+$MOZ_BRANDING_DIRECTORY/content/Makefile
 $MOZ_BRANDING_DIRECTORY/locales/Makefile
 mobile/android/chrome/Makefile
-mobile/android/chrome/tests/Makefile
 mobile/android/components/Makefile
-mobile/android/components/build/Makefile
 mobile/android/modules/Makefile
 mobile/android/installer/Makefile
 mobile/android/locales/Makefile
-mobile/android/Makefile
 mobile/android/themes/core/Makefile
 "
 
-if test -n "$MOZ_UPDATE_PACKAGING"; then
-   add_makefiles "
-     tools/update-packaging/Makefile
-   "
+if [ ! "$LIBXUL_SDK" ]; then
+  add_makefiles "
+    mobile/android/components/build/Makefile
+  "
 fi
+
+if [ "$ENABLE_TESTS" ]; then
+  add_makefiles "
+    mobile/android/chrome/tests/Makefile
+  "
+fi
--- a/mobile/xul/makefiles.sh
+++ b/mobile/xul/makefiles.sh
@@ -31,29 +31,34 @@
 # 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 *****
 
 add_makefiles "
+mobile/locales/Makefile
+mobile/xul/Makefile
 mobile/xul/app/Makefile
 mobile/xul/app/profile/extensions/Makefile
 $MOZ_BRANDING_DIRECTORY/Makefile
 $MOZ_BRANDING_DIRECTORY/content/Makefile
 $MOZ_BRANDING_DIRECTORY/locales/Makefile
 mobile/xul/chrome/Makefile
 mobile/xul/components/Makefile
-mobile/xul/components/build/Makefile
 mobile/xul/modules/Makefile
 mobile/xul/installer/Makefile
 mobile/xul/locales/Makefile
-mobile/locales/Makefile
-mobile/xul/Makefile
 mobile/xul/themes/core/Makefile
 "
 
+if [ ! "$LIBXUL_SDK" ]; then
+  add_makefiles "
+    mobile/xul/components/build/Makefile
+  "
+fi
+
 if [ "$ENABLE_TESTS" ]; then
   add_makefiles "
     mobile/xul/chrome/tests/Makefile
   "
 fi
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -1547,24 +1547,23 @@ CopyProperties(const nsAString& aKey, ns
 
 // Return whether upon a redirect code of httpStatus for method, the
 // request method should be rewritten to GET.
 //
 bool
 HttpBaseChannel::ShouldRewriteRedirectToGET(PRUint32 httpStatus,
                                             nsHttpAtom method)
 {
-  // always rewrite for 301 and 302, but see bug 598304
-  // and  RFC 2616, Section 8.3.
+  // for 301 and 302, only rewrite POST
   if (httpStatus == 301 || httpStatus == 302)
-    return true;
+    return method == nsHttp::Post;
 
-  // always rewrite for 303
+  // rewrite for 303 unless it was HEAD
   if (httpStatus == 303)
-    return true;
+    return method != nsHttp::Head;
 
   // otherwise, such as for 307, do not rewrite
   return false;
 }   
 
 // Return whether the specified method is safe as per RFC 2616, Section 9.1.1.
 bool
 HttpBaseChannel::IsSafeMethod(nsHttpAtom method)
--- a/netwerk/test/unit/test_XHR_redirects.js
+++ b/netwerk/test/unit/test_XHR_redirects.js
@@ -70,33 +70,33 @@ function run_test() {
   //   finalStatus is 200 when the redirect takes place, redirectType otherwise
   
   // Note that unsafe methods should not follow the redirect automatically
   // Of the methods below, DELETE, POST and PUT are unsafe
   
   // same-origin variant
   var tests = [
     // 301: rewrite just POST
-    [301, "DELETE", "GET", 200], // but see bug 598304
+    [301, "DELETE", null, 301],
     [301, "GET", "GET", 200],
-    [301, "HEAD", "GET", 200], // but see bug 598304
+    [301, "HEAD", "HEAD", 200],
     [301, "POST", "GET", 200],
-    [301, "PUT", "GET", 200], // but see bug 598304
-    [301, "PROPFIND", "GET", 200], // but see bug 598304
+    [301, "PUT", null, 301],
+    [301, "PROPFIND", "PROPFIND", 200],
     // 302: see 301
-    [302, "DELETE", "GET", 200], // but see bug 598304
+    [302, "DELETE", null, 302],
     [302, "GET", "GET", 200],
-    [302, "HEAD", "GET", 200], // but see bug 598304
+    [302, "HEAD", "HEAD", 200],
     [302, "POST", "GET", 200],
-    [302, "PUT", "GET", 200], // but see bug 598304
-    [302, "PROPFIND", "GET", 200], // but see bug 598304
+    [302, "PUT", null, 302],
+    [302, "PROPFIND", "PROPFIND", 200],
     // 303: rewrite to GET except HEAD
     [303, "DELETE", "GET", 200],
     [303, "GET", "GET", 200],
-    [303, "HEAD", "GET", 200],
+    [303, "HEAD", "HEAD", 200],
     [303, "POST", "GET", 200],
     [303, "PUT", "GET", 200],
     [303, "PROPFIND", "GET", 200],
     // 307: never rewrite
     [307, "DELETE", null, 307],
     [307, "GET", "GET", 200],
     [307, "HEAD", "HEAD", 200],
     [307, "POST", null, 307],
--- a/toolkit/components/downloads/nsDownloadManager.cpp
+++ b/toolkit/components/downloads/nsDownloadManager.cpp
@@ -106,21 +106,22 @@ static const PRInt64 gUpdateInterval = 4
 #define DM_DB_NAME             NS_LITERAL_STRING("downloads.sqlite")
 #define DM_DB_CORRUPT_FILENAME NS_LITERAL_STRING("downloads.sqlite.corrupt")
 
 #define NS_SYSTEMINFO_CONTRACTID "@mozilla.org/system-info;1"
 
 ////////////////////////////////////////////////////////////////////////////////
 //// nsDownloadManager
 
-NS_IMPL_ISUPPORTS3(
+NS_IMPL_ISUPPORTS4(
   nsDownloadManager
 , nsIDownloadManager
 , nsINavHistoryObserver
 , nsIObserver
+, nsISupportsWeakReference
 )
 
 nsDownloadManager *nsDownloadManager::gDownloadManagerService = nsnull;
 
 nsDownloadManager *
 nsDownloadManager::GetSingleton()
 {
   if (gDownloadManagerService) {
@@ -881,33 +882,29 @@ nsDownloadManager::Init()
   nsCOMPtr<nsINavHistoryService> history =
     do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID);
 
   // The following AddObserver calls must be the last lines in this function,
   // because otherwise, this function may fail (and thus, this object would be not
   // completely initialized), but the observerservice would still keep a reference
   // to us and notify us about shutdown, which may cause crashes.
   // failure to add an observer is not critical
-  //
-  // These observers will be cleaned up automatically at app shutdown.  We do
-  // not bother explicitly breaking the observers because we are a singleton
-  // that lives for the duration of the app.
-  (void)mObserverService->AddObserver(this, "quit-application", false);
-  (void)mObserverService->AddObserver(this, "quit-application-requested", false);
-  (void)mObserverService->AddObserver(this, "offline-requested", false);
-  (void)mObserverService->AddObserver(this, "sleep_notification", false);
-  (void)mObserverService->AddObserver(this, "wake_notification", false);
-  (void)mObserverService->AddObserver(this, "profile-before-change", false);
-  (void)mObserverService->AddObserver(this, NS_IOSERVICE_GOING_OFFLINE_TOPIC, false);
-  (void)mObserverService->AddObserver(this, NS_IOSERVICE_OFFLINE_STATUS_TOPIC, false);
-  (void)mObserverService->AddObserver(this, NS_PRIVATE_BROWSING_REQUEST_TOPIC, false);
-  (void)mObserverService->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, false);
+  (void)mObserverService->AddObserver(this, "quit-application", true);
+  (void)mObserverService->AddObserver(this, "quit-application-requested", true);
+  (void)mObserverService->AddObserver(this, "offline-requested", true);
+  (void)mObserverService->AddObserver(this, "sleep_notification", true);
+  (void)mObserverService->AddObserver(this, "wake_notification", true);
+  (void)mObserverService->AddObserver(this, "profile-before-change", true);
+  (void)mObserverService->AddObserver(this, NS_IOSERVICE_GOING_OFFLINE_TOPIC, true);
+  (void)mObserverService->AddObserver(this, NS_IOSERVICE_OFFLINE_STATUS_TOPIC, true);
+  (void)mObserverService->AddObserver(this, NS_PRIVATE_BROWSING_REQUEST_TOPIC, true);
+  (void)mObserverService->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, true);
 
   if (history)
-    (void)history->AddObserver(this, false);
+    (void)history->AddObserver(this, true);
 
   return NS_OK;
 }
 
 PRInt32
 nsDownloadManager::GetRetentionBehavior()
 {
   // We use 0 as the default, which is "remove when done"
--- a/toolkit/components/downloads/nsDownloadManager.h
+++ b/toolkit/components/downloads/nsDownloadManager.h
@@ -53,16 +53,17 @@
 #include "nsIDownloadProgressListener.h"
 #include "nsILocalFile.h"
 #include "nsIMIMEInfo.h"
 #include "nsINavHistoryService.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIStringBundle.h"
 #include "nsISupportsPrimitives.h"
+#include "nsWeakReference.h"
 #include "nsITimer.h"
 #include "nsString.h"
 
 #include "mozStorageHelper.h"
 #include "nsAutoPtr.h"
 #include "nsCOMArray.h"
 
 typedef PRInt16 DownloadState;
@@ -71,17 +72,18 @@ typedef PRInt16 DownloadType;
 class nsDownload;
 
 #ifdef DOWNLOAD_SCANNER
 #include "nsDownloadScanner.h"
 #endif
 
 class nsDownloadManager : public nsIDownloadManager,
                           public nsINavHistoryObserver,
-                          public nsIObserver
+                          public nsIObserver,
+                          public nsSupportsWeakReference
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOWNLOADMANAGER
   NS_DECL_NSINAVHISTORYOBSERVER
   NS_DECL_NSIOBSERVER
 
   nsresult Init();
--- a/toolkit/components/maintenanceservice/Makefile.in
+++ b/toolkit/components/maintenanceservice/Makefile.in
@@ -52,19 +52,20 @@ CPPSRCS = \
   $(NULL)
 
 # For debugging purposes only
 #DEFINES += -DDISABLE_UPDATER_AUTHENTICODE_CHECK
 
 PROGRAM = maintenanceservice$(BIN_SUFFIX)
 DIST_PROGRAM = maintenanceservice$(BIN_SUFFIX)
 
-# Don't link the maintenanceservice against libmozutils. See bug 687139
-MOZ_UTILS_LDFLAGS =
-MOZ_UTILS_PROGRAM_LDFLAGS =
+# Don't link the maintenanceservice against mozglue.dll. See bug 687139 and
+# bug 725876
+MOZ_GLUE_LDFLAGS =
+MOZ_GLUE_PROGRAM_LDFLAGS =
 
 LIBS += \
   ../../mozapps/update/common/$(LIB_PREFIX)updatecommon.$(LIB_SUFFIX) \
   ../../mozapps/readstrings/$(LIB_PREFIX)readstrings.$(LIB_SUFFIX) \
   $(NULL)
 
 USE_STATIC_LIBS = 1
 HAVE_PROGRESSUI = 1
--- a/toolkit/components/startup/Makefile.in
+++ b/toolkit/components/startup/Makefile.in
@@ -68,15 +68,13 @@ CMMSRCS += nsUserInfoMac.mm
 else
 CPPSRCS += nsUserInfoUnix.cpp
 endif
 endif
 endif
 
 XPCSHELL_TESTS = tests/unit
 
-ifdef ENABLE_TESTS
 ifneq (mobile,$(MOZ_BUILD_APP))
-DIRS += tests/browser
-endif
+TEST_DIRS += tests/browser
 endif
 
 include $(topsrcdir)/config/rules.mk
--- a/toolkit/mozapps/shared/Makefile.in
+++ b/toolkit/mozapps/shared/Makefile.in
@@ -45,14 +45,15 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE = toolkitShared
 
 EXTRA_PP_JS_MODULES = \
   CertUtils.jsm \
   FileUtils.jsm \
   $(NULL)
 
+TEST_DIRS += test/chrome
+
 ifdef ENABLE_TESTS
-DIRS += test/chrome
 XPCSHELL_TESTS = test/unit
 endif
 
 include $(topsrcdir)/config/rules.mk
--- a/toolkit/mozapps/update/Makefile.in
+++ b/toolkit/mozapps/update/Makefile.in
@@ -72,20 +72,18 @@ else
 ifdef MOZ_MAINTENANCE_SERVICE
 DIRS = ../readstrings
 ifneq ($(OS_TARGET),Android)
 DIRS += common
 endif
 endif
 endif
 
-ifdef ENABLE_TESTS
-DIRS += test_timermanager
+TEST_DIRS += test_timermanager
 # Update tests require the updater binary
 ifdef MOZ_UPDATER
-DIRS += test
+TEST_DIRS += test
 ifdef MOZ_MAINTENANCE_SERVICE
-DIRS += test_svc
-endif
+TEST_DIRS += test_svc
 endif
 endif
 
 include $(topsrcdir)/config/rules.mk
--- a/toolkit/toolkit-makefiles.sh
+++ b/toolkit/toolkit-makefiles.sh
@@ -62,36 +62,40 @@ MAKEFILES_dom="
   dom/interfaces/sidebar/Makefile
   dom/interfaces/storage/Makefile
   dom/interfaces/stylesheets/Makefile
   dom/interfaces/svg/Makefile
   dom/interfaces/traversal/Makefile
   dom/interfaces/xbl/Makefile
   dom/interfaces/xpath/Makefile
   dom/interfaces/xul/Makefile
-  dom/ipc/Makefile
   dom/base/Makefile
   dom/battery/Makefile
   dom/indexedDB/Makefile
+  dom/ipc/Makefile
+  dom/locales/Makefile
+  dom/network/Makefile
+  dom/network/interfaces/Makefile
+  dom/network/src/Makefile
+  dom/plugins/base/Makefile
+  dom/plugins/ipc/Makefile
+  dom/power/Makefile
   dom/sms/Makefile
   dom/sms/interfaces/Makefile
   dom/sms/src/Makefile
   dom/src/Makefile
   dom/src/events/Makefile
   dom/src/jsurl/Makefile
   dom/src/geolocation/Makefile
   dom/src/json/Makefile
   dom/src/offline/Makefile
   dom/src/notification/Makefile
   dom/src/storage/Makefile
   dom/system/Makefile
   dom/workers/Makefile
-  dom/locales/Makefile
-  dom/plugins/base/Makefile
-  dom/plugins/ipc/Makefile
 "
 
 MAKEFILES_editor="
   editor/Makefile
   editor/public/Makefile
   editor/idl/Makefile
   editor/txmgr/Makefile
   editor/txmgr/idl/Makefile
@@ -250,16 +254,17 @@ MAKEFILES_layout="
   layout/Makefile
   layout/base/Makefile
   layout/build/Makefile
   layout/forms/Makefile
   layout/generic/Makefile
   layout/ipc/Makefile
   layout/inspector/public/Makefile
   layout/inspector/src/Makefile
+  layout/media/Makefile
   layout/style/Makefile
   layout/style/xbl-marquee/Makefile
   layout/tables/Makefile
   layout/svg/base/src/Makefile
   layout/xul/base/public/Makefile
   layout/xul/base/src/Makefile
 "
 
@@ -463,17 +468,16 @@ MAKEFILES_xulapp="
   toolkit/components/console/Makefile
   toolkit/components/contentprefs/Makefile
   toolkit/components/cookie/Makefile
   toolkit/components/downloads/Makefile
   toolkit/components/exthelper/Makefile
   toolkit/components/filepicker/Makefile
   toolkit/components/find/Makefile
   toolkit/components/intl/Makefile
-  toolkit/components/maintenanceservice/Makefile
   toolkit/components/microformats/Makefile
   toolkit/components/parentalcontrols/Makefile
   toolkit/components/passwordmgr/Makefile
   toolkit/components/perf/Makefile
   toolkit/components/places/Makefile
   toolkit/components/prompts/Makefile
   toolkit/components/prompts/src/Makefile
   toolkit/components/startup/Makefile
@@ -709,16 +713,17 @@ fi
 #
 
 if [ "$ENABLE_TESTS" ]; then
   add_makefiles "
     caps/tests/mochitest/Makefile
     chrome/test/Makefile
     content/base/test/Makefile
     content/base/test/chrome/Makefile
+    content/base/test/websocket_hybi/Makefile
     content/canvas/test/Makefile
     content/canvas/test/crossorigin/Makefile
     content/canvas/test/webgl/Makefile
     content/events/test/Makefile
     content/html/content/test/Makefile
     content/html/content/test/bug649134/Makefile
     content/html/content/test/forms/Makefile
     content/html/document/test/Makefile
@@ -731,18 +736,21 @@ if [ "$ENABLE_TESTS" ]; then
     content/xslt/tests/mochitest/Makefile
     content/xul/content/test/Makefile
     content/xul/document/test/Makefile
     docshell/test/Makefile
     docshell/test/chrome/Makefile
     docshell/test/navigation/Makefile
     dom/battery/test/Makefile
     dom/indexedDB/test/Makefile
+    dom/indexedDB/test/unit/Makefile
+    dom/network/tests/Makefile
     dom/plugins/test/Makefile
     dom/plugins/test/testplugin/Makefile
+    dom/power/test/Makefile
     dom/sms/tests/Makefile
     dom/src/foo/Makefile
     dom/src/json/test/Makefile
     dom/src/jsurl/test/Makefile
     dom/tests/Makefile
     dom/tests/mochitest/Makefile
     dom/tests/mochitest/ajax/Makefile
     dom/tests/mochitest/ajax/jquery/Makefile
@@ -889,16 +897,17 @@ if [ "$ENABLE_TESTS" ]; then
     toolkit/components/urlformatter/tests/Makefile
     toolkit/components/viewsource/test/Makefile
     toolkit/components/viewsource/test/browser/Makefile
     toolkit/content/tests/Makefile
     toolkit/content/tests/chrome/Makefile
     toolkit/content/tests/chrome/rtlchrome/Makefile
     toolkit/content/tests/chrome/rtltest/Makefile
     toolkit/content/tests/widgets/Makefile
+    toolkit/devtools/debugger/tests/Makefile
     toolkit/mozapps/downloads/tests/Makefile
     toolkit/mozapps/downloads/tests/chrome/Makefile
     toolkit/mozapps/extensions/test/Makefile
     toolkit/mozapps/plugins/tests/Makefile
     toolkit/mozapps/shared/test/chrome/Makefile
     toolkit/mozapps/update/test_timermanager/Makefile
     toolkit/profile/test/Makefile
     toolkit/xre/test/Makefile
@@ -921,21 +930,23 @@ if [ "$ENABLE_TESTS" ]; then
       accessible/tests/mochitest/attributes/Makefile
       accessible/tests/mochitest/editabletext/Makefile
       accessible/tests/mochitest/elm/Makefile
       accessible/tests/mochitest/events/Makefile
       accessible/tests/mochitest/focus/Makefile
       accessible/tests/mochitest/hyperlink/Makefile
       accessible/tests/mochitest/hypertext/Makefile
       accessible/tests/mochitest/name/Makefile
+      accessible/tests/mochitest/pivot/Makefile
       accessible/tests/mochitest/relations/Makefile
       accessible/tests/mochitest/selectable/Makefile
       accessible/tests/mochitest/states/Makefile
       accessible/tests/mochitest/table/Makefile
       accessible/tests/mochitest/text/Makefile
+      accessible/tests/mochitest/textcaret/Makefile
       accessible/tests/mochitest/textselection/Makefile
       accessible/tests/mochitest/tree/Makefile
       accessible/tests/mochitest/treeupdate/Makefile
       accessible/tests/mochitest/value/Makefile
     "
   fi
   if [ "$BUILD_CTYPES" ]; then
     add_makefiles "
@@ -1002,16 +1013,21 @@ if [ "$ENABLE_TESTS" ]; then
     add_makefiles "
       toolkit/mozapps/update/test/Makefile
     "
     if [ "$OS_TARGET" != "Android" ]; then
       add_makefiles "
         toolkit/mozapps/update/test/chrome/Makefile
       "
     fi
+    if [ "$MOZ_MAINTENANCE_SERVICE" ]; then
+      add_makefiles "
+        toolkit/mozapps/update/test_svc/Makefile
+      "
+    fi
   fi
   if [ "$MOZ_URL_CLASSIFIER" ]; then
     add_makefiles "
       toolkit/components/url-classifier/tests/Makefile
       toolkit/components/url-classifier/tests/mochitest/Makefile
     "
   fi
   if [ "$MOZ_XTF" ]; then
@@ -1033,17 +1049,17 @@ if [ "$ENABLE_TESTS" ]; then
   if [ "$MOZ_BUILD_APP" != "mobile" ]; then
     add_makefiles "
       docshell/test/browser/Makefile
       dom/tests/browser/Makefile
       image/test/browser/Makefile
       toolkit/components/downloads/test/browser/Makefile
       toolkit/components/passwordmgr/test/browser/Makefile
       toolkit/components/places/tests/browser/Makefile
-      toolkit/components/startup/tests/Makefile
+      toolkit/components/startup/tests/browser/Makefile
       toolkit/content/tests/browser/Makefile
       toolkit/content/tests/browser/common/Makefile
       toolkit/content/tests/browser/data/Makefile
       toolkit/mozapps/extensions/test/browser/Makefile
       toolkit/mozapps/extensions/test/mochitest/Makefile
       toolkit/mozapps/extensions/test/xpinstall/Makefile
     "
   fi
@@ -1066,16 +1082,21 @@ if [ "$ENABLE_TESTS" ]; then
   fi
   if [ "$OS_ARCH" = "WINNT" ]; then
     add_makefiles "
       toolkit/xre/test/win/Makefile
       widget/windows/tests/Makefile
       xpcom/tests/windows/Makefile
     "
   fi
+  if [ "$MOZ_BUILD_APP" = "mobile/android" ]; then
+    add_makefiles "
+      testing/mochitest/roboextender/Makefile
+    "
+  fi
 fi
 
 
 #
 # Feature specific makefiles
 #
 
 if [ "$ACCESSIBILITY" ]; then
@@ -1137,16 +1158,17 @@ if [ "$MOZ_ANGLE" ]; then
     gfx/angle/src/libEGL/Makefile
   "
 fi
 
 if [ "$MOZ_B2G_RIL" ]; then
   add_makefiles "
     dom/system/b2g/Makefile
     dom/telephony/Makefile
+    dom/wifi/Makefile
     ipc/ril/Makefile
   "
 fi
 
 if [ "$MOZ_CRASHREPORTER" ]; then
   add_makefiles "
     toolkit/crashreporter/Makefile
   "
@@ -1245,16 +1267,22 @@ if [ "$MOZ_ENABLE_XREMOTE" ]; then
 fi
 
 if [ "$MOZ_FEEDS" ]; then
   add_makefiles "
     toolkit/components/feeds/Makefile
   "
 fi
 
+if [ "$MOZ_GRAPHITE" ]; then
+  add_makefiles "
+    gfx/graphite2/src/Makefile
+  "
+fi
+
 if [ "$MOZ_HELP_VIEWER" ]; then
   add_makefiles "
     toolkit/components/help/Makefile
   "
   if [ "$MOZ_WIDGET_TOOLKIT" = "cocoa" ]; then
     add_makefiles "
       toolkit/themes/pinstripe/help/Makefile
     "
@@ -1281,16 +1309,22 @@ fi
 
 if [ "$MOZ_JSDEBUGGER" ]; then
   add_makefiles "
     js/jsd/Makefile
     js/jsd/idl/Makefile
   "
 fi
 
+if [ "$MOZ_MAINTENANCE_SERVICE" ]; then
+  add_makefiles "
+    toolkit/components/maintenanceservice/Makefile
+  "
+fi
+
 if [ ! "$MOZ_NATIVE_SQLITE" ]; then
   add_makefiles "
     db/sqlite3/src/Makefile
   "
 fi
 
 if [ "$MOZ_PERMISSIONS" ]; then
   add_makefiles "
@@ -1325,31 +1359,41 @@ if [ "$MOZ_TOOLKIT_SEARCH" ]; then
   "
 fi
 
 if [ "$MOZ_UPDATER" ]; then
   add_makefiles "
     modules/libmar/Makefile
     modules/libmar/src/Makefile
     modules/libmar/tool/Makefile
-    toolkit/mozapps/readstrings/Makefile
   "
   if [ ! "$SYSTEM_BZ2" ]; then
     add_makefiles "
       modules/libbz2/Makefile
       modules/libbz2/src/Makefile
     "
   fi
   if [ "$OS_TARGET" != "Android" ]; then
     add_makefiles "
       toolkit/mozapps/update/updater/Makefile
     "
   fi
 fi
 
+if [ "$MOZ_UPDATER" -o "$MOZ_MAINTENANCE_SERVICE" ]; then
+  add_makefiles "
+    toolkit/mozapps/readstrings/Makefile
+  "
+  if [ "$OS_TARGET" != "Android" ]; then
+    add_makefiles "
+      toolkit/mozapps/update/common/Makefile
+    "
+  fi
+fi
+
 if [ "$MOZ_UPDATER" -o "$MOZ_UPDATE_PACKAGING" ]; then
   add_makefiles "
     other-licenses/bsdiff/Makefile
   "
 fi
 
 if [ "$MOZ_URL_CLASSIFIER" ]; then
   add_makefiles "
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -46,16 +46,21 @@
 #include "AndroidBridge.h"
 #include "nsAppShell.h"
 #include "nsOSHelperAppService.h"
 #include "nsWindow.h"
 #include "mozilla/Preferences.h"
 #include "nsThreadUtils.h"
 #include "nsIThreadManager.h"
 #include "mozilla/dom/sms/PSms.h"
+#include "gfxImageSurface.h"
+#include "gfxContext.h"
+#include "nsPresContext.h"
+#include "nsIDocShell.h"
+#include "nsPIDOMWindow.h"
 
 #ifdef DEBUG
 #define ALOG_BRIDGE(args...) ALOG(args)
 #else
 #define ALOG_BRIDGE(args...)
 #endif
 
 #define IME_FULLSCREEN_PREF "widget.ime.android.landscape_fullscreen"
@@ -98,16 +103,17 @@ AndroidBridge::Init(JNIEnv *jEnv,
     mHasNativeBitmapAccess = false;
     mHasNativeWindowAccess = false;
 
     mGeckoAppShellClass = (jclass) jEnv->NewGlobalRef(jGeckoAppShellClass);
 
     jNotifyIME = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIME", "(II)V");
     jNotifyIMEEnabled = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIMEEnabled", "(ILjava/lang/String;Ljava/lang/String;Z)V");
     jNotifyIMEChange = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIMEChange", "(Ljava/lang/String;III)V");
+    jNotifyScreenShot = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyScreenShot", "(Ljava/nio/ByteBuffer;III)V");
     jAcknowledgeEventSync = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "acknowledgeEventSync", "()V");
 
     jEnableDeviceMotion = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableDeviceMotion", "(Z)V");
     jEnableLocation = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableLocation", "(Z)V");
     jEnableSensor =
         (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass,
                                             "enableSensor", "(I)V");
     jDisableSensor =
@@ -1954,8 +1960,51 @@ AndroidBridge::HideSurface(jobject surfa
   jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
 
   jmethodID method = env->GetStaticMethodID(cls,
                                             "hideSurface",
                                             "(Landroid/view/Surface;)V");
   env->CallStaticVoidMethod(cls, method, surface);
 #endif
 }
+
+
+/* void takeScreenshot (in nsIDOMWindow win, in PRInt32 srcX, in PRInt32 srcY, in PRInt32 srcW, in PRInt32 srcH, in PRInt32 dstX, in PRInt32 dstY, in PRInt32 dstW, in PRInt32 dstH, in AString color); */
+NS_IMETHODIMP nsAndroidBridge::TakeScreenshot(nsIDOMWindow *window, PRInt32 srcX, PRInt32 srcY, PRInt32 srcW, PRInt32 srcH, PRInt32 dstW, PRInt32 dstH, PRInt32 tabId)
+{
+    nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(window);
+    if (!win)
+        return NS_ERROR_FAILURE;
+    nsRefPtr<nsPresContext> presContext;
+    nsIDocShell* docshell = win->GetDocShell();
+    if (docshell) {
+        docshell->GetPresContext(getter_AddRefs(presContext));
+    }
+    if (!presContext)
+        return NS_ERROR_FAILURE;
+    nscolor bgColor = NS_RGB(255, 255, 255);
+    nsIPresShell* presShell = presContext->PresShell();
+    PRUint32 renderDocFlags = (nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
+                               nsIPresShell::RENDER_DOCUMENT_RELATIVE);
+    nsRect r(nsPresContext::CSSPixelsToAppUnits(srcX),
+             nsPresContext::CSSPixelsToAppUnits(srcY),
+             nsPresContext::CSSPixelsToAppUnits(srcW),
+             nsPresContext::CSSPixelsToAppUnits(srcH));
+
+    nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(nsIntSize(dstW, dstH), gfxASurface::ImageFormatRGB16_565);
+    nsRefPtr<gfxContext> context = new gfxContext(surf);
+    nsresult rv = presShell->RenderDocument(r, renderDocFlags, bgColor, context);
+    NS_ENSURE_SUCCESS(rv, rv);
+    AndroidBridge::Bridge()->NotifyScreenshot(surf->Data(), surf->GetDataSize(), tabId, dstW, dstH);
+    return NS_OK;
+}
+
+void AndroidBridge::NotifyScreenshot(unsigned char* data, int size, int tabId, int width, int height)
+{
+    JNIEnv* jenv = GetJNIEnv();
+    if (!jenv)
+        return;
+    AutoLocalJNIFrame jniFrame(jenv, 1);
+    jobject buffer = jenv->NewDirectByteBuffer(data, size);
+    if (!buffer)
+        return;
+    jenv->CallStaticVoidMethod(mGeckoAppShellClass, jNotifyScreenShot, buffer, tabId, width, height);
+}
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -151,16 +151,18 @@ public:
     /* These are all implemented in Java */
     static void NotifyIME(int aType, int aState);
 
     static void NotifyIMEEnabled(int aState, const nsAString& aTypeHint,
                                  const nsAString& aActionHint);
 
     static void NotifyIMEChange(const PRUnichar *aText, PRUint32 aTextLen, int aStart, int aEnd, int aNewEnd);
 
+    void NotifyScreenshot(unsigned char* data, int size, int tabId, int width, int height);
+
     void AcknowledgeEventSync();
 
     void EnableDeviceMotion(bool aEnable);
 
     void EnableLocation(bool aEnable);
 
     void EnableSensor(int aSensorType);
 
@@ -415,16 +417,17 @@ protected:
     bool mHasNativeWindowAccess;
 
     nsCOMArray<nsIRunnable> mRunnableQueue;
 
     // other things
     jmethodID jNotifyIME;
     jmethodID jNotifyIMEEnabled;
     jmethodID jNotifyIMEChange;
+    jmethodID jNotifyScreenShot;
     jmethodID jAcknowledgeEventSync;
     jmethodID jEnableDeviceMotion;
     jmethodID jEnableLocation;
     jmethodID jEnableSensor;
     jmethodID jDisableSensor;
     jmethodID jReturnIMEQueryResult;
     jmethodID jNotifyAppShellReady;
     jmethodID jNotifyXreExit;
--- a/widget/android/nsIAndroidBridge.idl
+++ b/widget/android/nsIAndroidBridge.idl
@@ -1,9 +1,10 @@
 #include "nsISupports.idl"
+#include "nsIDOMWindow.idl"
 
 [scriptable, uuid(38b5c83a-3e8d-45c2-8311-6e36bd5116c0)]
 interface nsIAndroidDrawMetadataProvider : nsISupports {
   AString getDrawMetadata();
 
   /*
    * Returns true if the presentation shell corresponding to the currently-viewed document is
    * suppressing painting (which occurs during page transitions) and false otherwise.
@@ -11,9 +12,11 @@ interface nsIAndroidDrawMetadataProvider
   boolean paintingSuppressed();
 };
 
 [scriptable, uuid(7dd8441a-4f38-49b2-bd90-da69d02a96cf)]
 interface nsIAndroidBridge : nsISupports
 {
   AString handleGeckoMessage(in AString message);
   void setDrawMetadataProvider(in nsIAndroidDrawMetadataProvider provider);
+  void takeScreenshot(in nsIDOMWindow win, in PRInt32 srcX, in PRInt32 srcY, in PRInt32 srcW, in PRInt32 srcH, 
+		      in PRInt32 dstW, in PRInt32 dstH, in PRInt32 tabId);
 };
copy from widget/gtk2/gtk2drawing.c
copy to widget/gtk2/gtk3drawing.c
--- a/widget/gtk2/gtk2drawing.c
+++ b/widget/gtk2/gtk3drawing.c
@@ -18,16 +18,18 @@
  * Netscape Communications Corporation.
  * Portions created by the Initial Developer are Copyright (C) 2002
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *  Brian Ryner <bryner@brianryner.com>  (Original Author)
  *  Pierre Chanial <p_ch@verizon.net>
  *  Michael Ventnor <m.ventnor@gmail.com>
+ *  Martin Stransky <stransky@redhat.com>
+ *  Jan Horak <jhorak@redhat.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
@@ -47,20 +49,16 @@
 #include <gdk/gdkprivate.h>
 #include <string.h>
 #include "gtkdrawing.h"
 #include "nsDebug.h"
 #include "prinrval.h"
 
 #include <math.h>
 
-#define XTHICKNESS(style) (style->xthickness)
-#define YTHICKNESS(style) (style->ythickness)
-#define WINDOW_IS_MAPPED(window) ((window) && GDK_IS_WINDOW(window) && gdk_window_is_visible(window))
-
 static GtkWidget* gProtoWindow;
 static GtkWidget* gProtoLayout;
 static GtkWidget* gButtonWidget;
 static GtkWidget* gToggleButtonWidget;
 static GtkWidget* gButtonArrowWidget;
 static GtkWidget* gCheckboxWidget;
 static GtkWidget* gRadiobuttonWidget;
 static GtkWidget* gHorizScrollbarWidget;
@@ -100,16 +98,40 @@ static GtkWidget* gMenuSeparatorWidget;
 static GtkWidget* gHPanedWidget;
 static GtkWidget* gVPanedWidget;
 static GtkWidget* gScrolledWindowWidget;
 
 static style_prop_t style_prop_func;
 static gboolean have_arrow_scaling;
 static gboolean is_initialized;
 
+#define ARROW_UP      0
+#define ARROW_DOWN    G_PI
+#define ARROW_RIGHT   G_PI_2
+#define ARROW_LEFT    (G_PI+G_PI_2)
+
+static GtkStateFlags
+GetStateFlagsFromGtkWidgetState(GtkWidgetState* state)
+{
+    GtkStateFlags stateFlags = GTK_STATE_FLAG_NORMAL;
+
+    if (state->disabled)
+        stateFlags = GTK_STATE_FLAG_INSENSITIVE;
+    else {    
+        if (state->depressed || state->active)
+            stateFlags |= GTK_STATE_FLAG_ACTIVE;
+        if (state->inHover)
+            stateFlags |= GTK_STATE_FLAG_PRELIGHT;
+        if (state->focused)
+            stateFlags |= GTK_STATE_FLAG_FOCUSED;
+    }
+  
+    return stateFlags;
+}
+
 /* Because we have such an unconventional way of drawing widgets, signal to the GTK theme engine
    that they are drawing for Mozilla instead of a conventional GTK app so they can do any specific
    things they may want to do. */
 static void
 moz_gtk_set_widget_name(GtkWidget* widget)
 {
     gtk_widget_set_name(widget, "MozillaGtkWidget");
 }
@@ -138,17 +160,16 @@ setup_widget_prototype(GtkWidget* widget
     ensure_window_widget();
     if (!gProtoLayout) {
         gProtoLayout = gtk_fixed_new();
         gtk_container_add(GTK_CONTAINER(gProtoWindow), gProtoLayout);
     }
 
     gtk_container_add(GTK_CONTAINER(gProtoLayout), widget);
     gtk_widget_realize(widget);
-    g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
 ensure_button_widget()
 {
     if (!gButtonWidget) {
         gButtonWidget = gtk_button_new_with_label("M");
@@ -178,18 +199,16 @@ ensure_vpaned_widget()
 }
 
 static gint
 ensure_toggle_button_widget()
 {
     if (!gToggleButtonWidget) {
         gToggleButtonWidget = gtk_toggle_button_new();
         setup_widget_prototype(gToggleButtonWidget);
-        /* toggle button must be set active to get the right style on hover. */
-        GTK_TOGGLE_BUTTON(gToggleButtonWidget)->active = TRUE;
   }
   return MOZ_GTK_SUCCESS;
 }
 
 static gint
 ensure_button_arrow_widget()
 {
     if (!gButtonArrowWidget) {
@@ -283,17 +302,16 @@ ensure_entry_widget()
 static void
 moz_gtk_get_combo_box_inner_button(GtkWidget *widget, gpointer client_data)
 {
     if (GTK_IS_TOGGLE_BUTTON(widget)) {
         gComboBoxButtonWidget = widget;
         g_object_add_weak_pointer(G_OBJECT(widget),
                                   (gpointer) &gComboBoxButtonWidget);
         gtk_widget_realize(widget);
-        g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
     }
 }
 
 static void
 moz_gtk_get_combo_box_button_inner_widgets(GtkWidget *widget,
                                            gpointer client_data)
 {
     if (GTK_IS_SEPARATOR(widget)) {
@@ -302,17 +320,16 @@ moz_gtk_get_combo_box_button_inner_widge
                                   (gpointer) &gComboBoxSeparatorWidget);
     } else if (GTK_IS_ARROW(widget)) {
         gComboBoxArrowWidget = widget;
         g_object_add_weak_pointer(G_OBJECT(widget),
                                   (gpointer) &gComboBoxArrowWidget);
     } else
         return;
     gtk_widget_realize(widget);
-    g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
 }
 
 static gint
 ensure_combo_box_widgets()
 {
     GtkWidget* buttonChild;
 
     if (gComboBoxButtonWidget && gComboBoxArrowWidget)
@@ -326,34 +343,32 @@ ensure_combo_box_widgets()
 
     /* Get its inner Button */
     gtk_container_forall(GTK_CONTAINER(gComboBoxWidget),
                          moz_gtk_get_combo_box_inner_button,
                          NULL);
 
     if (gComboBoxButtonWidget) {
         /* Get the widgets inside the Button */
-        buttonChild = GTK_BIN(gComboBoxButtonWidget)->child;
+        buttonChild = gtk_bin_get_child(GTK_BIN(gComboBoxButtonWidget));
         if (GTK_IS_HBOX(buttonChild)) {
             /* appears-as-list = FALSE, cell-view = TRUE; the button
              * contains an hbox. This hbox is there because the ComboBox
              * needs to place a cell renderer, a separator, and an arrow in
              * the button when appears-as-list is FALSE. */
             gtk_container_forall(GTK_CONTAINER(buttonChild),
                                  moz_gtk_get_combo_box_button_inner_widgets,
                                  NULL);
         } else if(GTK_IS_ARROW(buttonChild)) {
             /* appears-as-list = TRUE, or cell-view = FALSE;
              * the button only contains an arrow */
             gComboBoxArrowWidget = buttonChild;
             g_object_add_weak_pointer(G_OBJECT(buttonChild), (gpointer)
                                       &gComboBoxArrowWidget);
             gtk_widget_realize(gComboBoxArrowWidget);
-            g_object_set_data(G_OBJECT(gComboBoxArrowWidget),
-                              "transparent-bg-hint", GINT_TO_POINTER(TRUE));
         }
     } else {
         /* Shouldn't be reached with current internal gtk implementation; we
          * use a generic toggle button as last resort fallback to avoid
          * crashing. */
         ensure_toggle_button_widget();
         gComboBoxButtonWidget = gToggleButtonWidget;
     }
@@ -393,60 +408,58 @@ moz_gtk_get_combo_box_entry_inner_widget
                                   (gpointer) &gComboBoxEntryButtonWidget);
     } else if (GTK_IS_ENTRY(widget)) {
         gComboBoxEntryTextareaWidget = widget;
         g_object_add_weak_pointer(G_OBJECT(widget),
                                   (gpointer) &gComboBoxEntryTextareaWidget);
     } else
         return;
     gtk_widget_realize(widget);
-    g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
 }
 
 static void
 moz_gtk_get_combo_box_entry_arrow(GtkWidget *widget, gpointer client_data)
 {
     if (GTK_IS_ARROW(widget)) {
         gComboBoxEntryArrowWidget = widget;
         g_object_add_weak_pointer(G_OBJECT(widget),
                                   (gpointer) &gComboBoxEntryArrowWidget);
         gtk_widget_realize(widget);
-        g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
     }
 }
 
 static gint
 ensure_combo_box_entry_widgets()
 {
     GtkWidget* buttonChild;
 
     if (gComboBoxEntryTextareaWidget &&
             gComboBoxEntryButtonWidget &&
             gComboBoxEntryArrowWidget)
         return MOZ_GTK_SUCCESS;
 
     /* Create a ComboBoxEntry if needed */
     if (!gComboBoxEntryWidget) {
-        gComboBoxEntryWidget = gtk_combo_box_entry_new();
+        gComboBoxEntryWidget = NULL; /* TODO - gtk_combo_box_entry_new();*/
         setup_widget_prototype(gComboBoxEntryWidget);
     }
 
     /* Get its inner Entry and Button */
     gtk_container_forall(GTK_CONTAINER(gComboBoxEntryWidget),
                          moz_gtk_get_combo_box_entry_inner_widgets,
                          NULL);
 
     if (!gComboBoxEntryTextareaWidget) {
         ensure_entry_widget();
         gComboBoxEntryTextareaWidget = gEntryWidget;
     }
 
     if (gComboBoxEntryButtonWidget) {
         /* Get the Arrow inside the Button */
-        buttonChild = GTK_BIN(gComboBoxEntryButtonWidget)->child;
+        buttonChild = gtk_bin_get_child(GTK_BIN(gComboBoxEntryButtonWidget));
         if (GTK_IS_HBOX(buttonChild)) {
             /* appears-as-list = FALSE, cell-view = TRUE; the button
              * contains an hbox. This hbox is there because ComboBoxEntry
              * inherits from ComboBox which needs to place a cell renderer,
              * a separator, and an arrow in the button when appears-as-list
              * is FALSE. Here the hbox should only contain an arrow, since
              * a ComboBoxEntry doesn't need all those widgets in the
              * button. */
@@ -455,18 +468,16 @@ ensure_combo_box_entry_widgets()
                                  NULL);
         } else if(GTK_IS_ARROW(buttonChild)) {
             /* appears-as-list = TRUE, or cell-view = FALSE;
              * the button only contains an arrow */
             gComboBoxEntryArrowWidget = buttonChild;
             g_object_add_weak_pointer(G_OBJECT(buttonChild), (gpointer)
                                       &gComboBoxEntryArrowWidget);
             gtk_widget_realize(gComboBoxEntryArrowWidget);
-            g_object_set_data(G_OBJECT(gComboBoxEntryArrowWidget),
-                              "transparent-bg-hint", GINT_TO_POINTER(TRUE));
         }
     } else {
         /* Shouldn't be reached with current internal gtk implementation;
          * we use a generic toggle button as last resort fallback to avoid
          * crashing. */
         ensure_toggle_button_widget();
         gComboBoxEntryButtonWidget = gToggleButtonWidget;
     }
@@ -496,17 +507,16 @@ ensure_handlebox_widget()
 static gint
 ensure_toolbar_widget()
 {
     if (!gToolbarWidget) {
         ensure_handlebox_widget();
         gToolbarWidget = gtk_toolbar_new();
         gtk_container_add(GTK_CONTAINER(gHandleBoxWidget), gToolbarWidget);
         gtk_widget_realize(gToolbarWidget);
-        g_object_set_data(G_OBJECT(gToolbarWidget), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
     }
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
 ensure_toolbar_separator_widget()
 {
     if (!gToolbarSeparatorWidget) {
@@ -584,93 +594,81 @@ static gint
 ensure_menu_bar_item_widget()
 {
     if (!gMenuBarItemWidget) {
         ensure_menu_bar_widget();
         gMenuBarItemWidget = gtk_menu_item_new();
         gtk_menu_shell_append(GTK_MENU_SHELL(gMenuBarWidget),
                               gMenuBarItemWidget);
         gtk_widget_realize(gMenuBarItemWidget);
-        g_object_set_data(G_OBJECT(gMenuBarItemWidget),
-                          "transparent-bg-hint", GINT_TO_POINTER(TRUE));
     }
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
 ensure_menu_popup_widget()
 {
     if (!gMenuPopupWidget) {
         ensure_menu_bar_item_widget();
         gMenuPopupWidget = gtk_menu_new();
         gtk_menu_item_set_submenu(GTK_MENU_ITEM(gMenuBarItemWidget),
                                   gMenuPopupWidget);
         gtk_widget_realize(gMenuPopupWidget);
-        g_object_set_data(G_OBJECT(gMenuPopupWidget),
-                          "transparent-bg-hint", GINT_TO_POINTER(TRUE));
     }
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
 ensure_menu_item_widget()
 {
     if (!gMenuItemWidget) {
         ensure_menu_popup_widget();
         gMenuItemWidget = gtk_menu_item_new_with_label("M");
         gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
                               gMenuItemWidget);
         gtk_widget_realize(gMenuItemWidget);
-        g_object_set_data(G_OBJECT(gMenuItemWidget),
-                          "transparent-bg-hint", GINT_TO_POINTER(TRUE));
     }
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
 ensure_image_menu_item_widget()
 {
     if (!gImageMenuItemWidget) {
         ensure_menu_popup_widget();
         gImageMenuItemWidget = gtk_image_menu_item_new();
         gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
                               gImageMenuItemWidget);
         gtk_widget_realize(gImageMenuItemWidget);
-        g_object_set_data(G_OBJECT(gImageMenuItemWidget),
-                          "transparent-bg-hint", GINT_TO_POINTER(TRUE));
     }
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
 ensure_menu_separator_widget()
 {
     if (!gMenuSeparatorWidget) {
         ensure_menu_popup_widget();
         gMenuSeparatorWidget = gtk_separator_menu_item_new();
         gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
                               gMenuSeparatorWidget);
         gtk_widget_realize(gMenuSeparatorWidget);
-        g_object_set_data(G_OBJECT(gMenuSeparatorWidget),
-                          "transparent-bg-hint", GINT_TO_POINTER(TRUE));
     }
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
 ensure_check_menu_item_widget()
 {
     if (!gCheckMenuItemWidget) {
         ensure_menu_popup_widget();
         gCheckMenuItemWidget = gtk_check_menu_item_new_with_label("M");
         gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
                               gCheckMenuItemWidget);
         gtk_widget_realize(gCheckMenuItemWidget);
-        g_object_set_data(G_OBJECT(gCheckMenuItemWidget),
-                          "transparent-bg-hint", GINT_TO_POINTER(TRUE));
     }
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
 ensure_tree_view_widget()
 {
     if (!gTreeViewWidget) {
@@ -712,22 +710,19 @@ ensure_tree_header_cell_widget()
         gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget),
                                     gMiddleTreeViewColumn);
 
         lastTreeViewColumn = gtk_tree_view_column_new();
         gtk_tree_view_column_set_title(lastTreeViewColumn, "M");
         gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget), lastTreeViewColumn);
 
         /* Use the middle column's header for our button */
-        gTreeHeaderCellWidget = gMiddleTreeViewColumn->button;
-        gTreeHeaderSortArrowWidget = gMiddleTreeViewColumn->arrow;
-        g_object_set_data(G_OBJECT(gTreeHeaderCellWidget),
-                          "transparent-bg-hint", GINT_TO_POINTER(TRUE));
-        g_object_set_data(G_OBJECT(gTreeHeaderSortArrowWidget),
-                          "transparent-bg-hint", GINT_TO_POINTER(TRUE));
+        /* TODO */
+        gTreeHeaderCellWidget = NULL;
+        gTreeHeaderSortArrowWidget = NULL;
     }
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
 ensure_expander_widget()
 {
     if (!gExpanderWidget) {
@@ -742,88 +737,36 @@ ensure_scrolled_window_widget()
 {
     if (!gScrolledWindowWidget) {
         gScrolledWindowWidget = gtk_scrolled_window_new(NULL, NULL);
         setup_widget_prototype(gScrolledWindowWidget);
     }
     return MOZ_GTK_SUCCESS;
 }
 
-static GtkStateType
-ConvertGtkState(GtkWidgetState* state)
-{
-    if (state->disabled)
-        return GTK_STATE_INSENSITIVE;
-    else if (state->depressed)
-        return (state->inHover ? GTK_STATE_PRELIGHT : GTK_STATE_ACTIVE);
-    else if (state->inHover)
-        return (state->active ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT);
-    else
-        return GTK_STATE_NORMAL;
-}
-
-static gint
-TSOffsetStyleGCArray(GdkGC** gcs, gint xorigin, gint yorigin)
-{
-    int i;
-    /* there are 5 gc's in each array, for each of the widget states */
-    for (i = 0; i < 5; ++i)
-        gdk_gc_set_ts_origin(gcs[i], xorigin, yorigin);
-    return MOZ_GTK_SUCCESS;
-}
-
-static gint
-TSOffsetStyleGCs(GtkStyle* style, gint xorigin, gint yorigin)
-{
-    TSOffsetStyleGCArray(style->fg_gc, xorigin, yorigin);
-    TSOffsetStyleGCArray(style->bg_gc, xorigin, yorigin);
-    TSOffsetStyleGCArray(style->light_gc, xorigin, yorigin);
-    TSOffsetStyleGCArray(style->dark_gc, xorigin, yorigin);
-    TSOffsetStyleGCArray(style->mid_gc, xorigin, yorigin);
-    TSOffsetStyleGCArray(style->text_gc, xorigin, yorigin);
-    TSOffsetStyleGCArray(style->base_gc, xorigin, yorigin);
-    gdk_gc_set_ts_origin(style->black_gc, xorigin, yorigin);
-    gdk_gc_set_ts_origin(style->white_gc, xorigin, yorigin);
-    return MOZ_GTK_SUCCESS;
-}
-
 gint
 moz_gtk_init()
 {
     GtkWidgetClass *entry_class;
 
     if (is_initialized)
         return MOZ_GTK_SUCCESS;
 
     is_initialized = TRUE;
     have_arrow_scaling = (gtk_major_version > 2 ||
                           (gtk_major_version == 2 && gtk_minor_version >= 12));
 
     /* Add style property to GtkEntry.
      * Adding the style property to the normal GtkEntry class means that it
      * will work without issues inside GtkComboBox and for Spinbuttons. */
     entry_class = g_type_class_ref(GTK_TYPE_ENTRY);
-    gtk_widget_class_install_style_property(entry_class,
-        g_param_spec_boolean("honors-transparent-bg-hint",
-                             "Transparent BG enabling flag",
-                             "If TRUE, the theme is able to draw the GtkEntry on non-prefilled background.",
-                             FALSE,
-                             G_PARAM_READWRITE));
 
     return MOZ_GTK_SUCCESS;
 }
 
-GdkColormap*
-moz_gtk_widget_get_colormap()
-{
-    /* Child widgets inherit the colormap from the GtkWindow. */
-    ensure_window_widget();
-    return gtk_widget_get_colormap(gProtoWindow);
-}
-
 gint
 moz_gtk_checkbox_get_metrics(gint* indicator_size, gint* indicator_spacing)
 {
     ensure_checkbox_widget();
 
     gtk_widget_style_get (gCheckboxWidget,
                           "indicator_size", indicator_size,
                           "indicator_spacing", indicator_spacing,
@@ -956,127 +899,101 @@ moz_gtk_button_get_inner_border(GtkWidge
     }
     else
         *inner_border = default_inner_border;
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_button_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_button_paint(cairo_t *cr, GdkRectangle* rect,
                      GdkRectangle* cliprect, GtkWidgetState* state,
                      GtkReliefStyle relief, GtkWidget* widget,
                      GtkTextDirection direction)
 {
-    GtkShadowType shadow_type;
-    GtkStyle* style = widget->style;
-    GtkStateType button_state = ConvertGtkState(state);
+    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+    GtkStyleContext* style = gtk_widget_get_style_context(widget);    
     gint x = rect->x, y=rect->y, width=rect->width, height=rect->height;
 
     gboolean interior_focus;
     gint focus_width, focus_pad;
 
     moz_gtk_widget_get_focus(widget, &interior_focus, &focus_width, &focus_pad);
-
-    if (WINDOW_IS_MAPPED(drawable)) {
-        gdk_window_set_back_pixmap(drawable, NULL, TRUE);
-        gdk_window_clear_area(drawable, cliprect->x, cliprect->y,
-                              cliprect->width, cliprect->height);
-    }
-
-    gtk_widget_set_state(widget, button_state);
     gtk_widget_set_direction(widget, direction);
 
-    if (state->isDefault)
-        GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_DEFAULT);
-
-    GTK_BUTTON(widget)->relief = relief;
-
-    /* Some theme engines love to cause us pain in that gtk_paint_focus is a
-       no-op on buttons and button-like widgets. They only listen to this flag. */
-    if (state->focused && !state->disabled)
-        GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
-
     if (!interior_focus && state->focused) {
         x += focus_width + focus_pad;
         y += focus_width + focus_pad;
         width -= 2 * (focus_width + focus_pad);
         height -= 2 * (focus_width + focus_pad);
     }
-
-    shadow_type = button_state == GTK_STATE_ACTIVE ||
-                      state->depressed ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
- 
+  
+    gtk_style_context_save(style);
+    gtk_style_context_set_state(style, state_flags);
+
     if (state->isDefault && relief == GTK_RELIEF_NORMAL) {
         /* handle default borders both outside and inside the button */
         gint default_top, default_left, default_bottom, default_right;
         moz_gtk_button_get_default_overflow(&default_top, &default_left,
                                             &default_bottom, &default_right);
         x -= default_left;
         y -= default_top;
         width += default_left + default_right;
         height += default_top + default_bottom;
-        gtk_paint_box(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_IN, cliprect,
-                      widget, "buttondefault", x, y, width, height);
-
+        gtk_render_background(style, cr, x, y, width, height);
+        gtk_render_frame(style, cr, x, y, width, height);
         moz_gtk_button_get_default_border(&default_top, &default_left,
                                           &default_bottom, &default_right);
         x += default_left;
         y += default_top;
         width -= (default_left + default_right);
         height -= (default_top + default_bottom);
     }
  
     if (relief != GTK_RELIEF_NONE || state->depressed ||
-        (button_state != GTK_STATE_NORMAL &&
-         button_state != GTK_STATE_INSENSITIVE)) {
-        TSOffsetStyleGCs(style, x, y);
+        (state_flags & GTK_STATE_FLAG_PRELIGHT)) {
         /* the following line can trigger an assertion (Crux theme)
            file ../../gdk/gdkwindow.c: line 1846 (gdk_window_clear_area):
            assertion `GDK_IS_WINDOW (window)' failed */
-        gtk_paint_box(style, drawable, button_state, shadow_type, cliprect,
-                      widget, "button", x, y, width, height);
+        gtk_render_background(style, cr, x, y, width, height);
+        gtk_render_frame(style, cr, x, y, width, height);
     }
 
     if (state->focused) {
         if (interior_focus) {
-            x += widget->style->xthickness + focus_pad;
-            y += widget->style->ythickness + focus_pad;
-            width -= 2 * (widget->style->xthickness + focus_pad);
-            height -= 2 * (widget->style->ythickness + focus_pad);
+            GtkBorder border;
+            gtk_style_context_get_border(style, state_flags, &border);
+            x += border.left + focus_pad;
+            y += border.top + focus_pad;
+            width -= 2 * (border.left + focus_pad);
+            height -= 2 * (border.top + focus_pad);
         } else {
             x -= focus_width + focus_pad;
             y -= focus_width + focus_pad;
             width += 2 * (focus_width + focus_pad);
             height += 2 * (focus_width + focus_pad);
         }
 
-        TSOffsetStyleGCs(style, x, y);
-        gtk_paint_focus(style, drawable, button_state, cliprect,
-                        widget, "button", x, y, width, height);
+        gtk_render_focus(style, cr, x, y, width, height);
     }
-
-    GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_DEFAULT);
-    GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
+    gtk_style_context_restore(style);
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_toggle_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_toggle_paint(cairo_t *cr, GdkRectangle* rect,
                      GdkRectangle* cliprect, GtkWidgetState* state,
                      gboolean selected, gboolean inconsistent,
                      gboolean isradio, GtkTextDirection direction)
 {
-    GtkStateType state_type = ConvertGtkState(state);
-    GtkShadowType shadow_type = (selected)?GTK_SHADOW_IN:GTK_SHADOW_OUT;
     gint indicator_size, indicator_spacing;
     gint x, y, width, height;
     gint focus_x, focus_y, focus_width, focus_height;
     GtkWidget *w;
-    GtkStyle *style;
+    GtkStyleContext *style;
 
     if (isradio) {
         moz_gtk_radio_get_metrics(&indicator_size, &indicator_spacing);
         w = gRadiobuttonWidget;
     } else {
         moz_gtk_checkbox_get_metrics(&indicator_size, &indicator_spacing);
         w = gCheckboxWidget;
     }
@@ -1092,1190 +1009,1058 @@ moz_gtk_toggle_paint(GdkDrawable* drawab
     width = indicator_size;
     height = indicator_size;
 
     focus_x = x - indicator_spacing;
     focus_y = y - indicator_spacing;
     focus_width = width + 2 * indicator_spacing;
     focus_height = height + 2 * indicator_spacing;
   
-    style = w->style;
-    TSOffsetStyleGCs(style, x, y);
+    style = gtk_widget_get_style_context(w);
 
     gtk_widget_set_sensitive(w, !state->disabled);
     gtk_widget_set_direction(w, direction);
-    GTK_TOGGLE_BUTTON(w)->active = selected;
+    gtk_style_context_save(style);
       
     if (isradio) {
-        gtk_paint_option(style, drawable, state_type, shadow_type, cliprect,
-                         gRadiobuttonWidget, "radiobutton", x, y,
-                         width, height);
+        gtk_style_context_add_class(style, GTK_STYLE_CLASS_RADIO);
+        if (selected) {
+            gtk_style_context_set_state(style, GTK_STATE_FLAG_ACTIVE);
+        }
+        gtk_render_option(style, cr, x, y, width, height);
         if (state->focused) {
-            gtk_paint_focus(style, drawable, GTK_STATE_ACTIVE, cliprect,
-                            gRadiobuttonWidget, "radiobutton", focus_x, focus_y,
+            gtk_render_focus(style, cr, focus_x, focus_y,
                             focus_width, focus_height);
         }
     }
     else {
        /*
         * 'indeterminate' type on checkboxes. In GTK, the shadow type
         * must also be changed for the state to be drawn.
-        */
+        */        
+        gtk_style_context_add_class(style, GTK_STYLE_CLASS_CHECK);
         if (inconsistent) {
+            gtk_style_context_set_state(style, GTK_STATE_FLAG_INCONSISTENT);
             gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(gCheckboxWidget), TRUE);
-            shadow_type = GTK_SHADOW_ETCHED_IN;
+        } else if (selected) {
+            gtk_style_context_set_state(style, GTK_STATE_FLAG_ACTIVE);
         } else {
             gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(gCheckboxWidget), FALSE);
         }
-
-        gtk_paint_check(style, drawable, state_type, shadow_type, cliprect, 
-                        gCheckboxWidget, "checkbutton", x, y, width, height);
+        gtk_render_check(style, cr, x, y, width, height);        
         if (state->focused) {
-            gtk_paint_focus(style, drawable, GTK_STATE_ACTIVE, cliprect,
-                            gCheckboxWidget, "checkbutton", focus_x, focus_y,
-                            focus_width, focus_height);
+            gtk_render_focus(style, cr, 
+                             focus_x, focus_y, focus_width, focus_height);
         }
     }
+    gtk_style_context_restore(style);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
 calculate_button_inner_rect(GtkWidget* button, GdkRectangle* rect,
                             GdkRectangle* inner_rect,
                             GtkTextDirection direction,
                             gboolean ignore_focus)
 {
     GtkBorder inner_border;
     gboolean interior_focus;
     gint focus_width, focus_pad;
-    GtkStyle* style;
-
-    style = button->style;
+    GtkStyleContext* style;
+    GtkBorder border;
+
+    style = gtk_widget_get_style_context(button);
 
     /* This mirrors gtkbutton's child positioning */
     moz_gtk_button_get_inner_border(button, &inner_border);
     moz_gtk_widget_get_focus(button, &interior_focus,
                              &focus_width, &focus_pad);
 
     if (ignore_focus)
         focus_width = focus_pad = 0;
 
-    inner_rect->x = rect->x + XTHICKNESS(style) + focus_width + focus_pad;
+    gtk_style_context_get_border(style, 0, &border);
+
+    inner_rect->x = rect->x + border.left + focus_width + focus_pad;
     inner_rect->x += direction == GTK_TEXT_DIR_LTR ?
                         inner_border.left : inner_border.right;
-    inner_rect->y = rect->y + inner_border.top + YTHICKNESS(style) +
+    inner_rect->y = rect->y + inner_border.top + border.top +
                     focus_width + focus_pad;
     inner_rect->width = MAX(1, rect->width - inner_border.left -
-       inner_border.right - (XTHICKNESS(style) + focus_pad + focus_width) * 2);
+       inner_border.right - (border.left + focus_pad + focus_width) * 2);
     inner_rect->height = MAX(1, rect->height - inner_border.top -
-       inner_border.bottom - (YTHICKNESS(style) + focus_pad + focus_width) * 2);
+       inner_border.bottom - (border.top + focus_pad + focus_width) * 2);
 
     return MOZ_GTK_SUCCESS;
 }
 
 
 static gint
 calculate_arrow_rect(GtkWidget* arrow, GdkRectangle* rect,
                      GdkRectangle* arrow_rect, GtkTextDirection direction)
 {
     /* defined in gtkarrow.c */
     gfloat arrow_scaling = 0.7;
     gfloat xalign, xpad;
     gint extent;
+    gint mxpad, mypad;
+    gfloat mxalign, myalign;
     GtkMisc* misc = GTK_MISC(arrow);
 
     if (have_arrow_scaling)
         gtk_widget_style_get(arrow, "arrow_scaling", &arrow_scaling, NULL);
 
-    extent = MIN((rect->width - misc->xpad * 2),
-                 (rect->height - misc->ypad * 2)) * arrow_scaling;
-
-    xalign = direction == GTK_TEXT_DIR_LTR ? misc->xalign : 1.0 - misc->xalign;
-    xpad = misc->xpad + (rect->width - extent) * xalign;
+    gtk_misc_get_padding(misc, &mxpad, &mypad); 
+    extent = MIN((rect->width - mxpad * 2),
+                 (rect->height - mypad * 2)) * arrow_scaling;
+
+    gtk_misc_get_alignment(misc, &mxalign, &myalign);
+    
+    xalign = direction == GTK_TEXT_DIR_LTR ? mxalign : 1.0 - mxalign;
+    xpad = mxpad + (rect->width - extent) * xalign;
 
     arrow_rect->x = direction == GTK_TEXT_DIR_LTR ?
                         floor(rect->x + xpad) : ceil(rect->x + xpad);
-    arrow_rect->y = floor(rect->y + misc->ypad +
-                          ((rect->height - extent) * misc->yalign));
+    arrow_rect->y = floor(rect->y + mypad +
+                          ((rect->height - extent) * myalign));
 
     arrow_rect->width = arrow_rect->height = extent;
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_scrollbar_button_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_scrollbar_button_paint(cairo_t *cr, GdkRectangle* rect,
                                GdkRectangle* cliprect, GtkWidgetState* state,
                                GtkScrollbarButtonFlags flags,
                                GtkTextDirection direction)
 {
-    GtkStateType state_type = ConvertGtkState(state);
-    GtkShadowType shadow_type = (state->active) ?
-        GTK_SHADOW_IN : GTK_SHADOW_OUT;
+    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+    GtkStateType saved_state;
     GdkRectangle arrow_rect;
-    GtkStyle* style;
+    gdouble arrow_angle;
+    GtkStyleContext* style;
     GtkWidget *scrollbar;
-    GtkArrowType arrow_type;
     gint arrow_displacement_x, arrow_displacement_y;
     const char* detail = (flags & MOZ_GTK_STEPPER_VERTICAL) ?
                            "vscrollbar" : "hscrollbar";
 
     ensure_scrollbar_widget();
 
     if (flags & MOZ_GTK_STEPPER_VERTICAL)
         scrollbar = gVertScrollbarWidget;
     else
         scrollbar = gHorizScrollbarWidget;
 
     gtk_widget_set_direction(scrollbar, direction);
 
-    /* Some theme engines (i.e., ClearLooks) check the scrollbar's allocation
-       to determine where it should paint rounded corners on the buttons.
-       We need to trick them into drawing the buttons the way we want them. */
-
-    scrollbar->allocation.x = rect->x;
-    scrollbar->allocation.y = rect->y;
-    scrollbar->allocation.width = rect->width;
-    scrollbar->allocation.height = rect->height;
-
     if (flags & MOZ_GTK_STEPPER_VERTICAL) {
-        scrollbar->allocation.height *= 5;
-        if (flags & MOZ_GTK_STEPPER_DOWN) {
-            arrow_type = GTK_ARROW_DOWN;
-            if (flags & MOZ_GTK_STEPPER_BOTTOM)
-                scrollbar->allocation.y -= 4 * rect->height;
-            else
-                scrollbar->allocation.y -= rect->height;
-
-        } else {
-            arrow_type = GTK_ARROW_UP;
-            if (flags & MOZ_GTK_STEPPER_BOTTOM)
-                scrollbar->allocation.y -= 3 * rect->height;
-        }
+        arrow_angle = (flags & MOZ_GTK_STEPPER_DOWN) ? ARROW_DOWN : ARROW_UP;        
     } else {
-        scrollbar->allocation.width *= 5;
-        if (flags & MOZ_GTK_STEPPER_DOWN) {
-            arrow_type = GTK_ARROW_RIGHT;
-            if (flags & MOZ_GTK_STEPPER_BOTTOM)
-                scrollbar->allocation.x -= 4 * rect->width;
-            else
-                scrollbar->allocation.x -= rect->width;
-        } else {
-            arrow_type = GTK_ARROW_LEFT;
-            if (flags & MOZ_GTK_STEPPER_BOTTOM)
-                scrollbar->allocation.x -= 3 * rect->width;
-        }
+        arrow_angle = (flags & MOZ_GTK_STEPPER_DOWN) ? ARROW_RIGHT : ARROW_LEFT;        
     }
 
-    style = scrollbar->style;
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-
-    gtk_paint_box(style, drawable, state_type, shadow_type, cliprect,
-                  scrollbar, detail, rect->x, rect->y,
-                  rect->width, rect->height);
+    style = gtk_widget_get_style_context(scrollbar);
+  
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_SCROLLBAR);  
+    gtk_style_context_set_state(style, state_flags);
+  
+    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
 
     arrow_rect.width = rect->width / 2;
     arrow_rect.height = rect->height / 2;
     arrow_rect.x = rect->x + (rect->width - arrow_rect.width) / 2;
     arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2;
 
-    if (state_type == GTK_STATE_ACTIVE) {
+    if (state_flags & GTK_STATE_FLAG_ACTIVE) {
         gtk_widget_style_get(scrollbar,
                              "arrow-displacement-x", &arrow_displacement_x,
                              "arrow-displacement-y", &arrow_displacement_y,
                              NULL);
 
         arrow_rect.x += arrow_displacement_x;
         arrow_rect.y += arrow_displacement_y;
     }
-
-    gtk_paint_arrow(style, drawable, state_type, shadow_type, cliprect,
-                    scrollbar, detail, arrow_type, TRUE, arrow_rect.x,
-                    arrow_rect.y, arrow_rect.width, arrow_rect.height);
+  
+    gtk_render_arrow(style, cr, arrow_angle,
+                     arrow_rect.x,
+                     arrow_rect.y, 
+                     arrow_rect.width);
+  
+    gtk_style_context_restore(style);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
 moz_gtk_scrollbar_trough_paint(GtkThemeWidgetType widget,
-                               GdkDrawable* drawable, GdkRectangle* rect,
+                               cairo_t *cr, GdkRectangle* rect,
                                GdkRectangle* cliprect, GtkWidgetState* state,
                                GtkTextDirection direction)
 {
-    GtkStyle* style;
+    GtkStyleContext* style;
     GtkScrollbar *scrollbar;
 
     ensure_scrollbar_widget();
 
     if (widget ==  MOZ_GTK_SCROLLBAR_TRACK_HORIZONTAL)
         scrollbar = GTK_SCROLLBAR(gHorizScrollbarWidget);
     else
         scrollbar = GTK_SCROLLBAR(gVertScrollbarWidget);
 
     gtk_widget_set_direction(GTK_WIDGET(scrollbar), direction);
-
-    style = GTK_WIDGET(scrollbar)->style;
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-    gtk_style_apply_default_background(style, drawable, TRUE, GTK_STATE_ACTIVE,
-                                       cliprect, rect->x, rect->y,
-                                       rect->width, rect->height);
-
-    gtk_paint_box(style, drawable, GTK_STATE_ACTIVE, GTK_SHADOW_IN, cliprect,
-                  GTK_WIDGET(scrollbar), "trough", rect->x, rect->y,
-                  rect->width, rect->height);
+    
+    style = gtk_widget_get_style_context(GTK_WIDGET(scrollbar));
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH);
+
+    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
 
     if (state->focused) {
-        gtk_paint_focus(style, drawable, GTK_STATE_ACTIVE, cliprect,
-                        GTK_WIDGET(scrollbar), "trough",
-                        rect->x, rect->y, rect->width, rect->height);
+        gtk_render_focus(style, cr,
+                         rect->x, rect->y, rect->width, rect->height);
     }
-
+    gtk_style_context_restore(style);
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
 moz_gtk_scrollbar_thumb_paint(GtkThemeWidgetType widget,
-                              GdkDrawable* drawable, GdkRectangle* rect,
+                              cairo_t *cr, GdkRectangle* rect,
                               GdkRectangle* cliprect, GtkWidgetState* state,
                               GtkTextDirection direction)
 {
-    GtkStateType state_type = (state->inHover || state->active) ?
-        GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
-    GtkShadowType shadow_type = GTK_SHADOW_OUT;
-    GtkStyle* style;
+    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+    GtkStyleContext* style;
     GtkScrollbar *scrollbar;
     GtkAdjustment *adj;
-    gboolean activate_slider;
 
     ensure_scrollbar_widget();
 
     if (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL)
         scrollbar = GTK_SCROLLBAR(gHorizScrollbarWidget);
     else
         scrollbar = GTK_SCROLLBAR(gVertScrollbarWidget);
 
     gtk_widget_set_direction(GTK_WIDGET(scrollbar), direction);
-
-    /* Make sure to set the scrollbar range before painting so that
-       everything is drawn properly.  At least the bluecurve (and
-       maybe other) themes don't draw the top or bottom black line
-       surrounding the scrollbar if the theme thinks that it's butted
-       up against the scrollbar arrows.  Note the increases of the
-       clip rect below. */
-    adj = gtk_range_get_adjustment(GTK_RANGE(scrollbar));
-
-    if (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) {
-        adj->page_size = rect->width;
-    }
-    else {
-        adj->page_size = rect->height;
-    }
-
-    adj->lower = 0;
-    adj->value = state->curpos;
-    adj->upper = state->maxpos;
-    gtk_adjustment_changed(adj);
-
-    style = GTK_WIDGET(scrollbar)->style;
-    
-    gtk_widget_style_get(GTK_WIDGET(scrollbar), "activate-slider",
-                         &activate_slider, NULL);
-    
-    if (activate_slider && state->active) {
-        shadow_type = GTK_SHADOW_IN;
-        state_type = GTK_STATE_ACTIVE;
-    }
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-
-    gtk_paint_slider(style, drawable, state_type, shadow_type, cliprect,
-                     GTK_WIDGET(scrollbar), "slider", rect->x, rect->y,
-                     rect->width,  rect->height,
+  
+    style = gtk_widget_get_style_context(GTK_WIDGET(scrollbar));
+    gtk_style_context_save(style);
+       
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_SLIDER);
+    gtk_style_context_set_state(style, state_flags);
+
+    gtk_render_slider(style, cr, rect->x, rect->y,
+                      rect->width,  rect->height,
                      (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) ?
                      GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
 
+    gtk_style_context_restore(style);
+
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_spin_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_spin_paint(cairo_t *cr, GdkRectangle* rect,
                    GtkTextDirection direction)
 {
-    GtkStyle* style;
+    GtkStyleContext* style;
 
     ensure_spin_widget();
     gtk_widget_set_direction(gSpinWidget, direction);
-    style = gSpinWidget->style;
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-    gtk_paint_box(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL,
-                  gSpinWidget, "spinbutton",
-                  rect->x, rect->y, rect->width, rect->height);
+    style = gtk_widget_get_style_context(gSpinWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON);
+    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_style_context_restore(style);
+
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_spin_updown_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_spin_updown_paint(cairo_t *cr, GdkRectangle* rect,
                           gboolean isDown, GtkWidgetState* state,
                           GtkTextDirection direction)
 {
     GdkRectangle arrow_rect;
-    GtkStateType state_type = ConvertGtkState(state);
-    GtkShadowType shadow_type = state_type == GTK_STATE_ACTIVE ?
-                                  GTK_SHADOW_IN : GTK_SHADOW_OUT;
-    GtkStyle* style;
+    GtkStyleContext* style;
 
     ensure_spin_widget();
-    style = gSpinWidget->style;
+    style = gtk_widget_get_style_context(gSpinWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON);
+    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
     gtk_widget_set_direction(gSpinWidget, direction);
 
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-    gtk_paint_box(style, drawable, state_type, shadow_type, NULL, gSpinWidget,
-                  isDown ? "spinbutton_down" : "spinbutton_up",
-                  rect->x, rect->y, rect->width, rect->height);
+    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+
 
     /* hard code these values */
     arrow_rect.width = 6;
     arrow_rect.height = 6;
     arrow_rect.x = rect->x + (rect->width - arrow_rect.width) / 2;
     arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2;
     arrow_rect.y += isDown ? -1 : 1;
 
-    gtk_paint_arrow(style, drawable, state_type, shadow_type, NULL,
-                    gSpinWidget, "spinbutton",
-                    isDown ? GTK_ARROW_DOWN : GTK_ARROW_UP, TRUE,
+    gtk_render_arrow(style, cr, 
+                    isDown ? ARROW_DOWN : ARROW_UP,
                     arrow_rect.x, arrow_rect.y,
-                    arrow_rect.width, arrow_rect.height);
-
+                    arrow_rect.width);
+    gtk_style_context_restore(style);
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_scale_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_scale_paint(cairo_t *cr, GdkRectangle* rect,
                     GdkRectangle* cliprect, GtkWidgetState* state,
                     GtkOrientation flags, GtkTextDirection direction)
 {
+  GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
   gint x = 0, y = 0;
-  GtkStateType state_type = ConvertGtkState(state);
-  GtkStyle* style;
+  GtkStyleContext* style;
   GtkWidget* widget;
+  GtkBorder border;
 
   ensure_scale_widget();
   widget = ((flags == GTK_ORIENTATION_HORIZONTAL) ? gHScaleWidget : gVScaleWidget);
   gtk_widget_set_direction(widget, direction);
 
-  style = widget->style;
+  style = gtk_widget_get_style_context(widget);
+  gtk_style_context_save(style);
+  gtk_style_context_add_class(style, GTK_STYLE_CLASS_SCALE);
+  gtk_style_context_get_border(style, state_flags, &border);
 
   if (flags == GTK_ORIENTATION_HORIZONTAL) {
-    x = XTHICKNESS(style);
+    x = border.left;
     y++;
   }
   else {
     x++;
-    y = YTHICKNESS(style);
+    y = border.top;
   }
 
-  TSOffsetStyleGCs(style, rect->x, rect->y);
-  gtk_style_apply_default_background(style, drawable, TRUE, GTK_STATE_NORMAL,
-                                     cliprect, rect->x, rect->y,
-                                     rect->width, rect->height);
-
-  gtk_paint_box(style, drawable, GTK_STATE_ACTIVE, GTK_SHADOW_IN, cliprect,
-                widget, "trough", rect->x + x, rect->y + y,
-                rect->width - 2*x, rect->height - 2*y);
+  gtk_render_background(style, cr, rect->x + x, rect->y + y,
+                        rect->width - 2*x, rect->height - 2*y);
+  gtk_render_frame(style, cr, rect->x + x, rect->y + y,
+                   rect->width - 2*x, rect->height - 2*y);
 
   if (state->focused)
-    gtk_paint_focus(style, drawable, state_type, cliprect, widget, "trough",
+    gtk_render_focus(style, cr, 
                     rect->x, rect->y, rect->width, rect->height);
-
+  gtk_style_context_restore(style);
   return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_scale_thumb_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_scale_thumb_paint(cairo_t *cr, GdkRectangle* rect,
                           GdkRectangle* cliprect, GtkWidgetState* state,
                           GtkOrientation flags, GtkTextDirection direction)
 {
-  GtkStateType state_type = ConvertGtkState(state);
-  GtkStyle* style;
+  GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+  GtkStyleContext* style;
   GtkWidget* widget;
   gint thumb_width, thumb_height, x, y;
 
   ensure_scale_widget();
   widget = ((flags == GTK_ORIENTATION_HORIZONTAL) ? gHScaleWidget : gVScaleWidget);
   gtk_widget_set_direction(widget, direction);
 
-  style = widget->style;
-
-  /* determine the thumb size, and position the thumb in the center in the opposite axis */
+  style = gtk_widget_get_style_context(widget);
+  gtk_style_context_add_class(style, GTK_STYLE_CLASS_SLIDER);
+  gtk_style_context_save(style);
+  gtk_style_context_set_state(style, state_flags);
+  /* determine the thumb size, and position the thumb in the center in the opposite axis 
+  */
   if (flags == GTK_ORIENTATION_HORIZONTAL) {
     moz_gtk_get_scalethumb_metrics(GTK_ORIENTATION_HORIZONTAL, &thumb_width, &thumb_height);
     x = rect->x;
     y = rect->y + (rect->height - thumb_height) / 2;
   }
   else {
     moz_gtk_get_scalethumb_metrics(GTK_ORIENTATION_VERTICAL, &thumb_height, &thumb_width);
     x = rect->x + (rect->width - thumb_width) / 2;
     y = rect->y;
   }
 
-  TSOffsetStyleGCs(style, rect->x, rect->y);
-  gtk_paint_slider(style, drawable, state_type, GTK_SHADOW_OUT, cliprect,
-                   widget, (flags == GTK_ORIENTATION_HORIZONTAL) ? "hscale" : "vscale",
-                   x, y, thumb_width, thumb_height, flags);
-
+  gtk_render_slider(style, cr, x, y, thumb_width, thumb_height, flags);
+  gtk_style_context_restore(style);
   return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_gripper_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_gripper_paint(cairo_t *cr, GdkRectangle* rect,
                       GdkRectangle* cliprect, GtkWidgetState* state,
                       GtkTextDirection direction)
 {
-    GtkStateType state_type = ConvertGtkState(state);
-    GtkShadowType shadow_type;
-    GtkStyle* style;
+    GtkStyleContext* style;
 
     ensure_handlebox_widget();
     gtk_widget_set_direction(gHandleBoxWidget, direction);
 
-    style = gHandleBoxWidget->style;
-    shadow_type = GTK_HANDLE_BOX(gHandleBoxWidget)->shadow_type;
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-    gtk_paint_box(style, drawable, state_type, shadow_type, cliprect,
-                  gHandleBoxWidget, "handlebox_bin", rect->x, rect->y,
-                  rect->width, rect->height);
+    style = gtk_widget_get_style_context(gHandleBoxWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
+    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
+
+    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_style_context_restore(style);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_hpaned_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_hpaned_paint(cairo_t *cr, GdkRectangle* rect,
                      GdkRectangle* cliprect, GtkWidgetState* state)
 {
-    GtkStateType hpaned_state = ConvertGtkState(state);
-
+    GtkStyleContext* style;
+    
     ensure_hpaned_widget();
-    gtk_paint_handle(gHPanedWidget->style, drawable, hpaned_state,
-                     GTK_SHADOW_NONE, cliprect, gHPanedWidget, "paned",
-                     rect->x, rect->y, rect->width, rect->height,
-                     GTK_ORIENTATION_VERTICAL);
+    style = gtk_widget_get_style_context(gHPanedWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_PANE_SEPARATOR);
+    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
+    gtk_render_handle(style, cr,
+                      rect->x, rect->y, rect->width, rect->height);
+    gtk_style_context_restore(style);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_vpaned_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_vpaned_paint(cairo_t *cr, GdkRectangle* rect,
                      GdkRectangle* cliprect, GtkWidgetState* state)
 {
-    GtkStateType vpaned_state = ConvertGtkState(state);
+    GtkStyleContext* style;
 
     ensure_vpaned_widget();
-    gtk_paint_handle(gVPanedWidget->style, drawable, vpaned_state,
-                     GTK_SHADOW_NONE, cliprect, gVPanedWidget, "paned",
-                     rect->x, rect->y, rect->width, rect->height,
-                     GTK_ORIENTATION_HORIZONTAL);
+    style = gtk_widget_get_style_context(gVPanedWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_PANE_SEPARATOR);
+    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
+    gtk_render_handle(style, cr,
+                      rect->x, rect->y, rect->width, rect->height);                     
+    gtk_style_context_restore(style);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_caret_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_caret_paint(cairo_t *cr, GdkRectangle* rect,
                     GdkRectangle* cliprect, GtkTextDirection direction)
 {
     GdkRectangle location = *rect;
+
     if (direction == GTK_TEXT_DIR_RTL) {
         /* gtk_draw_insertion_cursor ignores location.width */
         location.x = rect->x + rect->width;
     }
 
     ensure_entry_widget();
-    gtk_draw_insertion_cursor(gEntryWidget, drawable, cliprect,
+    gtk_draw_insertion_cursor(gEntryWidget, cr,
                               &location, TRUE, direction, FALSE);
-
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_entry_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_entry_paint(cairo_t *cr, GdkRectangle* rect,
                     GdkRectangle* cliprect, GtkWidgetState* state,
                     GtkWidget* widget, GtkTextDirection direction)
 {
-    GtkStateType bg_state = state->disabled ?
-                                GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL;
-    gint x, y, width = rect->width, height = rect->height;
-    GtkStyle* style;
+    gint x = rect->x, y = rect->y, width = rect->width, height = rect->height;
+    GtkStyleContext* style;
     gboolean interior_focus;
-    gboolean theme_honors_transparency = FALSE;
     gint focus_width;
 
     gtk_widget_set_direction(widget, direction);
 
-    style = widget->style;
+    style = gtk_widget_get_style_context(widget);
 
     gtk_widget_style_get(widget,
                          "interior-focus", &interior_focus,
                          "focus-line-width", &focus_width,
-                         "honors-transparent-bg-hint", &theme_honors_transparency,
                          NULL);
 
     /* gtkentry.c uses two windows, one for the entire widget and one for the
      * text area inside it. The background of both windows is set to the "base"
      * color of the new state in gtk_entry_state_changed, but only the inner
      * textarea window uses gtk_paint_flat_box when exposed */
 
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-
     /* This gets us a lovely greyish disabledish look */
     gtk_widget_set_sensitive(widget, !state->disabled);
 
-    /* GTK fills the outer widget window with the base color before drawing the widget.
-     * Some older themes rely on this behavior, but many themes nowadays use rounded
-     * corners on their widgets. While most GTK apps are blissfully unaware of this
-     * problem due to their use of the default window background, we render widgets on
-     * many kinds of backgrounds on the web.
-     * If the theme is able to cope with transparency, then we can skip pre-filling
-     * and notify the theme it will paint directly on the canvas. */
-    if (theme_honors_transparency) {
-        g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
-    } else {
-        gdk_draw_rectangle(drawable, style->base_gc[bg_state], TRUE,
-                           cliprect->x, cliprect->y, cliprect->width, cliprect->height);
-        g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(FALSE));
-    }
-
-    /* Get the position of the inner window, see _gtk_entry_get_borders */
-    x = XTHICKNESS(style);
-    y = YTHICKNESS(style);
-
-    if (!interior_focus) {
-        x += focus_width;
-        y += focus_width;
-    }
-
-    /* Simulate an expose of the inner window */
-    gtk_paint_flat_box(style, drawable, bg_state, GTK_SHADOW_NONE,
-                       cliprect, widget, "entry_bg",  rect->x + x,
-                       rect->y + y, rect->width - 2*x, rect->height - 2*y);
-
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_ENTRY);
+  
     /* Now paint the shadow and focus border.
      * We do like in gtk_entry_draw_frame, we first draw the shadow, a tad
      * smaller when focused if the focus is not interior, then the focus. */
-    x = rect->x;
-    y = rect->y;
 
     if (state->focused && !state->disabled) {
         /* This will get us the lit borders that focused textboxes enjoy on
          * some themes. */
-        GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
-
+        gtk_style_context_set_state(style, GTK_STATE_FLAG_FOCUSED);
         if (!interior_focus) {
             /* Indent the border a little bit if we have exterior focus 
                (this is what GTK does to draw native entries) */
             x += focus_width;
             y += focus_width;
             width -= 2 * focus_width;
             height -= 2 * focus_width;
         }
     }
 
-    gtk_paint_shadow(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_IN,
-                     cliprect, widget, "entry", x, y, width, height);
+    if (state->disabled) {
+        gtk_style_context_set_state(style, GTK_STATE_FLAG_INSENSITIVE);
+    }
+
+    gtk_render_background(style, cr, x, y, width, height);
+    gtk_render_frame(style, cr, x, y, width, height);
 
     if (state->focused && !state->disabled) {
         if (!interior_focus) {
-            gtk_paint_focus(style, drawable,  GTK_STATE_NORMAL, cliprect,
-                            widget, "entry",
-                            rect->x, rect->y, rect->width, rect->height);
+            gtk_render_focus(style, cr, rect->x, rect->y, rect->width, rect->height);
         }
-
-        /* Now unset the focus flag. We don't want other entries to look
-         * like they're focused too! */
-        GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
     }
+    gtk_style_context_restore(style);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint 
-moz_gtk_treeview_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_treeview_paint(cairo_t *cr, GdkRectangle* rect,
                        GdkRectangle* cliprect, GtkWidgetState* state,
                        GtkTextDirection direction)
 {
     gint xthickness, ythickness;
-
-    GtkStyle *style;
-    GtkStateType state_type;
+    GtkStyleContext *style;
+    GtkStyleContext *style_tree;
+    GtkStateFlags state_flags;
+    GtkBorder border;
 
     ensure_tree_view_widget();
     ensure_scrolled_window_widget();
 
     gtk_widget_set_direction(gTreeViewWidget, direction);
     gtk_widget_set_direction(gScrolledWindowWidget, direction);
 
     /* only handle disabled and normal states, otherwise the whole background
      * area will be painted differently with other states */
-    state_type = state->disabled ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL;
-
-    /* In GTK the treeview sets the background of the window
-     * which contains the cells to the treeview base color.
-     * If we don't set it here the background color will not be correct.*/
-    gtk_widget_modify_bg(gTreeViewWidget, state_type,
-                         &gTreeViewWidget->style->base[state_type]);
-
-    style = gScrolledWindowWidget->style;
-    xthickness = XTHICKNESS(style);
-    ythickness = YTHICKNESS(style);
-
-    TSOffsetStyleGCs(gTreeViewWidget->style, rect->x, rect->y);
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-
-    gtk_paint_flat_box(gTreeViewWidget->style, drawable, state_type,
-                       GTK_SHADOW_NONE, cliprect, gTreeViewWidget, "treeview",
-                       rect->x + xthickness, rect->y + ythickness,
-                       rect->width - 2 * xthickness,
-                       rect->height - 2 * ythickness);
-
-    gtk_paint_shadow(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_IN,
-                     cliprect, gScrolledWindowWidget, "scrolled_window",
+    state_flags = state->disabled ? GTK_STATE_FLAG_INSENSITIVE : GTK_STATE_FLAG_NORMAL;
+
+    style = gtk_widget_get_style_context(gScrolledWindowWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME);    
+    gtk_style_context_get_border(style, state_flags, &border);
+    xthickness = border.left;
+    ythickness = border.top;    
+
+    style_tree = gtk_widget_get_style_context(gTreeViewWidget);
+    gtk_style_context_save(style_tree);
+    gtk_style_context_add_class(style_tree, GTK_STYLE_CLASS_VIEW);
+    
+    gtk_render_background(style_tree, cr,
+                          rect->x + xthickness, rect->y + ythickness,
+                          rect->width - 2 * xthickness,
+                          rect->height - 2 * ythickness);
+    gtk_render_frame(style, cr, 
                      rect->x, rect->y, rect->width, rect->height); 
-
+    gtk_style_context_restore(style);
+    gtk_style_context_restore(style_tree);
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_tree_header_cell_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_tree_header_cell_paint(cairo_t *cr, GdkRectangle* rect,
                                GdkRectangle* cliprect, GtkWidgetState* state,
                                gboolean isSorted, GtkTextDirection direction)
 {
-    gtk_tree_view_column_set_sort_indicator(gMiddleTreeViewColumn,
-                                            isSorted);
-
-    moz_gtk_button_paint(drawable, rect, cliprect, state, GTK_RELIEF_NORMAL,
+    moz_gtk_button_paint(cr, rect, cliprect, state, GTK_RELIEF_NORMAL,
                          gTreeHeaderCellWidget, direction);
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_tree_header_sort_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_tree_header_sort_arrow_paint(cairo_t *cr, GdkRectangle* rect,
                                      GdkRectangle* cliprect,
-                                     GtkWidgetState* state, GtkArrowType flags,
+                                     GtkWidgetState* state, GtkArrowType arrow_type,
                                      GtkTextDirection direction)
 {
     GdkRectangle arrow_rect;
-    GtkStateType state_type = ConvertGtkState(state);
-    GtkShadowType shadow_type = GTK_SHADOW_IN;
-    GtkArrowType arrow_type = flags;
-    GtkStyle* style;
+    gdouble arrow_angle;
+    GtkStyleContext* style;
 
     ensure_tree_header_cell_widget();
     gtk_widget_set_direction(gTreeHeaderSortArrowWidget, direction);
 
     /* hard code these values */
     arrow_rect.width = 11;
     arrow_rect.height = 11;
     arrow_rect.x = rect->x + (rect->width - arrow_rect.width) / 2;
     arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2;
-
-    style = gTreeHeaderSortArrowWidget->style;
-    TSOffsetStyleGCs(style, arrow_rect.x, arrow_rect.y);
-
-    gtk_paint_arrow(style, drawable, state_type, shadow_type, cliprect,
-                    gTreeHeaderSortArrowWidget, "arrow",  arrow_type, TRUE,
-                    arrow_rect.x, arrow_rect.y,
-                    arrow_rect.width, arrow_rect.height);
-
+    style = gtk_widget_get_style_context(gTreeHeaderSortArrowWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
+
+    switch (arrow_type) {
+    case GTK_ARROW_LEFT:
+        arrow_angle = ARROW_LEFT;
+        break;
+    case GTK_ARROW_RIGHT:
+        arrow_angle = ARROW_RIGHT;
+        break;
+    case GTK_ARROW_DOWN:
+        arrow_angle = ARROW_DOWN;
+        break;
+    default:
+        arrow_angle = ARROW_UP;
+        break;
+    }
+    if (arrow_type != GTK_ARROW_NONE)
+        gtk_render_arrow(style, cr, arrow_angle,
+                         arrow_rect.x, arrow_rect.y,
+                         arrow_rect.width);
+    gtk_style_context_restore(style);
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_treeview_expander_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_treeview_expander_paint(cairo_t *cr, GdkRectangle* rect,
                                 GdkRectangle* cliprect, GtkWidgetState* state,
                                 GtkExpanderStyle expander_state,
                                 GtkTextDirection direction)
 {
-    GtkStyle *style;
-    GtkStateType state_type;
+    GtkStyleContext *style;
 
     ensure_tree_view_widget();
     gtk_widget_set_direction(gTreeViewWidget, direction);
 
-    style = gTreeViewWidget->style;
-
+    style = gtk_widget_get_style_context(gTreeViewWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_EXPANDER);
     /* Because the frame we get is of the entire treeview, we can't get the precise
      * event state of one expander, thus rendering hover and active feedback useless. */
-    state_type = state->disabled ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL;
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-    gtk_paint_expander(style, drawable, state_type, cliprect, gTreeViewWidget, "treeview",
-                       rect->x + rect->width / 2, rect->y + rect->height / 2, expander_state);
-
+    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
+    gtk_render_expander(style, cr,
+                        rect->x + rect->width / 2, rect->y + rect->height / 2,
+                        rect->width, rect->height);
+    gtk_style_context_restore(style);
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_expander_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_expander_paint(cairo_t *cr, GdkRectangle* rect,
                        GdkRectangle* cliprect, GtkWidgetState* state,
                        GtkExpanderStyle expander_state,
                        GtkTextDirection direction)
 {
-    GtkStyle *style;
-    GtkStateType state_type = ConvertGtkState(state);
+    GtkStyleContext *style;
 
     ensure_expander_widget();
     gtk_widget_set_direction(gExpanderWidget, direction);
 
-    style = gExpanderWidget->style;
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-    gtk_paint_expander(style, drawable, state_type, cliprect, gExpanderWidget, "expander",
-                       rect->x + rect->width / 2, rect->y + rect->height / 2, expander_state);
-
+    style = gtk_widget_get_style_context(gExpanderWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_EXPANDER);
+    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
+    gtk_render_expander(style, cr, 
+                        rect->x + rect->width / 2, rect->y + rect->height / 2,
+						rect->width, rect->height);
+    gtk_style_context_restore(style);
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_combo_box_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_combo_box_paint(cairo_t *cr, GdkRectangle* rect,
                         GdkRectangle* cliprect, GtkWidgetState* state,
                         gboolean ishtml, GtkTextDirection direction)
 {
     GdkRectangle arrow_rect, real_arrow_rect;
     gint arrow_size, separator_width;
     gboolean wide_separators;
-    GtkStateType state_type = ConvertGtkState(state);
-    GtkShadowType shadow_type = state->active ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
-    GtkStyle* style;
+    GtkStyleContext* style;
     GtkRequisition arrow_req;
 
     ensure_combo_box_widgets();
 
     /* Also sets the direction on gComboBoxButtonWidget, which is then
      * inherited by the separator and arrow */
-    moz_gtk_button_paint(drawable, rect, cliprect, state, GTK_RELIEF_NORMAL,
+    moz_gtk_button_paint(cr, rect, cliprect, state, GTK_RELIEF_NORMAL,
                          gComboBoxButtonWidget, direction);
 
     calculate_button_inner_rect(gComboBoxButtonWidget,
                                 rect, &arrow_rect, direction, ishtml);
     /* Now arrow_rect contains the inner rect ; we want to correct the width
      * to what the arrow needs (see gtk_combo_box_size_allocate) */
     gtk_widget_size_request(gComboBoxArrowWidget, &arrow_req);
     if (direction == GTK_TEXT_DIR_LTR)
         arrow_rect.x += arrow_rect.width - arrow_req.width;
     arrow_rect.width = arrow_req.width;
 
     calculate_arrow_rect(gComboBoxArrowWidget,
                          &arrow_rect, &real_arrow_rect, direction);
 
-    style = gComboBoxArrowWidget->style;
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-
-    gtk_widget_size_allocate(gComboBoxWidget, rect);
-
-    gtk_paint_arrow(style, drawable, state_type, shadow_type, cliprect,
-                    gComboBoxArrowWidget, "arrow",  GTK_ARROW_DOWN, TRUE,
-                    real_arrow_rect.x, real_arrow_rect.y,
-                    real_arrow_rect.width, real_arrow_rect.height);
-
+    style = gtk_widget_get_style_context(gComboBoxArrowWidget);
+    gtk_render_arrow(style, cr, ARROW_DOWN,
+                     real_arrow_rect.x, real_arrow_rect.y,
+                     real_arrow_rect.width);
 
     /* If there is no separator in the theme, there's nothing left to do. */
     if (!gComboBoxSeparatorWidget)
         return MOZ_GTK_SUCCESS;
-
-    style = gComboBoxSeparatorWidget->style;
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-
+    style = gtk_widget_get_style_context(gComboBoxSeparatorWidget);
     gtk_widget_style_get(gComboBoxSeparatorWidget,
                          "wide-separators", &wide_separators,
                          "separator-width", &separator_width,
                          NULL);
 
     if (wide_separators) {
         if (direction == GTK_TEXT_DIR_LTR)
             arrow_rect.x -= separator_width;
         else
             arrow_rect.x += arrow_rect.width;
-
-        gtk_paint_box(style, drawable,
-                      GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT,
-                      cliprect, gComboBoxSeparatorWidget, "vseparator",
-                      arrow_rect.x, arrow_rect.y,
-                      separator_width, arrow_rect.height);
+        
+        gtk_render_frame(style, cr, arrow_rect.x, arrow_rect.y, separator_width, arrow_rect.height);
     } else {
-        if (direction == GTK_TEXT_DIR_LTR)
-            arrow_rect.x -= XTHICKNESS(style);
+        if (direction == GTK_TEXT_DIR_LTR) {
+            GtkBorder border;
+            gtk_style_context_get_border(style, GetStateFlagsFromGtkWidgetState(state), &border);
+            arrow_rect.x -= border.left;
+        }
         else
             arrow_rect.x += arrow_rect.width;
-
-        gtk_paint_vline(style, drawable, GTK_STATE_NORMAL, cliprect,
-                        gComboBoxSeparatorWidget, "vseparator",
-                        arrow_rect.y, arrow_rect.y + arrow_rect.height,
-                        arrow_rect.x);
+        
+        gtk_render_line(style, cr, 
+                        arrow_rect.x, arrow_rect.y, 
+                        arrow_rect.x, arrow_rect.y + arrow_rect.height);
     }
-
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_arrow_paint(cairo_t *cr, GdkRectangle* rect,
                     GdkRectangle* cliprect, GtkWidgetState* state,
                     GtkArrowType arrow_type, GtkTextDirection direction)
 {
-    GtkStyle* style;
-    GtkStateType state_type = ConvertGtkState(state);
-    GtkShadowType shadow_type = state->active ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
+    GtkStyleContext* style;
+    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
     GdkRectangle arrow_rect;
+    gdouble arrow_angle = ARROW_UP;
 
     ensure_button_arrow_widget();
-    style = gButtonArrowWidget->style;
+    style = gtk_widget_get_style_context(gButtonArrowWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_set_state(style, state_flags);
     gtk_widget_set_direction(gButtonArrowWidget, direction);
 
     calculate_arrow_rect(gButtonArrowWidget, rect, &arrow_rect,
                          direction);
 
     if (direction == GTK_TEXT_DIR_RTL) {
         if (arrow_type == GTK_ARROW_LEFT)
-            arrow_type = GTK_ARROW_RIGHT;
+            arrow_angle = ARROW_RIGHT;
         else if (arrow_type == GTK_ARROW_RIGHT)
-            arrow_type = GTK_ARROW_LEFT;
+            arrow_angle = ARROW_LEFT;
+    } else if (arrow_type == GTK_ARROW_DOWN) {
+        arrow_angle = ARROW_DOWN;
     }
-
-    TSOffsetStyleGCs(style, arrow_rect.x, arrow_rect.y);
-    gtk_paint_arrow(style, drawable, state_type, shadow_type, cliprect,
-                    gButtonArrowWidget, "arrow",  arrow_type, TRUE,
-                    arrow_rect.x, arrow_rect.y, arrow_rect.width, arrow_rect.height);
-
+    if (arrow_type != GTK_ARROW_NONE)
+        gtk_render_arrow(style, cr, arrow_angle,
+                         arrow_rect.x, arrow_rect.y, arrow_rect.width);                    
+    gtk_style_context_restore(style);
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_combo_box_entry_button_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_combo_box_entry_button_paint(cairo_t *cr, GdkRectangle* rect,
                                      GdkRectangle* cliprect,
                                      GtkWidgetState* state,
                                      gboolean input_focus,
                                      GtkTextDirection direction)
 {
     gint x_displacement, y_displacement;
     GdkRectangle arrow_rect, real_arrow_rect;
-    GtkStateType state_type = ConvertGtkState(state);
-    GtkShadowType shadow_type = state->active ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
-    GtkStyle* style;
+    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+    GtkStyleContext* style;
 
     ensure_combo_box_entry_widgets();
 
-    if (input_focus) {
-        /* Some themes draw a complementary focus ring for the dropdown button
-         * when the dropdown entry has focus */
-        GTK_WIDGET_SET_FLAGS(gComboBoxEntryTextareaWidget, GTK_HAS_FOCUS);
-    }
-
-    moz_gtk_button_paint(drawable, rect, cliprect, state, GTK_RELIEF_NORMAL,
+    moz_gtk_button_paint(cr, rect, cliprect, state, GTK_RELIEF_NORMAL,
                          gComboBoxEntryButtonWidget, direction);
 
-    if (input_focus)
-        GTK_WIDGET_UNSET_FLAGS(gComboBoxEntryTextareaWidget, GTK_HAS_FOCUS);
-
     calculate_button_inner_rect(gComboBoxEntryButtonWidget,
                                 rect, &arrow_rect, direction, FALSE);
-    if (state_type == GTK_STATE_ACTIVE) {
+    if (state_flags & GTK_STATE_FLAG_ACTIVE) {
         gtk_widget_style_get(gComboBoxEntryButtonWidget,
                              "child-displacement-x", &x_displacement,
                              "child-displacement-y", &y_displacement,
                              NULL);
         arrow_rect.x += x_displacement;
         arrow_rect.y += y_displacement;
     }
 
     calculate_arrow_rect(gComboBoxEntryArrowWidget,
                          &arrow_rect, &real_arrow_rect, direction);
 
-    style = gComboBoxEntryArrowWidget->style;
-    TSOffsetStyleGCs(style, real_arrow_rect.x, real_arrow_rect.y);
-
-    gtk_paint_arrow(style, drawable, state_type, shadow_type, cliprect,
-                    gComboBoxEntryArrowWidget, "arrow",  GTK_ARROW_DOWN, TRUE,
+    style = gtk_widget_get_style_context(gComboBoxEntryArrowWidget);
+
+    gtk_render_arrow(style, cr, ARROW_DOWN,
                     real_arrow_rect.x, real_arrow_rect.y,
-                    real_arrow_rect.width, real_arrow_rect.height);
+                    real_arrow_rect.width);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_container_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_container_paint(cairo_t *cr, GdkRectangle* rect,
                         GdkRectangle* cliprect, GtkWidgetState* state, 
                         gboolean isradio, GtkTextDirection direction)
 {
-    GtkStateType state_type = ConvertGtkState(state);
-    GtkStyle* style;
+    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+    GtkStyleContext* style;
     GtkWidget *widget;
     gboolean interior_focus;
     gint focus_width, focus_pad;
 
     if (isradio) {
         ensure_radiobutton_widget();
         widget = gRadiobuttonWidget;
     } else {
         ensure_checkbox_widget();
         widget = gCheckboxWidget;
     }
     gtk_widget_set_direction(widget, direction);
 
-    style = widget->style;
-    moz_gtk_widget_get_focus(widget, &interior_focus, &focus_width,
-                             &focus_pad);
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-
-    /* The detail argument for the gtk_paint_* calls below are "checkbutton"
-       even for radio buttons, to match what gtk does. */
-
+    style = gtk_widget_get_style_context(widget);
+    gtk_style_context_save(style);
+    moz_gtk_widget_get_focus(widget, &interior_focus, &focus_width, &focus_pad);
+    gtk_style_context_set_state(style, state_flags);
+  
     /* this is for drawing a prelight box */
-    if (state_type == GTK_STATE_PRELIGHT || state_type == GTK_STATE_ACTIVE) {
-        gtk_paint_flat_box(style, drawable, GTK_STATE_PRELIGHT,
-                           GTK_SHADOW_ETCHED_OUT, cliprect, widget,
-                           "checkbutton",
-                           rect->x, rect->y, rect->width, rect->height);
+    if (state_flags & GTK_STATE_FLAG_PRELIGHT) {
+        gtk_render_background(style, cr,
+                              rect->x, rect->y, rect->width, rect->height);
     }
-
-    if (state_type != GTK_STATE_NORMAL && state_type != GTK_STATE_PRELIGHT)
-        state_type = GTK_STATE_NORMAL;
-
+  
     if (state->focused && !interior_focus) {
-        gtk_paint_focus(style, drawable, state_type, cliprect, widget,
-                        "checkbutton",
+        gtk_render_focus(style, cr,
                         rect->x, rect->y, rect->width, rect->height);
     }
-
+    gtk_style_context_restore(style);
+  
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_toggle_label_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_toggle_label_paint(cairo_t *cr, GdkRectangle* rect,
                            GdkRectangle* cliprect, GtkWidgetState* state, 
                            gboolean isradio, GtkTextDirection direction)
 {
-    GtkStateType state_type;
-    GtkStyle *style;
+    GtkStyleContext *style;
     GtkWidget *widget;
     gboolean interior_focus;
 
     if (!state->focused)
         return MOZ_GTK_SUCCESS;
 
     if (isradio) {
         ensure_radiobutton_widget();
         widget = gRadiobuttonWidget;
     } else {
         ensure_checkbox_widget();
         widget = gCheckboxWidget;
     }
+    style = gtk_widget_get_style_context(widget);
+    gtk_style_context_save(style);
+    if (isradio) {
+      gtk_style_context_add_class(style, GTK_STYLE_CLASS_RADIO);
+    } else {
+      gtk_style_context_add_class(style, GTK_STYLE_CLASS_CHECK);
+    }
     gtk_widget_set_direction(widget, direction);
 
     gtk_widget_style_get(widget, "interior-focus", &interior_focus, NULL);
     if (!interior_focus)
         return MOZ_GTK_SUCCESS;
 
-    state_type = ConvertGtkState(state);
-
-    style = widget->style;
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-
-    /* Always "checkbutton" to match gtkcheckbutton.c */
-    gtk_paint_focus(style, drawable, state_type, cliprect, widget,
-                    "checkbutton",
+    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
+    gtk_render_focus(style, cr,
                     rect->x, rect->y, rect->width, rect->height);
+    gtk_style_context_restore(style);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_toolbar_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_toolbar_paint(cairo_t *cr, GdkRectangle* rect,
                       GdkRectangle* cliprect, GtkTextDirection direction)
 {
-    GtkStyle* style;
-    GtkShadowType shadow_type;
+    GtkStyleContext* style;
 
     ensure_toolbar_widget();
     gtk_widget_set_direction(gToolbarWidget, direction);
 
-    style = gToolbarWidget->style;
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-
-    gtk_style_apply_default_background(style, drawable, TRUE,
-                                       GTK_STATE_NORMAL,
-                                       cliprect, rect->x, rect->y,
-                                       rect->width, rect->height);
-
-    gtk_widget_style_get(gToolbarWidget, "shadow-type", &shadow_type, NULL);
-
-    gtk_paint_box (style, drawable, GTK_STATE_NORMAL, shadow_type,
-                   cliprect, gToolbarWidget, "toolbar",
-                   rect->x, rect->y, rect->width, rect->height);
+    style = gtk_widget_get_style_context(gToolbarWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLBAR);
+
+    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_style_context_restore(style);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_toolbar_separator_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_toolbar_separator_paint(cairo_t *cr, GdkRectangle* rect,
                                 GdkRectangle* cliprect,
                                 GtkTextDirection direction)
 {
-    GtkStyle* style;
+    GtkStyleContext* style;
     gint     separator_width;
     gint     paint_width;
     gboolean wide_separators;
     
     /* Defined as constants in GTK+ 2.10.14 */
     const double start_fraction = 0.2;
     const double end_fraction = 0.8;
 
     ensure_toolbar_separator_widget();
     gtk_widget_set_direction(gToolbarSeparatorWidget, direction);
 
-    style = gToolbarSeparatorWidget->style;
+    style = gtk_widget_get_style_context(gToolbarSeparatorWidget);
 
     gtk_widget_style_get(gToolbarWidget,
                          "wide-separators", &wide_separators,
                          "separator-width", &separator_width,
                          NULL);
 
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-
     if (wide_separators) {
         if (separator_width > rect->width)
             separator_width = rect->width;
-
-        gtk_paint_box(style, drawable,
-                      GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT,
-                      cliprect, gToolbarWidget, "vseparator",
-                      rect->x + (rect->width - separator_width) / 2,
-                      rect->y + rect->height * start_fraction,
-                      separator_width,
-                      rect->height * (end_fraction - start_fraction));
-                       
+        
+        gtk_render_frame(style, cr,
+                          rect->x + (rect->width - separator_width) / 2,
+                          rect->y + rect->height * start_fraction,
+                          separator_width,
+                          rect->height * (end_fraction - start_fraction));
     } else {
-        paint_width = style->xthickness;
+        GtkBorder border;
+        gtk_style_context_get_border(style, 0, &border);    
+    
+        paint_width = border.left;
         
         if (paint_width > rect->width)
             paint_width = rect->width;
-    
-        gtk_paint_vline(style, drawable,
-                        GTK_STATE_NORMAL, cliprect, gToolbarSeparatorWidget,
-                        "toolbar",
+        
+        gtk_render_line(style, cr, 
+                        rect->x + (rect->width - paint_width) / 2,
                         rect->y + rect->height * start_fraction,
-                        rect->y + rect->height * end_fraction,
-                        rect->x + (rect->width - paint_width) / 2);
+                        rect->x + (rect->width - paint_width) / 2,
+                        rect->y + rect->height * end_fraction);
     }
-    
-    return MOZ_GTK_SUCCESS;
-}
-
-static gint
-moz_gtk_tooltip_paint(GdkDrawable* drawable, GdkRectangle* rect,
-                      GdkRectangle* cliprect, GtkTextDirection direction)
-{
-    GtkStyle* style;
-
-    ensure_tooltip_widget();
-    gtk_widget_set_direction(gTooltipWidget, direction);
-
-    style = gtk_rc_get_style_by_paths(gtk_settings_get_default(),
-                                      "gtk-tooltips", "GtkWindow",
-                                      GTK_TYPE_WINDOW);
-
-    style = gtk_style_attach(style, gTooltipWidget->window);
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-    gtk_paint_flat_box(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
-                       cliprect, gTooltipWidget, "tooltip",
-                       rect->x, rect->y, rect->width, rect->height);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_resizer_paint(GdkDrawable* drawable, GdkRectangle* rect,
-                      GdkRectangle* cliprect, GtkWidgetState* state,
-                      GtkTextDirection direction)
+moz_gtk_tooltip_paint(cairo_t *cr, GdkRectangle* rect,
+                      GdkRectangle* cliprect, GtkTextDirection direction)
 {
-    GtkStyle* style;
-    GtkStateType state_type = ConvertGtkState(state);
-
-    ensure_frame_widget();
-    gtk_widget_set_direction(gStatusbarWidget, direction);
-
-    style = gStatusbarWidget->style;
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-
-    gtk_paint_resize_grip(style, drawable, state_type, cliprect, gStatusbarWidget,
-                          "statusbar", (direction == GTK_TEXT_DIR_LTR) ?
-                          GDK_WINDOW_EDGE_SOUTH_EAST :
-                          GDK_WINDOW_EDGE_SOUTH_WEST,
-                          rect->x, rect->y, rect->width, rect->height);
+    GtkStyleContext* style;
+
+    ensure_tooltip_widget();
+    gtk_widget_set_direction(gTooltipWidget, direction);
+
+    style = gtk_widget_get_style_context(gTooltipWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
+    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_style_context_restore(style);
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_frame_paint(GdkDrawable* drawable, GdkRectangle* rect,
-                    GdkRectangle* cliprect, GtkTextDirection direction)
+moz_gtk_resizer_paint(cairo_t *cr, GdkRectangle* rect,
+                      GdkRectangle* cliprect, GtkWidgetState* state,
+                      GtkTextDirection direction)
 {
-    GtkStyle* style;
-    GtkShadowType shadow_type;
+    GtkStyleContext* style;
 
     ensure_frame_widget();
-    gtk_widget_set_direction(gFrameWidget, direction);
-
-    style = gFrameWidget->style;
-
-    gtk_widget_style_get(gStatusbarWidget, "shadow-type", &shadow_type, NULL);
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-    gtk_paint_shadow(style, drawable, GTK_STATE_NORMAL, shadow_type,
-                     cliprect, gFrameWidget, "frame", rect->x, rect->y,
-                     rect->width, rect->height);
+    gtk_widget_set_direction(gStatusbarWidget, direction);
+
+    style = gtk_widget_get_style_context(gStatusbarWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
+    gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
+
+    gtk_render_handle(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_style_context_restore(style);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_progressbar_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_frame_paint(cairo_t *cr, GdkRectangle* rect,
+                    GdkRectangle* cliprect, GtkTextDirection direction)
+{
+    GtkStyleContext* style;
+
+    ensure_frame_widget();
+    gtk_widget_set_direction(gFrameWidget, direction);
+    style = gtk_widget_get_style_context(gFrameWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME);
+
+    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_style_context_restore(style);
+    return MOZ_GTK_SUCCESS;
+}
+
+static gint
+moz_gtk_progressbar_paint(cairo_t *cr, GdkRectangle* rect,
                           GdkRectangle* cliprect, GtkTextDirection direction)
 {
-    GtkStyle* style;
+    GtkStyleContext* style;
 
     ensure_progress_widget();
     gtk_widget_set_direction(gProgressWidget, direction);
 
-    style = gProgressWidget->style;
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-    gtk_paint_box(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_IN,
-                  cliprect, gProgressWidget, "trough", rect->x, rect->y,
-                  rect->width, rect->height);
+    style = gtk_widget_get_style_context(gProgressWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH);
+    
+    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_style_context_restore(style);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_progress_chunk_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_progress_chunk_paint(cairo_t *cr, GdkRectangle* rect,
                              GdkRectangle* cliprect, GtkTextDirection direction,
                              GtkThemeWidgetType widget)
 {
-    GtkStyle* style;
+    GtkStyleContext* style;
 
     ensure_progress_widget();
     gtk_widget_set_direction(gProgressWidget, direction);
 
-    style = gProgressWidget->style;
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
+    style = gtk_widget_get_style_context(gProgressWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_PROGRESSBAR);
 
     if (widget == MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE ||
         widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE) {
       /**
        * The bar's size and the bar speed are set depending of the progress'
        * size. These could also be constant for all progress bars easily.
        */
       gboolean vertical = (widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE);
@@ -2300,59 +2085,67 @@ moz_gtk_progress_chunk_paint(GdkDrawable
       if (vertical) {
         rect->y += (dx < travel / 2) ? dx : travel - dx;
         rect->height = barSize;
       } else {
         rect->x += (dx < travel / 2) ? dx : travel - dx;
         rect->width = barSize;
       }
     }
-
-    gtk_paint_box(style, drawable, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
-                  cliprect, gProgressWidget, "bar", rect->x, rect->y,
-                  rect->width, rect->height);
+  
+    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_render_activity(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_style_context_restore(style);
 
     return MOZ_GTK_SUCCESS;
 }
 
 gint
 moz_gtk_get_tab_thickness(void)
 {
+    GtkBorder border;
+
     ensure_tab_widget();
-    if (YTHICKNESS(gTabWidget->style) < 2)
+    GtkStyleContext * style = gtk_widget_get_style_context(gTabWidget);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_NOTEBOOK);
+    gtk_style_context_get_border(style, 0, &border);
+
+    if (border.top < 2)
         return 2; /* some themes don't set ythickness correctly */
 
-    return YTHICKNESS(gTabWidget->style);
+    return border.top;
 }
 
+/* actual small tabs */
 static gint
-moz_gtk_tab_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_tab_paint(cairo_t *cr, GdkRectangle* rect,
                   GdkRectangle* cliprect, GtkWidgetState* state,
                   GtkTabFlags flags, GtkTextDirection direction)
 {
     /* When the tab isn't selected, we just draw a notebook extension.
      * When it is selected, we overwrite the adjacent border of the tabpanel
      * touching the tab with a pierced border (called "the gap") to make the
      * tab appear physically attached to the tabpanel; see details below. */
 
-    GtkStyle* style;
+    GtkStyleContext* style;
     GdkRectangle focusRect;
 
     ensure_tab_widget();
     gtk_widget_set_direction(gTabWidget, direction);
 
-    style = gTabWidget->style;
+    style = gtk_widget_get_style_context(gTabWidget);    
     focusRect = *rect;
-    TSOffsetStyleGCs(style, rect->x, rect->y);
+
+    gtk_style_context_save(style);
 
     if ((flags & MOZ_GTK_TAB_SELECTED) == 0) {
         /* Only draw the tab */
-        gtk_paint_extension(style, drawable, GTK_STATE_ACTIVE, GTK_SHADOW_OUT,
-                            cliprect, gTabWidget, "tab",
-                            rect->x, rect->y, rect->width, rect->height,
+        gtk_style_context_set_state(style, GTK_STATE_FLAG_NORMAL);
+        gtk_render_extension(style, cr,
+                             rect->x, rect->y, rect->width, rect->height,
                             (flags & MOZ_GTK_TAB_BOTTOM) ?
                                 GTK_POS_TOP : GTK_POS_BOTTOM );
     } else {
         /* Draw the tab and the gap
          * We want the gap to be positioned exactly on the tabpanel top
          * border; since tabbox.css may set a negative margin so that the tab
          * frame rect already overlaps the tabpanel frame rect, we need to take
          * that into account when drawing. To that effect, nsNativeThemeGTK
@@ -2401,414 +2194,439 @@ moz_gtk_tab_paint(GdkDrawable* drawable,
         gap_loffset = gap_roffset = 20; /* should be enough */
         if (flags & MOZ_GTK_TAB_FIRST) {
             if (direction == GTK_TEXT_DIR_RTL)
                 gap_roffset = 0;
             else
                 gap_loffset = 0;
         }
 
+        gtk_style_context_set_state(style, GTK_STATE_FLAG_ACTIVE);
+
+        /* Adwaita theme engine crashes without it (rhbz#713764) */
+        gtk_style_context_add_region(style, GTK_STYLE_REGION_TAB, 0);      
+
         if (flags & MOZ_GTK_TAB_BOTTOM) {
-            /* Draw the tab */
+            /* Draw the tab on bottom */
             focusRect.y += gap_voffset;
             focusRect.height -= gap_voffset;
-            gtk_paint_extension(style, drawable, GTK_STATE_NORMAL,
-                                GTK_SHADOW_OUT, cliprect, gTabWidget, "tab",
-                                rect->x, rect->y + gap_voffset, rect->width,
-                                rect->height - gap_voffset, GTK_POS_TOP);
+
+            gtk_render_extension(style, cr,
+                                 rect->x, rect->y + gap_voffset, rect->width,
+                                 rect->height - gap_voffset, GTK_POS_TOP);
 
             /* Draw the gap; erase with background color before painting in
              * case theme does not */
-            gtk_style_apply_default_background(style, drawable, TRUE,
-                                               GTK_STATE_NORMAL, cliprect,
-                                               rect->x,
-                                               rect->y + gap_voffset
-                                                       - gap_height,
-                                               rect->width, gap_height);
-            gtk_paint_box_gap(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
-                              cliprect, gTabWidget, "notebook",
-                              rect->x - gap_loffset,
-                              rect->y + gap_voffset - 3 * gap_height,
-                              rect->width + gap_loffset + gap_roffset,
-                              3 * gap_height, GTK_POS_BOTTOM,
-                              gap_loffset, rect->width);
+            gtk_render_background(style, cr,
+                                 rect->x,
+                                 rect->y + gap_voffset
+                                         - gap_height,
+                                 rect->width, gap_height);
+            gtk_render_frame_gap(style, cr,
+                                 rect->x - gap_loffset,
+                                 rect->y + gap_voffset - 3 * gap_height,
+                                 rect->width + gap_loffset + gap_roffset,
+                                 3 * gap_height, GTK_POS_BOTTOM,
+                                 gap_loffset, gap_loffset + rect->width);
+                                 
         } else {
-            /* Draw the tab */
+            /* Draw the tab on top */
             focusRect.height -= gap_voffset;
-            gtk_paint_extension(style, drawable, GTK_STATE_NORMAL,
-                                GTK_SHADOW_OUT, cliprect, gTabWidget, "tab",
-                                rect->x, rect->y, rect->width,
-                                rect->height - gap_voffset, GTK_POS_BOTTOM);
+            gtk_render_extension(style, cr,
+                                 rect->x, rect->y, rect->width,
+                                 rect->height - gap_voffset, GTK_POS_BOTTOM);
 
             /* Draw the gap; erase with background color before painting in
              * case theme does not */
-            gtk_style_apply_default_background(style, drawable, TRUE,
-                                               GTK_STATE_NORMAL, cliprect,
-                                               rect->x,
-                                               rect->y + rect->height
-                                                       - gap_voffset,
-                                               rect->width, gap_height);
-            gtk_paint_box_gap(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
-                              cliprect, gTabWidget, "notebook",
-                              rect->x - gap_loffset,
-                              rect->y + rect->height - gap_voffset,
-                              rect->width + gap_loffset + gap_roffset,
-                              3 * gap_height, GTK_POS_TOP,
-                              gap_loffset, rect->width);
+            gtk_render_background(style, cr,
+                                  rect->x,
+                                  rect->y + rect->height
+                                          - gap_voffset,
+                                  rect->width, gap_height);
+            gtk_render_frame_gap(style, cr,
+                                 rect->x - gap_loffset,
+                                 rect->y + rect->height - gap_voffset,
+                                 rect->width + gap_loffset + gap_roffset,
+                                 3 * gap_height, GTK_POS_TOP,
+                                 gap_loffset, gap_loffset + rect->width);
         }
-
     }
 
     if (state->focused) {
       /* Paint the focus ring */
-      focusRect.x += XTHICKNESS(style);
-      focusRect.width -= XTHICKNESS(style) * 2;
-      focusRect.y += YTHICKNESS(style);
-      focusRect.height -= YTHICKNESS(style) * 2;
-
-      gtk_paint_focus(style, drawable,
-                      /* Believe it or not, NORMAL means a selected tab and
-                         ACTIVE means an unselected tab. */
-                      (flags & MOZ_GTK_TAB_SELECTED) ? GTK_STATE_NORMAL
-                                                     : GTK_STATE_ACTIVE,
-                      cliprect, gTabWidget, "tab",
+      GtkBorder border;
+      gtk_style_context_get_border(style, GetStateFlagsFromGtkWidgetState(state), &border);
+
+      focusRect.x += border.left;
+      focusRect.width -= (border.left + border.right);
+      focusRect.y += border.top;
+      focusRect.height -= (border.top + border.bottom);
+
+      gtk_render_focus(style, cr,
                       focusRect.x, focusRect.y, focusRect.width, focusRect.height);
     }
 
+    gtk_style_context_restore(style);
+
+    return MOZ_GTK_SUCCESS;
+}
+
+/* tab area*/
+static gint
+moz_gtk_tabpanels_paint(cairo_t *cr, GdkRectangle* rect,
+                        GdkRectangle* cliprect, GtkTextDirection direction)
+{
+    GtkStyleContext* style;
+
+    ensure_tab_widget();
+    gtk_widget_set_direction(gTabWidget, direction);
+
+    style = gtk_widget_get_style_context(gTabWidget);
+    gtk_style_context_save(style);
+
+    gtk_render_background(style, cr, rect->x, rect->y, 
+                          rect->width, rect->height);
+    /*
+     * The gap size is not needed in moz_gtk_tabpanels_paint because 
+     * the gap will be painted with the foreground tab in moz_gtk_tab_paint.
+     *
+     * However, if moz_gtk_tabpanels_paint just uses gtk_render_frame(), 
+     * the theme will think that there are no tabs and may draw something 
+     * different.Hence the trick of using two clip regions, and drawing the 
+     * gap outside each clip region, to get the correct frame for 
+     * a tabpanel with tabs.
+     */
+    /* left side */
+    cairo_save(cr);
+    cairo_rectangle(rect->x, rect->y,
+                    rect->x + rect->width / 2,
+                    rect->y + rect->height)
+    cairo_clip(cr);
+    gtk_render_frame_gap(style, cr,
+                         rect->x, rect->y,
+                         rect->width, rect->height,
+                         GTK_POS_TOP, rect->width - 1, rect->width);
+    cairo_restore(cr);
+    
+    /* right side */
+    cairo_save(cr);
+    cairo_rectangle(rect->x + rect->width / 2, rect->y,
+                    rect->x + rect->width,
+                    rect->y + rect->height)
+    cairo_clip(cr);
+    gtk_render_frame_gap(style, cr,
+                         rect->x, rect->y,
+                         rect->width, rect->height,
+                         GTK_POS_TOP, 0, 1);
+    cairo_restore(cr);
+
+    gtk_style_context_restore(style);
+    return MOZ_GTK_SUCCESS;
+}
+
+static gint
+moz_gtk_tab_scroll_arrow_paint(cairo_t *cr, GdkRectangle* rect,
+                               GdkRectangle* cliprect, GtkWidgetState* state,
+                               GtkArrowType arrow_type,
+                               GtkTextDirection direction)
+{
+    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+    GtkStyleContext* style;
+    gdouble arrow_angle;
+    gint arrow_size = MIN(rect->width, rect->height);
+    gint x = rect->x + (rect->width - arrow_size) / 2;
+    gint y = rect->y + (rect->height - arrow_size) / 2;
+
+    ensure_tab_widget();
+
+    style = gtk_widget_get_style_context(gTabWidget);
+    gtk_style_context_save(style);
+    if (direction == GTK_TEXT_DIR_RTL) {
+        arrow_type = (arrow_type == GTK_ARROW_LEFT) ?
+                         GTK_ARROW_RIGHT : GTK_ARROW_LEFT;
+    }    
+    switch (arrow_type) {
+    case GTK_ARROW_LEFT:
+        arrow_angle = ARROW_LEFT;
+        break;
+    case GTK_ARROW_RIGHT:
+        arrow_angle = ARROW_RIGHT;
+        break;
+    case GTK_ARROW_DOWN:
+        arrow_angle = ARROW_DOWN;
+        break;
+    default:
+        arrow_angle = ARROW_UP;
+        break;      
+    }
+    if (arrow_type != GTK_ARROW_NONE)  {        
+        gtk_style_context_add_class(style, GTK_STYLE_CLASS_NOTEBOOK); /* TODO TEST */
+        gtk_style_context_set_state(style, state_flags);
+        gtk_render_arrow(style, cr, arrow_angle,
+                         x, y, arrow_size);
+    }
+    gtk_style_context_restore(style);
+    return MOZ_GTK_SUCCESS;
+}
+
+static gint
+moz_gtk_menu_bar_paint(cairo_t *cr, GdkRectangle* rect,
+                       GdkRectangle* cliprect, GtkTextDirection direction)
+{
+    GtkStyleContext* style;
+
+    ensure_menu_bar_widget();
+    gtk_widget_set_direction(gMenuBarWidget, direction);
+
+    style = gtk_widget_get_style_context(gMenuBarWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
+    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_style_context_restore(style);
+    
+    return MOZ_GTK_SUCCESS;
+}
+
+static gint
+moz_gtk_menu_popup_paint(cairo_t *cr, GdkRectangle* rect,
+                         GdkRectangle* cliprect, GtkTextDirection direction)
+{
+    GtkStyleContext* style;
+
+    ensure_menu_popup_widget();
+    gtk_widget_set_direction(gMenuPopupWidget, direction);
+
+    style = gtk_widget_get_style_context(gMenuPopupWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENU);
+
+    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_style_context_restore(style);
+
+    return MOZ_GTK_SUCCESS;
+}
+
+static gint
+moz_gtk_menu_separator_paint(cairo_t *cr, GdkRectangle* rect,
+                             GdkRectangle* cliprect, GtkTextDirection direction)
+{
+    GtkStyleContext* style;
+    gboolean wide_separators;
+    gint separator_height;
+    guint horizontal_padding;
+    gint paint_height;
+    GtkBorder border;
+
+    ensure_menu_separator_widget();
+    gtk_widget_set_direction(gMenuSeparatorWidget, direction);
+
+    style = gtk_widget_get_style_context(gMenuSeparatorWidget);
+
+    gtk_style_context_save(style);
+
+    gtk_widget_style_get(gMenuSeparatorWidget,
+                         "wide-separators",    &wide_separators,
+                         "separator-height",   &separator_height,
+                         "horizontal-padding", &horizontal_padding,
+                         NULL);
+
+    gtk_style_context_get_border(style, 0, &border);
+
+    if (wide_separators) {
+        if (separator_height > rect->height)
+            separator_height = rect->height;
+
+        gtk_render_frame(style, cr,
+                          rect->x + horizontal_padding + border.left,
+                          rect->y + (rect->height - separator_height - border.top) / 2,
+                          rect->width - 2 * (horizontal_padding + border.left),
+                          separator_height);        
+    } else {
+        paint_height = border.top;
+        if (paint_height > rect->height)
+            paint_height = rect->height;
+        
+        gtk_render_line(style, cr,
+                        rect->x + horizontal_padding + border.left,
+                        rect->y + (rect->height - border.top) / 2,
+                        rect->x + rect->width - horizontal_padding - border.left - 1,
+                        rect->y + (rect->height - border.top) / 2);
+    }
+
+    gtk_style_context_restore(style);
+    return MOZ_GTK_SUCCESS;
+}
+
+static gint
+moz_gtk_menu_item_paint(cairo_t *cr, GdkRectangle* rect,
+                        GdkRectangle* cliprect, GtkWidgetState* state,
+                        gint flags, GtkTextDirection direction)
+{
+    GtkStyleContext* style;
+    GtkWidget* item_widget;
+
+    if (state->inHover && !state->disabled) {
+        gtk_style_context_save(style);
+        style = gtk_widget_get_style_context(item_widget);
+    
+        if (flags & MOZ_TOPLEVEL_MENU_ITEM) {
+            ensure_menu_bar_item_widget();
+            item_widget = gMenuBarItemWidget;
+            gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
+        } else {
+            ensure_menu_item_widget();
+            item_widget = gMenuItemWidget;
+        }
+      
+        gtk_widget_set_direction(item_widget, direction);
+        gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUITEM);
+        gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
+
+        gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+        gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+        gtk_style_context_restore(style);
+    }
+
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_tabpanels_paint(GdkDrawable* drawable, GdkRectangle* rect,
-                        GdkRectangle* cliprect, GtkTextDirection direction)
-{
-    /* We have three problems here:
-     * - Most engines draw gtk_paint_box differently to gtk_paint_box_gap, the
-     *   former implies there are no tabs, eg. Clearlooks.
-     * - Wanting a gap of width 0 doesn't actually guarantee a zero-width gap, eg.
-     *   Clearlooks.
-     * - Our old approach of a negative X position could cause rendering errors
-     *   on the box's corner, eg. themes using the Pixbuf engine.
-     */
-    GtkStyle* style;
-    GdkRectangle halfClipRect;
-
-    ensure_tab_widget();
-    gtk_widget_set_direction(gTabWidget, direction);
-
-    style = gTabWidget->style;
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-
-    /* Our approach is as follows:
-     * - Draw the box in two passes. Pass in a clip rect to draw the left half of the
-     *   box, with the gap specified to the right outside the clip rect so that it is
-     *   not drawn.
-     * - The right half is drawn with the gap to the left outside the modified clip rect.
-     */
-    if (!gdk_rectangle_intersect(rect, cliprect, &halfClipRect))
-      return MOZ_GTK_SUCCESS;
-
-    halfClipRect.width = (halfClipRect.width / 2) + 1;
-    gtk_paint_box_gap(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
-                      &halfClipRect, gTabWidget, "notebook", rect->x, rect->y,
-                      rect->width, rect->height,
-                      GTK_POS_TOP, halfClipRect.width + 1, 0);
-
-    halfClipRect.x += halfClipRect.width;
-    gtk_paint_box_gap(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
-                      &halfClipRect, gTabWidget, "notebook", rect->x, rect->y,
-                      rect->width, rect->height,
-                      GTK_POS_TOP, -10, 0);
-
-    return MOZ_GTK_SUCCESS;
-}
-
-static gint
-moz_gtk_tab_scroll_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect,
-                               GdkRectangle* cliprect, GtkWidgetState* state,
-                               GtkArrowType arrow_type,
-                               GtkTextDirection direction)
+moz_gtk_menu_arrow_paint(cairo_t *cr, GdkRectangle* rect,
+                         GdkRectangle* cliprect, GtkWidgetState* state,
+                         GtkTextDirection direction)
 {
-    GtkStateType state_type = ConvertGtkState(state);
-    GtkShadowType shadow_type = state->active ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
-    GtkStyle* style;
-    gint arrow_size = MIN(rect->width, rect->height);
-    gint x = rect->x + (rect->width - arrow_size) / 2;
-    gint y = rect->y + (rect->height - arrow_size) / 2;
-
-    ensure_tab_widget();
-
-    style = gTabWidget->style;
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-
-    if (direction == GTK_TEXT_DIR_RTL) {
-        arrow_type = (arrow_type == GTK_ARROW_LEFT) ?
-                         GTK_ARROW_RIGHT : GTK_ARROW_LEFT;
-    }
-
-    gtk_paint_arrow(style, drawable, state_type, shadow_type, NULL,
-                    gTabWidget, "notebook", arrow_type, TRUE,
-                    x, y, arrow_size, arrow_size);
-
-    return MOZ_GTK_SUCCESS;
-}
-
-static gint
-moz_gtk_menu_bar_paint(GdkDrawable* drawable, GdkRectangle* rect,
-                       GdkRectangle* cliprect, GtkTextDirection direction)
-{
-    GtkStyle* style;
-    GtkShadowType shadow_type;
-    ensure_menu_bar_widget();
-    gtk_widget_set_direction(gMenuBarWidget, direction);
-
-    gtk_widget_style_get(gMenuBarWidget, "shadow-type", &shadow_type, NULL);
-
-    style = gMenuBarWidget->style;
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-    gtk_style_apply_default_background(style, drawable, TRUE, GTK_STATE_NORMAL,
-                                       cliprect, rect->x, rect->y,
-                                       rect->width, rect->height);
-
-    gtk_paint_box(style, drawable, GTK_STATE_NORMAL, shadow_type,
-                  cliprect, gMenuBarWidget, "menubar", rect->x, rect->y,
-                  rect->width, rect->height);
-    return MOZ_GTK_SUCCESS;
-}
-
-static gint
-moz_gtk_menu_popup_paint(GdkDrawable* drawable, GdkRectangle* rect,
-                         GdkRectangle* cliprect, GtkTextDirection direction)
-{
-    GtkStyle* style;
-    ensure_menu_popup_widget();
-    gtk_widget_set_direction(gMenuPopupWidget, direction);
-
-    style = gMenuPopupWidget->style;
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-    gtk_style_apply_default_background(style, drawable, TRUE, GTK_STATE_NORMAL,
-                                       cliprect, rect->x, rect->y,
-                                       rect->width, rect->height);
-    gtk_paint_box(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_OUT, 
-                  cliprect, gMenuPopupWidget, "menu",
-                  rect->x, rect->y, rect->width, rect->height);
+    GtkStyleContext* style;
+    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+
+    ensure_menu_item_widget();
+    gtk_widget_set_direction(gMenuItemWidget, direction);
+
+    style = gtk_widget_get_style_context(gMenuItemWidget);
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUITEM);
+    gtk_style_context_set_state(style, state_flags);
+    gtk_render_arrow(style, cr,
+                    (direction == GTK_TEXT_DIR_LTR) ? ARROW_RIGHT : ARROW_LEFT,
+                    rect->x, rect->y, rect->width);
+    gtk_style_context_restore(style);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_menu_separator_paint(GdkDrawable* drawable, GdkRectangle* rect,
-                             GdkRectangle* cliprect, GtkTextDirection direction)
-{
-    GtkStyle* style;
-    gboolean wide_separators;
-    gint separator_height;
-    guint horizontal_padding;
-    gint paint_height;
-
-    ensure_menu_separator_widget();
-    gtk_widget_set_direction(gMenuSeparatorWidget, direction);
-
-    style = gMenuSeparatorWidget->style;
-
-    gtk_widget_style_get(gMenuSeparatorWidget,
-                         "wide-separators",    &wide_separators,
-                         "separator-height",   &separator_height,
-                         "horizontal-padding", &horizontal_padding,
-                         NULL);
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-
-    if (wide_separators) {
-        if (separator_height > rect->height)
-            separator_height = rect->height;
-
-        gtk_paint_box(style, drawable,
-                      GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT,
-                      cliprect, gMenuSeparatorWidget, "hseparator",
-                      rect->x + horizontal_padding + style->xthickness,
-                      rect->y + (rect->height - separator_height - style->ythickness) / 2,
-                      rect->width - 2 * (horizontal_padding + style->xthickness),
-                      separator_height);
-    } else {
-        paint_height = style->ythickness;
-        if (paint_height > rect->height)
-            paint_height = rect->height;
-
-        gtk_paint_hline(style, drawable,
-                        GTK_STATE_NORMAL, cliprect, gMenuSeparatorWidget,
-                        "menuitem",
-                        rect->x + horizontal_padding + style->xthickness,
-                        rect->x + rect->width - horizontal_padding - style->xthickness - 1,
-                        rect->y + (rect->height - style->ythickness) / 2);
-    }
-
-    return MOZ_GTK_SUCCESS;
-}
-
-static gint
-moz_gtk_menu_item_paint(GdkDrawable* drawable, GdkRectangle* rect,
-                        GdkRectangle* cliprect, GtkWidgetState* state,
-                        gint flags, GtkTextDirection direction)
-{
-    GtkStyle* style;
-    GtkShadowType shadow_type;
-    GtkWidget* item_widget;
-
-    if (state->inHover && !state->disabled) {
-        if (flags & MOZ_TOPLEVEL_MENU_ITEM) {
-            ensure_menu_bar_item_widget();
-            item_widget = gMenuBarItemWidget;
-        } else {
-            ensure_menu_item_widget();
-            item_widget = gMenuItemWidget;
-        }
-        gtk_widget_set_direction(item_widget, direction);
-        
-        style = item_widget->style;
-        TSOffsetStyleGCs(style, rect->x, rect->y);
-
-        gtk_widget_style_get(item_widget, "selected-shadow-type",
-                             &shadow_type, NULL);
-
-        gtk_paint_box(style, drawable, GTK_STATE_PRELIGHT, shadow_type,
-                      cliprect, item_widget, "menuitem", rect->x, rect->y,
-                      rect->width, rect->height);
-    }
-
-    return MOZ_GTK_SUCCESS;
-}
-
-static gint
-moz_gtk_menu_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect,
-                         GdkRectangle* cliprect, GtkWidgetState* state,
-                         GtkTextDirection direction)
-{
-    GtkStyle* style;
-    GtkStateType state_type = ConvertGtkState(state);
-
-    ensure_menu_item_widget();
-    gtk_widget_set_direction(gMenuItemWidget, direction);
-
-    style = gMenuItemWidget->style;
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-    gtk_paint_arrow(style, drawable, state_type,
-                    (state_type == GTK_STATE_PRELIGHT) ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
-                    cliprect, gMenuItemWidget, "menuitem",
-                    (direction == GTK_TEXT_DIR_LTR) ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT,
-                    TRUE, rect->x, rect->y, rect->width, rect->height);
-
-    return MOZ_GTK_SUCCESS;
-}
-
-static gint
-moz_gtk_check_menu_item_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_check_menu_item_paint(cairo_t *cr, GdkRectangle* rect,
                               GdkRectangle* cliprect, GtkWidgetState* state,
                               gboolean checked, gboolean isradio,
                               GtkTextDirection direction)
 {
-    GtkStateType state_type = ConvertGtkState(state);
-    GtkStyle* style;
-    GtkShadowType shadow_type = (checked)?GTK_SHADOW_IN:GTK_SHADOW_OUT;
+    GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+    GtkStyleContext* style;
+    GtkBorder border;
     gint offset;
     gint indicator_size, horizontal_padding;
     gint x, y;
 
-    moz_gtk_menu_item_paint(drawable, rect, cliprect, state, FALSE, direction);
+    moz_gtk_menu_item_paint(cr, rect, cliprect, state, FALSE, direction);
 
     ensure_check_menu_item_widget();
     gtk_widget_set_direction(gCheckMenuItemWidget, direction);
 
     gtk_widget_style_get (gCheckMenuItemWidget,
                           "indicator-size", &indicator_size,
                           "horizontal-padding", &horizontal_padding,
                           NULL);
 
-    if (checked || GTK_CHECK_MENU_ITEM(gCheckMenuItemWidget)->always_show_toggle) {
-      style = gCheckMenuItemWidget->style;
-
-      offset = GTK_CONTAINER(gCheckMenuItemWidget)->border_width +
-             gCheckMenuItemWidget->style->xthickness + 2;
-
-      x = (direction == GTK_TEXT_DIR_RTL) ?
-            rect->width - indicator_size - offset - horizontal_padding: rect->x + offset + horizontal_padding;
-      y = rect->y + (rect->height - indicator_size) / 2;
-
-      TSOffsetStyleGCs(style, x, y);
-      gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gCheckMenuItemWidget),
-                                     checked);
-
-      if (isradio) {
-        gtk_paint_option(style, drawable, state_type, shadow_type, cliprect,
-                         gCheckMenuItemWidget, "option",
-                         x, y, indicator_size, indicator_size);
-      } else {
-        gtk_paint_check(style, drawable, state_type, shadow_type, cliprect,
-                        gCheckMenuItemWidget, "check",
-                        x, y, indicator_size, indicator_size);
-      }
+    style = gtk_widget_get_style_context(gCheckMenuItemWidget);
+    gtk_style_context_save(style);
+    if (isradio) {
+      gtk_style_context_add_class(style, GTK_STYLE_CLASS_RADIO);
+    } else {
+      gtk_style_context_add_class(style, GTK_STYLE_CLASS_CHECK);
     }
 
+    if (checked)
+      state_flags |= GTK_STATE_FLAG_ACTIVE;
+    
+    gtk_style_context_set_state(style, state_flags);
+    gtk_style_context_get_border(style, state_flags, &border);
+
+    offset = gtk_container_get_border_width(GTK_CONTAINER(gCheckMenuItemWidget)) +
+                                            border.left + 2;
+
+    x = (direction == GTK_TEXT_DIR_RTL) ?
+          rect->width - indicator_size - offset - horizontal_padding: rect->x + offset + horizontal_padding;
+    y = rect->y + (rect->height - indicator_size) / 2;
+
+    if (isradio) {
+      gtk_render_option(style, cr, x, y, indicator_size, indicator_size);
+    } else {
+      gtk_render_check(style, cr, x, y, indicator_size, indicator_size);
+    }
+    gtk_style_context_restore(style);
+
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_window_paint(GdkDrawable* drawable, GdkRectangle* rect,
+moz_gtk_window_paint(cairo_t *cr, GdkRectangle* rect,
                      GdkRectangle* cliprect, GtkTextDirection direction)
 {
-    GtkStyle* style;
+    GtkStyleContext* style;
 
     ensure_window_widget();
     gtk_widget_set_direction(gProtoWindow, direction);
 
-    style = gProtoWindow->style;
-
-    TSOffsetStyleGCs(style, rect->x, rect->y);
-    gtk_style_apply_default_background(style, drawable, TRUE,
-                                       GTK_STATE_NORMAL,
-                                       cliprect, rect->x, rect->y,
-                                       rect->width, rect->height);
+    style = gtk_widget_get_style_context(gProtoWindow);	
+    gtk_style_context_save(style);
+    gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
+    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_style_context_restore(style);
+
     return MOZ_GTK_SUCCESS;
 }
 
 gint
 moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top,
                           gint* right, gint* bottom, GtkTextDirection direction,
                           gboolean inhtml)
 {
     GtkWidget* w;
+    GtkStyleContext* style;
+    GtkBorder border;
 
     switch (widget) {
     case MOZ_GTK_BUTTON:
         {
             GtkBorder inner_border;
             gboolean interior_focus;
             gint focus_width, focus_pad;
 
             ensure_button_widget();
-            *left = *top = *right = *bottom = GTK_CONTAINER(gButtonWidget)->border_width;
+            *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gButtonWidget));
 
             /* Don't add this padding in HTML, otherwise the buttons will
                become too big and stuff the layout. */
             if (!inhtml) {
                 moz_gtk_widget_get_focus(gButtonWidget, &interior_focus, &focus_width, &focus_pad);
                 moz_gtk_button_get_inner_border(gButtonWidget, &inner_border);
                 *left += focus_width + focus_pad + inner_border.left;
                 *right += focus_width + focus_pad + inner_border.right;
                 *top += focus_width + focus_pad + inner_border.top;
                 *bottom += focus_width + focus_pad + inner_border.bottom;
             }
-
-            *left += gButtonWidget->style->xthickness;
-            *right += gButtonWidget->style->xthickness;
-            *top += gButtonWidget->style->ythickness;
-            *bottom += gButtonWidget->style->ythickness;
+          
+            style = gtk_widget_get_style_context(gButtonWidget);
+            gtk_style_context_get_border(style, 0, &border);
+          
+            *left += border.left;
+            *right += border.right;
+            *top += border.top;
+            *bottom += border.bottom;
             return MOZ_GTK_SUCCESS;
         }
     case MOZ_GTK_ENTRY:
         ensure_entry_widget();
         w = gEntryWidget;
         break;
     case MOZ_GTK_TREEVIEW:
         ensure_tree_view_widget();
@@ -2822,29 +2640,32 @@ moz_gtk_get_widget_border(GtkThemeWidget
              * That is why the following code is the same as for MOZ_GTK_BUTTON.  
              * */
 
             GtkBorder inner_border;
             gboolean interior_focus;
             gint focus_width, focus_pad;
 
             ensure_tree_header_cell_widget();
-            *left = *top = *right = *bottom = GTK_CONTAINER(gTreeHeaderCellWidget)->border_width;
+            *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gTreeHeaderCellWidget));
 
             moz_gtk_widget_get_focus(gTreeHeaderCellWidget, &interior_focus, &focus_width, &focus_pad);
             moz_gtk_button_get_inner_border(gTreeHeaderCellWidget, &inner_border);
             *left += focus_width + focus_pad + inner_border.left;
             *right += focus_width + focus_pad + inner_border.right;
             *top += focus_width + focus_pad + inner_border.top;
             *bottom += focus_width + focus_pad + inner_border.bottom;
+        
+            style = gtk_widget_get_style_context(gTreeHeaderCellWidget);
+            gtk_style_context_get_border(style, 0, &border);
             
-            *left += gTreeHeaderCellWidget->style->xthickness;
-            *right += gTreeHeaderCellWidget->style->xthickness;
-            *top += gTreeHeaderCellWidget->style->ythickness;
-            *bottom += gTreeHeaderCellWidget->style->ythickness;
+            *left += border.left;
+            *right += border.right;
+            *top += border.top;
+            *bottom += border.bottom;
             return MOZ_GTK_SUCCESS;
         }
     case MOZ_GTK_TREE_HEADER_SORTARROW:
         ensure_tree_header_cell_widget();
         w = gTreeHeaderSortArrowWidget;
         break;
     case MOZ_GTK_DROPDOWN_ENTRY:
         ensure_combo_box_entry_widgets();
@@ -2860,41 +2681,46 @@ moz_gtk_get_widget_border(GtkThemeWidget
              * doesn't come too close to the arrow, or in some cases spill
              * into the arrow. */
             gboolean ignored_interior_focus, wide_separators;
             gint focus_width, focus_pad, separator_width;
             GtkRequisition arrow_req;
 
             ensure_combo_box_widgets();
 
-            *left = GTK_CONTAINER(gComboBoxButtonWidget)->border_width;
+            *left = gtk_container_get_border_width(GTK_CONTAINER(gComboBoxButtonWidget));
 
             if (!inhtml) {
                 moz_gtk_widget_get_focus(gComboBoxButtonWidget,
                                          &ignored_interior_focus,
                                          &focus_width, &focus_pad);
                 *left += focus_width + focus_pad;
             }
-
-            *top = *left + gComboBoxButtonWidget->style->ythickness;
-            *left += gComboBoxButtonWidget->style->xthickness;
+          
+            style = gtk_widget_get_style_context(gComboBoxButtonWidget);
+            gtk_style_context_get_border(style, 0, &border);
+
+            *top = *left + border.top;
+            *left += border.left;
 
             *right = *left; *bottom = *top;
 
             /* If there is no separator, don't try to count its width. */
             separator_width = 0;
             if (gComboBoxSeparatorWidget) {
                 gtk_widget_style_get(gComboBoxSeparatorWidget,
                                      "wide-separators", &wide_separators,
                                      "separator-width", &separator_width,
                                      NULL);
 
-                if (!wide_separators)
-                    separator_width =
-                        XTHICKNESS(gComboBoxSeparatorWidget->style);
+                if (!wide_separators) {
+                    style = gtk_widget_get_style_context(gComboBoxSeparatorWidget);
+                    gtk_style_context_get_border(style, 0, &border);
+                    separator_width = border.left;
+                }
             }
 
             gtk_widget_size_request(gComboBoxArrowWidget, &arrow_req);
 
             if (direction == GTK_TEXT_DIR_RTL)
                 *left += separator_width + arrow_req.width;
             else
                 *right += separator_width + arrow_req.width;
@@ -2969,17 +2795,17 @@ moz_gtk_get_widget_border(GtkThemeWidget
                 w = gCheckboxWidget;
             } else {
                 ensure_radiobutton_widget();
                 moz_gtk_widget_get_focus(gRadiobuttonWidget, &interior_focus,
                                         &focus_width, &focus_pad);
                 w = gRadiobuttonWidget;
             }
 
-            *left = *top = *right = *bottom = GTK_CONTAINER(w)->border_width;
+            *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(w));
 
             if (!interior_focus) {
                 *left += (focus_width + focus_pad);
                 *right += (focus_width + focus_pad);
                 *top += (focus_width + focus_pad);
                 *bottom += (focus_width + focus_pad);
             }
 
@@ -3035,20 +2861,28 @@ moz_gtk_get_widget_border(GtkThemeWidget
     case MOZ_GTK_TAB_SCROLLARROW:
     case MOZ_GTK_ENTRY_CARET:
         *left = *top = *right = *bottom = 0;
         return MOZ_GTK_SUCCESS;
     default:
         g_warning("Unsupported widget type: %d", widget);
         return MOZ_GTK_UNKNOWN_WIDGET;
     }
-
-    *right = *left = XTHICKNESS(w->style);
-    *bottom = *top = YTHICKNESS(w->style);
-
+    /* TODO - we're still missing some widget implementations */
+    if (!w) {
+      *right = *left = 0;
+      *bottom = *top = 0;
+    } else {
+      style = gtk_widget_get_style_context(w);
+      gtk_style_context_get_border(style, 0, &border);
+      *left = border.left;
+      *right = border.right;
+      *top = border.top;
+      *bottom = border.bottom;
+    }
     return MOZ_GTK_SUCCESS;
 }
 
 gint
 moz_gtk_get_combo_box_entry_button_size(gint* width, gint* height)
 {
     /*
      * We get the requisition of the drop down button, which includes
@@ -3093,31 +2927,30 @@ moz_gtk_get_arrow_size(gint* width, gint
     return MOZ_GTK_SUCCESS;
 }
 
 gint
 moz_gtk_get_toolbar_separator_width(gint* size)
 {
     gboolean wide_separators;
     gint separator_width;
-    GtkStyle* style;
+    GtkStyleContext* style;
+    GtkBorder border;
 
     ensure_toolbar_widget();
-
-    style = gToolbarWidget->style;
+    style = gtk_widget_get_style_context(gToolbarWidget);
 
     gtk_widget_style_get(gToolbarWidget,
                          "space-size", size,
                          "wide-separators",  &wide_separators,
                          "separator-width", &separator_width,
                          NULL);
-
     /* Just in case... */
-    *size = MAX(*size, (wide_separators ? separator_width : style->xthickness));
-
+    gtk_style_context_get_border(style, 0, &border);
+    *size = MAX(*size, (wide_separators ? separator_width : border.left));
     return MOZ_GTK_SUCCESS;
 }
 
 gint
 moz_gtk_get_expander_size(gint* size)
 {
     ensure_expander_widget();
     gtk_widget_style_get(gExpanderWidget,
@@ -3136,30 +2969,35 @@ moz_gtk_get_treeview_expander_size(gint*
                          NULL);
 
     return MOZ_GTK_SUCCESS;
 }
 
 gint
 moz_gtk_get_menu_separator_height(gint *size)
 {
-    gboolean wide_separators;
-    gint     separator_height;
+    gboolean  wide_separators;
+    gint      separator_height;
+    GtkBorder border;
+    GtkStyleContext* style;
 
     ensure_menu_separator_widget();
 
     gtk_widget_style_get(gMenuSeparatorWidget,
                           "wide-separators",  &wide_separators,
                           "separator-height", &separator_height,
                           NULL);
 
+    style = gtk_widget_get_style_context(gMenuSeparatorWidget);
+    gtk_style_context_get_border(style, 0, &border);
+
     if (wide_separators)
-        *size = separator_height + gMenuSeparatorWidget->style->ythickness;
+        *size = separator_height + border.top;
     else
-        *size = gMenuSeparatorWidget->style->ythickness * 2;
+        *size = border.top + border.bottom;
 
     return MOZ_GTK_SUCCESS;
 }
 
 gint
 moz_gtk_get_scalethumb_metrics(GtkOrientation orient, gint* thumb_length, gint* thumb_height)
 {
   GtkWidget* widget;
@@ -3182,18 +3020,18 @@ moz_gtk_get_scrollbar_metrics(MozGtkScro
 
     gtk_widget_style_get (gHorizScrollbarWidget,
                           "slider_width", &metrics->slider_width,
                           "trough_border", &metrics->trough_border,
                           "stepper_size", &metrics->stepper_size,
                           "stepper_spacing", &metrics->stepper_spacing,
                           NULL);
 
-    metrics->min_slider_size =
-        GTK_RANGE(gHorizScrollbarWidget)->min_slider_size;
+    metrics->min_slider_size = 
+        gtk_range_get_min_slider_size(GTK_RANGE(gHorizScrollbarWidget));
 
     return MOZ_GTK_SUCCESS;
 }
 
 gboolean
 moz_gtk_images_in_menus()
 {
     gboolean result;
@@ -3214,215 +3052,217 @@ moz_gtk_images_in_buttons()
 
     ensure_button_widget();
     settings = gtk_widget_get_settings(gButtonWidget);
 
     g_object_get(settings, "gtk-button-images", &result, NULL);
     return result;
 }
 
+/* cairo_t *cr argument has to be a system-cairo. */
+/* TODO: GdkRectangle* cliprect is unused, shall we remove it? */
 gint
-moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable,
+moz_gtk_widget_paint(GtkThemeWidgetType widget, cairo_t *cr,
                      GdkRectangle* rect, GdkRectangle* cliprect,
                      GtkWidgetState* state, gint flags,
                      GtkTextDirection direction)
 {
     switch (widget) {
     case MOZ_GTK_BUTTON:
         if (state->depressed) {
             ensure_toggle_button_widget();
-            return moz_gtk_button_paint(drawable, rect, cliprect, state,
+            return moz_gtk_button_paint(cr, rect, cliprect, state,
                                         (GtkReliefStyle) flags,
                                         gToggleButtonWidget, direction);
         }
         ensure_button_widget();
-        return moz_gtk_button_paint(drawable, rect, cliprect, state,
+        return moz_gtk_button_paint(cr, rect, cliprect, state,
                                     (GtkReliefStyle) flags, gButtonWidget,
                                     direction);
         break;
     case MOZ_GTK_CHECKBUTTON:
     case MOZ_GTK_RADIOBUTTON:
-        return moz_gtk_toggle_paint(drawable, rect, cliprect, state,
+        return moz_gtk_toggle_paint(cr, rect, cliprect, state,
                                     !!(flags & MOZ_GTK_WIDGET_CHECKED),
                                     !!(flags & MOZ_GTK_WIDGET_INCONSISTENT),
                                     (widget == MOZ_GTK_RADIOBUTTON),
                                     direction);
         break;
     case MOZ_GTK_SCROLLBAR_BUTTON:
-        return moz_gtk_scrollbar_button_paint(drawable, rect, cliprect, state,
+        return moz_gtk_scrollbar_button_paint(cr, rect, cliprect, state,
                                               (GtkScrollbarButtonFlags) flags,
                                               direction);
         break;
     case MOZ_GTK_SCROLLBAR_TRACK_HORIZONTAL:
     case MOZ_GTK_SCROLLBAR_TRACK_VERTICAL:
-        return moz_gtk_scrollbar_trough_paint(widget, drawable, rect,
+        return moz_gtk_scrollbar_trough_paint(widget, cr, rect,
                                               cliprect, state, direction);
         break;
     case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL:
     case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL:
-        return moz_gtk_scrollbar_thumb_paint(widget, drawable, rect,
+        return moz_gtk_scrollbar_thumb_paint(widget, cr, rect,
                                              cliprect, state, direction);
         break;
     case MOZ_GTK_SCALE_HORIZONTAL:
     case MOZ_GTK_SCALE_VERTICAL:
-        return moz_gtk_scale_paint(drawable, rect, cliprect, state,
+        return moz_gtk_scale_paint(cr, rect, cliprect, state,
                                    (GtkOrientation) flags, direction);
         break;
     case MOZ_GTK_SCALE_THUMB_HORIZONTAL:
     case MOZ_GTK_SCALE_THUMB_VERTICAL:
-        return moz_gtk_scale_thumb_paint(drawable, rect, cliprect, state,
+        return moz_gtk_scale_thumb_paint(cr, rect, cliprect, state,
                                          (GtkOrientation) flags, direction);
         break;
     case MOZ_GTK_SPINBUTTON:
-        return moz_gtk_spin_paint(drawable, rect, direction);
+        return moz_gtk_spin_paint(cr, rect, direction);
         break;
     case MOZ_GTK_SPINBUTTON_UP:
     case MOZ_GTK_SPINBUTTON_DOWN:
-        return moz_gtk_spin_updown_paint(drawable, rect,
+        return moz_gtk_spin_updown_paint(cr, rect,
                                          (widget == MOZ_GTK_SPINBUTTON_DOWN),
                                          state, direction);
         break;
     case MOZ_GTK_SPINBUTTON_ENTRY:
         ensure_spin_widget();
-        return moz_gtk_entry_paint(drawable, rect, cliprect, state,
+        return moz_gtk_entry_paint(cr, rect, cliprect, state,
                                    gSpinWidget, direction);
         break;
     case MOZ_GTK_GRIPPER:
-        return moz_gtk_gripper_paint(drawable, rect, cliprect, state,
+        return moz_gtk_gripper_paint(cr, rect, cliprect, state,
                                      direction);
         break;
     case MOZ_GTK_TREEVIEW:
-        return moz_gtk_treeview_paint(drawable, rect, cliprect, state,
+        return moz_gtk_treeview_paint(cr, rect, cliprect, state,
                                       direction);
         break;
     case MOZ_GTK_TREE_HEADER_CELL:
-        return moz_gtk_tree_header_cell_paint(drawable, rect, cliprect, state,
+        return moz_gtk_tree_header_cell_paint(cr, rect, cliprect, state,
                                               flags, direction);
         break;
     case MOZ_GTK_TREE_HEADER_SORTARROW:
-        return moz_gtk_tree_header_sort_arrow_paint(drawable, rect, cliprect,
+        return moz_gtk_tree_header_sort_arrow_paint(cr, rect, cliprect,
                                                     state,
                                                     (GtkArrowType) flags,
                                                     direction);
         break;
     case MOZ_GTK_TREEVIEW_EXPANDER:
-        return moz_gtk_treeview_expander_paint(drawable, rect, cliprect, state,
+        return moz_gtk_treeview_expander_paint(cr, rect, cliprect, state,
                                                (GtkExpanderStyle) flags, direction);
         break;
     case MOZ_GTK_EXPANDER:
-        return moz_gtk_expander_paint(drawable, rect, cliprect, state,
+        return moz_gtk_expander_paint(cr, rect, cliprect, state,
                                       (GtkExpanderStyle) flags, direction);
         break;
     case MOZ_GTK_ENTRY:
         ensure_entry_widget();
-        return moz_gtk_entry_paint(drawable, rect, cliprect, state,
+        return moz_gtk_entry_paint(cr, rect, cliprect, state,
                                    gEntryWidget, direction);
         break;
     case MOZ_GTK_ENTRY_CARET:
-        return moz_gtk_caret_paint(drawable, rect, cliprect, direction);
+        return moz_gtk_caret_paint(cr, rect, cliprect, direction);
         break;
     case MOZ_GTK_DROPDOWN:
-        return moz_gtk_combo_box_paint(drawable, rect, cliprect, state,
+        return moz_gtk_combo_box_paint(cr, rect, cliprect, state,
                                        (gboolean) flags, direction);
         break;
     case MOZ_GTK_DROPDOWN_ARROW:
-        return moz_gtk_combo_box_entry_button_paint(drawable, rect, cliprect,
+        return moz_gtk_combo_box_entry_button_paint(cr, rect, cliprect,
                                                     state, flags, direction);
         break;
     case MOZ_GTK_DROPDOWN_ENTRY:
         ensure_combo_box_entry_widgets();
-        return moz_gtk_entry_paint(drawable, rect, cliprect, state,
+        return moz_gtk_entry_paint(cr, rect, cliprect, state,
                                    gComboBoxEntryTextareaWidget, direction);
         break;
     case MOZ_GTK_CHECKBUTTON_CONTAINER:
     case MOZ_GTK_RADIOBUTTON_CONTAINER:
-        return moz_gtk_container_paint(drawable, rect, cliprect, state,
+        return moz_gtk_container_paint(cr, rect, cliprect, state,
                                        (widget == MOZ_GTK_RADIOBUTTON_CONTAINER),
                                        direction);
         break;
     case MOZ_GTK_CHECKBUTTON_LABEL:
     case MOZ_GTK_RADIOBUTTON_LABEL:
-        return moz_gtk_toggle_label_paint(drawable, rect, cliprect, state,
+        return moz_gtk_toggle_label_paint(cr, rect, cliprect, state,
                                           (widget == MOZ_GTK_RADIOBUTTON_LABEL),
                                           direction);
         break;
     case MOZ_GTK_TOOLBAR:
-        return moz_gtk_toolbar_paint(drawable, rect, cliprect, direction);
+        return moz_gtk_toolbar_paint(cr, rect, cliprect, direction);
         break;
     case MOZ_GTK_TOOLBAR_SEPARATOR:
-        return moz_gtk_toolbar_separator_paint(drawable, rect, cliprect,
+        return moz_gtk_toolbar_separator_paint(cr, rect, cliprect,
                                                direction);
         break;
     case MOZ_GTK_TOOLTIP:
-        return moz_gtk_tooltip_paint(drawable, rect, cliprect, direction);
+        return moz_gtk_tooltip_paint(cr, rect, cliprect, direction);
         break;
     case MOZ_GTK_FRAME:
-        return moz_gtk_frame_paint(drawable, rect, cliprect, direction);
+        return moz_gtk_frame_paint(cr, rect, cliprect, direction);
         break;
     case MOZ_GTK_RESIZER:
-        return moz_gtk_resizer_paint(drawable, rect, cliprect, state,
+        return moz_gtk_resizer_paint(cr, rect, cliprect, state,
                                      direction);
         break;
     case MOZ_GTK_PROGRESSBAR:
-        return moz_gtk_progressbar_paint(drawable, rect, cliprect, direction);
+        return moz_gtk_progressbar_paint(cr, rect, cliprect, direction);
         break;
     case MOZ_GTK_PROGRESS_CHUNK:
     case MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE:
     case MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE:
-        return moz_gtk_progress_chunk_paint(drawable, rect, cliprect,
+        return moz_gtk_progress_chunk_paint(cr, rect, cliprect,
                                             direction, widget);
         break;
     case MOZ_GTK_TAB:
-        return moz_gtk_tab_paint(drawable, rect, cliprect, state,
+        return moz_gtk_tab_paint(cr, rect, cliprect, state,
                                  (GtkTabFlags) flags, direction);
         break;
     case MOZ_GTK_TABPANELS:
-        return moz_gtk_tabpanels_paint(drawable, rect, cliprect, direction);
+        return moz_gtk_tabpanels_paint(cr, rect, cliprect, direction);
         break;
     case MOZ_GTK_TAB_SCROLLARROW:
-        return moz_gtk_tab_scroll_arrow_paint(drawable, rect, cliprect, state,
+        return moz_gtk_tab_scroll_arrow_paint(cr, rect, cliprect, state,
                                               (GtkArrowType) flags, direction);
         break;
     case MOZ_GTK_MENUBAR:
-        return moz_gtk_menu_bar_paint(drawable, rect, cliprect, direction);
+        return moz_gtk_menu_bar_paint(cr, rect, cliprect, direction);
         break;
     case MOZ_GTK_MENUPOPUP:
-        return moz_gtk_menu_popup_paint(drawable, rect, cliprect, direction);
+        return moz_gtk_menu_popup_paint(cr, rect, cliprect, direction);
         break;
     case MOZ_GTK_MENUSEPARATOR:
-        return moz_gtk_menu_separator_paint(drawable, rect, cliprect,
+        return moz_gtk_menu_separator_paint(cr, rect, cliprect,
                                             direction);
         break;
     case MOZ_GTK_MENUITEM:
-        return moz_gtk_menu_item_paint(drawable, rect, cliprect, state, flags,
+        return moz_gtk_menu_item_paint(cr, rect, cliprect, state, flags,
                                        direction);
         break;
     case MOZ_GTK_MENUARROW:
-        return moz_gtk_menu_arrow_paint(drawable, rect, cliprect, state,
+        return moz_gtk_menu_arrow_paint(cr, rect, cliprect, state,
                                         direction);
         break;
     case MOZ_GTK_TOOLBARBUTTON_ARROW:
-        return moz_gtk_arrow_paint(drawable, rect, cliprect, state,
+        return moz_gtk_arrow_paint(cr, rect, cliprect, state,
                                    (GtkArrowType) flags, direction);
         break;
     case MOZ_GTK_CHECKMENUITEM:
     case MOZ_GTK_RADIOMENUITEM:
-        return moz_gtk_check_menu_item_paint(drawable, rect, cliprect, state,
+        return moz_gtk_check_menu_item_paint(cr, rect, cliprect, state,
                                              (gboolean) flags,
                                              (widget == MOZ_GTK_RADIOMENUITEM),
                                              direction);
         break;
     case MOZ_GTK_SPLITTER_HORIZONTAL:
-        return moz_gtk_vpaned_paint(drawable, rect, cliprect, state);
+        return moz_gtk_vpaned_paint(cr, rect, cliprect, state);
         break;
     case MOZ_GTK_SPLITTER_VERTICAL:
-        return moz_gtk_hpaned_paint(drawable, rect, cliprect, state);
+        return moz_gtk_hpaned_paint(cr, rect, cliprect, state);
         break;
     case MOZ_GTK_WINDOW:
-        return moz_gtk_window_paint(drawable, rect, cliprect, direction);
+        return moz_gtk_window_paint(cr, rect, cliprect, direction);
         break;
     default:
         g_warning("Unknown widget type: %d", widget);
     }
 
     return MOZ_GTK_UNKNOWN_WIDGET;
 }
 
--- a/widget/gtk2/gtkdrawing.h
+++ b/widget/gtk2/gtkdrawing.h
@@ -241,38 +241,48 @@ gint moz_gtk_enable_style_props(style_pr
 /**
  * Perform cleanup of the drawing library. You should call this function
  * when your program exits, or you no longer need the library.
  *
  * returns: MOZ_GTK_SUCCESS if there was no error, an error code otherwise
  */
 gint moz_gtk_shutdown();
 
+#if defined(MOZ_WIDGET_GTK2)
 /**
  * Retrieves the colormap to use for drawables passed to moz_gtk_widget_paint.
  */
 GdkColormap* moz_gtk_widget_get_colormap();
+#endif
 
 /*** Widget drawing ***/
+#if defined(MOZ_WIDGET_GTK2)
 /**
  * Paint a widget in the current theme.
  * widget:    a constant giving the widget to paint
  * drawable:  the drawable to paint to;
  *            it's colormap must be moz_gtk_widget_get_colormap().
  * rect:      the bounding rectangle for the widget
  * cliprect:  a clipprect rectangle for this painting operation
  * state:     the state of the widget.  ignored for some widgets.
  * flags:     widget-dependant flags; see the GtkThemeWidgetType definition.
  * direction: the text direction, to draw the widget correctly LTR and RTL.
  */
 gint
 moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable,
                      GdkRectangle* rect, GdkRectangle* cliprect,
                      GtkWidgetState* state, gint flags,
                      GtkTextDirection direction);
+#else
+gint
+moz_gtk_widget_paint(GtkThemeWidgetType widget, cairo_t *cr,
+                     GdkRectangle* rect, GdkRectangle* cliprect,
+                     GtkWidgetState* state, gint flags,
+                     GtkTextDirection direction);
+#endif
 
 
 /*** Widget metrics ***/
 /**
  * Get the border size of a widget
  * left/right:  [OUT] the widget's left/right border
  * top/bottom:  [OUT] the widget's top/bottom border
  * direction:   the text direction for the widget