Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Mon, 02 Jan 2012 18:36:40 -0800
changeset 105495 df210db11b95aadf4b23fc6ba6a3cfa26e40b820
parent 105494 89bcd34af8946a1bc4010d631142b8acce9938d3 (current diff)
parent 83642 44d992ccc97a76b333509576f4ccdf0da89299be (diff)
child 105496 7de07d39318d74b878c531838cb96993daaff957
push id23447
push userdanderson@mozilla.com
push dateTue, 11 Sep 2012 17:34:27 +0000
treeherderautoland@fdfaef738a00 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone12.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from mozilla-central.
browser/base/content/browser-context.inc
browser/base/content/nsContextMenu.js
browser/base/content/test/test_contextmenu.html
browser/components/shell/src/nsGNOMEShellService.cpp
caps/src/nsScriptSecurityManager.cpp
config/autoconf.mk.in
configure.in
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
content/base/src/nsDOMFile.cpp
content/base/src/nsGenericElement.cpp
content/base/src/nsXMLHttpRequest.cpp
content/canvas/src/WebGLContext.h
content/canvas/test/test_canvas.html
content/events/public/nsEventDispatcher.h
content/events/src/nsDOMDataTransfer.cpp
content/events/src/nsDOMEvent.cpp
content/html/content/src/nsHTMLInputElement.cpp
content/media/webm/nsWebMReader.cpp
content/media/webm/nsWebMReader.h
content/svg/content/src/Makefile.in
content/svg/content/src/nsSVGAElement.cpp
content/svg/content/src/nsSVGAElement.h
content/svg/content/src/nsSVGAltGlyphElement.cpp
content/svg/content/src/nsSVGAnimateMotionElement.cpp
content/svg/content/src/nsSVGAnimateTransformElement.cpp
content/svg/content/src/nsSVGAnimationElement.cpp
content/svg/content/src/nsSVGAnimationElement.h
content/svg/content/src/nsSVGDefsElement.cpp
content/svg/content/src/nsSVGElement.cpp
content/svg/content/src/nsSVGElement.h
content/svg/content/src/nsSVGElementList.h
content/svg/content/src/nsSVGFeatures.cpp
content/svg/content/src/nsSVGFeatures.h
content/svg/content/src/nsSVGFilterElement.cpp
content/svg/content/src/nsSVGFilterElement.h
content/svg/content/src/nsSVGForeignObjectElement.cpp
content/svg/content/src/nsSVGForeignObjectElement.h
content/svg/content/src/nsSVGGElement.cpp
content/svg/content/src/nsSVGGradientElement.cpp
content/svg/content/src/nsSVGGradientElement.h
content/svg/content/src/nsSVGImageElement.cpp
content/svg/content/src/nsSVGLineElement.cpp
content/svg/content/src/nsSVGMaskElement.cpp
content/svg/content/src/nsSVGMaskElement.h
content/svg/content/src/nsSVGPathElement.cpp
content/svg/content/src/nsSVGPathGeometryElement.cpp
content/svg/content/src/nsSVGPathGeometryElement.h
content/svg/content/src/nsSVGPatternElement.cpp
content/svg/content/src/nsSVGPatternElement.h
content/svg/content/src/nsSVGRectElement.cpp
content/svg/content/src/nsSVGSVGElement.cpp
content/svg/content/src/nsSVGSVGElement.h
content/svg/content/src/nsSVGSwitchElement.cpp
content/svg/content/src/nsSVGSwitchElement.h
content/svg/content/src/nsSVGSymbolElement.cpp
content/svg/content/src/nsSVGTSpanElement.cpp
content/svg/content/src/nsSVGTextElement.cpp
content/svg/content/src/nsSVGTextPathElement.cpp
content/svg/content/src/nsSVGUseElement.cpp
content/svg/content/src/nsSVGUseElement.h
content/xul/document/src/nsXULDocument.cpp
docshell/base/nsDocShell.cpp
dom/base/nsBarProps.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
dom/base/nsDOMClassInfoClasses.h
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/workers/RuntimeService.cpp
dom/workers/WorkerPrivate.cpp
editor/libeditor/base/nsEditor.cpp
editor/libeditor/base/nsEditorCommands.cpp
editor/libeditor/html/nsHTMLDataTransfer.cpp
editor/libeditor/html/nsHTMLEditor.h
editor/libeditor/text/nsPlaintextEditor.cpp
editor/txmgr/src/nsTransactionManager.cpp
editor/txmgr/src/nsTransactionManager.h
embedding/components/find/src/nsWebBrowserFind.cpp
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
extensions/spellcheck/src/mozInlineSpellChecker.cpp
gfx/thebes/gfxPangoFonts.cpp
gfx/ycbcr/QuellGccWarnings.patch
ipc/chromium/src/build/build_config.h
js/src/config/autoconf.mk.in
js/src/configure.in
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/BytecodeEmitter.h
js/src/frontend/FoldConstants.cpp
js/src/frontend/ParseNode.cpp
js/src/frontend/ParseNode.h
js/src/frontend/Parser.cpp
js/src/gc/Barrier.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsgcinlines.h
js/src/jsinfer.cpp
js/src/jsinfer.h
js/src/jsinterp.cpp
js/src/jsiter.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsprobes.cpp
js/src/jspropertycache.cpp
js/src/jsproxy.cpp
js/src/jsprvtd.h
js/src/jsreflect.cpp
js/src/jsscope.cpp
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jsstr.cpp
js/src/jstypedarray.cpp
js/src/jsxml.cpp
js/src/methodjit/Compiler.cpp
js/src/methodjit/Compiler.h
js/src/methodjit/StubCalls.cpp
js/src/shell/js.cpp
js/src/vm/Debugger.cpp
js/src/vm/GlobalObject.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsDisplayList.cpp
layout/base/nsDocumentViewer.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/base/nsPresShell.cpp
layout/base/tests/test_reftests_with_caret.html
layout/forms/nsComboboxControlFrame.cpp
layout/generic/TextOverflow.cpp
layout/generic/crashtests/crashtests.list
layout/generic/nsFrame.cpp
layout/generic/nsHTMLReflowMetrics.h
layout/generic/nsIFrame.h
layout/generic/nsLineLayout.cpp
layout/generic/nsSelection.cpp
layout/generic/nsTextFrameThebes.cpp
layout/reftests/bugs/reftest.list
layout/reftests/reftest-sanity/reftest.list
layout/reftests/svg/reftest.list
layout/style/nsCSSStyleSheet.h
layout/style/nsComputedDOMStyle.cpp
layout/svg/base/src/nsSVGForeignObjectFrame.cpp
layout/svg/base/src/nsSVGForeignObjectFrame.h
layout/svg/base/src/nsSVGOuterSVGFrame.cpp
layout/svg/base/src/nsSVGOuterSVGFrame.h
layout/tables/crashtests/crashtests.list
layout/tables/nsCellMap.cpp
layout/tools/reftest/reftest.js
layout/tools/reftest/remotereftest.py
mfbt/Util.h
mobile/android/base/GeckoApp.java
modules/libpref/src/init/all.js
netwerk/dns/nsDNSService2.cpp
testing/mochitest/runtestsremote.py
testing/testsuite-targets.mk
toolkit/components/aboutmemory/content/aboutMemory.js
toolkit/components/telemetry/TelemetryPing.js
toolkit/content/widgets/videocontrols.css
toolkit/mozapps/extensions/AddonRepository.jsm
toolkit/mozapps/extensions/XPIProvider.jsm
toolkit/mozapps/installer/packager.mk
widget/src/android/nsWindow.cpp
xpcom/base/nsCycleCollector.cpp
xpcom/base/nsMemoryReporterManager.cpp
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1324588296000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1325216886000">
   <emItems>
       <emItem  blockID="i41" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
                         <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i8" id="{B13721C7-F507-4982-B2E5-502A71474FED}">
                         <versionRange  minVersion=" " severity="1">
                     </versionRange>
@@ -111,16 +111,18 @@
       <emItem  blockID="i6" id="{3f963a5b-e555-4543-90e2-c3908898db71}">
                         <versionRange  minVersion=" " maxVersion="8.5">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i12" id="masterfiler@gmail.com">
                         <versionRange  severity="3">
                     </versionRange>
                   </emItem>
+      <emItem  blockID="i48" id="admin@youtubespeedup.com">
+                        </emItem>
       <emItem  blockID="i20" id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
                         <versionRange  minVersion="0.1" maxVersion="5.2.0.7164" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i47" id="youtube@youtube2.com">
                         </emItem>
       <emItem  blockID="i17" id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
                         <versionRange  minVersion="2.2" maxVersion="2.2">
--- a/browser/base/content/browser-context.inc
+++ b/browser/base/content/browser-context.inc
@@ -41,16 +41,20 @@
       <menuseparator id="page-menu-separator"/>
       <menuitem id="spell-no-suggestions"
                 disabled="true"
                 label="&spellNoSuggestions.label;"/>
       <menuitem id="spell-add-to-dictionary"
                 label="&spellAddToDictionary.label;"
                 accesskey="&spellAddToDictionary.accesskey;"
                 oncommand="InlineSpellCheckerUI.addToDictionary();"/>
+      <menuitem id="spell-undo-add-to-dictionary"
+                label="&spellUndoAddToDictionary.label;"
+                accesskey="&spellUndoAddToDictionary.accesskey;"
+                oncommand="InlineSpellCheckerUI.undoAddToDictionary();" />
       <menuseparator id="spell-suggestions-separator"/>
       <menuitem id="context-openlinkincurrent"
                 label="&openLinkCmdInCurrent.label;"
                 accesskey="&openLinkCmdInCurrent.accesskey;"
                 oncommand="gContextMenu.openLinkInCurrent();"/>
       <menuitem id="context-openlinkintab"
                 label="&openLinkCmdInTab.label;"
                 accesskey="&openLinkCmdInTab.accesskey;"
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -332,16 +332,17 @@ nsContextMenu.prototype = {
     var canSpell = InlineSpellCheckerUI.canSpellCheck;
     var onMisspelling = InlineSpellCheckerUI.overMisspelling;
     this.showItem("spell-check-enabled", canSpell);
     this.showItem("spell-separator", canSpell || this.onEditableArea);
     document.getElementById("spell-check-enabled")
             .setAttribute("checked", canSpell && InlineSpellCheckerUI.enabled);
 
     this.showItem("spell-add-to-dictionary", onMisspelling);
+    this.showItem("spell-undo-add-to-dictionary", InlineSpellCheckerUI.canUndo());
 
     // suggestion list
     this.showItem("spell-suggestions-separator", onMisspelling);
     if (onMisspelling) {
       var suggestionsSeparator =
         document.getElementById("spell-add-to-dictionary");
       var numsug =
         InlineSpellCheckerUI.addSuggestionsToMenu(suggestionsSeparator.parentNode,
--- a/browser/base/content/test/test_bug364677.html
+++ b/browser/base/content/test/test_bug364677.html
@@ -18,17 +18,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 364677 **/
 SimpleTest.waitForExplicitFinish();
 
 addLoadEvent(function() {
   // Need privs because the feed seems to have an about:feeds principal or some
   // such.  It's not same-origin with us in any case.
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   is($("testFrame").contentDocument.documentElement.id, "feedHandler",
      "Feed served as text/xml without a channel/link should have been sniffed");
 });
 addLoadEvent(SimpleTest.finish);
 </script>
 </pre>
 </body>
 </html>
--- a/browser/base/content/test/test_bug395533.html
+++ b/browser/base/content/test/test_bug395533.html
@@ -18,17 +18,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 395533 **/
 SimpleTest.waitForExplicitFinish();
 
 addLoadEvent(function() {
   // Need privs because the feed seems to have an about:feeds principal or some
   // such.  It's not same-origin with us in any case.
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   is($("testFrame").contentDocument.documentElement.id, "",
      "Text got sniffed as a feed?");
 });
 addLoadEvent(SimpleTest.finish);
 
 
 
 
--- a/browser/base/content/test/test_contextmenu.html
+++ b/browser/base/content/test/test_contextmenu.html
@@ -14,16 +14,17 @@ Browser context menu tests.
 </div>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Login Manager: multiple login autocomplete. **/
 
 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+Components.utils.import("resource://gre/modules/InlineSpellChecker.jsm");
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 function openContextMenuFor(element, shiftkey, shouldWaitForFocus) {
     // Context menu should be closed before we open it again.
     is(contextMenu.state, "closed", "checking if popup is closed");
 
@@ -509,22 +510,46 @@ function runTest(testNum) {
                           "context-selectall",   true,
                           "---",                 null,
                           "spell-check-enabled", true,
                           "spell-dictionaries",  true,
                               ["spell-check-dictionary-en-US", true,
                                "---",                          null,
                                "spell-add-dictionaries",       true], null,
                          ].concat(inspectItems));
-
+        contextMenu.ownerDocument.getElementById("spell-add-to-dictionary").doCommand(); // Add to dictionary
         closeContextMenu();
-        openContextMenuFor(contenteditable); // Invoke context menu for next test.
+        openContextMenuFor(textarea, false, true); // Invoke context menu for next test.
+        break;
+    
+    case 15:    
+        // Context menu for textarea after a word has been added
+        // to the dictionary
+        checkContextMenu(["spell-undo-add-to-dictionary", true,
+                          "context-undo",        false,
+                          "---",                 null,
+                          "context-cut",         false,
+                          "context-copy",        false,
+                          "context-paste",       null, // ignore clipboard state
+                          "context-delete",      false,
+                          "---",                 null,
+                          "context-selectall",   true,
+                          "---",                 null,
+                          "spell-check-enabled", true,
+                          "spell-dictionaries",  true,
+                              ["spell-check-dictionary-en-US", true,
+                               "---",                          null,
+                               "spell-add-dictionaries",       true], null,
+                         ].concat(inspectItems));
+        contextMenu.ownerDocument.getElementById("spell-undo-add-to-dictionary").doCommand(); // Undo add to dictionary
+        closeContextMenu();
+        openContextMenuFor(contenteditable);
         break;
 
-    case 15:
+    case 16:
         // Context menu for contenteditable
         checkContextMenu(["spell-no-suggestions", false,
                           "spell-add-to-dictionary", true,
                           "---",                 null,
                           "context-undo",        false,
                           "---",                 null,
                           "context-cut",         false,
                           "context-copy",        false,
@@ -539,17 +564,17 @@ function runTest(testNum) {
                                "---",                          null,
                                "spell-add-dictionaries",       true], null
                          ].concat(inspectItems));
 
         closeContextMenu();
         openContextMenuFor(inputspell); // Invoke context menu for next test.
         break;
 
-    case 16:
+    case 17:
         // Context menu for spell-check input
         checkContextMenu(["*prodigality",        true, // spelling suggestion
                           "spell-add-to-dictionary", true,
                           "---",                 null,
                           "context-undo",        false,
                           "---",                 null,
                           "context-cut",         false,
                           "context-copy",        false,
@@ -564,23 +589,23 @@ function runTest(testNum) {
                                "---",                          null,
                                "spell-add-dictionaries",       true], null
                          ].concat(inspectItems));
 
         closeContextMenu();
         openContextMenuFor(link); // Invoke context menu for next test.
         break;
 
-    case 17:
+    case 18:
         executeCopyCommand("cmd_copyLink", "http://mozilla.com/");
         closeContextMenu();
         openContextMenuFor(pagemenu); // Invoke context menu for next test.
         break;
 
-    case 18:
+    case 19:
         // Context menu for element with assigned content context menu
         checkContextMenu(["+Plain item",          {type: "", icon: "", checked: false, disabled: false},
                           "+Disabled item",       {type: "", icon: "", checked: false, disabled: true},
                           "+Item w/ textContent", {type: "", icon: "", checked: false, disabled: false},
                           "---",                  null,
                           "+Checkbox",            {type: "checkbox", icon: "", checked: true, disabled: false},
                           "---",                  null,
                           "+Radio1",              {type: "checkbox", icon: "", checked: true, disabled: false},
@@ -613,17 +638,17 @@ function runTest(testNum) {
                           "context-viewinfo",     true
                          ].concat(inspectItems));
 
         invokeItemAction("0");
         closeContextMenu();
         openContextMenuFor(pagemenu, true); // Invoke context menu for next test.
         break;
 
-    case 19:
+    case 20:
         // Context menu for element with assigned content context menu
         // The shift key should bypass content context menu processing
         checkContextMenu(["context-back",         false,
                           "context-forward",      false,
                           "context-reload",       true,
                           "context-stop",         false,
                           "---",                  null,
                           "context-bookmarkpage", true,
--- a/browser/base/content/test/test_feed_discovery.html
+++ b/browser/base/content/test/test_feed_discovery.html
@@ -18,21 +18,19 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 377611 **/
 
 var rv = { tests: null };
 var testCheckInterval = null;
 
 function startTest() {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-
   var url = window.location.href.replace(/test_feed_discovery\.html/,
                                          'feed_discovery.html');
-  window.openDialog(url, '', 'dialog=no,width=10,height=10', rv);
+  SpecialPowers.openDialog(window, [url, '', 'dialog=no,width=10,height=10', rv]);
   testCheckInterval = window.setInterval(tryIfTestIsFinished, 500);
 }
 
 function tryIfTestIsFinished() {
   if (rv.tests) {
     window.clearInterval(testCheckInterval);
     checkTest();
   }
--- a/browser/components/feeds/test/test_bug494328.html
+++ b/browser/components/feeds/test/test_bug494328.html
@@ -16,17 +16,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 494328 **/
 SimpleTest.waitForExplicitFinish();
 
 addLoadEvent(function() {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   var links = $("testFrame").contentDocument.getElementById("feedContent").querySelectorAll("div.enclosure > a");
   is(links[0].textContent, "Episode 1", "filename decoded incorrectly");
   is(links[1].textContent, "Episode #2", "filename decoded incorrectly");
   is(links[2].textContent, "http://www.example.com/podcasts/Episode #3/", "filename decoded incorrectly");
   is(links[3].textContent, "Is This Episode #4?", "filename decoded incorrectly");
 });
 addLoadEvent(SimpleTest.finish);
 
--- a/browser/components/sessionstore/content/aboutSessionRestore.js
+++ b/browser/components/sessionstore/content/aboutSessionRestore.js
@@ -135,17 +135,17 @@ function restoreSession() {
   var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
   var top = getBrowserWindow();
   
   // if there's only this page open, reuse the window for restoring the session
   if (top.gBrowser.tabs.length == 1) {
     ss.setWindowState(top, stateString, true);
     return;
   }
-  
+
   // restore the session into a new window and close the current tab
   var newWindow = top.openDialog(top.location, "_blank", "chrome,dialog=no,all");
   newWindow.addEventListener("load", function() {
     newWindow.removeEventListener("load", arguments.callee, true);
     ss.setWindowState(newWindow, stateString, true);
     
     var tabbrowser = top.gBrowser;
     var tabIndex = tabbrowser.getBrowserIndexForDocument(document);
--- a/browser/components/shell/src/nsGNOMEShellService.cpp
+++ b/browser/components/shell/src/nsGNOMEShellService.cpp
@@ -312,21 +312,19 @@ nsGNOMEShellService::SetDefaultBrowser(b
     nsCOMPtr<nsIStringBundleService> bundleService =
       do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIStringBundle> brandBundle;
     rv = bundleService->CreateBundle(BRAND_PROPERTIES, getter_AddRefs(brandBundle));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    nsString brandShortName, brandFullName;
+    nsString brandShortName;
     brandBundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(),
                                    getter_Copies(brandShortName));
-    brandBundle->GetStringFromName(NS_LITERAL_STRING("brandFullName").get(),
-                                   getter_Copies(brandFullName));
 
     // use brandShortName as the application id.
     NS_ConvertUTF16toUTF8 id(brandShortName);
     nsCOMPtr<nsIGIOMimeApp> appInfo;
     rv = giovfs->CreateAppFromCommand(mAppPath,
                                       id,
                                       getter_AddRefs(appInfo));
     NS_ENSURE_SUCCESS(rv, rv);
--- a/browser/themes/gnomestripe/browser.css
+++ b/browser/themes/gnomestripe/browser.css
@@ -1020,22 +1020,17 @@ toolbar[iconsize="small"] #feed-button {
   margin-bottom: 0;
   color: GrayText;
 }
 
 /* Favicon */
 #page-proxy-favicon {
   width: 16px;
   height: 16px;
-}
-
-#page-proxy-stack {
-  width: 24px;
-  height: 20px;
-  padding: 2px 4px;
+  margin: 2px 4px;
 }
 
 #page-proxy-favicon:not([src]) {
   list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
 }
 
 #page-proxy-favicon[pageproxystate="invalid"] {
   opacity: 0.3;
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -1106,21 +1106,16 @@ toolbar[mode="icons"] #zoom-in-button {
 
 #page-proxy-favicon {
   width: 16px;
   height: 16px;
   margin: 0px;
   padding: 0px;
 }
 
-#page-proxy-stack {
-  width: 16px;
-  height: 16px;
-}
-
 #page-proxy-favicon:not([src]) {
   list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
 }
 
 #page-proxy-favicon[pageproxystate="invalid"] {
   opacity: 0.5;
 }
 
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -1485,22 +1485,17 @@ html|*.urlbar-input:-moz-lwtheme:-moz-pl
   -moz-image-region: rect(0px, 33px, 14px, 22px);
 }
 
 /* page proxy icon */
 
 #page-proxy-favicon {
   width: 16px;
   height: 16px;
-}
-
-#page-proxy-stack {
-  width: 24px;
-  height: 18px;
-  padding: 1px 4px;
+  margin: 1px 4px;
 }
 
 #page-proxy-favicon:not([src]) {
   list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
 }
 
 #page-proxy-favicon[pageproxystate="invalid"] {
   opacity: 0.5;
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -57,16 +57,17 @@ DIRS += pgo
 
 ifdef ENABLE_TESTS
   DIRS += autoconf/test
 ifeq (android,$(MOZ_WIDGET_TOOLKIT))
   DIRS += mobile/sutagent/android \
           mobile/sutagent/android/watcher \
           mobile/sutagent/android/ffxcp \
           mobile/sutagent/android/fencp \
+          mobile/robocop \
           $(NULL)
 endif
 endif
 
 ifdef MOZ_APP_BASENAME
 DIST_FILES = application.ini
 
 ifdef LIBXUL_SDK
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -404,33 +404,27 @@ user_pref("extensions.getAddons.maxResul
 user_pref("extensions.getAddons.get.url", "http://%(server)s/extensions-dummy/repositoryGetURL");
 user_pref("extensions.getAddons.search.browseURL", "http://%(server)s/extensions-dummy/repositoryBrowseURL");
 user_pref("extensions.getAddons.search.url", "http://%(server)s/extensions-dummy/repositorySearchURL");
 """ % { "server" : self.webServer + ":" + str(self.httpPort) }
     prefs.append(part)
 
     if useServerLocations == False:
       part = """
-user_pref("capability.principal.codebase.p1.granted",
-          "UniversalXPConnect UniversalBrowserRead UniversalBrowserWrite \
-           UniversalPreferencesRead UniversalPreferencesWrite \
-           UniversalFileRead");
+user_pref("capability.principal.codebase.p1.granted", "UniversalXPConnect");
 user_pref("capability.principal.codebase.p1.id", "%(origin)s");
 user_pref("capability.principal.codebase.p1.subjectName", "");
 """  % { "origin": "http://" + self.webServer + ":" + str(self.httpPort) }
       prefs.append(part)
     else:
       # Grant God-power to all the privileged servers on which tests run.
       privileged = filter(lambda loc: "privileged" in loc.options, locations)
       for (i, l) in itertools.izip(itertools.count(1), privileged):
         part = """
-user_pref("capability.principal.codebase.p%(i)d.granted",
-          "UniversalXPConnect UniversalBrowserRead UniversalBrowserWrite \
-           UniversalPreferencesRead UniversalPreferencesWrite \
-           UniversalFileRead");
+user_pref("capability.principal.codebase.p%(i)d.granted", "UniversalXPConnect");
 user_pref("capability.principal.codebase.p%(i)d.id", "%(origin)s");
 user_pref("capability.principal.codebase.p%(i)d.subjectName", "");
 """  % { "i": i,
          "origin": (l.scheme + "://" + l.host + ":" + str(l.port)) }
         prefs.append(part)
 
       # We need to proxy every server but the primary one.
       origins = ["'%s://%s:%s'" % (l.scheme, l.host, l.port)
new file mode 100644
--- /dev/null
+++ b/build/mobile/robocop/Assert.java.in
@@ -0,0 +1,53 @@
+#filter substitution
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Firefox Mobile Test Framework.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Trevor Fairey <tnfairey@gmail.com>
+ * David Burns <dburns@mozilla.com>
+ * Joel Maher <joel.maher@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package @ANDROID_PACKAGE_NAME@;
+
+public interface Assert {
+  void dumpLog(String message);
+  void setLogFile(String filename);
+
+  void ok(boolean condition, String name, String diag);
+  void is(Object a, Object b, String name);
+  void isnot(Object a, Object b, String name);
+  void todo(boolean condition, String name, String diag);
+  void todo_is(Object a, Object b, String name);
+  void todo_isnot(Object a, Object b, String name);
+  void info(String name, String message);
+}
new file mode 100644
--- /dev/null
+++ b/build/mobile/robocop/FennecNativeAssert.java.in
@@ -0,0 +1,212 @@
+#filter substitution
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Firefox Mobile Test Framework.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Trevor Fairey <tnfairey@gmail.com>
+ * David Burns <dburns@mozilla.com>
+ * Joel Maher <joel.maher@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package @ANDROID_PACKAGE_NAME@;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.HashMap;
+import java.util.List;
+
+import java.lang.Class;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.InvocationHandler;
+import java.lang.Long;
+
+import android.app.Activity;
+import android.util.Log;
+import android.view.View;
+
+import org.json.*;
+
+import com.jayway.android.robotium.solo.Solo;
+
+public class FennecNativeAssert implements Assert {
+  // Map of IDs to element names.
+  private HashMap locators = null;
+  private String logFile = null;
+  
+  // Objects for reflexive access of fennec classes.
+
+  private LinkedList<testInfo> testList = new LinkedList<testInfo>();
+
+  // If waiting for an event.
+  private boolean asleep = false;
+
+  public FennecNativeAssert(){
+  }
+
+  // Write information to a logfile and logcat
+  public void dumpLog(String message)
+  {
+    File file = new File(logFile);
+    BufferedWriter bw = null;
+
+    try {
+      bw = new BufferedWriter(new FileWriter(logFile, true));
+      bw.write(message);
+      bw.newLine();
+    } catch(IOException e) {
+      Log.e("Robocop", "exception with file writer on: " + logFile);
+    } finally {
+      try {
+        if (bw != null) {
+          bw.flush();
+          bw.close();
+        }
+      } catch (IOException ex) {
+        ex.printStackTrace();
+      }
+    }
+
+    Log.i("Robocop", message);
+  }
+
+  // Set the filename used for dumpLog.
+  public void setLogFile(String filename)
+  {
+    logFile = filename;
+  }
+
+
+  class testInfo {
+    public boolean result;
+    public String name;
+    public String diag;
+    public boolean todo;
+    public testInfo(boolean r, String n, String d, boolean t) {
+      result = r;
+      name = n;
+      diag = d;
+      todo = t;
+    }
+
+  }
+
+
+  private void _logResult(testInfo test, String passString, String failString)
+  {
+    boolean isError = true;
+    String resultString = failString;
+    if(test.result || test.todo){
+      isError = false;
+    }
+    if(test.result)
+    {
+      resultString = passString;
+    }
+    String diag= test.name;
+    if(test.diag!=null) diag+= " - " + test.diag;
+
+    String message = resultString + " | " + "ROBOCOP" + " | " + diag;
+    if(isError) {
+      if(logFile == null)
+      {
+        assert(false);
+      }
+      else {
+        dumpLog(message);
+      }
+    }
+    else {
+      dumpLog(message);
+    }
+  }
+
+  public void ok(boolean condition, String name, String diag) {
+    testInfo test = new testInfo(condition, name, diag, false);
+    _logResult(test, "TEST-PASS", "TEST-UNEXPECTED-FAIL");
+    testList.add(test);
+  }
+
+  public void is(Object a, Object b, String name) {
+    boolean pass = a.equals(b);
+    String diag = "got " + a.toString() + ", expected " + b.toString();
+    if(pass) {
+      diag = a.toString() + " should equal " + b.toString();
+    }
+    ok(pass, name, diag);
+  }
+  
+  public void isnot(Object a, Object b, String name) {
+    boolean pass = !a.equals(b);
+    String diag = "didn't expect " + a.toString() + ", but got it";
+    if(pass) {
+      diag = a.toString() + " should not equal " + b.toString();
+    }
+    ok(pass, name, diag);
+  }
+
+  public void todo(boolean condition, String name, String diag) {
+    testInfo test = new testInfo(condition, name, diag, true);
+    _logResult(test, "TEST-UNEXPECTED-PASS", "TEST-KNOWN-FAIL");
+    testList.add(test);
+  }
+
+  public void todo_is(Object a, Object b, String name) {
+    boolean pass = a.equals(b);
+    String diag = "got " + a.toString() + ", expected " + b.toString();
+    if(pass) {
+      diag = a.toString() + " should equal " + b.toString();
+    }
+    todo(pass, name, diag);
+  }
+  
+  public void todo_isnot(Object a, Object b, String name) {
+    boolean pass = !a.equals(b);
+    String diag = "didn't expect " + a.toString() + ", but got it";
+    if(pass) {
+      diag = a.toString() + " should not equal " + b.toString();
+    }
+    todo(pass, name, diag);
+  }
+
+  public void info(String name, String message) {
+    testInfo test = new testInfo(true, name, message, false);
+    _logResult(test, "TEST-INFO", "INFO FAILED?");
+  }
+}
--- a/build/mobile/robocop/Makefile.in
+++ b/build/mobile/robocop/Makefile.in
@@ -46,26 +46,35 @@ include $(DEPTH)/config/autoconf.mk
 MODULE = robocop
 
 ROBOTIUM_PATH = $(srcdir)/robotium-solo-3.0.jar
 
 JAVAFILES = \
   R.java \
 
 _JAVA_HARNESS = \
+  Actions.java \
+  Assert.java \
   Driver.java \
   Element.java \
-  Actions.java \
+  FennecNativeActions.java \
+  FennecNativeAssert.java \
+  FennecNativeDriver.java \
   FennecNativeElement.java \
   RoboCopException.java \
-  FennecNativeDriver.java \
-  FennecNativeActions.java \
+  $(NULL)
 
 _JAVA_TESTS = $(patsubst $(TESTPATH)/%.in,%,$(wildcard $(TESTPATH)/*.java.in))
 
+_TEST_FILES = \
+  $(TESTPATH)/robocop_blank_01.html \
+  $(TESTPATH)/robocop_blank_02.html \
+  $(TESTPATH)/robocop_blank_03.html \
+  $(NULL)
+
 _ROBOCOP_TOOLS = \
   $(TESTPATH)/robocop.ini \
   parse_ids.py \
   $(NULL)
 
 GARBAGE += \
   AndroidManifest.xml \
   _JAVA_TESTS \
@@ -99,38 +108,38 @@ AndroidManifest.xml: % : %.in
 $(_JAVA_TESTS): % : $(TESTPATH)/%.in
 	$(NSINSTALL) -D $(DEPTH)/mobile/android/base/tests
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $< > $(DEPTH)/mobile/android/base/tests/$@
 
 $(_ROBOCOP_TOOLS):
 	cp $(TESTPATH)/robocop.ini robocop.ini
 	cp $(srcdir)/parse_ids.txt parse_ids.txt
 
+libs:: $(_TEST_FILES)
+	$(NSINSTALL) -D $(DEPTH)/_tests/testing/mochitest/tests/robocop
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/robocop/
+
 tools:: robocop.apk
 
 classes.dex: robocop.ap_
 classes.dex: $(_ROBOCOP_TOOLS)
 classes.dex: $(_JAVA_HARNESS)
 classes.dex: $(_JAVA_TESTS)
-classes.dex: $(TEST_FILES)
 	$(NSINSTALL) -D classes
 	$(JAVAC) $(JAVAC_FLAGS) -d classes $(JAVAFILES) $(_JAVA_HARNESS) $(addprefix $(DEPTH)/mobile/android/base/tests/,$(_JAVA_TESTS))
 	$(DX) --dex --output=$@ classes $(ROBOTIUM_PATH)
 
 robocop.ap_: AndroidManifest.xml
 	$(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -I . -S res -F $@ -J ./
 
-robocop-unsigned-unaligned.apk: robocop.ap_ classes.dex
-	$(APKBUILDER) $@ -v $(APKBUILDER_FLAGS) -z robocop.ap_ -f classes.dex
-
-robocop-unaligned.apk: robocop-unsigned-unaligned.apk
-	cp robocop-unsigned-unaligned.apk $@
-	jarsigner -keystore ~/.android/debug.keystore -storepass android -keypass android $@ androiddebugkey
-
-robocop.apk: robocop-unaligned.apk
-	$(ZIPALIGN) -f -v 4 robocop-unaligned.apk $@
+robocop.apk: robocop.ap_ classes.dex
+	$(APKBUILDER) robocop-raw.apk -v $(APKBUILDER_FLAGS) -z robocop.ap_ -f classes.dex
+ifdef JARSIGNER
+	$(JARSIGNER) robocop-raw.apk
+endif
+	$(ZIPALIGN) -f -v 4 robocop-raw.apk $@
 	cp $(TESTPATH)/robocop.ini robocop.ini
 	cp $(srcdir)/parse_ids.py parse_ids.py
 
 export::
 	$(NSINSTALL) -D res
 	@(cd $(srcdir)/res && tar $(TAR_CREATE_FLAGS) - *) | (cd $(DEPTH)/build/mobile/robocop/res && tar -xf -)
 
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -1084,29 +1084,16 @@ nsScriptSecurityManager::CheckSameOrigin
 
     /*
     * Content can't ever touch chrome (we check for UniversalXPConnect later)
     */
     if (aObject == mSystemPrincipal)
         return NS_ERROR_DOM_PROP_ACCESS_DENIED;
 
     /*
-    * If we failed the origin tests it still might be the case that we
-    * are a signed script and have permissions to do this operation.
-    * Check for that here.
-    */
-    bool capabilityEnabled = false;
-    const char* cap = aAction == nsIXPCSecurityManager::ACCESS_SET_PROPERTY ?
-                      "UniversalBrowserWrite" : "UniversalBrowserRead";
-    rv = IsCapabilityEnabled(cap, &capabilityEnabled);
-    NS_ENSURE_SUCCESS(rv, rv);
-    if (capabilityEnabled)
-        return NS_OK;
-
-    /*
     ** Access tests failed, so now report error.
     */
     return NS_ERROR_DOM_PROP_ACCESS_DENIED;
 }
 
 nsresult
 nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
                                       ClassInfoData& aClassData,
@@ -1316,26 +1303,26 @@ nsScriptSecurityManager::CheckLoadURIFro
     rv = CheckLoadURIWithPrincipal(principal, aURI,
                                    nsIScriptSecurityManager::STANDARD);
     if (NS_SUCCEEDED(rv)) {
         // OK to load
         return NS_OK;
     }
 
     // See if we're attempting to load a file: URI. If so, let a
-    // UniversalFileRead capability trump the above check.
+    // UniversalXPConnect capability trump the above check.
     bool isFile = false;
     bool isRes = false;
     if (NS_FAILED(aURI->SchemeIs("file", &isFile)) ||
         NS_FAILED(aURI->SchemeIs("resource", &isRes)))
         return NS_ERROR_FAILURE;
     if (isFile || isRes)
     {
         bool enabled;
-        if (NS_FAILED(IsCapabilityEnabled("UniversalFileRead", &enabled)))
+        if (NS_FAILED(IsCapabilityEnabled("UniversalXPConnect", &enabled)))
             return NS_ERROR_FAILURE;
         if (enabled)
             return NS_OK;
     }
 
     // Report error.
     nsCAutoString spec;
     if (NS_FAILED(aURI->GetAsciiSpec(spec)))
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -215,20 +215,16 @@ MOZ_FIX_LINK_PATHS=@MOZ_FIX_LINK_PATHS@
 
 XPCOM_FROZEN_LDOPTS=@XPCOM_FROZEN_LDOPTS@
 XPCOM_LIBS=@XPCOM_LIBS@
 LIBXUL_LIBS=@LIBXUL_LIBS@
 
 ENABLE_STRIP	= @ENABLE_STRIP@
 PKG_SKIP_STRIP	= @PKG_SKIP_STRIP@
 
-ClientWallet=1
-CookieManagement=1
-SingleSignon=1
-
 MOZ_POST_DSO_LIB_COMMAND = @MOZ_POST_DSO_LIB_COMMAND@
 MOZ_POST_PROGRAM_COMMAND = @MOZ_POST_PROGRAM_COMMAND@
 
 MOZ_BUILD_ROOT             = @MOZ_BUILD_ROOT@
 
 MOZ_XUL                    = @MOZ_XUL@
 
 NECKO_PROTOCOLS = @NECKO_PROTOCOLS@
@@ -591,19 +587,16 @@ export CL_INCLUDES_PREFIX = @CL_INCLUDES
 MOZ_AUTO_DEPS	= @MOZ_AUTO_DEPS@
 COMPILER_DEPEND = @COMPILER_DEPEND@
 MDDEPDIR        := @MDDEPDIR@
 CC_WRAPPER = @CC_WRAPPER@
 CXX_WRAPPER = @CXX_WRAPPER@
 
 MOZ_DEMANGLE_SYMBOLS = @MOZ_DEMANGLE_SYMBOLS@
 
-# XXX - these need to be cleaned up and have real checks added -cls
-CM_BLDTYPE=dbg
-AWT_11=1
 OS_TARGET=@OS_TARGET@
 OS_ARCH=@OS_ARCH@
 OS_RELEASE=@OS_RELEASE@
 OS_TEST=@OS_TEST@
 CPU_ARCH=@CPU_ARCH@
 INTEL_ARCHITECTURE=@INTEL_ARCHITECTURE@
 
 # For Solaris build
--- a/configure.in
+++ b/configure.in
@@ -331,16 +331,17 @@ if test -n "$gonkdir" ; then
     if test -z "$HOST_CXXFLAGS" ; then
         HOST_CXXFLAGS=" "
     fi
     if test -z "$HOST_LDFLAGS" ; then
         HOST_LDFLAGS=" "
     fi
 
     AC_DEFINE(ANDROID)
+    AC_DEFINE(HAVE_SYS_UIO_H)
     CROSS_COMPILE=1
     MOZ_CHROME_FILE_FORMAT=omni
     ZLIB_DIR=yes
     direct_nspr_config=1
 else
 case "$target" in
 *-android*|*-linuxandroid*)
     if test -z "$android_ndk" ; then
@@ -1859,65 +1860,46 @@ if test "$GNU_CC"; then
     fi
     WARNINGS_AS_ERRORS='-Werror'
     DSO_CFLAGS=''
     DSO_PIC_CFLAGS='-fPIC'
     ASFLAGS="$ASFLAGS -fPIC"
     _MOZ_RTTI_FLAGS_ON=-frtti
     _MOZ_RTTI_FLAGS_OFF=-fno-rtti
 
-    # Turn on GNU-specific warnings:
-    # -Wall - turn on a lot of warnings
-    # -pedantic - this is turned on below
-    # -Wpointer-arith - enabled with -pedantic, but good to have even if not
-    # -Werror=declaration-after-statement - MSVC doesn't like these
-    # -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
-    #
-    _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall -Wpointer-arith -Wdeclaration-after-statement -Wempty-body"
-    
-    # Turn off the following warnings that -Wall/-pedantic turn on:
-    # -Woverlength-strings - we exceed the minimum maximum length all the time
-    #
-    _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wno-overlength-strings"
-
+    # Turn on GNU specific features
+    # -Wall - turn on all warnings
+    # -pedantic - make compiler warn about non-ANSI stuff, and
+    #             be a little bit stricter
+    # -Wdeclaration-after-statement - MSVC doesn't like these
+    # Warnings slamm took out for now (these were giving more noise than help):
+    # -Wbad-function-cast - warns when casting a function to a new return type
+    # -Wshadow - removed because it generates more noise than help --pete
+    _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall -W -Wno-unused -Wpointer-arith -Wdeclaration-after-statement"
     if test -z "$INTEL_CC" -a -z "$CLANG_CC"; then
        # Don't use -Wcast-align with ICC or clang
        case "$CPU_ARCH" in
            # And don't use it on hppa, ia64, sparc, arm, since it's noisy there
            hppa | ia64 | sparc | arm)
            ;;
            *)
         _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wcast-align"
            ;;
        esac
     fi
 
     dnl Turn pedantic on but disable the warnings for long long
     _PEDANTIC=1
 
+    if test -z "$INTEL_CC"; then
+      _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -W"
+    fi
+
     _DEFINES_CFLAGS='-include $(DEPTH)/mozilla-config.h -DMOZILLA_CLIENT'
     _USE_CPP_INCLUDE_FLAG=1
-
-    AC_CACHE_CHECK(whether the compiler supports -Wtype-limits,
-                   ac_cc_has_wtype_limits,
-        [
-            AC_LANG_SAVE
-            AC_LANG_C
-            _SAVE_CFLAGS="$CFLAGS"
-            CFLAGS="$CFLAGS -Wtype-limits"
-            AC_TRY_COMPILE([],
-                           [return(0);],
-                           ac_cc_has_wtype_limits="yes",
-                           ac_cc_has_wtype_limits="no")
-            CFLAGS="$_SAVE_CFLAGS"
-            AC_LANG_RESTORE
-        ])
-    if test "$ac_cc_has_wtype_limits" = "yes"; then
-        _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wtype-limits"
-    fi
 elif test "$SOLARIS_SUNPRO_CC"; then
     DSO_CFLAGS=''
     if test "$CPU_ARCH" = "sparc"; then
         # for Sun Studio on Solaris/SPARC
         DSO_PIC_CFLAGS='-xcode=pic32'
     else
         DSO_PIC_CFLAGS='-KPIC'
     fi
@@ -1935,32 +1917,18 @@ else
     DSO_CFLAGS=''
     DSO_PIC_CFLAGS='-KPIC'
     _DEFINES_CFLAGS='$(ACDEFINES) -D_MOZILLA_CONFIG_H_ -DMOZILLA_CLIENT'
 fi
 
 if test "$GNU_CXX"; then
     # FIXME: Let us build with strict aliasing. bug 414641.
     CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-strict-aliasing"
-
-    # Turn on GNU-specific warnings:
-    # -Wall - turn on a lot of warnings
-    # -pedantic - this is turned on below
-    # -Wpointer-arith - enabled with -pedantic, but good to have even if not
-    # -Woverloaded-virtual - ???
-    # -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
-    #
-    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall -Wpointer-arith -Woverloaded-virtual -Wempty-body"
-
-    # Turn off the following warnings that -Wall/-pedantic turn on:
-    # -Woverlength-strings - we exceed the minimum maximum length all the time
-    # -Wctor-dtor-privacy - ???
-    #
-    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-overlength-strings -Wno-ctor-dtor-privacy"
-
+    # Turn on GNU specific features
+    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall -Wpointer-arith -Woverloaded-virtual -Wsynth -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor"
     if test -z "$INTEL_CXX" -a -z "$CLANG_CXX"; then
        # Don't use -Wcast-align with ICC or clang
        case "$CPU_ARCH" in
            # And don't use it on hppa, ia64, sparc, arm, since it's noisy there
            hppa | ia64 | sparc | arm)
            ;;
            *)
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wcast-align"
@@ -2051,34 +2019,16 @@ if test "$GNU_CXX"; then
                            ac_has_werror_return_type="no")
             CXXFLAGS="$_SAVE_CXXFLAGS"
             AC_LANG_RESTORE
         ])
     if test "$ac_has_werror_return_type" = "yes"; then
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=return-type"
     fi
 
-    AC_CACHE_CHECK(whether the compiler supports -Wtype-limits,
-                   ac_has_wtype_limits,
-        [
-            AC_LANG_SAVE
-            AC_LANG_CPLUSPLUS
-            _SAVE_CXXFLAGS="$CXXFLAGS"
-            CXXFLAGS="$CXXFLAGS -Wtype-limits"
-            AC_TRY_COMPILE([],
-                           [return(0);],
-                           ac_has_wtype_limits="yes",
-                           ac_has_wtype_limits="no")
-            CXXFLAGS="$_SAVE_CXXFLAGS"
-            AC_LANG_RESTORE
-        ])
-    if test "$ac_has_wtype_limits" = "yes"; then
-        _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wtype-limits"
-    fi
-
 else
     _DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -D_MOZILLA_CONFIG_H_ $(ACDEFINES)'
 fi
 
 dnl gcc can come with its own linker so it is better to use the pass-thru calls
 dnl MKSHLIB_FORCE_ALL is used to force the linker to include all object
 dnl files present in an archive. MKSHLIB_UNFORCE_ALL reverts the linker to
 dnl normal behavior.
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -227,20 +227,19 @@ public:
 
   static bool     IsCallerChrome();
 
   static bool     IsCallerTrustedForRead();
 
   static bool     IsCallerTrustedForWrite();
 
   /**
-   * Check whether a caller is trusted to have aCapability.  This also
-   * checks for UniversalXPConnect in addition to aCapability.
+   * Check whether a caller has UniversalXPConnect.
    */
-  static bool     IsCallerTrustedForCapability(const char* aCapability);
+  static bool     CallerHasUniversalXPConnect();
 
   static bool     IsImageSrcSetDisabled();
 
   /**
    * Returns the parent node of aChild crossing document boundaries.
    */
   static nsINode* GetCrossDocParentNode(nsINode* aChild);
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -1143,26 +1143,19 @@ nsContentUtils::Shutdown()
 
   NS_IF_RELEASE(sSameOriginChecker);
   
   nsTextEditorState::ShutDown();
 }
 
 // static
 bool
-nsContentUtils::IsCallerTrustedForCapability(const char* aCapability)
-{
-  // The secman really should handle UniversalXPConnect case, since that
-  // should include UniversalBrowserRead... doesn't right now, though.
+nsContentUtils::CallerHasUniversalXPConnect()
+{
   bool hasCap;
-  if (NS_FAILED(sSecurityManager->IsCapabilityEnabled(aCapability, &hasCap)))
-    return false;
-  if (hasCap)
-    return true;
-    
   if (NS_FAILED(sSecurityManager->IsCapabilityEnabled("UniversalXPConnect",
                                                       &hasCap)))
     return false;
   return hasCap;
 }
 
 /**
  * Checks whether two nodes come from the same origin. aTrustedNode is
@@ -1222,26 +1215,19 @@ nsContentUtils::CanCallerAccess(nsIPrinc
   bool subsumes;
   nsresult rv = aSubjectPrincipal->Subsumes(aPrincipal, &subsumes);
   NS_ENSURE_SUCCESS(rv, false);
 
   if (subsumes) {
     return true;
   }
 
-  // The subject doesn't subsume aPrincipal.  Allow access only if the subject
-  // has either "UniversalXPConnect" (if aPrincipal is system principal) or
-  // "UniversalBrowserRead" (in all other cases).
-  bool isSystem;
-  rv = sSecurityManager->IsSystemPrincipal(aPrincipal, &isSystem);
-  isSystem = NS_FAILED(rv) || isSystem;
-  const char* capability =
-    NS_FAILED(rv) || isSystem ? "UniversalXPConnect" : "UniversalBrowserRead";
-
-  return IsCallerTrustedForCapability(capability);
+  // The subject doesn't subsume aPrincipal. Allow access only if the subject
+  // has UniversalXPConnect.
+  return CallerHasUniversalXPConnect();
 }
 
 // static
 bool
 nsContentUtils::CanCallerAccess(nsIDOMNode *aNode)
 {
   // XXXbz why not check the IsCapabilityEnabled thing up front, and not bother
   // with the system principal games?  But really, there should be a simpler
@@ -1464,23 +1450,23 @@ nsContentUtils::IsCallerChrome()
   }
 
   return is_caller_chrome;
 }
 
 bool
 nsContentUtils::IsCallerTrustedForRead()
 {
-  return IsCallerTrustedForCapability("UniversalBrowserRead");
+  return CallerHasUniversalXPConnect();
 }
 
 bool
 nsContentUtils::IsCallerTrustedForWrite()
 {
-  return IsCallerTrustedForCapability("UniversalBrowserWrite");
+  return CallerHasUniversalXPConnect();
 }
 
 bool
 nsContentUtils::IsImageSrcSetDisabled()
 {
   return Preferences::GetBool("dom.disable_image_src_set") &&
          !IsCallerChrome();
 }
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -160,22 +160,22 @@ nsDOMFileBase::GetName(nsAString &aFileN
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMFileBase::GetMozFullPath(nsAString &aFileName)
 {
   NS_ASSERTION(mIsFile, "Should only be called on files");
 
-  // It is unsafe to call IsCallerTrustedForCapability on a non-main thread. If
+  // It is unsafe to call CallerHasUniversalXPConnect on a non-main thread. If
   // you hit the following assertion you need to figure out some other way to
   // determine privileges and call GetMozFullPathInternal.
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
-  if (nsContentUtils::IsCallerTrustedForCapability("UniversalFileRead")) {
+  if (nsContentUtils::CallerHasUniversalXPConnect()) {
     return GetMozFullPathInternal(aFileName);
   }
   aFileName.Truncate();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMFileBase::GetMozFullPathInternal(nsAString &aFileName)
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -2124,17 +2124,18 @@ nsGenericElement::GetBoundingClientRect(
   
   nsIFrame* frame = GetPrimaryFrame(Flush_Layout);
   if (!frame) {
     // display:none, perhaps? Return the empty rect
     return NS_OK;
   }
 
   nsRect r = nsLayoutUtils::GetAllInFlowRectsUnion(frame,
-          nsLayoutUtils::GetContainingBlockForClientRect(frame));
+          nsLayoutUtils::GetContainingBlockForClientRect(frame),
+          nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
   rect->SetLayoutRect(r);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGenericElement::GetElementsByClassName(const nsAString& aClasses,
                                          nsIDOMNodeList** aReturn)
 {
@@ -2152,17 +2153,18 @@ nsGenericElement::GetClientRects(nsIDOMC
   if (!frame) {
     // display:none, perhaps? Return an empty list
     *aResult = rectList.forget().get();
     return NS_OK;
   }
 
   nsLayoutUtils::RectListBuilder builder(rectList);
   nsLayoutUtils::GetAllInFlowRects(frame,
-          nsLayoutUtils::GetContainingBlockForClientRect(frame), &builder);
+          nsLayoutUtils::GetContainingBlockForClientRect(frame), &builder,
+          nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
   if (NS_FAILED(builder.mRV))
     return builder.mRV;
   *aResult = rectList.forget().get();
   return NS_OK;
 }
 
 
 //----------------------------------------------------------------------
@@ -2435,17 +2437,17 @@ nsGenericElement::InternalIsSupported(ns
     }
   } else if (PL_strcasecmp(f, "XPath") == 0) {
     if (aVersion.IsEmpty() ||
         PL_strcmp(v, "3.0") == 0) {
       *aReturn = true;
     }
   } else if (PL_strcasecmp(f, "SVGEvents") == 0 ||
              PL_strcasecmp(f, "SVGZoomEvents") == 0 ||
-             nsSVGFeatures::HaveFeature(aObject, aFeature)) {
+             nsSVGFeatures::HasFeature(aObject, aFeature)) {
     if (aVersion.IsEmpty() ||
         PL_strcmp(v, "1.0") == 0 ||
         PL_strcmp(v, "1.1") == 0) {
       *aReturn = true;
     }
   }
   else if (NS_SMILEnabled() && PL_strcasecmp(f, "TimeControl") == 0) {
     if (aVersion.IsEmpty() || PL_strcmp(v, "1.0") == 0) {
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -2744,20 +2744,20 @@ nsXMLHttpRequest::SetRequestHeader(const
     return NS_ERROR_FAILURE; // must be called before first setRequestHeader()
 
   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
   if (!httpChannel) {
     return NS_OK;
   }
 
   // Prevent modification to certain HTTP headers (see bug 302263), unless
-  // the executing script has UniversalBrowserWrite permission.
+  // the executing script has UniversalXPConnect.
 
   bool privileged;
-  rv = IsCapabilityEnabled("UniversalBrowserWrite", &privileged);
+  rv = IsCapabilityEnabled("UniversalXPConnect", &privileged);
   if (NS_FAILED(rv))
     return NS_ERROR_FAILURE;
 
   if (!privileged) {
     // Check for dangerous headers
     const char *kInvalidHeaders[] = {
       "accept-charset", "accept-encoding", "access-control-request-headers",
       "access-control-request-method", "connection", "content-length",
--- a/content/base/test/test_bug345339.html
+++ b/content/base/test/test_bug345339.html
@@ -57,17 +57,17 @@ function afterReload() {
     is(iframeDoc.getElementById("radio1").checked, false,
        "radio button #1 value preserved");
     is(iframeDoc.getElementById("radio2").checked, true,
        "radio button #2 value preserved");
     isnot(iframeDoc.getElementById("password").value, "123456",
        "password field value forgotten");
     is(iframeDoc.getElementById("hidden").value, "gecko",
        "hidden field value preserved");
-    netscape.security.PrivilegeManager.enablePrivilege("UniversalFileRead");
+    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
     is(iframeDoc.getElementById("file").value, filePath,
        "file field value preserved");
 
     SimpleTest.finish();
 }
 </script>
 </pre>
 </body>
--- a/content/base/test/test_bug380418.html
+++ b/content/base/test/test_bug380418.html
@@ -17,17 +17,17 @@
 
 	SimpleTest.waitForExplicitFinish();
 	
 	var request = new XMLHttpRequest();
 	request.open("GET", window.location.href, false);
 	request.send(null);
 	
 	// Try reading headers in privileged context
-	netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect UniversalBrowserRead");
+	netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 	is(request.getResponseHeader("Set-Cookie"), "test", "Reading Set-Cookie response header in privileged context");
 	is(request.getResponseHeader("Set-Cookie2"), "test2", "Reading Set-Cookie2 response header in privileged context");
 	is(request.getResponseHeader("X-Dummy"), "test", "Reading X-Dummy response header in privileged context");
 	
 	ok(/\bSet-Cookie:/i.test(request.getAllResponseHeaders()), "Looking for Set-Cookie in all response headers in privileged context");
 	ok(/\bSet-Cookie2:/i.test(request.getAllResponseHeaders()), "Looking for Set-Cookie2 in all response headers in privileged context");
 	ok(/\bX-Dummy:/i.test(request.getAllResponseHeaders()), "Looking for X-Dummy in all response headers in privileged context");
 	
--- a/content/base/test/test_xhr_forbidden_headers.html
+++ b/content/base/test/test_xhr_forbidden_headers.html
@@ -50,17 +50,17 @@ var i, request;
 
 // Try setting headers in unprivileged context
 request = new XMLHttpRequest();
 request.open("GET", window.location.href);
 for (i = 0; i < headers.length; i++)
   request.setRequestHeader(headers[i], "test" + i);
 
 // Read out headers
-netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect UniversalBrowserWrite");
+netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 var channel = request.channel.QueryInterface(Components.interfaces.nsIHttpChannel);
 for (i = 0; i < headers.length; i++) {
   // Retrieving Content-Length will throw an exception
   var value = null;
   try {
     value = channel.getRequestHeader(headers[i]);
   }
   catch(e) {}
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -90,17 +90,17 @@ namespace mozilla {
 class WebGLTexture;
 class WebGLBuffer;
 class WebGLProgram;
 class WebGLShader;
 class WebGLFramebuffer;
 class WebGLRenderbuffer;
 class WebGLUniformLocation;
 class WebGLExtension;
-class WebGLVertexAttribData;
+struct WebGLVertexAttribData;
 
 class WebGLContextBoundObject;
 
 enum FakeBlackStatus { DoNotNeedFakeBlack, DoNeedFakeBlack, DontKnowIfNeedFakeBlack };
 
 struct VertexAttrib0Status {
     enum { Default, EmulatedUninitializedArray, EmulatedInitializedArray };
 };
--- a/content/canvas/test/test_canvas.html
+++ b/content/canvas/test/test_canvas.html
@@ -21019,17 +21019,17 @@ ctx667.fillStyle = 'rgba(12, 16, 244, 0.
 ctx667.fillRect(75, 0, 25, 25);
 var img = new Image();
 deferTest();
 img.onload = wrapFunction(function ()
 {
     ctx667.drawImage(img, 0, 25);
     // (The alpha values do not really survive float->int conversion, so just
     // do approximate comparisons)
-    netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
+    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
     isPixel(ctx667, 12,40, 1,3,254,255, 0);
     isPixel(ctx667, 37,40, 8,252,248,191, 2);
     isPixel(ctx667, 62,40, 6,10,250,127, 4);
     isPixel(ctx667, 87,40, 12,16,244,63, 8);
 });
 img.src = canvas667.toDataURL();
 
 
@@ -21146,17 +21146,17 @@ ctx672.fillRect(0, 40, 100, 10);
 var data = canvas672.toDataURL();
 ctx672.fillStyle = '#f00';
 ctx672.fillRect(0, 0, 100, 50);
 var img = new Image();
 deferTest();
 img.onload = wrapFunction(function ()
 {
     ctx672.drawImage(img, 0, 0);
-    netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
+    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
     isPixel(ctx672, 12,20, 255,255,0,255, 0);
     isPixel(ctx672, 50,20, 0,255,255,255, 0);
     isPixel(ctx672, 87,20, 0,0,255,255, 0);
     isPixel(ctx672, 50,45, 255,255,255,255, 0);
 });
 img.src = data;
 
 
--- a/content/events/public/nsEventDispatcher.h
+++ b/content/events/public/nsEventDispatcher.h
@@ -250,17 +250,17 @@ public:
                            nsEventStatus* aEventStatus = nsnull,
                            nsDispatchingCallback* aCallback = nsnull,
                            nsCOMArray<nsIDOMEventTarget>* aTargets = nsnull);
 
   /**
    * Dispatches an event.
    * If aDOMEvent is not nsnull, it is used for dispatching
    * (aEvent can then be nsnull) and (if aDOMEvent is not |trusted| already),
-   * the |trusted| flag is set based on the UniversalBrowserWrite capability.
+   * the |trusted| flag is set based on the UniversalXPConnect capability.
    * Otherwise this works like nsEventDispatcher::Dispatch.
    * @note Use this method when dispatching nsIDOMEvent.
    */
   static nsresult DispatchDOMEvent(nsISupports* aTarget,
                                    nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
                                    nsPresContext* aPresContext,
                                    nsEventStatus* aEventStatus);
 
--- a/content/events/src/nsDOMDataTransfer.cpp
+++ b/content/events/src/nsDOMDataTransfer.cpp
@@ -447,21 +447,21 @@ nsDOMDataTransfer::MozGetDataAt(const ns
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
 
   nsAutoString format;
   GetRealFormat(aFormat, format);
 
   nsTArray<TransferItem>& item = mItems[aIndex];
 
   // allow access to any data in the drop and dragdrop events, or if the
-  // UniversalBrowserRead privilege is set, otherwise only allow access to
+  // UniversalXPConnect privilege is set, otherwise only allow access to
   // data from the same principal.
   nsIPrincipal* principal = nsnull;
   if (mEventType != NS_DRAGDROP_DROP && mEventType != NS_DRAGDROP_DRAGDROP &&
-      !nsContentUtils::IsCallerTrustedForCapability("UniversalBrowserRead")) {
+      !nsContentUtils::CallerHasUniversalXPConnect()) {
     nsresult rv = NS_OK;
     principal = GetCurrentPrincipal(&rv);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   PRUint32 count = item.Length();
   for (PRUint32 i = 0; i < count; i++) {
     TransferItem& formatitem = item[i];
@@ -520,17 +520,17 @@ nsDOMDataTransfer::MozSetDataAt(const ns
   // item. Specifying an index equal to the current length will add a new item.
   if (aIndex > mItems.Length())
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
 
   // don't allow non-chrome to add file data
   // XXX perhaps this should also limit any non-string type as well
   if ((aFormat.EqualsLiteral("application/x-moz-file-promise") ||
        aFormat.EqualsLiteral("application/x-moz-file")) &&
-       !nsContentUtils::IsCallerTrustedForCapability("UniversalXPConnect")) {
+       !nsContentUtils::CallerHasUniversalXPConnect()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsresult rv = NS_OK;
   nsIPrincipal* principal = GetCurrentPrincipal(&rv);
   NS_ENSURE_SUCCESS(rv, rv);
   return SetDataWithPrincipal(aFormat, aData, aIndex, principal);
 }
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -575,17 +575,17 @@ nsDOMEvent::InitEvent(const nsAString& a
   // Make sure this event isn't already being dispatched.
   NS_ENSURE_TRUE(!NS_IS_EVENT_IN_DISPATCH(mEvent), NS_ERROR_INVALID_ARG);
 
   if (NS_IS_TRUSTED_EVENT(mEvent)) {
     // Ensure the caller is permitted to dispatch trusted DOM events.
 
     bool enabled = false;
     nsContentUtils::GetSecurityManager()->
-      IsCapabilityEnabled("UniversalBrowserWrite", &enabled);
+      IsCapabilityEnabled("UniversalXPConnect", &enabled);
 
     if (!enabled) {
       SetTrusted(false);
     }
   }
 
   NS_ENSURE_SUCCESS(SetEventType(aEventTypeArg), NS_ERROR_FAILURE);
 
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -936,17 +936,17 @@ nsresult
 nsHTMLInputElement::GetValueInternal(nsAString& aValue) const
 {
   switch (GetValueMode()) {
     case VALUE_MODE_VALUE:
       mInputData.mState->GetValue(aValue, true);
       return NS_OK;
 
     case VALUE_MODE_FILENAME:
-      if (nsContentUtils::IsCallerTrustedForCapability("UniversalFileRead")) {
+      if (nsContentUtils::CallerHasUniversalXPConnect()) {
         if (mFiles.Count()) {
           return mFiles[0]->GetMozFullPath(aValue);
         }
         else {
           aValue.Truncate();
         }
       } else {
         // Just return the leaf name
@@ -985,19 +985,19 @@ nsHTMLInputElement::IsValueEmpty() const
 
 NS_IMETHODIMP 
 nsHTMLInputElement::SetValue(const nsAString& aValue)
 {
   // check security.  Note that setting the value to the empty string is always
   // OK and gives pages a way to clear a file input if necessary.
   if (mType == NS_FORM_INPUT_FILE) {
     if (!aValue.IsEmpty()) {
-      if (!nsContentUtils::IsCallerTrustedForCapability("UniversalFileRead")) {
+      if (!nsContentUtils::CallerHasUniversalXPConnect()) {
         // setting the value of a "FILE" input widget requires the
-        // UniversalFileRead privilege
+        // UniversalXPConnect privilege
         return NS_ERROR_DOM_SECURITY_ERR;
       }
       const PRUnichar *name = PromiseFlatString(aValue).get();
       return MozSetFileNameArray(&name, 1);
     }
     else {
       ClearFiles(true);
     }
@@ -1032,17 +1032,17 @@ nsHTMLInputElement::GetList(nsIDOMHTMLEl
 
   CallQueryInterface(element, aValue);
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsHTMLInputElement::MozGetFileNameArray(PRUint32 *aLength, PRUnichar ***aFileNames)
 {
-  if (!nsContentUtils::IsCallerTrustedForCapability("UniversalFileRead")) {
+  if (!nsContentUtils::CallerHasUniversalXPConnect()) {
     // Since this function returns full paths it's important that normal pages
     // can't call it.
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   *aLength = mFiles.Count();
   PRUnichar **ret =
     static_cast<PRUnichar **>(NS_Alloc(mFiles.Count() * sizeof(PRUnichar*)));
@@ -1059,19 +1059,19 @@ nsHTMLInputElement::MozGetFileNameArray(
   *aFileNames = ret;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsHTMLInputElement::MozSetFileNameArray(const PRUnichar **aFileNames, PRUint32 aLength)
 {
-  if (!nsContentUtils::IsCallerTrustedForCapability("UniversalFileRead")) {
+  if (!nsContentUtils::CallerHasUniversalXPConnect()) {
     // setting the value of a "FILE" input widget requires the
-    // UniversalFileRead privilege
+    // UniversalXPConnect privilege
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsCOMArray<nsIDOMFile> files;
   for (PRUint32 i = 0; i < aLength; ++i) {
     nsCOMPtr<nsIFile> file;
     if (StringBeginsWith(nsDependentString(aFileNames[i]),
                          NS_LITERAL_STRING("file:"),
--- a/content/html/content/test/test_bug143220.html
+++ b/content/html/content/test/test_bug143220.html
@@ -31,17 +31,17 @@ function initVals() {
   var file = dirSvc.get("XpcomLib", Components.interfaces.nsILocalFile);
   isnot(file, null, "Must have file here");
 
   leafName = file.leafName;
   fullPath = file.path;
 }
 
 function initControl1() {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalFileRead");
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   $("i1").value = fullPath;
   is($("i1").value, fullPath, "Should have set full path 1");
 }
 
 function initControl2() {
   netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   $("i2").value = fullPath;
   is($("i2").value, fullPath, "Should have set full path 2");
--- a/content/html/content/test/test_bug388558.html
+++ b/content/html/content/test/test_bug388558.html
@@ -18,17 +18,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 388558 **/
 var inputChange = 0;
 var textareaChange = 0;
 
 function testUserInput() {
-  netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserWrite');
+  netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
   var input = document.getElementById("input");
   var textarea = document.getElementById("textarea");
 
   input.focus();
   input.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).setUserInput("foo");
   input.blur();
   is(inputChange, 1, "Input element should have got one change event.");
 
--- a/content/media/webm/nsWebMReader.cpp
+++ b/content/media/webm/nsWebMReader.cpp
@@ -132,19 +132,22 @@ nsWebMReader::nsWebMReader(nsBuiltinDeco
   mContext(nsnull),
   mPacketCount(0),
   mChannels(0),
   mVideoTrack(0),
   mAudioTrack(0),
   mAudioStartUsec(-1),
   mAudioFrames(0),
   mHasVideo(false),
-  mHasAudio(false)
+  mHasAudio(false),
+  mForceStereoMode(0)
 {
   MOZ_COUNT_CTOR(nsWebMReader);
+
+  Preferences::GetInt("media.webm.force_stereo_mode", &mForceStereoMode);
 }
 
 nsWebMReader::~nsWebMReader()
 {
   Cleanup();
 
   mVideoPackets.Reset();
   mAudioPackets.Reset();
@@ -301,35 +304,31 @@ nsresult nsWebMReader::ReadMetadata(nsVi
       case NESTEGG_VIDEO_STEREO_TOP_BOTTOM:
         mInfo.mStereoMode = STEREO_MODE_TOP_BOTTOM;
         break;
       case NESTEGG_VIDEO_STEREO_RIGHT_LEFT:
         mInfo.mStereoMode = STEREO_MODE_RIGHT_LEFT;
         break;
       }
 
-      PRInt32 forceStereoMode;
-      if (NS_SUCCEEDED(Preferences::GetInt("media.webm.force_stereo_mode",
-                                           &forceStereoMode))) {
-        switch (forceStereoMode) {
-        case 1:
-          mInfo.mStereoMode = STEREO_MODE_LEFT_RIGHT;
-          break;
-        case 2:
-          mInfo.mStereoMode = STEREO_MODE_RIGHT_LEFT;
-          break;
-        case 3:
-          mInfo.mStereoMode = STEREO_MODE_TOP_BOTTOM;
-          break;
-        case 4:
-          mInfo.mStereoMode = STEREO_MODE_BOTTOM_TOP;
-          break;
-        default:
-          mInfo.mStereoMode = STEREO_MODE_MONO;
-        }
+      switch (mForceStereoMode) {
+      case 1:
+        mInfo.mStereoMode = STEREO_MODE_LEFT_RIGHT;
+        break;
+      case 2:
+        mInfo.mStereoMode = STEREO_MODE_RIGHT_LEFT;
+        break;
+      case 3:
+        mInfo.mStereoMode = STEREO_MODE_TOP_BOTTOM;
+        break;
+      case 4:
+        mInfo.mStereoMode = STEREO_MODE_BOTTOM_TOP;
+        break;
+      default:
+        mInfo.mStereoMode = STEREO_MODE_MONO;
       }
     }
     else if (!mHasAudio && type == NESTEGG_TRACK_AUDIO) {
       nestegg_audio_params params;
       r = nestegg_track_audio_params(mContext, track, &params);
       if (r == -1) {
         Cleanup();
         return NS_ERROR_FAILURE;
--- a/content/media/webm/nsWebMReader.h
+++ b/content/media/webm/nsWebMReader.h
@@ -235,11 +235,15 @@ private:
   nsIntSize mInitialFrame;
 
   // Picture region, as relative to the initial frame size.
   nsIntRect mPicture;
 
   // Booleans to indicate if we have audio and/or video data
   bool mHasVideo;
   bool mHasAudio;
+
+  // Value of the "media.webm.force_stereo_mode" pref, which we need off the
+  // main thread.
+  PRInt32 mForceStereoMode;
 };
 
 #endif
new file mode 100644
--- /dev/null
+++ b/content/svg/content/src/DOMSVGStringList.cpp
@@ -0,0 +1,199 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla SVG Project code.
+ *
+ * The Initial Developer of the Original Code is
+ * Robert Longson <longsonr@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "DOMSVGStringList.h"
+#include "DOMSVGTests.h"
+#include "nsDOMError.h"
+#include "nsCOMPtr.h"
+#include "nsSVGAttrTearoffTable.h"
+
+// See the architecture comment in this file's header.
+
+namespace mozilla {
+
+static nsSVGAttrTearoffTable<SVGStringList, DOMSVGStringList>
+  sSVGStringListTearoffTable;
+
+NS_SVG_VAL_IMPL_CYCLE_COLLECTION(DOMSVGStringList, mElement)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGStringList)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGStringList)
+
+} // namespace mozilla
+
+DOMCI_DATA(SVGStringList, mozilla::DOMSVGStringList)
+namespace mozilla {
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGStringList)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMSVGStringList)
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGStringList)
+NS_INTERFACE_MAP_END
+
+
+/* static */ already_AddRefed<DOMSVGStringList>
+DOMSVGStringList::GetDOMWrapper(SVGStringList *aList,
+                                nsSVGElement *aElement,
+                                bool aIsConditionalProcessingAttribute,
+                                PRUint8 aAttrEnum)
+{
+  DOMSVGStringList *wrapper =
+    sSVGStringListTearoffTable.GetTearoff(aList);
+  if (!wrapper) {
+    wrapper = new DOMSVGStringList(aElement, 
+                                   aIsConditionalProcessingAttribute,
+                                   aAttrEnum);
+    sSVGStringListTearoffTable.AddTearoff(aList, wrapper);
+  }
+  NS_ADDREF(wrapper);
+  return wrapper;
+}
+
+DOMSVGStringList::~DOMSVGStringList()
+{
+  // Script no longer has any references to us.
+  sSVGStringListTearoffTable.RemoveTearoff(&InternalList());
+}
+
+// ----------------------------------------------------------------------------
+// nsIDOMSVGStringList implementation:
+
+NS_IMETHODIMP
+DOMSVGStringList::GetNumberOfItems(PRUint32 *aNumberOfItems)
+{
+  *aNumberOfItems = InternalList().Length();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMSVGStringList::Clear()
+{
+  if (InternalList().IsExplicitlySet()) {
+    InternalList().Clear();
+    mElement->DidChangeStringList(mIsConditionalProcessingAttribute,
+                                  mAttrEnum);
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMSVGStringList::Initialize(const nsAString & newItem, nsAString & _retval)
+{
+  if (InternalList().IsExplicitlySet()) {
+    InternalList().Clear();
+  }
+  return InsertItemBefore(newItem, 0, _retval);
+}
+
+NS_IMETHODIMP
+DOMSVGStringList::GetItem(PRUint32 index,
+                          nsAString & _retval)
+{
+  if (index >= InternalList().Length()) {
+    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+  }
+  _retval = InternalList()[index];
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMSVGStringList::InsertItemBefore(const nsAString & newItem,
+                                   PRUint32 index,
+                                   nsAString & _retval)
+{
+  index = NS_MIN(index, InternalList().Length());
+
+  // Ensure we have enough memory so we can avoid complex error handling below:
+  if (!InternalList().SetCapacity(InternalList().Length() + 1)) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  InternalList().InsertItem(index, newItem);
+
+  mElement->DidChangeStringList(mIsConditionalProcessingAttribute, mAttrEnum);
+  _retval = newItem;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMSVGStringList::ReplaceItem(const nsAString & newItem,
+                              PRUint32 index,
+                              nsAString & _retval)
+{
+  if (index >= InternalList().Length()) {
+    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+  }
+
+  _retval = InternalList()[index];
+  InternalList().ReplaceItem(index, newItem);
+
+  mElement->DidChangeStringList(mIsConditionalProcessingAttribute, mAttrEnum);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMSVGStringList::RemoveItem(PRUint32 index,
+                             nsAString & _retval)
+{
+  if (index >= InternalList().Length()) {
+    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+  }
+
+  InternalList().RemoveItem(index);
+
+  mElement->DidChangeStringList(mIsConditionalProcessingAttribute, mAttrEnum);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMSVGStringList::AppendItem(const nsAString & newItem,
+                             nsAString & _retval)
+{
+  return InsertItemBefore(newItem, InternalList().Length(), _retval);
+}
+
+SVGStringList &
+DOMSVGStringList::InternalList()
+{
+  if (mIsConditionalProcessingAttribute) {
+    nsCOMPtr<DOMSVGTests> tests = do_QueryInterface(mElement);
+    return tests->mStringListAttributes[mAttrEnum];
+  }
+  return mElement->GetStringListInfo().mStringLists[mAttrEnum];
+}
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/content/svg/content/src/DOMSVGStringList.h
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla SVG Project code.
+ *
+ * The Initial Developer of the Original Code is
+ * Robert Longson <longsonr@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_DOMSVGSTRINGLIST_H__
+#define MOZILLA_DOMSVGSTRINGLIST_H__
+
+#include "nsIDOMSVGStringList.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsCOMArray.h"
+#include "nsAutoPtr.h"
+
+class nsSVGElement;
+
+namespace mozilla {
+
+class SVGStringList;
+
+/**
+ * Class DOMSVGStringList
+ *
+ * This class is used to create the DOM tearoff objects that wrap internal
+ * SVGPathData objects.
+ *
+ * See the architecture comment in DOMSVGAnimatedLengthList.h first (that's
+ * LENGTH list), then continue reading the remainder of this comment.
+ *
+ * The architecture of this class is similar to that of DOMSVGLengthList
+ * except for two important aspects:
+ *
+ * First, since there is no nsIDOMSVGAnimatedStringList interface in SVG, we
+ * have no parent DOMSVGAnimatedStringList (unlike DOMSVGLengthList which has
+ * a parent DOMSVGAnimatedLengthList class). As a consequence, much of the
+ * logic that would otherwise be in DOMSVGAnimatedStringList (and is in
+ * DOMSVGAnimatedLengthList) is contained in this class.
+ *
+ * Second, since there is no nsIDOMSVGString interface in SVG, we have no
+ * DOMSVGString items to maintain. As far as script is concerned, objects
+ * of this class contain a list of strings, not a list of mutable objects
+ * like the other SVG list types. As a result, unlike the other SVG list
+ * types, this class does not create its items lazily on demand and store
+ * them so it can return the same objects each time. It simply returns a new
+ * string each time any given item is requested.
+ */
+class DOMSVGStringList : public nsIDOMSVGStringList
+{
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS(DOMSVGStringList)
+  NS_DECL_NSIDOMSVGSTRINGLIST
+
+  /**
+   * Factory method to create and return a DOMSVGStringList wrapper
+   * for a given internal SVGStringList object. The factory takes care
+   * of caching the object that it returns so that the same object can be
+   * returned for the given SVGStringList each time it is requested.
+   * The cached object is only removed from the cache when it is destroyed due
+   * to there being no more references to it. If that happens, any subsequent
+   * call requesting the DOM wrapper for the SVGStringList will naturally
+   * result in a new DOMSVGStringList being returned.
+   */
+  static already_AddRefed<DOMSVGStringList>
+    GetDOMWrapper(SVGStringList *aList,
+                  nsSVGElement *aElement,
+                  bool aIsConditionalProcessingAttribute,
+                  PRUint8 aAttrEnum);
+
+private:
+  /**
+   * Only our static GetDOMWrapper() factory method may create objects of our
+   * type.
+   */
+  DOMSVGStringList(nsSVGElement *aElement,
+                   bool aIsConditionalProcessingAttribute, PRUint8 aAttrEnum)
+    : mElement(aElement)
+    , mAttrEnum(aAttrEnum)
+    , mIsConditionalProcessingAttribute(aIsConditionalProcessingAttribute)
+  {}
+
+  ~DOMSVGStringList();
+
+  void DidChangeStringList(PRUint8 aAttrEnum, bool aDoSetAttr);
+
+  SVGStringList &InternalList();
+
+  // Strong ref to our element to keep it alive.
+  nsRefPtr<nsSVGElement> mElement;
+
+  PRUint8 mAttrEnum;
+
+  bool    mIsConditionalProcessingAttribute;
+};
+
+} // namespace mozilla
+
+#endif // MOZILLA_DOMSVGSTRINGLIST_H__
new file mode 100644
--- /dev/null
+++ b/content/svg/content/src/DOMSVGTests.cpp
@@ -0,0 +1,289 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * The Initial Developer of the Original Code is
+ * Robert Longson <longsonr@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "DOMSVGTests.h"
+#include "DOMSVGStringList.h"
+#include "nsSVGFeatures.h"
+#include "nsSVGSwitchElement.h"
+#include "nsCharSeparatedTokenizer.h"
+#include "nsStyleUtil.h"
+#include "nsSVGUtils.h"
+#include "mozilla/Preferences.h"
+
+using namespace mozilla;
+
+NS_IMPL_ISUPPORTS1(DOMSVGTests, nsIDOMSVGTests)
+
+DOMSVGTests::StringListInfo DOMSVGTests::sStringListInfo[3] =
+{
+  { &nsGkAtoms::requiredFeatures, false },
+  { &nsGkAtoms::requiredExtensions, false },
+  { &nsGkAtoms::systemLanguage, true }
+};
+
+/* readonly attribute nsIDOMSVGStringList requiredFeatures; */
+NS_IMETHODIMP
+DOMSVGTests::GetRequiredFeatures(nsIDOMSVGStringList * *aRequiredFeatures)
+{
+  nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
+  *aRequiredFeatures = DOMSVGStringList::GetDOMWrapper(
+                         &mStringListAttributes[FEATURES], element, true, FEATURES).get();
+  return NS_OK;
+}
+
+/* readonly attribute nsIDOMSVGStringList requiredExtensions; */
+NS_IMETHODIMP
+DOMSVGTests::GetRequiredExtensions(nsIDOMSVGStringList * *aRequiredExtensions)
+{
+  nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
+  *aRequiredExtensions = DOMSVGStringList::GetDOMWrapper(
+                           &mStringListAttributes[EXTENSIONS], element, true, EXTENSIONS).get();
+  return NS_OK;
+}
+
+/* readonly attribute nsIDOMSVGStringList systemLanguage; */
+NS_IMETHODIMP
+DOMSVGTests::GetSystemLanguage(nsIDOMSVGStringList * *aSystemLanguage)
+{
+  nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
+  *aSystemLanguage = DOMSVGStringList::GetDOMWrapper(
+                       &mStringListAttributes[LANGUAGE], element, true, LANGUAGE).get();
+  return NS_OK;
+}
+
+/* boolean hasExtension (in DOMString extension); */
+NS_IMETHODIMP
+DOMSVGTests::HasExtension(const nsAString & extension, bool *_retval)
+{
+  *_retval = nsSVGFeatures::HasExtension(extension);
+  return NS_OK;
+}
+
+bool
+DOMSVGTests::IsConditionalProcessingAttribute(const nsIAtom* aAttribute) const
+{
+  for (PRUint32 i = 0; i < ArrayLength(sStringListInfo); i++) {
+    if (aAttribute == *sStringListInfo[i].mName) {
+      return true;
+    }
+  }
+  return false;
+}
+
+PRInt32
+DOMSVGTests::GetBestLanguagePreferenceRank(const nsSubstring& aAcceptLangs) const
+{
+  const nsDefaultStringComparator defaultComparator;
+
+  PRInt32 lowestRank = -1;
+
+  for (PRUint32 i = 0; i < mStringListAttributes[LANGUAGE].Length(); i++) {
+    nsCharSeparatedTokenizer languageTokenizer(aAcceptLangs, ',');
+    PRInt32 index = 0;
+    while (languageTokenizer.hasMoreTokens()) {
+      const nsSubstring &languageToken = languageTokenizer.nextToken();
+      bool exactMatch = (languageToken == mStringListAttributes[LANGUAGE][i]);
+      bool prefixOnlyMatch =
+        !exactMatch &&
+        nsStyleUtil::DashMatchCompare(mStringListAttributes[LANGUAGE][i],
+                                      languageTokenizer.nextToken(),
+                                      defaultComparator);
+      if (index == 0 && exactMatch) {
+        // best possible match
+        return 0;
+      }
+      if ((exactMatch || prefixOnlyMatch) &&
+          (lowestRank == -1 || 2 * index + prefixOnlyMatch < lowestRank)) {
+        lowestRank = 2 * index + prefixOnlyMatch;
+      }
+      ++index;
+    }
+  }
+  return lowestRank;
+}
+
+const nsString * const DOMSVGTests::kIgnoreSystemLanguage = (nsString *) 0x01;
+
+bool
+DOMSVGTests::PassesConditionalProcessingTests(const nsString *aAcceptLangs) const
+{
+  // Required Features
+  if (mStringListAttributes[FEATURES].IsExplicitlySet()) {
+    if (mStringListAttributes[FEATURES].IsEmpty()) {
+      return false;
+    }
+    nsCOMPtr<nsIContent> content(
+      do_QueryInterface(const_cast<DOMSVGTests*>(this)));
+
+    for (PRUint32 i = 0; i < mStringListAttributes[FEATURES].Length(); i++) {
+      if (!nsSVGFeatures::HasFeature(content, mStringListAttributes[FEATURES][i])) {
+        return false;
+      }
+    }
+  }
+
+  // Required Extensions
+  //
+  // The requiredExtensions  attribute defines a list of required language
+  // extensions. Language extensions are capabilities within a user agent that
+  // go beyond the feature set defined in the SVG specification.
+  // Each extension is identified by a URI reference.
+  // For now, claim that mozilla's SVG implementation supports XHTML and MathML.
+  if (mStringListAttributes[EXTENSIONS].IsExplicitlySet()) {
+    if (mStringListAttributes[EXTENSIONS].IsEmpty()) {
+      return false;
+    }
+    for (PRUint32 i = 0; i < mStringListAttributes[EXTENSIONS].Length(); i++) {
+      if (!nsSVGFeatures::HasExtension(mStringListAttributes[EXTENSIONS][i])) {
+        return false;
+      }
+    }
+  }
+
+  if (aAcceptLangs == kIgnoreSystemLanguage) {
+    return true;
+  }
+
+  // systemLanguage
+  //
+  // Evaluates to "true" if one of the languages indicated by user preferences
+  // exactly equals one of the languages given in the value of this parameter,
+  // or if one of the languages indicated by user preferences exactly equals a
+  // prefix of one of the languages given in the value of this parameter such
+  // that the first tag character following the prefix is "-".
+  if (mStringListAttributes[LANGUAGE].IsExplicitlySet()) {
+    if (mStringListAttributes[LANGUAGE].IsEmpty()) {
+      return false;
+    }
+
+    // Get our language preferences
+    const nsAutoString acceptLangs(aAcceptLangs ? *aAcceptLangs :
+      Preferences::GetLocalizedString("intl.accept_languages"));
+
+    if (acceptLangs.IsEmpty()) {
+      NS_WARNING("no default language specified for systemLanguage conditional test");
+      return false;
+    }
+
+    const nsDefaultStringComparator defaultComparator;
+
+    for (PRUint32 i = 0; i < mStringListAttributes[LANGUAGE].Length(); i++) {
+      nsCharSeparatedTokenizer languageTokenizer(acceptLangs, ',');
+      while (languageTokenizer.hasMoreTokens()) {
+        if (nsStyleUtil::DashMatchCompare(mStringListAttributes[LANGUAGE][i],
+                                          languageTokenizer.nextToken(),
+                                          defaultComparator)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  return true;
+}
+
+bool
+DOMSVGTests::ParseConditionalProcessingAttribute(nsIAtom* aAttribute,
+                                                 const nsAString& aValue,
+                                                 nsAttrValue& aResult)
+{
+  for (PRUint32 i = 0; i < ArrayLength(sStringListInfo); i++) {
+    if (aAttribute == *sStringListInfo[i].mName) {
+      nsresult rv = mStringListAttributes[i].SetValue(
+                      aValue, sStringListInfo[i].mIsCommaSeparated);
+      if (NS_FAILED(rv)) {
+        mStringListAttributes[i].Clear();
+      }
+      MaybeInvalidate();
+      return true;
+    }
+  }
+  return false;
+}
+
+void
+DOMSVGTests::GetValue(PRUint8 aAttrEnum, nsAString& aValue) const
+{
+  NS_ABORT_IF_FALSE(aAttrEnum >= 0 && aAttrEnum < ArrayLength(sStringListInfo),
+                    "aAttrEnum out of range");
+  mStringListAttributes[aAttrEnum].GetValue(
+    aValue, sStringListInfo[aAttrEnum].mIsCommaSeparated);
+}
+
+void
+DOMSVGTests::UnsetAttr(const nsIAtom* aAttribute)
+{
+  for (PRUint32 i = 0; i < ArrayLength(sStringListInfo); i++) {
+    if (aAttribute == *sStringListInfo[i].mName) {
+      mStringListAttributes[i].Clear();
+      MaybeInvalidate();
+      return;
+    }
+  }
+}
+
+void
+DOMSVGTests::DidChangeStringList(PRUint8 aAttrEnum)
+{
+  NS_ASSERTION(aAttrEnum < ArrayLength(sStringListInfo), "aAttrEnum out of range");
+
+  nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
+
+  nsAutoString serializedValue;
+  GetValue(aAttrEnum, serializedValue);
+
+  nsAttrValue attrValue(serializedValue);
+  element->SetParsedAttr(kNameSpaceID_None,
+                         *sStringListInfo[aAttrEnum].mName,
+                         nsnull, attrValue, true);
+
+  MaybeInvalidate();
+}
+
+void
+DOMSVGTests::MaybeInvalidate()
+{
+  nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
+
+  nsIContent* parent = element->GetFlattenedTreeParent();
+  
+  if (parent &&
+      parent->NodeInfo()->Equals(nsGkAtoms::svgSwitch, kNameSpaceID_SVG)) {
+    static_cast<nsSVGSwitchElement*>(parent)->MaybeInvalidate();
+  }
+}
new file mode 100644
--- /dev/null
+++ b/content/svg/content/src/DOMSVGTests.h
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * The Initial Developer of the Original Code is
+ * Robert Longson <longsonr@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_DOMSVGTESTS_H__
+#define MOZILLA_DOMSVGTESTS_H__
+
+#include "nsIDOMSVGTests.h"
+#include "SVGStringList.h"
+
+class DOMSVGTests : public nsIDOMSVGTests
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIDOMSVGTESTS
+
+  friend class mozilla::DOMSVGStringList;
+  typedef mozilla::SVGStringList SVGStringList;
+
+  /**
+   * Compare the language name(s) in a systemLanguage attribute to the
+   * user's language preferences, as defined in
+   * http://www.w3.org/TR/SVG11/struct.html#SystemLanguageAttribute
+   * We have a match if a language name in the users language preferences
+   * exactly equals one of the language names or exactly equals a prefix of
+   * one of the language names in the systemLanguage attribute.
+   * @returns 2 * the lowest index in the aAcceptLangs that matches + 1
+   * if only the prefix matches, or -1 if no indices match.
+   * XXX This algorithm is O(M*N).
+   */
+  PRInt32 GetBestLanguagePreferenceRank(const nsSubstring& aAcceptLangs) const;
+
+  /**
+   * Special value to pass to PassesConditionalProcessingTests to ignore systemLanguage
+   * attributes
+   */
+  static const nsString * const kIgnoreSystemLanguage;
+
+  /**
+   * Check whether the conditional processing attributes requiredFeatures,
+   * requiredExtensions and systemLanguage all "return true" if they apply to
+   * and are specified on the given element. Returns true if this element
+   * should be rendered, false if it should not.
+   *
+   * @param aAcceptLangs Optional parameter to pass in the value of the
+   *   intl.accept_languages preference if the caller has it cached.
+   *   Alternatively, pass in kIgnoreSystemLanguage to skip the systemLanguage
+   *   check if the caller is giving that special treatment.
+   */
+  bool PassesConditionalProcessingTests(
+         const nsString *aAcceptLangs = nsnull) const;
+
+  /**
+   * Returns true if the attribute is one of the conditional processing
+   * attributes.
+   */
+  bool IsConditionalProcessingAttribute(const nsIAtom* aAttribute) const;
+
+  bool ParseConditionalProcessingAttribute(
+         nsIAtom* aAttribute,
+         const nsAString& aValue,
+         nsAttrValue& aResult);
+
+  /**
+   * Serialises the conditional processing attribute.
+   */
+  void GetValue(PRUint8 aAttrEnum, nsAString& aValue) const;
+
+  /**
+   * Unsets a conditional processing attribute.
+   */
+  void UnsetAttr(const nsIAtom* aAttribute);
+
+  void DidChangeStringList(PRUint8 aAttrEnum);
+
+  void MaybeInvalidate();
+
+private:
+
+  struct StringListInfo {
+    nsIAtom** mName;
+    bool      mIsCommaSeparated;
+  };
+
+  enum { FEATURES, EXTENSIONS, LANGUAGE };
+  SVGStringList mStringListAttributes[3];
+  static StringListInfo sStringListInfo[3];
+};
+
+#endif // MOZILLA_DOMSVGTESTS_H__
--- a/content/svg/content/src/Makefile.in
+++ b/content/svg/content/src/Makefile.in
@@ -56,16 +56,18 @@ CPPSRCS		= \
 		DOMSVGLengthList.cpp \
 		DOMSVGMatrix.cpp \
 		DOMSVGNumber.cpp \
 		DOMSVGNumberList.cpp \
 		DOMSVGPathSeg.cpp \
 		DOMSVGPathSegList.cpp \
 		DOMSVGPoint.cpp \
 		DOMSVGPointList.cpp \
+		DOMSVGStringList.cpp \
+		DOMSVGTests.cpp \
 		DOMSVGTransform.cpp \
 		DOMSVGTransformList.cpp \
 		nsDOMSVGZoomEvent.cpp \
 		nsDOMSVGEvent.cpp \
 		nsSVGAElement.cpp \
 		nsSVGAltGlyphElement.cpp \
 		nsSVGAngle.cpp \
 		nsSVGBoolean.cpp \
@@ -129,16 +131,17 @@ CPPSRCS		= \
 		SVGAnimatedPreserveAspectRatio.cpp \
 		SVGAnimatedTransformList.cpp \
 		SVGLength.cpp \
 		SVGLengthList.cpp \
 		SVGNumberList.cpp \
 		SVGPathData.cpp \
 		SVGPathSegUtils.cpp \
 		SVGPointList.cpp \
+		SVGStringList.cpp \
 		SVGTransform.cpp \
 		SVGTransformList.cpp \
 		SVGTransformListParser.cpp \
 		nsSVGAnimateElement.cpp \
 		nsSVGAnimateTransformElement.cpp \
 		nsSVGAnimateMotionElement.cpp \
 		nsSVGAnimationElement.cpp \
 		nsSVGMpathElement.cpp \
new file mode 100644
--- /dev/null
+++ b/content/svg/content/src/SVGStringList.cpp
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla SVG Project code.
+ *
+ * The Initial Developer of the Original Code is
+ * Robert Longson <longsonr@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mozilla/Util.h"
+
+#include "SVGStringList.h"
+#include "nsSVGElement.h"
+#include "nsDOMError.h"
+#include "nsString.h"
+#include "nsSVGUtils.h"
+#include "nsTextFormatter.h"
+#include "nsWhitespaceTokenizer.h"
+#include "nsCharSeparatedTokenizer.h"
+#include "nsMathUtils.h"
+
+namespace mozilla {
+
+nsresult
+SVGStringList::CopyFrom(const SVGStringList& rhs)
+{
+  if (!mStrings.SetCapacity(rhs.Length())) {
+    // Yes, we do want fallible alloc here
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+  mStrings = rhs.mStrings;
+  mIsSet = true;
+  return NS_OK;
+}
+
+void
+SVGStringList::GetValue(nsAString& aValue, bool aIsCommaSeparated) const
+{
+  aValue.Truncate();
+  PRUint32 last = mStrings.Length() - 1;
+  for (PRUint32 i = 0; i < mStrings.Length(); ++i) {
+    aValue.Append(mStrings[i]);
+    if (i != last) {
+      if (aIsCommaSeparated) {
+        aValue.Append(',');
+      }
+      aValue.Append(' ');
+    }
+  }
+}
+
+nsresult
+SVGStringList::SetValue(const nsAString& aValue, bool aIsCommaSeparated)
+{
+  SVGStringList temp;
+
+  if (aIsCommaSeparated) {
+    nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
+      tokenizer(aValue, ',');
+
+    while (tokenizer.hasMoreTokens()) {
+      if (!temp.AppendItem(tokenizer.nextToken())) {
+        return NS_ERROR_OUT_OF_MEMORY;
+      }
+    }
+    if (tokenizer.lastTokenEndedWithSeparator()) {
+      return NS_ERROR_DOM_SYNTAX_ERR; // trailing comma
+    }
+  } else {
+    nsWhitespaceTokenizer tokenizer(aValue);
+
+    while (tokenizer.hasMoreTokens()) {
+      if (!temp.AppendItem(tokenizer.nextToken())) {
+        return NS_ERROR_OUT_OF_MEMORY;
+      }
+    }
+  }
+
+  return CopyFrom(temp);
+}
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/content/svg/content/src/SVGStringList.h
@@ -0,0 +1,174 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla SVG Project code.
+ *
+ * The Initial Developer of the Original Code is
+ * Robert Longson <longsonr@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_SVGSTRINGLIST_H__
+#define MOZILLA_SVGSTRINGLIST_H__
+
+#include "nsTArray.h"
+#include "nsSVGElement.h"
+
+namespace mozilla {
+
+/**
+ *
+ * The DOM wrapper class for this class is DOMSVGStringList.
+ */
+class SVGStringList
+{
+  friend class DOMSVGStringList;
+
+public:
+
+  SVGStringList() : mIsSet(false) {}
+  ~SVGStringList(){}
+
+  nsresult SetValue(const nsAString& aValue, bool aIsCommaSeparated);
+
+  void Clear() {
+    mStrings.Clear();
+    mIsSet = false;
+  }
+
+  /// This may return an incomplete string on OOM, but that's acceptable.
+  void GetValue(nsAString& aValue, bool aIsCommaSeparated) const;
+
+  bool IsEmpty() const {
+    return mStrings.IsEmpty();
+  }
+
+  PRUint32 Length() const {
+    return mStrings.Length();
+  }
+
+  const nsAString& operator[](PRUint32 aIndex) const {
+    return mStrings[aIndex];
+  }
+
+  bool operator==(const SVGStringList& rhs) const {
+    return mStrings == rhs.mStrings;
+  }
+
+  bool SetCapacity(PRUint32 size) {
+    return mStrings.SetCapacity(size);
+  }
+
+  void Compact() {
+    mStrings.Compact();
+  }
+
+  // Returns true if the animated value of this stringlist has been explicitly
+  // set by taking on the base value which has been explicitly set by markup
+  // or a DOM call, false otherwise.
+  bool IsExplicitlySet() const
+    { return mIsSet; }
+
+  // Access to methods that can modify objects of this type is deliberately
+  // limited. This is to reduce the chances of someone modifying objects of
+  // this type without taking the necessary steps to keep DOM wrappers in sync.
+  // If you need wider access to these methods, consider adding a method to
+  // SVGAnimatedStringList and having that class act as an intermediary so it
+  // can take care of keeping DOM wrappers in sync.
+
+protected:
+
+  /**
+   * This may fail on OOM if the internal capacity needs to be increased, in
+   * which case the list will be left unmodified.
+   */
+  nsresult CopyFrom(const SVGStringList& rhs);
+
+  nsAString& operator[](PRUint32 aIndex) {
+    return mStrings[aIndex];
+  }
+
+  /**
+   * This may fail (return false) on OOM if the internal capacity is being
+   * increased, in which case the list will be left unmodified.
+   */
+  bool SetLength(PRUint32 aStringOfItems) {
+    return mStrings.SetLength(aStringOfItems);
+  }
+
+private:
+
+  // Marking the following private only serves to show which methods are only
+  // used by our friend classes (as opposed to our subclasses) - it doesn't
+  // really provide additional safety.
+
+  bool InsertItem(PRUint32 aIndex, const nsAString &aString) {
+    if (aIndex >= mStrings.Length()) {
+      aIndex = mStrings.Length();
+    }
+    if (mStrings.InsertElementAt(aIndex, aString)) {
+      mIsSet = true;
+      return true;
+    }
+    return false;
+  }
+
+  void ReplaceItem(PRUint32 aIndex, const nsAString &aString) {
+    NS_ABORT_IF_FALSE(aIndex < mStrings.Length(),
+                      "DOM wrapper caller should have raised INDEX_SIZE_ERR");
+    mStrings[aIndex] = aString;
+  }
+
+  void RemoveItem(PRUint32 aIndex) {
+    NS_ABORT_IF_FALSE(aIndex < mStrings.Length(),
+                      "DOM wrapper caller should have raised INDEX_SIZE_ERR");
+    mStrings.RemoveElementAt(aIndex);
+  }
+
+  bool AppendItem(const nsAString &aString) {
+    if (mStrings.AppendElement(aString)) {
+      mIsSet = true;
+      return true;
+    }
+    return false;
+  }
+
+protected:
+
+  /* See SVGLengthList for the rationale for using nsTArray<float> instead
+   * of nsTArray<float, 1>.
+   */
+  nsTArray<nsString> mStrings;
+  bool mIsSet;
+};
+
+} // namespace mozilla
+
+#endif // MOZILLA_SVGSTRINGLIST_H__
--- a/content/svg/content/src/nsSVGAElement.cpp
+++ b/content/svg/content/src/nsSVGAElement.cpp
@@ -62,21 +62,22 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(A)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGAElement, nsSVGAElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGAElement, nsSVGAElementBase)
 
 DOMCI_NODE_DATA(SVGAElement, nsSVGAElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGAElement)
-  NS_NODE_INTERFACE_TABLE7(nsSVGAElement,
+  NS_NODE_INTERFACE_TABLE8(nsSVGAElement,
                            nsIDOMNode,
                            nsIDOMElement,
                            nsIDOMSVGElement,
                            nsIDOMSVGAElement,
+                           nsIDOMSVGTests,
                            nsIDOMSVGURIReference,
                            nsILink,
                            Link)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGAElementBase)
 
 
 //----------------------------------------------------------------------
--- a/content/svg/content/src/nsSVGAElement.h
+++ b/content/svg/content/src/nsSVGAElement.h
@@ -38,23 +38,25 @@
 #ifndef NS_SVGAELEMENT_H_
 #define NS_SVGAELEMENT_H_
 
 #include "nsSVGGraphicElement.h"
 #include "nsIDOMSVGAElement.h"
 #include "nsIDOMSVGURIReference.h"
 #include "nsILink.h"
 #include "nsSVGString.h"
+#include "DOMSVGTests.h"
 
 #include "Link.h"
 
 typedef nsSVGGraphicElement nsSVGAElementBase;
 
 class nsSVGAElement : public nsSVGAElementBase,
                       public nsIDOMSVGAElement,
+                      public DOMSVGTests,
                       public nsIDOMSVGURIReference,
                       public nsILink,
                       public mozilla::dom::Link
 {
 protected:
   friend nsresult NS_NewSVGAElement(nsIContent **aResult,
                                     already_AddRefed<nsINodeInfo> aNodeInfo);
   nsSVGAElement(already_AddRefed<nsINodeInfo> aNodeInfo);
--- a/content/svg/content/src/nsSVGAltGlyphElement.cpp
+++ b/content/svg/content/src/nsSVGAltGlyphElement.cpp
@@ -99,19 +99,20 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(AltGlyph)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGAltGlyphElement,nsSVGAltGlyphElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGAltGlyphElement,nsSVGAltGlyphElementBase)
 
 DOMCI_NODE_DATA(SVGAltGlyphElement, nsSVGAltGlyphElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGAltGlyphElement)
-  NS_NODE_INTERFACE_TABLE7(nsSVGAltGlyphElement, nsIDOMNode, nsIDOMElement,
+  NS_NODE_INTERFACE_TABLE8(nsSVGAltGlyphElement, nsIDOMNode, nsIDOMElement,
                            nsIDOMSVGElement, nsIDOMSVGAltGlyphElement,
                            nsIDOMSVGTextPositioningElement, nsIDOMSVGTextContentElement,
+                           nsIDOMSVGTests,
                            nsIDOMSVGURIReference)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAltGlyphElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGAltGlyphElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGAltGlyphElement::nsSVGAltGlyphElement(already_AddRefed<nsINodeInfo> aNodeInfo)
--- a/content/svg/content/src/nsSVGAnimateElement.cpp
+++ b/content/svg/content/src/nsSVGAnimateElement.cpp
@@ -76,19 +76,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(Animate)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGAnimateElement,nsSVGAnimateElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGAnimateElement,nsSVGAnimateElementBase)
 
 DOMCI_NODE_DATA(SVGAnimateElement, nsSVGAnimateElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGAnimateElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGAnimateElement, nsIDOMNode, nsIDOMElement,
+  NS_NODE_INTERFACE_TABLE6(nsSVGAnimateElement, nsIDOMNode, nsIDOMElement,
                            nsIDOMSVGElement, nsIDOMSVGAnimationElement,
-                           nsIDOMSVGAnimateElement)
+                           nsIDOMSVGTests, nsIDOMSVGAnimateElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimateElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGAnimateElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGAnimateElement::nsSVGAnimateElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGAnimateElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGAnimateMotionElement.cpp
+++ b/content/svg/content/src/nsSVGAnimateMotionElement.cpp
@@ -46,19 +46,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(AnimateMotion
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGAnimateMotionElement,nsSVGAnimateMotionElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGAnimateMotionElement,nsSVGAnimateMotionElementBase)
 
 DOMCI_NODE_DATA(SVGAnimateMotionElement, nsSVGAnimateMotionElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGAnimateMotionElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGAnimateMotionElement, nsIDOMNode,
+  NS_NODE_INTERFACE_TABLE6(nsSVGAnimateMotionElement, nsIDOMNode,
                            nsIDOMElement, nsIDOMSVGElement,
-                           nsIDOMSVGAnimationElement,
+                           nsIDOMSVGAnimationElement, nsIDOMSVGTests,
                            nsIDOMSVGAnimateMotionElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimateMotionElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGAnimateMotionElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGAnimateMotionElement::nsSVGAnimateMotionElement(already_AddRefed<nsINodeInfo> aNodeInfo)
--- a/content/svg/content/src/nsSVGAnimateTransformElement.cpp
+++ b/content/svg/content/src/nsSVGAnimateTransformElement.cpp
@@ -87,19 +87,20 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(AnimateTransf
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGAnimateTransformElement,nsSVGAnimateTransformElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGAnimateTransformElement,nsSVGAnimateTransformElementBase)
 
 DOMCI_NODE_DATA(SVGAnimateTransformElement, nsSVGAnimateTransformElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGAnimateTransformElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGAnimateTransformElement, nsIDOMNode,
+  NS_NODE_INTERFACE_TABLE6(nsSVGAnimateTransformElement, nsIDOMNode,
                            nsIDOMElement, nsIDOMSVGElement,
                            nsIDOMSVGAnimationElement,
+                           nsIDOMSVGTests,
                            nsIDOMSVGAnimateTransformElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimateTransformElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGAnimateTransformElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGAnimateTransformElement::nsSVGAnimateTransformElement(already_AddRefed<nsINodeInfo> aNodeInfo)
--- a/content/svg/content/src/nsSVGAnimationElement.cpp
+++ b/content/svg/content/src/nsSVGAnimationElement.cpp
@@ -50,16 +50,17 @@ using namespace mozilla::dom;
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGAnimationElement, nsSVGAnimationElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGAnimationElement, nsSVGAnimationElementBase)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGAnimationElement)
   NS_INTERFACE_MAP_ENTRY(nsISMILAnimationElement)
   NS_INTERFACE_MAP_ENTRY(nsIDOMElementTimeControl)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMSVGTests)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGAnimationElementBase)
 
 // Cycle collection magic -- based on nsSVGUseElement
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsSVGAnimationElement)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsSVGAnimationElement,
                                                 nsSVGAnimationElementBase)
   tmp->mHrefTarget.Unlink();
   tmp->mTimedElement.Unlink();
--- a/content/svg/content/src/nsSVGAnimationElement.h
+++ b/content/svg/content/src/nsSVGAnimationElement.h
@@ -38,23 +38,25 @@
 
 #ifndef NS_SVGANIMATIONELEMENT_H_
 #define NS_SVGANIMATIONELEMENT_H_
 
 #include "nsSVGElement.h"
 #include "nsAutoPtr.h"
 #include "nsReferencedElement.h"
 #include "nsIDOMSVGAnimationElement.h"
+#include "DOMSVGTests.h"
 #include "nsIDOMElementTimeControl.h"
 #include "nsISMILAnimationElement.h"
 #include "nsSMILTimedElement.h"
 
 typedef nsSVGElement nsSVGAnimationElementBase;
 
 class nsSVGAnimationElement : public nsSVGAnimationElementBase,
+                              public DOMSVGTests,
                               public nsISMILAnimationElement,
                               public nsIDOMElementTimeControl
 {
 protected:
   nsSVGAnimationElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   nsresult Init();
 
 public:
--- a/content/svg/content/src/nsSVGCircleElement.cpp
+++ b/content/svg/content/src/nsSVGCircleElement.cpp
@@ -95,18 +95,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(Circle)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGCircleElement,nsSVGCircleElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGCircleElement,nsSVGCircleElementBase)
 
 DOMCI_NODE_DATA(SVGCircleElement, nsSVGCircleElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGCircleElement)
-  NS_NODE_INTERFACE_TABLE4(nsSVGCircleElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGCircleElement)
+  NS_NODE_INTERFACE_TABLE5(nsSVGCircleElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGCircleElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGCircleElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGCircleElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGCircleElement::nsSVGCircleElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGCircleElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGClipPathElement.cpp
+++ b/content/svg/content/src/nsSVGClipPathElement.cpp
@@ -55,18 +55,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(ClipPath)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGClipPathElement,nsSVGClipPathElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGClipPathElement,nsSVGClipPathElementBase)
 
 DOMCI_NODE_DATA(SVGClipPathElement, nsSVGClipPathElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGClipPathElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGClipPathElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGClipPathElement,
+  NS_NODE_INTERFACE_TABLE6(nsSVGClipPathElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGClipPathElement,
                            nsIDOMSVGUnitTypes)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGClipPathElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGClipPathElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGClipPathElement::nsSVGClipPathElement(already_AddRefed<nsINodeInfo> aNodeInfo)
--- a/content/svg/content/src/nsSVGClipPathElement.h
+++ b/content/svg/content/src/nsSVGClipPathElement.h
@@ -35,22 +35,24 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __NS_SVGCLIPPATHELEMENT_H__
 #define __NS_SVGCLIPPATHELEMENT_H__
 
 #include "nsSVGGraphicElement.h"
 #include "nsIDOMSVGClipPathElement.h"
 #include "nsIDOMSVGUnitTypes.h"
+#include "DOMSVGTests.h"
 #include "nsSVGEnum.h"
 
 typedef nsSVGGraphicElement nsSVGClipPathElementBase;
 
 class nsSVGClipPathElement : public nsSVGClipPathElementBase,
                              public nsIDOMSVGClipPathElement,
+                             public DOMSVGTests,
                              public nsIDOMSVGUnitTypes
 {
   friend class nsSVGClipPathFrame;
 
 protected:
   friend nsresult NS_NewSVGClipPathElement(nsIContent **aResult,
                                            already_AddRefed<nsINodeInfo> aNodeInfo);
   nsSVGClipPathElement(already_AddRefed<nsINodeInfo> aNodeInfo);
--- a/content/svg/content/src/nsSVGDefsElement.cpp
+++ b/content/svg/content/src/nsSVGDefsElement.cpp
@@ -35,23 +35,25 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Util.h"
 
 #include "nsSVGGraphicElement.h"
 #include "nsIDOMSVGDefsElement.h"
+#include "DOMSVGTests.h"
 
 using namespace mozilla;
 
 typedef nsSVGGraphicElement nsSVGDefsElementBase;
 
 class nsSVGDefsElement : public nsSVGDefsElementBase,
-                         public nsIDOMSVGDefsElement
+                         public nsIDOMSVGDefsElement,
+                         public DOMSVGTests
 {
 protected:
   friend nsresult NS_NewSVGDefsElement(nsIContent **aResult,
                                        already_AddRefed<nsINodeInfo> aNodeInfo);
   nsSVGDefsElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   
 public:
   // interfaces:
@@ -83,18 +85,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(Defs)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGDefsElement,nsSVGDefsElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGDefsElement,nsSVGDefsElementBase)
 
 DOMCI_NODE_DATA(SVGDefsElement, nsSVGDefsElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGDefsElement)
-  NS_NODE_INTERFACE_TABLE4(nsSVGDefsElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGDefsElement)
+  NS_NODE_INTERFACE_TABLE5(nsSVGDefsElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGDefsElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGDefsElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGDefsElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGDefsElement::nsSVGDefsElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGDefsElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -35,17 +35,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Util.h"
 
 #include "nsSVGElement.h"
 #include "nsSVGSVGElement.h"
-#include "nsSVGSwitchElement.h"
 #include "nsIDocument.h"
 #include "nsRange.h"
 #include "nsIDOMAttr.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsMutationEvent.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsBindingManager.h"
@@ -76,16 +75,17 @@
 #include "nsSVGEnum.h"
 #include "nsSVGViewBox.h"
 #include "nsSVGString.h"
 #include "SVGAnimatedNumberList.h"
 #include "SVGAnimatedLengthList.h"
 #include "SVGAnimatedPointList.h"
 #include "SVGAnimatedPathSegList.h"
 #include "SVGAnimatedTransformList.h"
+#include "DOMSVGTests.h"
 #include "nsIDOMSVGUnitTypes.h"
 #include "nsSVGRect.h"
 #include "nsIFrame.h"
 #include "prdtoa.h"
 #include <stdarg.h>
 #include "nsSMILMappedAttribute.h"
 #include "SVGMotionSMILAttr.h"
 
@@ -270,29 +270,16 @@ nsSVGElement::AfterSetAttr(PRInt32 aName
     mContentStyleRule = nsnull;
   }
 
   if (IsEventName(aName) && aValue) {
     nsresult rv = AddScriptEventListener(GetEventNameForAttr(aName), *aValue);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  if (aNamespaceID == kNameSpaceID_None &&
-      (aName == nsGkAtoms::requiredFeatures ||
-       aName == nsGkAtoms::requiredExtensions ||
-       aName == nsGkAtoms::systemLanguage)) {
-
-    nsIContent* parent = GetFlattenedTreeParent();
-  
-    if (parent &&
-        parent->NodeInfo()->Equals(nsGkAtoms::svgSwitch, kNameSpaceID_SVG)) {
-      static_cast<nsSVGSwitchElement*>(parent)->MaybeInvalidate();
-    }
-  }
-
   return nsSVGElementBase::AfterSetAttr(aNamespaceID, aName, aValue, aNotify);
 }
 
 bool
 nsSVGElement::ParseAttribute(PRInt32 aNamespaceID,
                              nsIAtom* aAttribute,
                              const nsAString& aValue,
                              nsAttrValue& aResult)
@@ -477,16 +464,40 @@ nsSVGElement::ParseAttribute(PRInt32 aNa
           }
           foundMatch = true;
           break;
         }
       }
     }
 
     if (!foundMatch) {
+      // Check for conditional processing attributes
+      nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(this));
+      if (tests && tests->ParseConditionalProcessingAttribute(
+                            aAttribute, aValue, aResult)) {
+        foundMatch = true;
+      }
+    }
+
+    if (!foundMatch) {
+      // Check for StringList attribute
+      StringListAttributesInfo stringListInfo = GetStringListInfo();
+      for (i = 0; i < stringListInfo.mStringListCount; i++) {
+        if (aAttribute == *stringListInfo.mStringListInfo[i].mName) {
+          rv = stringListInfo.mStringLists[i].SetValue(aValue, false);
+          if (NS_FAILED(rv)) {
+            stringListInfo.Reset(i);
+          }
+          foundMatch = true;
+          break;
+        }
+      }
+    }
+
+    if (!foundMatch) {
       // Check for nsSVGViewBox attribute
       if (aAttribute == nsGkAtoms::viewBox) {
         nsSVGViewBox* viewBox = GetViewBox();
         if (viewBox) {
           rv = viewBox->SetBaseValueString(aValue, this);
           if (NS_FAILED(rv)) {
             viewBox->Init();
           }
@@ -719,16 +730,33 @@ nsSVGElement::UnsetAttrInternal(PRInt32 
     if (GetTransformListAttrName() == aName) {
       SVGAnimatedTransformList *transformList = GetAnimatedTransformList();
       if (transformList) {
         transformList->ClearBaseValue();
         DidChangeTransformList(false);
         return;
       }
     }
+
+    // Check for conditional processing attributes
+    nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(this));
+    if (tests && tests->IsConditionalProcessingAttribute(aName)) {
+      tests->UnsetAttr(aName);
+      return;
+    }
+
+    // Check if this is a string list attribute going away
+    StringListAttributesInfo stringListInfo = GetStringListInfo();
+
+    for (PRUint32 i = 0; i < stringListInfo.mStringListCount; i++) {
+      if (aName == *stringListInfo.mStringListInfo[i].mName) {
+        stringListInfo.Reset(i);
+        return;
+      }
+    }
   }
 
   // Check if this is a string attribute going away
   StringAttributesInfo stringInfo = GetStringInfo();
 
   for (PRUint32 i = 0; i < stringInfo.mStringCount; i++) {
     if (aNamespaceID == stringInfo.mStringInfo[i].mNamespaceID &&
         aName == *stringInfo.mStringInfo[i].mName) {
@@ -749,22 +777,21 @@ nsSVGElement::UnsetAttr(PRInt32 aNamespa
 
 nsChangeHint
 nsSVGElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
                                      PRInt32 aModType) const
 {
   nsChangeHint retval =
     nsSVGElementBase::GetAttributeChangeHint(aAttribute, aModType);
 
-  if (aAttribute == nsGkAtoms::requiredFeatures ||
-      aAttribute == nsGkAtoms::requiredExtensions ||
-      aAttribute == nsGkAtoms::systemLanguage) {
+  nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(const_cast<nsSVGElement*>(this)));
+  if (tests && tests->IsConditionalProcessingAttribute(aAttribute)) {
     // It would be nice to only reconstruct the frame if the value returned by
-    // NS_SVG_PassesConditionalProcessingTests has changed, but we don't know
-    // that
+    // DOMSVGTests::PassesConditionalProcessingTests has changed, but we don't
+    // know that
     NS_UpdateHint(retval, nsChangeHint_ReconstructFrame);
   }
   return retval;
 }
 
 bool
 nsSVGElement::IsNodeOfType(PRUint32 aFlags) const
 {
@@ -2113,16 +2140,54 @@ nsSVGElement::DidAnimateString(PRUint8 a
   if (frame) {
     StringAttributesInfo info = GetStringInfo();
     frame->AttributeChanged(info.mStringInfo[aAttrEnum].mNamespaceID,
                             *info.mStringInfo[aAttrEnum].mName,
                             nsIDOMMutationEvent::MODIFICATION);
   }
 }
 
+nsSVGElement::StringListAttributesInfo
+nsSVGElement::GetStringListInfo()
+{
+  return StringListAttributesInfo(nsnull, nsnull, 0);
+}
+
+void
+nsSVGElement::DidChangeStringList(bool aIsConditionalProcessingAttribute,
+                                  PRUint8 aAttrEnum)
+{
+  if (aIsConditionalProcessingAttribute) {
+    nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(this));
+    tests->DidChangeStringList(aAttrEnum);
+    return;
+  }
+
+  StringListAttributesInfo info = GetStringListInfo();
+
+  NS_ASSERTION(info.mStringListCount > 0,
+               "DidChangeStringList on element with no string list attribs");
+
+  NS_ASSERTION(aAttrEnum < info.mStringListCount, "aAttrEnum out of range");
+
+  nsAutoString serializedValue;
+  info.mStringLists[aAttrEnum].GetValue(serializedValue, this);
+
+  nsAttrValue attrValue(serializedValue);
+  SetParsedAttr(kNameSpaceID_None, *info.mStringListInfo[aAttrEnum].mName,
+                nsnull, attrValue, true);
+}
+
+void
+nsSVGElement::StringListAttributesInfo::Reset(PRUint8 aAttrEnum)
+{
+  mStringLists[aAttrEnum].Clear();
+  // caller notifies
+}
+
 nsresult
 nsSVGElement::ReportAttributeParseFailure(nsIDocument* aDocument,
                                           nsIAtom* aAttribute,
                                           const nsAString& aValue)
 {
   const nsAFlatString& attributeValue = PromiseFlatString(aValue);
   const PRUnichar *strings[] = { aAttribute->GetUTF16String(),
                                  attributeValue.get() };
--- a/content/svg/content/src/nsSVGElement.h
+++ b/content/svg/content/src/nsSVGElement.h
@@ -71,16 +71,18 @@ namespace mozilla {
 class SVGAnimatedNumberList;
 class SVGNumberList;
 class SVGAnimatedLengthList;
 class SVGUserUnitList;
 class SVGAnimatedPointList;
 class SVGAnimatedPathSegList;
 class SVGAnimatedPreserveAspectRatio;
 class SVGAnimatedTransformList;
+class SVGStringList;
+class DOMSVGStringList;
 }
 
 typedef nsStyledElementNotElementCSSInlineStyle nsSVGElementBase;
 
 class nsSVGElement : public nsSVGElementBase    // nsIContent
 {
 protected:
   nsSVGElement(already_AddRefed<nsINodeInfo> aNodeInfo);
@@ -91,16 +93,17 @@ public:
   typedef mozilla::SVGNumberList SVGNumberList;
   typedef mozilla::SVGAnimatedNumberList SVGAnimatedNumberList;
   typedef mozilla::SVGUserUnitList SVGUserUnitList;
   typedef mozilla::SVGAnimatedLengthList SVGAnimatedLengthList;
   typedef mozilla::SVGAnimatedPointList SVGAnimatedPointList;
   typedef mozilla::SVGAnimatedPathSegList SVGAnimatedPathSegList;
   typedef mozilla::SVGAnimatedPreserveAspectRatio SVGAnimatedPreserveAspectRatio;
   typedef mozilla::SVGAnimatedTransformList SVGAnimatedTransformList;
+  typedef mozilla::SVGStringList SVGStringList;
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIContent interface methods
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
@@ -172,16 +175,18 @@ public:
   virtual void DidChangeViewBox(bool aDoSetAttr);
   virtual void DidChangePreserveAspectRatio(bool aDoSetAttr);
   virtual void DidChangeNumberList(PRUint8 aAttrEnum, bool aDoSetAttr);
   virtual void DidChangeLengthList(PRUint8 aAttrEnum, bool aDoSetAttr);
   virtual void DidChangePointList(bool aDoSetAttr);
   virtual void DidChangePathSegList(bool aDoSetAttr);
   virtual void DidChangeTransformList(bool aDoSetAttr);
   virtual void DidChangeString(PRUint8 aAttrEnum) {}
+  void DidChangeStringList(bool aIsConditionalProcessingAttribute,
+                           PRUint8 aAttrEnum);
 
   virtual void DidAnimateLength(PRUint8 aAttrEnum);
   virtual void DidAnimateNumber(PRUint8 aAttrEnum);
   virtual void DidAnimateNumberPair(PRUint8 aAttrEnum);
   virtual void DidAnimateInteger(PRUint8 aAttrEnum);
   virtual void DidAnimateIntegerPair(PRUint8 aAttrEnum);
   virtual void DidAnimateAngle(PRUint8 aAttrEnum);
   virtual void DidAnimateBoolean(PRUint8 aAttrEnum);
@@ -484,31 +489,53 @@ protected:
                          StringInfo *aStringInfo,
                          PRUint32 aStringCount) :
       mStrings(aStrings), mStringInfo(aStringInfo), mStringCount(aStringCount)
       {}
 
     void Reset(PRUint8 aAttrEnum);
   };
 
+  friend class mozilla::DOMSVGStringList;
+
+  struct StringListInfo {
+    nsIAtom**    mName;
+  };
+
+  struct StringListAttributesInfo {
+    SVGStringList*    mStringLists;
+    StringListInfo*   mStringListInfo;
+    PRUint32          mStringListCount;
+
+    StringListAttributesInfo(SVGStringList  *aStringLists,
+                             StringListInfo *aStringListInfo,
+                             PRUint32 aStringListCount) :
+      mStringLists(aStringLists), mStringListInfo(aStringListInfo),
+      mStringListCount(aStringListCount)
+      {}
+
+    void Reset(PRUint8 aAttrEnum);
+  };
+
   virtual LengthAttributesInfo GetLengthInfo();
   virtual NumberAttributesInfo GetNumberInfo();
   virtual NumberPairAttributesInfo GetNumberPairInfo();
   virtual IntegerAttributesInfo GetIntegerInfo();
   virtual IntegerPairAttributesInfo GetIntegerPairInfo();
   virtual AngleAttributesInfo GetAngleInfo();
   virtual BooleanAttributesInfo GetBooleanInfo();
   virtual EnumAttributesInfo GetEnumInfo();
   // We assume all viewboxes and preserveAspectRatios are alike
   // so we don't need to wrap the class
   virtual nsSVGViewBox *GetViewBox();
   virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio();
   virtual NumberListAttributesInfo GetNumberListInfo();
   virtual LengthListAttributesInfo GetLengthListInfo();
   virtual StringAttributesInfo GetStringInfo();
+  virtual StringListAttributesInfo GetStringListInfo();
 
   static nsSVGEnumMapping sSVGUnitTypesMap[];
 
 private:
   void UnsetAttrInternal(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
                          bool aNotify);
 
   nsRefPtr<mozilla::css::StyleRule> mContentStyleRule;
deleted file mode 100644
--- a/content/svg/content/src/nsSVGElementList.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Scooter Morris.
- * Portions created by the Initial Developer are Copyright (C) 2006
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Scooter Morris <scootermorris@comcast.net>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/**
- * This file is used to help create a mapping from a specified SVG element to
- * attributes supported by that element. This mapping can be used to help
- * ensure that we don't accidentally implement support for attributes like
- * requiredFeatures on elements for which the SVG specification does not
- * define support.
- *
- * To use, include this file into another file after defining the SVG_ELEMENT
- * C preprocessor macro as appropriate.
- *
- * The following constants represent the following attributes:
- *
- * ATTRS_CONDITIONAL
- *   The requiredFeatures, requiredExtensions, and systemLanguage attributes
- *
- * ATTRS_EXTERNAL
- *   The externalResourcesRequired attribute
- *
- * ATTRS_ALL
- *   A convenience value indicating support for all of the above
- *
- * ATTRS_NONE
- *   A convenience value indicating support for none of the above
- */
-
-//This file must not have include guards.
-
-#define ATTRS_NONE        0x00
-#define ATTRS_CONDITIONAL 0x01
-#define ATTRS_EXTERNAL    0x02
-#define ATTRS_ALL         (ATTRS_CONDITIONAL | ATTRS_EXTERNAL)
-// tags
-SVG_ELEMENT(a, ATTRS_ALL)
-SVG_ELEMENT(altGlyph, ATTRS_ALL)
-SVG_ELEMENT(altGlyphDef, ATTRS_NONE)
-SVG_ELEMENT(altGlyphItem, ATTRS_NONE)
-SVG_ELEMENT(animate, ATTRS_ALL)
-SVG_ELEMENT(animateColor, ATTRS_ALL)
-SVG_ELEMENT(animateMotion, ATTRS_ALL)
-SVG_ELEMENT(animateTransform, ATTRS_ALL)
-SVG_ELEMENT(circle, ATTRS_ALL)
-SVG_ELEMENT(clipPath, ATTRS_ALL)
-SVG_ELEMENT(colorProfile, ATTRS_NONE)
-SVG_ELEMENT(cursor, ATTRS_ALL)
-SVG_ELEMENT(definition_src, ATTRS_NONE)
-SVG_ELEMENT(defs, ATTRS_ALL)
-SVG_ELEMENT(desc, ATTRS_NONE)
-SVG_ELEMENT(ellipse, ATTRS_ALL)
-SVG_ELEMENT(feBlend, ATTRS_NONE)
-SVG_ELEMENT(feColorMatrix, ATTRS_NONE)
-SVG_ELEMENT(feComponentTransfer, ATTRS_NONE)
-SVG_ELEMENT(feComposite, ATTRS_NONE)
-SVG_ELEMENT(feConvolveMatrix, ATTRS_NONE)
-SVG_ELEMENT(feDiffuseLighting, ATTRS_NONE)
-SVG_ELEMENT(feDisplacementMap, ATTRS_NONE)
-SVG_ELEMENT(feDistantLight, ATTRS_NONE)
-SVG_ELEMENT(feFlood, ATTRS_NONE)
-SVG_ELEMENT(feFuncR, ATTRS_NONE)
-SVG_ELEMENT(feFuncG, ATTRS_NONE)
-SVG_ELEMENT(feFuncB, ATTRS_NONE)
-SVG_ELEMENT(feFuncA, ATTRS_NONE)
-SVG_ELEMENT(feGaussianBlur, ATTRS_NONE)
-SVG_ELEMENT(feImage, ATTRS_EXTERNAL)
-SVG_ELEMENT(feMerge, ATTRS_NONE)
-SVG_ELEMENT(feMergeNode, ATTRS_NONE)
-SVG_ELEMENT(feMorphology, ATTRS_NONE)
-SVG_ELEMENT(feOffset, ATTRS_NONE)
-SVG_ELEMENT(fePointLight, ATTRS_NONE)
-SVG_ELEMENT(feSpecularLighting, ATTRS_NONE)
-SVG_ELEMENT(feSpotLight, ATTRS_NONE)
-SVG_ELEMENT(feTile, ATTRS_NONE)
-SVG_ELEMENT(feTurbulence, ATTRS_NONE)
-SVG_ELEMENT(filter, ATTRS_EXTERNAL)
-SVG_ELEMENT(font, ATTRS_EXTERNAL)
-SVG_ELEMENT(font_face, ATTRS_NONE)
-SVG_ELEMENT(font_face_format, ATTRS_NONE)
-SVG_ELEMENT(font_face_name, ATTRS_NONE)
-SVG_ELEMENT(font_face_src, ATTRS_NONE)
-SVG_ELEMENT(font_face_uri, ATTRS_NONE)
-SVG_ELEMENT(foreignObject, ATTRS_ALL)
-SVG_ELEMENT(g, ATTRS_ALL)
-SVG_ELEMENT(glyph, ATTRS_NONE)
-SVG_ELEMENT(glyphRef, ATTRS_NONE)
-SVG_ELEMENT(hkern, ATTRS_NONE)
-SVG_ELEMENT(image, ATTRS_ALL)
-SVG_ELEMENT(line, ATTRS_ALL)
-SVG_ELEMENT(linearGradient, ATTRS_EXTERNAL)
-SVG_ELEMENT(marker, ATTRS_NONE)
-SVG_ELEMENT(mask, ATTRS_ALL)
-SVG_ELEMENT(metadata, ATTRS_NONE)
-SVG_ELEMENT(missingGlyph, ATTRS_NONE)
-SVG_ELEMENT(mpath, ATTRS_EXTERNAL)
-SVG_ELEMENT(path, ATTRS_ALL)
-SVG_ELEMENT(pattern, ATTRS_ALL)
-SVG_ELEMENT(polygon, ATTRS_ALL)
-SVG_ELEMENT(polyline, ATTRS_ALL)
-SVG_ELEMENT(radialGradient, ATTRS_EXTERNAL)
-SVG_ELEMENT(rect, ATTRS_ALL)
-SVG_ELEMENT(script, ATTRS_EXTERNAL)
-SVG_ELEMENT(set, ATTRS_ALL)
-SVG_ELEMENT(stop, ATTRS_NONE)
-SVG_ELEMENT(style, ATTRS_NONE)
-SVG_ELEMENT(svg, ATTRS_ALL)
-SVG_ELEMENT(svgSwitch, ATTRS_ALL) // switch is a C++ keyword, hence svgSwitch
-SVG_ELEMENT(symbol, ATTRS_NONE)
-SVG_ELEMENT(text, ATTRS_ALL)
-SVG_ELEMENT(textPath, ATTRS_ALL)
-SVG_ELEMENT(title, ATTRS_NONE)
-SVG_ELEMENT(tref, ATTRS_ALL)
-SVG_ELEMENT(tspan, ATTRS_ALL)
-SVG_ELEMENT(use, ATTRS_ALL)
-SVG_ELEMENT(view, ATTRS_EXTERNAL)
-SVG_ELEMENT(vkern, ATTRS_NONE)
--- a/content/svg/content/src/nsSVGEllipseElement.cpp
+++ b/content/svg/content/src/nsSVGEllipseElement.cpp
@@ -97,18 +97,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(Ellipse)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGEllipseElement,nsSVGEllipseElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGEllipseElement,nsSVGEllipseElementBase)
 
 DOMCI_NODE_DATA(SVGEllipseElement, nsSVGEllipseElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGEllipseElement)
-  NS_NODE_INTERFACE_TABLE4(nsSVGEllipseElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGEllipseElement)
+  NS_NODE_INTERFACE_TABLE5(nsSVGEllipseElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGEllipseElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGEllipseElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGEllipseElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGEllipseElement::nsSVGEllipseElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGEllipseElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGFeatures.cpp
+++ b/content/svg/content/src/nsSVGFeatures.cpp
@@ -42,30 +42,23 @@
  * This file contains code to help implement the Conditional Processing
  * section of the SVG specification (i.e. the <switch> element and the
  * requiredFeatures, requiredExtensions and systemLanguage attributes).
  *
  *   http://www.w3.org/TR/SVG11/struct.html#ConditionalProcessing
  */
 
 #include "nsSVGFeatures.h"
-#include "nsGkAtoms.h"
 #include "nsIContent.h"
-#include "nsContentUtils.h"
-#include "nsWhitespaceTokenizer.h"
-#include "nsCharSeparatedTokenizer.h"
-#include "nsStyleUtil.h"
-#include "nsSVGUtils.h"
-#include "nsServiceManagerUtils.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 
 /*static*/ bool
-nsSVGFeatures::HaveFeature(nsISupports* aObject, const nsAString& aFeature)
+nsSVGFeatures::HasFeature(nsISupports* aObject, const nsAString& aFeature)
 {
   if (aFeature.EqualsLiteral("http://www.w3.org/TR/SVG11/feature#Script")) {
     nsCOMPtr<nsIContent> content(do_QueryInterface(aObject));
     if (content) {
       nsIDocument *doc = content->GetCurrentDoc();
       if (doc && doc->IsResourceDoc()) {
         // no scripting in SVG images or external resource documents
         return false;
@@ -77,173 +70,17 @@ nsSVGFeatures::HaveFeature(nsISupports* 
 #define SVG_UNSUPPORTED_FEATURE(str)
 #include "nsSVGFeaturesList.h"
 #undef SVG_SUPPORTED_FEATURE
 #undef SVG_UNSUPPORTED_FEATURE
   return false;
 }
 
 /*static*/ bool
-nsSVGFeatures::HaveFeatures(nsISupports* aObject, const nsSubstring& aFeatures)
-{
-  nsWhitespaceTokenizer tokenizer(aFeatures);
-  while (tokenizer.hasMoreTokens()) {
-    if (!HaveFeature(aObject, tokenizer.nextToken())) {
-      return false;
-    }
-  }
-  return true;
-}
-
-/*static*/ bool
-nsSVGFeatures::HaveExtension(const nsAString& aExtension)
+nsSVGFeatures::HasExtension(const nsAString& aExtension)
 {
 #define SVG_SUPPORTED_EXTENSION(str) if (aExtension.EqualsLiteral(str)) return true;
   SVG_SUPPORTED_EXTENSION("http://www.w3.org/1999/xhtml")
   SVG_SUPPORTED_EXTENSION("http://www.w3.org/1998/Math/MathML")
 #undef SVG_SUPPORTED_EXTENSION
 
   return false;
 }
-
-/*static*/ bool
-nsSVGFeatures::HaveExtensions(const nsSubstring& aExtensions)
-{
-  nsWhitespaceTokenizer tokenizer(aExtensions);
-  while (tokenizer.hasMoreTokens()) {
-    if (!HaveExtension(tokenizer.nextToken())) {
-      return false;
-    }
-  }
-  return true;
-}
-
-/*static*/ bool
-nsSVGFeatures::MatchesLanguagePreferences(const nsSubstring& aAttribute,
-                                          const nsSubstring& aAcceptLangs) 
-{
-  const nsDefaultStringComparator defaultComparator;
-
-  nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
-    attributeTokenizer(aAttribute, ',');
-
-  while (attributeTokenizer.hasMoreTokens()) {
-    const nsSubstring &attributeToken = attributeTokenizer.nextToken();
-    nsCharSeparatedTokenizer languageTokenizer(aAcceptLangs, ',');
-    while (languageTokenizer.hasMoreTokens()) {
-      if (nsStyleUtil::DashMatchCompare(attributeToken,
-                                        languageTokenizer.nextToken(),
-                                        defaultComparator)) {
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-/*static*/ PRInt32
-nsSVGFeatures::GetBestLanguagePreferenceRank(const nsSubstring& aAttribute,
-                                             const nsSubstring& aAcceptLangs) 
-{
-  const nsDefaultStringComparator defaultComparator;
-
-  nsCharSeparatedTokenizer attributeTokenizer(aAttribute, ',');
-  PRInt32 lowestRank = -1;
-
-  while (attributeTokenizer.hasMoreTokens()) {
-    const nsSubstring &attributeToken = attributeTokenizer.nextToken();
-    nsCharSeparatedTokenizer languageTokenizer(aAcceptLangs, ',');
-    PRInt32 index = 0;
-    while (languageTokenizer.hasMoreTokens()) {
-      const nsSubstring &languageToken = languageTokenizer.nextToken();
-      bool exactMatch = (languageToken == attributeToken);
-      bool prefixOnlyMatch =
-        !exactMatch &&
-        nsStyleUtil::DashMatchCompare(attributeToken,
-                                      languageTokenizer.nextToken(),
-                                      defaultComparator);
-      if (index == 0 && exactMatch) {
-        // best possible match
-        return 0;
-      }
-      if ((exactMatch || prefixOnlyMatch) &&
-          (lowestRank == -1 || 2 * index + prefixOnlyMatch < lowestRank)) {
-        lowestRank = 2 * index + prefixOnlyMatch;
-      }
-      ++index;
-    }
-  }
-  return lowestRank;
-}
-
-/*static*/ bool
-nsSVGFeatures::ElementSupportsAttributes(const nsIAtom *aTagName, PRUint16 aAttr)
-{
-#define SVG_ELEMENT(_atom, _supports) if (aTagName == nsGkAtoms::_atom) return (_supports & aAttr) != 0;
-#include "nsSVGElementList.h"
-#undef SVG_ELEMENT
-  return false;
-}
-
-const nsString * const nsSVGFeatures::kIgnoreSystemLanguage = (nsString *) 0x01;
-
-/*static*/ bool
-nsSVGFeatures::PassesConditionalProcessingTests(nsIContent *aContent,
-                                                const nsString *aAcceptLangs)
-{
-  if (!aContent->IsElement()) {
-    return false;
-  }
-
-  if (!ElementSupportsAttributes(aContent->Tag(), ATTRS_CONDITIONAL)) {
-    return true;
-  }
-
-  // Required Features
-  nsAutoString value;
-  if (aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::requiredFeatures, value)) {
-    if (value.IsEmpty() || !HaveFeatures(aContent, value)) {
-      return false;
-    }
-  }
-
-  // Required Extensions
-  //
-  // The requiredExtensions  attribute defines a list of required language
-  // extensions. Language extensions are capabilities within a user agent that
-  // go beyond the feature set defined in the SVG specification.
-  // Each extension is identified by a URI reference.
-  // For now, claim that mozilla's SVG implementation supports XHTML and MathML.
-  if (aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::requiredExtensions, value)) {
-    if (value.IsEmpty() || !HaveExtensions(value)) {
-      return false;
-    }
-  }
-
-  if (aAcceptLangs == kIgnoreSystemLanguage) {
-    return true;
-  }
-
-  // systemLanguage
-  //
-  // Evaluates to "true" if one of the languages indicated by user preferences
-  // exactly equals one of the languages given in the value of this parameter,
-  // or if one of the languages indicated by user preferences exactly equals a
-  // prefix of one of the languages given in the value of this parameter such
-  // that the first tag character following the prefix is "-".
-  if (aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::systemLanguage,
-                        value)) {
-
-    const nsAutoString acceptLangs(aAcceptLangs ? *aAcceptLangs :
-      Preferences::GetLocalizedString("intl.accept_languages"));
-
-    // Get our language preferences
-    if (!acceptLangs.IsEmpty()) {
-      return MatchesLanguagePreferences(value, acceptLangs);
-    } else {
-      // For now, evaluate to true.
-      NS_WARNING("no default language specified for systemLanguage conditional test");
-      return !value.IsEmpty();
-    }
-  }
-
-  return true;
-}
--- a/content/svg/content/src/nsSVGFeatures.h
+++ b/content/svg/content/src/nsSVGFeatures.h
@@ -36,119 +36,33 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __NS_SVGFEATURES_H__
 #define __NS_SVGFEATURES_H__
 
 #include "nsString.h"
 
-class nsIContent;
-class nsIAtom;
-
 class nsSVGFeatures
 {
 public:
   /**
    * Check whether we support the given feature string.
    *
    * @param aObject the object, which should support the feature,
    *        for example nsIDOMNode or nsIDOMDOMImplementation
    * @param aFeature one of the feature strings specified at
    *    http://www.w3.org/TR/SVG11/feature.html
    */
   static bool
-  HaveFeature(nsISupports* aObject, const nsAString& aFeature);
-
-  /**
-   * Compare the language name(s) in a systemLanguage attribute to the
-   * user's language preferences, as defined in
-   * http://www.w3.org/TR/SVG11/struct.html#SystemLanguageAttribute
-   * We have a match if a language name in the users language preferences
-   * exactly equals one of the language names or exactly equals a prefix of
-   * one of the language names in the systemLanguage attribute.
-   * @returns 2 * the lowest index in the aAcceptLangs that matches + 1
-   * if only the prefix matches, or -1 if no indices match.
-   * XXX This algorithm is O(M*N).
-   */
-  static int
-  GetBestLanguagePreferenceRank(const nsSubstring& aAttribute,
-                                const nsSubstring& aAcceptLangs);
-
-  /**
-   * Special value to pass to PassesConditionalProcessingTests to ignore systemLanguage
-   * attributes
-   */
-  static const nsString * const kIgnoreSystemLanguage;
-
-  /**
-   * Check whether the conditional processing attributes requiredFeatures,
-   * requiredExtensions and systemLanguage all "return true" if they apply to
-   * and are specified on the given element. Returns true if this element
-   * should be rendered, false if it should not.
-   *
-   * @param aContent the element to test
-   * @param aAcceptLangs Optional parameter to pass in the value of the
-   *   intl.accept_languages preference if the caller has it cached.
-   *   Alternatively, pass in kIgnoreSystemLanguage to skip the systemLanguage
-   *   check if the caller is giving that special treatment.
-   */
-  static bool
-  PassesConditionalProcessingTests(nsIContent *aContent,
-                                   const nsString *aAcceptLangs = nsnull);
-
-private:
-  /**
-   * Check whether we support the given list of feature strings.
-   *
-   * @param aObject the object, which should support the feature,
-   *        for example nsIDOMNode or nsIDOMDOMImplementation
-   * @param aFeatures a whitespace separated list containing one or more of the
-   *   feature strings specified at http://www.w3.org/TR/SVG11/feature.html
-   */
-  static bool
-  HaveFeatures(nsISupports* aObject, const nsSubstring& aFeatures);
+  HasFeature(nsISupports* aObject, const nsAString& aFeature);
 
   /**
    * Check whether we support the given extension string.
    *
    * @param aExtension the URI of an extension. Known extensions are
    *   "http://www.w3.org/1999/xhtml" and "http://www.w3.org/1998/Math/MathML"
    */
   static bool
-  HaveExtension(const nsAString& aExtension);
-
-  /**
-   * Check whether we support the given list of extension strings.
-   *
-   * @param aExtension a whitespace separated list containing one or more
-   *   extension strings
-   */
-  static bool
-  HaveExtensions(const nsSubstring& aExtensions);
-
-  /**
-   * Compare the language name(s) in a systemLanguage attribute to the
-   * user's language preferences, as defined in
-   * http://www.w3.org/TR/SVG11/struct.html#SystemLanguageAttribute
-   * We have a match if a language name in the users language preferences
-   * exactly equals one of the language names or exactly equals a prefix of
-   * one of the language names in the systemLanguage attribute.
-   * XXX This algorithm is O(M*N).
-   */
-  static bool
-  MatchesLanguagePreferences(const nsSubstring& aAttribute,
-                             const nsSubstring& aAcceptLangs); 
-
-  /**
-   * Check whether this element supports the specified attributes
-   * (i.e. whether the SVG specification defines the attributes
-   * for the specified element).
-   *
-   * @param aTagName the tag for the element
-   * @param aAttr the conditional to test for, either
-   *    ATTRS_TEST or ATTRS_EXTERNAL
-   */
-  static bool
-  ElementSupportsAttributes(const nsIAtom *aTagName, PRUint16 aAttr);
+  HasExtension(const nsAString& aExtension);
 };
 
 #endif // __NS_SVGFEATURES_H__
--- a/content/svg/content/src/nsSVGFilterElement.cpp
+++ b/content/svg/content/src/nsSVGFilterElement.cpp
@@ -79,18 +79,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(Filter)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGFilterElement,nsSVGFilterElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGFilterElement,nsSVGFilterElementBase)
 
 DOMCI_NODE_DATA(SVGFilterElement, nsSVGFilterElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGFilterElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGFilterElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGFilterElement,
+  NS_NODE_INTERFACE_TABLE6(nsSVGFilterElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGFilterElement,
                            nsIDOMSVGURIReference)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFilterElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGFilterElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGFilterElement::nsSVGFilterElement(already_AddRefed<nsINodeInfo> aNodeInfo)
--- a/content/svg/content/src/nsSVGFilterElement.h
+++ b/content/svg/content/src/nsSVGFilterElement.h
@@ -36,25 +36,27 @@
 
 #ifndef __NS_SVGFILTERELEMENT_H__
 #define __NS_SVGFILTERELEMENT_H__
 
 #include "nsSVGGraphicElement.h"
 #include "nsIDOMSVGFilterElement.h"
 #include "nsIDOMSVGURIReference.h"
 #include "nsIDOMSVGUnitTypes.h"
+#include "DOMSVGTests.h"
 #include "nsSVGLength2.h"
 #include "nsSVGIntegerPair.h"
 #include "nsSVGEnum.h"
 #include "nsSVGString.h"
 
 typedef nsSVGGraphicElement nsSVGFilterElementBase;
 
 class nsSVGFilterElement : public nsSVGFilterElementBase,
                            public nsIDOMSVGFilterElement,
+                           public DOMSVGTests,
                            public nsIDOMSVGURIReference,
                            public nsIDOMSVGUnitTypes
 {
   friend class nsSVGFilterFrame;
   friend class nsAutoFilterInstance;
 
 protected:
   friend nsresult NS_NewSVGFilterElement(nsIContent **aResult,
--- a/content/svg/content/src/nsSVGForeignObjectElement.cpp
+++ b/content/svg/content/src/nsSVGForeignObjectElement.cpp
@@ -57,18 +57,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(ForeignObject
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGForeignObjectElement,nsSVGForeignObjectElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGForeignObjectElement,nsSVGForeignObjectElementBase)
 
 DOMCI_NODE_DATA(SVGForeignObjectElement, nsSVGForeignObjectElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGForeignObjectElement)
-  NS_NODE_INTERFACE_TABLE4(nsSVGForeignObjectElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGForeignObjectElement)
+  NS_NODE_INTERFACE_TABLE5(nsSVGForeignObjectElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGForeignObjectElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGForeignObjectElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGForeignObjectElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGForeignObjectElement::nsSVGForeignObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGForeignObjectElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGForeignObjectElement.h
+++ b/content/svg/content/src/nsSVGForeignObjectElement.h
@@ -36,22 +36,24 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __NS_SVGFOREIGNOBJECTELEMENT_H__
 #define __NS_SVGFOREIGNOBJECTELEMENT_H__
 
 #include "nsSVGGraphicElement.h"
 #include "nsIDOMSVGForeignObjectElem.h"
+#include "DOMSVGTests.h"
 #include "nsSVGLength2.h"
 
 typedef nsSVGGraphicElement nsSVGForeignObjectElementBase;
 
 class nsSVGForeignObjectElement : public nsSVGForeignObjectElementBase,
-                                  public nsIDOMSVGForeignObjectElement
+                                  public nsIDOMSVGForeignObjectElement,
+                                  public DOMSVGTests
 {
   friend class nsSVGForeignObjectFrame;
 
 protected:
   friend nsresult NS_NewSVGForeignObjectElement(nsIContent **aResult,
                                                 already_AddRefed<nsINodeInfo> aNodeInfo);
   nsSVGForeignObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
--- a/content/svg/content/src/nsSVGGElement.cpp
+++ b/content/svg/content/src/nsSVGGElement.cpp
@@ -35,23 +35,25 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Util.h"
 
 #include "nsSVGGraphicElement.h"
 #include "nsIDOMSVGGElement.h"
+#include "DOMSVGTests.h"
 
 using namespace mozilla;
 
 typedef nsSVGGraphicElement nsSVGGElementBase;
 
 class nsSVGGElement : public nsSVGGElementBase,
-                      public nsIDOMSVGGElement
+                      public nsIDOMSVGGElement,
+                      public DOMSVGTests
 {
 protected:
   friend nsresult NS_NewSVGGElement(nsIContent **aResult,
                                     already_AddRefed<nsINodeInfo> aNodeInfo);
   nsSVGGElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   
 public:
   // interfaces:
@@ -83,18 +85,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(G)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGGElement,nsSVGGElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGGElement,nsSVGGElementBase)
 
 DOMCI_NODE_DATA(SVGGElement, nsSVGGElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGGElement)
-  NS_NODE_INTERFACE_TABLE4(nsSVGGElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGGElement)
+  NS_NODE_INTERFACE_TABLE5(nsSVGGElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGGElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGGElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGGElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGGElement::nsSVGGElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGGElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGGradientElement.cpp
+++ b/content/svg/content/src/nsSVGGradientElement.cpp
@@ -178,18 +178,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(LinearGradien
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGLinearGradientElement,nsSVGLinearGradientElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGLinearGradientElement,nsSVGLinearGradientElementBase)
 
 DOMCI_NODE_DATA(SVGLinearGradientElement, nsSVGLinearGradientElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGLinearGradientElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGLinearGradientElement, nsIDOMNode,
+  NS_NODE_INTERFACE_TABLE6(nsSVGLinearGradientElement, nsIDOMNode,
                            nsIDOMElement, nsIDOMSVGElement,
+                           nsIDOMSVGTests,
                            nsIDOMSVGGradientElement,
                            nsIDOMSVGLinearGradientElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGLinearGradientElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGLinearGradientElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
@@ -267,18 +268,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(RadialGradien
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGRadialGradientElement,nsSVGRadialGradientElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGRadialGradientElement,nsSVGRadialGradientElementBase)
 
 DOMCI_NODE_DATA(SVGRadialGradientElement, nsSVGRadialGradientElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGRadialGradientElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGRadialGradientElement, nsIDOMNode,
+  NS_NODE_INTERFACE_TABLE6(nsSVGRadialGradientElement, nsIDOMNode,
                            nsIDOMElement, nsIDOMSVGElement,
+                           nsIDOMSVGTests,
                            nsIDOMSVGGradientElement,
                            nsIDOMSVGRadialGradientElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGRadialGradientElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGRadialGradientElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
--- a/content/svg/content/src/nsSVGGradientElement.h
+++ b/content/svg/content/src/nsSVGGradientElement.h
@@ -36,28 +36,30 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __NS_SVGGRADIENTELEMENT_H__
 #define __NS_SVGGRADIENTELEMENT_H__
 
 #include "nsIDOMSVGURIReference.h"
 #include "nsIDOMSVGGradientElement.h"
+#include "DOMSVGTests.h"
 #include "nsIDOMSVGUnitTypes.h"
 #include "nsSVGStylableElement.h"
 #include "nsSVGLength2.h"
 #include "nsSVGEnum.h"
 #include "nsSVGString.h"
 #include "SVGAnimatedTransformList.h"
 
 //--------------------- Gradients------------------------
 
 typedef nsSVGStylableElement nsSVGGradientElementBase;
 
 class nsSVGGradientElement : public nsSVGGradientElementBase,
+                             public DOMSVGTests,
                              public nsIDOMSVGURIReference,
                              public nsIDOMSVGUnitTypes
 {
   friend class nsSVGGradientFrame;
 
 protected:
   nsSVGGradientElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
--- a/content/svg/content/src/nsSVGImageElement.cpp
+++ b/content/svg/content/src/nsSVGImageElement.cpp
@@ -67,18 +67,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(Image)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGImageElement,nsSVGImageElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGImageElement,nsSVGImageElementBase)
 
 DOMCI_NODE_DATA(SVGImageElement, nsSVGImageElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGImageElement)
-  NS_NODE_INTERFACE_TABLE7(nsSVGImageElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGImageElement,
+  NS_NODE_INTERFACE_TABLE8(nsSVGImageElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGImageElement,
                            nsIDOMSVGURIReference, imgIDecoderObserver,
                            nsIImageLoadingContent)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGImageElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGImageElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
--- a/content/svg/content/src/nsSVGLineElement.cpp
+++ b/content/svg/content/src/nsSVGLineElement.cpp
@@ -101,18 +101,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(Line)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGLineElement,nsSVGLineElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGLineElement,nsSVGLineElementBase)
 
 DOMCI_NODE_DATA(SVGLineElement, nsSVGLineElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGLineElement)
-  NS_NODE_INTERFACE_TABLE4(nsSVGLineElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGLineElement)
+  NS_NODE_INTERFACE_TABLE5(nsSVGLineElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGLineElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGLineElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGLineElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGLineElement::nsSVGLineElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGLineElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGMaskElement.cpp
+++ b/content/svg/content/src/nsSVGMaskElement.cpp
@@ -70,19 +70,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(Mask)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGMaskElement,nsSVGMaskElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGMaskElement,nsSVGMaskElementBase)
 
 DOMCI_NODE_DATA(SVGMaskElement, nsSVGMaskElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGMaskElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGMaskElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGMaskElement,
-                           nsIDOMSVGUnitTypes)
+  NS_NODE_INTERFACE_TABLE6(nsSVGMaskElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGMaskElement, nsIDOMSVGUnitTypes)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGMaskElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGMaskElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGMaskElement::nsSVGMaskElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGMaskElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGMaskElement.h
+++ b/content/svg/content/src/nsSVGMaskElement.h
@@ -34,26 +34,28 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __NS_SVGMASKELEMENT_H__
 #define __NS_SVGMASKELEMENT_H__
 
 #include "nsSVGStylableElement.h"
 #include "nsIDOMSVGMaskElement.h"
+#include "DOMSVGTests.h"
 #include "nsIDOMSVGUnitTypes.h"
 #include "nsSVGLength2.h"
 #include "nsSVGEnum.h"
 
 //--------------------- Masks ------------------------
 
 typedef nsSVGStylableElement nsSVGMaskElementBase;
 
 class nsSVGMaskElement : public nsSVGMaskElementBase,
                          public nsIDOMSVGMaskElement,
+                         public DOMSVGTests,
                          public nsIDOMSVGUnitTypes
 {
   friend class nsSVGMaskFrame;
 
 protected:
   friend nsresult NS_NewSVGMaskElement(nsIContent **aResult,
                                        already_AddRefed<nsINodeInfo> aNodeInfo);
   nsSVGMaskElement(already_AddRefed<nsINodeInfo> aNodeInfo);
--- a/content/svg/content/src/nsSVGPathElement.cpp
+++ b/content/svg/content/src/nsSVGPathElement.cpp
@@ -62,19 +62,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(Path)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGPathElement,nsSVGPathElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGPathElement,nsSVGPathElementBase)
 
 DOMCI_NODE_DATA(SVGPathElement, nsSVGPathElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGPathElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGPathElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGPathElement,
-                           nsIDOMSVGAnimatedPathData)
+  NS_NODE_INTERFACE_TABLE6(nsSVGPathElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGPathElement, nsIDOMSVGAnimatedPathData)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGPathElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGPathElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGPathElement::nsSVGPathElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGPathElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGPathGeometryElement.cpp
+++ b/content/svg/content/src/nsSVGPathGeometryElement.cpp
@@ -31,16 +31,29 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsSVGPathGeometryElement.h"
 
+//----------------------------------------------------------------------
+// nsISupports methods
+
+NS_IMPL_ADDREF_INHERITED(nsSVGPathGeometryElement, nsSVGPathGeometryElementBase)
+NS_IMPL_RELEASE_INHERITED(nsSVGPathGeometryElement, nsSVGPathGeometryElementBase)
+
+NS_INTERFACE_MAP_BEGIN(nsSVGPathGeometryElement)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMSVGTests)
+NS_INTERFACE_MAP_END_INHERITING(nsSVGPathGeometryElementBase)
+
+//----------------------------------------------------------------------
+// Implementation
+
 nsSVGPathGeometryElement::nsSVGPathGeometryElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGPathGeometryElementBase(aNodeInfo)
 {
 }
 
 bool
 nsSVGPathGeometryElement::AttributeDefinesGeometry(const nsIAtom *aName)
 {
--- a/content/svg/content/src/nsSVGPathGeometryElement.h
+++ b/content/svg/content/src/nsSVGPathGeometryElement.h
@@ -33,35 +33,40 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __NS_SVGPATHGEOMETRYELEMENT_H__
 #define __NS_SVGPATHGEOMETRYELEMENT_H__
 
 #include "nsSVGGraphicElement.h"
+#include "DOMSVGTests.h"
 #include "nsTArray.h"
 #include "gfxPath.h"
 #include "gfxMatrix.h"
 
 struct nsSVGMark {
   float x, y, angle;
   nsSVGMark(float aX, float aY, float aAngle) :
     x(aX), y(aY), angle(aAngle) {}
 };
 
 class gfxContext;
 
 typedef nsSVGGraphicElement nsSVGPathGeometryElementBase;
 
-class nsSVGPathGeometryElement : public nsSVGPathGeometryElementBase
+class nsSVGPathGeometryElement : public nsSVGPathGeometryElementBase,
+                                 public DOMSVGTests
 {
 public:
   nsSVGPathGeometryElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
+  // interfaces:
+  NS_DECL_ISUPPORTS_INHERITED
+
   virtual bool AttributeDefinesGeometry(const nsIAtom *aName);
   virtual bool IsMarkable();
   virtual void GetMarkPoints(nsTArray<nsSVGMark> *aMarks);
   virtual void ConstructPath(gfxContext *aCtx) = 0;
   virtual already_AddRefed<gfxFlattenedPath> GetFlattenedPath(const gfxMatrix &aMatrix);
 };
 
 #endif
--- a/content/svg/content/src/nsSVGPatternElement.cpp
+++ b/content/svg/content/src/nsSVGPatternElement.cpp
@@ -80,20 +80,20 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(Pattern)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGPatternElement,nsSVGPatternElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGPatternElement,nsSVGPatternElementBase)
 
 DOMCI_NODE_DATA(SVGPatternElement, nsSVGPatternElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGPatternElement)
-  NS_NODE_INTERFACE_TABLE7(nsSVGPatternElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGFitToViewBox,
-                           nsIDOMSVGURIReference, nsIDOMSVGPatternElement,
-                           nsIDOMSVGUnitTypes)
+  NS_NODE_INTERFACE_TABLE8(nsSVGPatternElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGFitToViewBox, nsIDOMSVGURIReference,
+                           nsIDOMSVGPatternElement, nsIDOMSVGUnitTypes)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGPatternElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGPatternElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGPatternElement::nsSVGPatternElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGPatternElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGPatternElement.h
+++ b/content/svg/content/src/nsSVGPatternElement.h
@@ -38,32 +38,34 @@
 
 #ifndef __NS_SVGPATTERNELEMENT_H__
 #define __NS_SVGPATTERNELEMENT_H__
 
 #include "nsSVGStylableElement.h"
 #include "nsIDOMSVGURIReference.h"
 #include "nsIDOMSVGFitToViewBox.h"
 #include "nsIDOMSVGPatternElement.h"
+#include "DOMSVGTests.h"
 #include "nsIDOMSVGUnitTypes.h"
 #include "nsSVGLength2.h"
 #include "nsSVGEnum.h"
 #include "nsSVGString.h"
 #include "nsSVGViewBox.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
 #include "SVGAnimatedTransformList.h"
 
 //--------------------- Patterns ------------------------
 
 typedef nsSVGStylableElement nsSVGPatternElementBase;
 
 class nsSVGPatternElement : public nsSVGPatternElementBase,
+                            public nsIDOMSVGPatternElement,
+                            public DOMSVGTests,
                             public nsIDOMSVGURIReference,
                             public nsIDOMSVGFitToViewBox,
-                            public nsIDOMSVGPatternElement,
                             public nsIDOMSVGUnitTypes
 {
   friend class nsSVGPatternFrame;
 
 protected:
   friend nsresult NS_NewSVGPatternElement(nsIContent **aResult,
                                           already_AddRefed<nsINodeInfo> aNodeInfo);
   nsSVGPatternElement(already_AddRefed<nsINodeInfo> aNodeInfo);
--- a/content/svg/content/src/nsSVGPolygonElement.cpp
+++ b/content/svg/content/src/nsSVGPolygonElement.cpp
@@ -77,18 +77,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(Polygon)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGPolygonElement,nsSVGPolygonElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGPolygonElement,nsSVGPolygonElementBase)
 
 DOMCI_NODE_DATA(SVGPolygonElement, nsSVGPolygonElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGPolygonElement)
-  NS_NODE_INTERFACE_TABLE4(nsSVGPolygonElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGPolygonElement)
+  NS_NODE_INTERFACE_TABLE5(nsSVGPolygonElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGPolygonElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGPolygonElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGPolygonElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGPolygonElement::nsSVGPolygonElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGPolygonElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGPolylineElement.cpp
+++ b/content/svg/content/src/nsSVGPolylineElement.cpp
@@ -71,18 +71,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(Polyline)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGPolylineElement,nsSVGPolylineElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGPolylineElement,nsSVGPolylineElementBase)
 
 DOMCI_NODE_DATA(SVGPolylineElement, nsSVGPolylineElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGPolylineElement)
-  NS_NODE_INTERFACE_TABLE4(nsSVGPolylineElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGPolylineElement)
+  NS_NODE_INTERFACE_TABLE5(nsSVGPolylineElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGPolylineElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGPolylineElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGPolylineElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGPolylineElement::nsSVGPolylineElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGPolylineElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGRectElement.cpp
+++ b/content/svg/content/src/nsSVGRectElement.cpp
@@ -98,18 +98,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(Rect)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGRectElement,nsSVGRectElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGRectElement,nsSVGRectElementBase)
 
 DOMCI_NODE_DATA(SVGRectElement, nsSVGRectElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGRectElement)
-  NS_NODE_INTERFACE_TABLE4(nsSVGRectElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGRectElement)
+  NS_NODE_INTERFACE_TABLE5(nsSVGRectElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGRectElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGRectElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGRectElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGRectElement::nsSVGRectElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGRectElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGSVGElement.cpp
+++ b/content/svg/content/src/nsSVGSVGElement.cpp
@@ -177,18 +177,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(nsSVGSVGElement,nsSVGSVGElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGSVGElement,nsSVGSVGElementBase)
 
 DOMCI_NODE_DATA(SVGSVGElement, nsSVGSVGElement)
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsSVGSVGElement)
-  NS_NODE_INTERFACE_TABLE7(nsSVGSVGElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGSVGElement,
+  NS_NODE_INTERFACE_TABLE8(nsSVGSVGElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGSVGElement,
                            nsIDOMSVGFitToViewBox, nsIDOMSVGLocatable,
                            nsIDOMSVGZoomAndPan)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGSVGElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGSVGElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
--- a/content/svg/content/src/nsSVGSVGElement.h
+++ b/content/svg/content/src/nsSVGSVGElement.h
@@ -37,16 +37,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __NS_SVGSVGELEMENT_H__
 #define __NS_SVGSVGELEMENT_H__
 
 #include "nsSVGStylableElement.h"
 #include "nsIDOMSVGSVGElement.h"
+#include "DOMSVGTests.h"
 #include "nsIDOMSVGFitToViewBox.h"
 #include "nsIDOMSVGLocatable.h"
 #include "nsIDOMSVGZoomAndPan.h"
 #include "nsIDOMSVGMatrix.h"
 #include "nsIDOMSVGPoint.h"
 #include "nsSVGLength2.h"
 #include "nsSVGEnum.h"
 #include "nsSVGViewBox.h"
@@ -113,16 +114,17 @@ public:
     return width != rhs.width || height != rhs.height;
   }
   float width;
   float height;
 };
 
 class nsSVGSVGElement : public nsSVGSVGElementBase,
                         public nsIDOMSVGSVGElement,
+                        public DOMSVGTests,
                         public nsIDOMSVGFitToViewBox,
                         public nsIDOMSVGLocatable,
                         public nsIDOMSVGZoomAndPan
 {
   friend class nsSVGOuterSVGFrame;
   friend class nsSVGInnerSVGFrame;
   friend class nsSVGImageFrame;
 
--- a/content/svg/content/src/nsSVGSetElement.cpp
+++ b/content/svg/content/src/nsSVGSetElement.cpp
@@ -77,19 +77,19 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(Set)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGSetElement,nsSVGSetElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGSetElement,nsSVGSetElementBase)
 
 DOMCI_NODE_DATA(SVGSetElement, nsSVGSetElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGSetElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGSetElement, nsIDOMNode, nsIDOMElement,
+  NS_NODE_INTERFACE_TABLE6(nsSVGSetElement, nsIDOMNode, nsIDOMElement,
                            nsIDOMSVGElement, nsIDOMSVGAnimationElement,
-                           nsIDOMSVGSetElement)
+                           nsIDOMSVGTests, nsIDOMSVGSetElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGSetElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGSetElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGSetElement::nsSVGSetElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGSetElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGSwitchElement.cpp
+++ b/content/svg/content/src/nsSVGSwitchElement.cpp
@@ -31,18 +31,18 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Util.h"
 
-#include "nsSVGFeatures.h"
 #include "nsSVGSwitchElement.h"
+#include "DOMSVGTests.h"
 #include "nsIFrame.h"
 #include "nsISVGChildFrame.h"
 #include "nsSVGUtils.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 
 ////////////////////////////////////////////////////////////////////////
@@ -66,18 +66,19 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ADDREF_INHERITED(nsSVGSwitchElement,nsSVGSwitchElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGSwitchElement,nsSVGSwitchElementBase)
 
 DOMCI_NODE_DATA(SVGSwitchElement, nsSVGSwitchElement)
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsSVGSwitchElement)
-  NS_NODE_INTERFACE_TABLE4(nsSVGSwitchElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGSwitchElement)
+  NS_NODE_INTERFACE_TABLE5(nsSVGSwitchElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGSwitchElement,
+                           nsIDOMSVGTests)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGSwitchElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGSwitchElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGSwitchElement::nsSVGSwitchElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGSwitchElementBase(aNodeInfo)
@@ -170,47 +171,54 @@ nsSVGSwitchElement::FindActiveChild() co
     Preferences::GetLocalizedString("intl.accept_languages");
 
   if (allowReorder && !acceptLangs.IsEmpty()) {
     PRInt32 bestLanguagePreferenceRank = -1;
     nsIContent *bestChild = nsnull;
     for (nsIContent* child = nsINode::GetFirstChild();
          child;
          child = child->GetNextSibling()) {
-      if (nsSVGFeatures::PassesConditionalProcessingTests(
-            child, nsSVGFeatures::kIgnoreSystemLanguage)) {
-        nsAutoString value;
-        if (child->GetAttr(kNameSpaceID_None, nsGkAtoms::systemLanguage,
-                           value)) {
+
+      if (!child->IsElement()) {
+        continue;
+      }
+      nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(child));
+      if (tests) {
+        if (tests->PassesConditionalProcessingTests(
+                            DOMSVGTests::kIgnoreSystemLanguage)) {
           PRInt32 languagePreferenceRank =
-            nsSVGFeatures::GetBestLanguagePreferenceRank(value, acceptLangs);
+              tests->GetBestLanguagePreferenceRank(acceptLangs);
           switch (languagePreferenceRank) {
           case 0:
             // best possible match
             return child;
           case -1:
             // not found
             break;
           default:
             if (bestLanguagePreferenceRank == -1 ||
                 languagePreferenceRank < bestLanguagePreferenceRank) {
               bestLanguagePreferenceRank = languagePreferenceRank;
               bestChild = child;
             }
             break;
           }
-        } else if (!bestChild) {
-          bestChild = child;
         }
+      } else if (!bestChild) {
+         bestChild = child;
       }
     }
     return bestChild;
   }
 
   for (nsIContent* child = nsINode::GetFirstChild();
        child;
        child = child->GetNextSibling()) {
-    if (nsSVGFeatures::PassesConditionalProcessingTests(child, &acceptLangs)) {
+    if (!child->IsElement()) {
+      continue;
+    }
+    nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(child));
+    if (!tests || tests->PassesConditionalProcessingTests(&acceptLangs)) {
       return child;
     }
   }
   return nsnull;
 }
--- a/content/svg/content/src/nsSVGSwitchElement.h
+++ b/content/svg/content/src/nsSVGSwitchElement.h
@@ -36,21 +36,23 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __NS_SVGSWITCHELEMENT_H__
 #define __NS_SVGSWITCHELEMENT_H__
 
 #include "nsSVGGraphicElement.h"
 #include "nsIDOMSVGSwitchElement.h"
+#include "DOMSVGTests.h"
 
 typedef nsSVGGraphicElement nsSVGSwitchElementBase;
 
 class nsSVGSwitchElement : public nsSVGSwitchElementBase,
-                           public nsIDOMSVGSwitchElement
+                           public nsIDOMSVGSwitchElement,
+                           public DOMSVGTests
 {
   friend class nsSVGSwitchFrame;
 protected:
   friend nsresult NS_NewSVGSwitchElement(nsIContent **aResult,
                                          already_AddRefed<nsINodeInfo> aNodeInfo);
   nsSVGSwitchElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
 public:
--- a/content/svg/content/src/nsSVGSymbolElement.cpp
+++ b/content/svg/content/src/nsSVGSymbolElement.cpp
@@ -32,28 +32,30 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Util.h"
 
 #include "nsIDOMSVGSymbolElement.h"
+#include "DOMSVGTests.h"
 #include "nsSVGStylableElement.h"
 #include "nsSVGViewBox.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
 #include "nsIDOMSVGFitToViewBox.h"
 #include "nsGkAtoms.h"
 
 using namespace mozilla;
 typedef nsSVGStylableElement nsSVGSymbolElementBase;
 
 class nsSVGSymbolElement : public nsSVGSymbolElementBase,
-                           public nsIDOMSVGFitToViewBox,
-                           public nsIDOMSVGSymbolElement
+                           public nsIDOMSVGSymbolElement,
+                           public DOMSVGTests,
+                           public nsIDOMSVGFitToViewBox
 {
 protected:
   friend nsresult NS_NewSVGSymbolElement(nsIContent **aResult,
                                          already_AddRefed<nsINodeInfo> aNodeInfo);
   nsSVGSymbolElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
 public:
   // interfaces:
--- a/content/svg/content/src/nsSVGTSpanElement.cpp
+++ b/content/svg/content/src/nsSVGTSpanElement.cpp
@@ -90,20 +90,21 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(TSpan)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGTSpanElement,nsSVGTSpanElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGTSpanElement,nsSVGTSpanElementBase)
 
 DOMCI_NODE_DATA(SVGTSpanElement, nsSVGTSpanElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGTSpanElement)
-  NS_NODE_INTERFACE_TABLE6(nsSVGTSpanElement, nsIDOMNode, nsIDOMElement,
+  NS_NODE_INTERFACE_TABLE7(nsSVGTSpanElement, nsIDOMNode, nsIDOMElement,
                            nsIDOMSVGElement, nsIDOMSVGTSpanElement,
                            nsIDOMSVGTextPositioningElement,
-                           nsIDOMSVGTextContentElement)
+                           nsIDOMSVGTextContentElement,
+                           nsIDOMSVGTests)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGTSpanElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGTSpanElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGTSpanElement::nsSVGTSpanElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGTSpanElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGTextContentElement.cpp
+++ b/content/svg/content/src/nsSVGTextContentElement.cpp
@@ -36,16 +36,26 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsSVGTextContentElement.h"
 #include "DOMSVGPoint.h"
 
 using namespace mozilla;
 
+//----------------------------------------------------------------------
+// nsISupports methods
+
+NS_IMPL_ADDREF_INHERITED(nsSVGTextContentElement, nsSVGTextContentElementBase)
+NS_IMPL_RELEASE_INHERITED(nsSVGTextContentElement, nsSVGTextContentElementBase)
+
+NS_INTERFACE_MAP_BEGIN(nsSVGTextContentElement)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMSVGTests)
+NS_INTERFACE_MAP_END_INHERITING(nsSVGTextContentElementBase)
+
 /* readonly attribute nsIDOMSVGAnimatedLength textLength; */
 NS_IMETHODIMP nsSVGTextContentElement::GetTextLength(nsIDOMSVGAnimatedLength * *aTextLength)
 {
   NS_NOTYETIMPLEMENTED("nsSVGTextContentElement::GetTextLength");
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 /* readonly attribute nsIDOMSVGAnimatedEnumeration lengthAdjust; */
--- a/content/svg/content/src/nsSVGTextContentElement.h
+++ b/content/svg/content/src/nsSVGTextContentElement.h
@@ -37,28 +37,31 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __NS_SVGTEXTCONTENTELEMENTBASE_H__
 #define __NS_SVGTEXTCONTENTELEMENTBASE_H__
 
 #include "nsIDOMSVGTextContentElement.h"
 #include "nsSVGTextContainerFrame.h"
 #include "nsSVGStylableElement.h"
+#include "DOMSVGTests.h"
 
 typedef nsSVGStylableElement nsSVGTextContentElementBase;
 
 /**
  * Note that nsSVGTextElement does not inherit nsSVGTextPositioningElement, or
  * this class - it reimplements us instead (see its documenting comment). The
  * upshot is that any changes to this class also need to be made in
  * nsSVGTextElement.
  */
-class nsSVGTextContentElement : public nsSVGTextContentElementBase
+class nsSVGTextContentElement : public nsSVGTextContentElementBase,
+                                public DOMSVGTests
 {
 public:
+  NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGTEXTCONTENTELEMENT
 
 protected:
 
   nsSVGTextContentElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsSVGTextContentElementBase(aNodeInfo)
   {}
 
--- a/content/svg/content/src/nsSVGTextElement.cpp
+++ b/content/svg/content/src/nsSVGTextElement.cpp
@@ -48,16 +48,17 @@
 #include "nsDOMError.h"
 #include "SVGAnimatedLengthList.h"
 #include "DOMSVGAnimatedLengthList.h"
 #include "SVGLengthList.h"
 #include "SVGNumberList.h"
 #include "SVGAnimatedNumberList.h"
 #include "DOMSVGAnimatedNumberList.h"
 #include "DOMSVGPoint.h"
+#include "DOMSVGTests.h"
 
 using namespace mozilla;
 
 typedef nsSVGGraphicElement nsSVGTextElementBase;
 
 /**
  * This class does not inherit nsSVGTextPositioningElement - it reimplements it
  * instead.
@@ -66,17 +67,18 @@ typedef nsSVGGraphicElement nsSVGTextEle
  * nsSVGGraphicElement, but we don't want two instances of nsSVGStylableElement
  * and all the classes it inherits. Instead we choose to inherit one of the
  * classes (nsSVGGraphicElement) and reimplement the missing pieces from the
  * other (nsSVGTextPositioningElement (and thus nsSVGTextContentElement)). Care
  * must be taken when making changes to the reimplemented pieces to keep
  * nsSVGTextPositioningElement in sync (and vice versa).
  */
 class nsSVGTextElement : public nsSVGTextElementBase,
-                         public nsIDOMSVGTextElement // nsIDOMSVGTextPositioningElement
+                         public nsIDOMSVGTextElement, // nsIDOMSVGTextPositioningElement
+                         public DOMSVGTests
 {
 protected:
   friend nsresult NS_NewSVGTextElement(nsIContent **aResult,
                                        already_AddRefed<nsINodeInfo> aNodeInfo);
   nsSVGTextElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   
 public:
   // interfaces:
@@ -125,20 +127,21 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(Text)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGTextElement,nsSVGTextElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGTextElement,nsSVGTextElementBase)
 
 DOMCI_NODE_DATA(SVGTextElement, nsSVGTextElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGTextElement)
-  NS_NODE_INTERFACE_TABLE6(nsSVGTextElement, nsIDOMNode, nsIDOMElement,
+  NS_NODE_INTERFACE_TABLE7(nsSVGTextElement, nsIDOMNode, nsIDOMElement,
                            nsIDOMSVGElement, nsIDOMSVGTextElement,
                            nsIDOMSVGTextPositioningElement,
-                           nsIDOMSVGTextContentElement)
+                           nsIDOMSVGTextContentElement,
+                           nsIDOMSVGTests)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGTextElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGTextElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGTextElement::nsSVGTextElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGTextElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGTextPathElement.cpp
+++ b/content/svg/content/src/nsSVGTextPathElement.cpp
@@ -88,19 +88,20 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(TextPath)
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGTextPathElement,nsSVGTextPathElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGTextPathElement,nsSVGTextPathElementBase)
 
 DOMCI_NODE_DATA(SVGTextPathElement, nsSVGTextPathElement)
 
 NS_INTERFACE_TABLE_HEAD(nsSVGTextPathElement)
-  NS_NODE_INTERFACE_TABLE6(nsSVGTextPathElement, nsIDOMNode, nsIDOMElement,
+  NS_NODE_INTERFACE_TABLE7(nsSVGTextPathElement, nsIDOMNode, nsIDOMElement,
                            nsIDOMSVGElement, nsIDOMSVGTextPathElement,
-                           nsIDOMSVGTextContentElement, nsIDOMSVGURIReference)
+                           nsIDOMSVGTextContentElement, nsIDOMSVGTests,
+                           nsIDOMSVGURIReference)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGTextPathElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGTextPathElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGTextPathElement::nsSVGTextPathElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGTextPathElementBase(aNodeInfo)
--- a/content/svg/content/src/nsSVGUseElement.cpp
+++ b/content/svg/content/src/nsSVGUseElement.cpp
@@ -87,18 +87,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(nsSVGUseElement,nsSVGUseElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGUseElement,nsSVGUseElementBase)
 
 DOMCI_NODE_DATA(SVGUseElement, nsSVGUseElement)
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsSVGUseElement)
-  NS_NODE_INTERFACE_TABLE6(nsSVGUseElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGURIReference,
+  NS_NODE_INTERFACE_TABLE7(nsSVGUseElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGTests,
+                           nsIDOMSVGURIReference,
                            nsIDOMSVGUseElement, nsIMutationObserver)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGUseElement)
   if (aIID.Equals(NS_GET_IID(nsSVGUseElement)))
     foundInterface = reinterpret_cast<nsISupports*>(this);
   else
 NS_INTERFACE_MAP_END_INHERITING(nsSVGUseElementBase)
 
 //----------------------------------------------------------------------
--- a/content/svg/content/src/nsSVGUseElement.h
+++ b/content/svg/content/src/nsSVGUseElement.h
@@ -35,16 +35,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __NS_SVGUSEELEMENT_H__
 #define __NS_SVGUSEELEMENT_H__
 
 #include "nsIDOMSVGAnimatedString.h"
 #include "nsIDOMSVGURIReference.h"
 #include "nsIDOMSVGUseElement.h"
+#include "DOMSVGTests.h"
 #include "nsStubMutationObserver.h"
 #include "nsSVGGraphicElement.h"
 #include "nsSVGLength2.h"
 #include "nsSVGString.h"
 #include "nsTArray.h"
 #include "nsReferencedElement.h"
 #include "mozilla/dom/FromParser.h"
 
@@ -58,18 +59,19 @@ class nsINodeInfo;
 nsresult
 NS_NewSVGSVGElement(nsIContent **aResult,
                     already_AddRefed<nsINodeInfo> aNodeInfo,
                     mozilla::dom::FromParser aFromParser);
 
 typedef nsSVGGraphicElement nsSVGUseElementBase;
 
 class nsSVGUseElement : public nsSVGUseElementBase,
+                        public nsIDOMSVGUseElement,
+                        public DOMSVGTests,
                         public nsIDOMSVGURIReference,
-                        public nsIDOMSVGUseElement,
                         public nsStubMutationObserver
 {
   friend class nsSVGUseFrame;
 protected:
   friend nsresult NS_NewSVGUseElement(nsIContent **aResult,
                                       already_AddRefed<nsINodeInfo> aNodeInfo);
   nsSVGUseElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsSVGUseElement();
--- a/content/svg/content/test/test_SVGxxxList.xhtml
+++ b/content/svg/content/test/test_SVGxxxList.xhtml
@@ -271,86 +271,43 @@ var tests = [
       for (var prop in itemA) {
         if (!SVGPathSeg.hasOwnProperty(prop) &&
             prop != 'pathSegTypeAsLetter') {
           is(itemA[prop], itemB[prop], message);
         }
       }
     }
   },
-/*
-  {
-    // SVGPathSegList test:
-    target_element_id: 'path',
-    attr_name: 'd',
-    prop_name: null, // SVGAnimatedPathData is an inherited interface!
-    bv_name: 'normalizedPathSegList',
-    av_name: 'animatedNormalizedPathSegList',
-    el_type: 'SVGPathElement',
-    prop_type: null,
-    list_type: 'SVGPathSegList',
-    item_type: 'SVGPathSeg',
-    attr_val_3a: '',
-    attr_val_3b: '',
-    attr_val_4 : '',
-    attr_val_5a: '',
-    attr_val_5b: '',
-    item_constructor: function() {
-      // XXX return different values each time
-      return SVGPathElement.createSVGPathSegLinetoAbs(1, 1);
-    },
-    item_is: function(itemA, itemB, message) {
-      ok(typeof(itemA.pathSegTypeAsLetter) != 'undefined' &&
-         typeof(itemB.pathSegTypeAsLetter) != 'undefined',
-         'expecting pathSegTypeAsLetter property');
-
-      // First: are we dealing  with the same type of segment?
-      is(itemA.pathSegTypeAsLetter, itemB.pathSegTypeAsLetter, message);
-      if (itemA.pathSegTypeAsLetter != itemB.pathSegTypeAsLetter)
-        return;  // The rest of this function is nonsense if types don't match.
-
-      // Make sure property-counts match (so we can iterate across itemA's
-      // properties and not worry about itemB having extra properties that
-      // we might be skipping over).
-      is(keys(itemA).length, keys(itemB).length,
-        'expecting same property-count when comparing path segs of same type.');
-
-      // Compare the properties, skipping the constant properties inherited
-      // from 'SVGPathSeg', and skipping the pathSegTypeAsLetter field since we
-      // already checked that above. 
-      for (var prop in itemA) {
-        if (!SVGPathSeg.hasOwnProperty(prop) &&
-            prop != 'pathSegTypeAsLetter') {
-          is(itemA[prop], itemB[prop], message);
-        }
-      }
-    }
-  },
   {
     // SVGStringList test:
     target_element_id: 'g',
     attr_name: 'requiredFeatures', // requiredExtensions, systemLanguage, viewTarget
     prop_name: null, // SVGStringList attributes are not animatable
     bv_name: 'requiredFeatures',
     av_name: null,
     el_type: 'SVGGElement',
     prop_type: null,
     list_type: 'SVGStringList',
     item_type: 'DOMString',
-    attr_val_3a: '',
-    attr_val_3b: '',
-    attr_val_4 : '',
-    attr_val_5a: '',
-    attr_val_5b: '',
+    attr_val_3a: 'http://www.w3.org/TR/SVG11/feature#Shape http://www.w3.org/TR/SVG11/feature#Image ' +
+                 'http://www.w3.org/TR/SVG11/feature#Style',
+    attr_val_3b: 'http://www.w3.org/TR/SVG11/feature#CoreAttribute http://www.w3.org/TR/SVG11/feature#Structure ' +
+                 'http://www.w3.org/TR/SVG11/feature#Gradient',
+    attr_val_4 : 'http://www.w3.org/TR/SVG11/feature#Pattern http://www.w3.org/TR/SVG11/feature#Clip ' +
+                 'http://www.w3.org/TR/SVG11/feature#Mask http://www.w3.org/TR/SVG11/feature#Extensibility',
+    attr_val_5a: 'http://www.w3.org/TR/SVG11/feature#BasicStructure http://www.w3.org/TR/SVG11/feature#BasicText ' +
+                 'http://www.w3.org/TR/SVG11/feature#BasicPaintAttribute http://www.w3.org/TR/SVG11/feature#BasicGraphicsAttribute ' +
+                 'http://www.w3.org/TR/SVG11/feature#BasicClip',
+    attr_val_5b: 'http://www.w3.org/TR/SVG11/feature#DocumentEventsAttribute http://www.w3.org/TR/SVG11/feature#GraphicalEventsAttribute ' +
+                 'http://www.w3.org/TR/SVG11/feature#AnimationEventsAttribute http://www.w3.org/TR/SVG11/feature#Hyperlinking ' +
+                 'http://www.w3.org/TR/SVG11/feature#XlinkAttribute',
     item_constructor: function() {
-      // XXX return a meaningful string
-      return ;
+      return 'http://www.w3.org/TR/SVG11/feature#XlinkAttribute';
     }
   },
-  */
   {
     // SVGTransformList test:
     target_element_id: 'g',
     attr_name: 'transform', // gradientTransform, patternTransform
     prop_name: 'transform',
     bv_name: 'baseVal',
     av_name: 'animVal',
     el_type: 'SVGGElement',
@@ -530,46 +487,49 @@ function run_baseVal_API_tests()
     ok(t.baseVal.getItem(0) === item,
        'The list item at index 0 should be the exact same object as the '+
        'object that was passed to the '+t.list_type+'.initialize() method, '+
        'since the item that was passed to that method did not already '+
        'belong to a list.');
 
     t.element.setAttribute(t.attr_name, t.attr_val_4);
 
-    var old_items = get_array_of_list_items(t.baseVal);
-    item = t.baseVal.getItem(3);
-    res = t.baseVal.initialize(item);
+    if (t.item_type != "DOMString") {
+      var old_items = get_array_of_list_items(t.baseVal);
+      item = t.baseVal.getItem(3);
+      res = t.baseVal.initialize(item);
 
-    ok(res !== item &&
-       t.baseVal.getItem(0) !== item &&
-       t.baseVal.getItem(0) !== old_items[0] &&
-       res === t.baseVal.getItem(0),
-       'The method '+t.list_type+'.initialize() should clone the object that '+
-       'is passed in if that object is already in a list.');
-    // [SVGWG issue] not what the spec currently says
+      ok(res !== item &&
+         t.baseVal.getItem(0) !== item &&
+         t.baseVal.getItem(0) !== old_items[0] &&
+         res === t.baseVal.getItem(0),
+         'The method '+t.list_type+'.initialize() should clone the object that '+
+         'is passed in if that object is already in a list.');
+      // [SVGWG issue] not what the spec currently says
 
-    item = t.baseVal.getItem(0);
-    res = t.baseVal.initialize(item);
+
+      item = t.baseVal.getItem(0);
+      res = t.baseVal.initialize(item);
 
-    ok(res !== item &&
-       t.baseVal.getItem(0) !== item,
-       'The method '+t.list_type+'.initialize() should clone the object that '+
-       'is passed in, even if that object is the only item in that list.');
-    // [SVGWG issue] not what the spec currently says
+      ok(res !== item &&
+         t.baseVal.getItem(0) !== item,
+         'The method '+t.list_type+'.initialize() should clone the object that '+
+         'is passed in, even if that object is the only item in that list.');
+      // [SVGWG issue] not what the spec currently says
 
-    threw = false;
-    try {
-      t.baseVal.initialize({});
-    } catch(e) {
-      threw = true;
+      threw = false;
+      try {
+        t.baseVal.initialize({});
+      } catch(e) {
+        threw = true;
+      }
+      ok(threw,
+         'The method '+t.list_type+'.initialize() should throw if passed an '+
+         'object of the wrong type.');
     }
-    ok(threw,
-       'The method '+t.list_type+'.initialize() should throw if passed an '+
-       'object of the wrong type.');
 
     // Test .insertItemBefore():
 
     t.element.setAttribute(t.attr_name, t.attr_val_4);
 
     old_items = get_array_of_list_items(t.baseVal);
     item = t.item_constructor();
     res = t.baseVal.insertItemBefore(item, 2);
@@ -599,61 +559,67 @@ function run_baseVal_API_tests()
        'method is out of bounds, the supplied list item should be appended '+
        'to the list.');
 
     item = t.baseVal.getItem(4);
     res = t.baseVal.insertItemBefore(item, 2);
 
     is(t.baseVal.numberOfItems, 7,
        'The '+t.list_type+' object should contain seven list items.');
-    ok(res !== item &&
-       t.baseVal.getItem(2) !== item &&
-       t.baseVal.getItem(2) !== old_items[2] &&
-       res === t.baseVal.getItem(2),
-       'The method '+t.list_type+'.insertItemBefore() should clone the '+
-       'object that is passed in if that object is already in a list.');
-    // [SVGWG issue] not what the spec currently says
+    if (t.item_type != "DOMString") {
+      ok(res !== item &&
+         t.baseVal.getItem(2) !== item &&
+         t.baseVal.getItem(2) !== old_items[2] &&
+         res === t.baseVal.getItem(2),
+         'The method '+t.list_type+'.insertItemBefore() should clone the '+
+         'object that is passed in if that object is already in a list.');
+      // [SVGWG issue] not what the spec currently says
+    }
 
     item = t.baseVal.getItem(2);
     res = t.baseVal.insertItemBefore(item, 2);
 
     is(t.baseVal.numberOfItems, 8,
        'The '+t.list_type+' object should contain eight list items.');
-    ok(res !== item &&
-       t.baseVal.getItem(2) !== item,
-       'The method '+t.list_type+'.insertItemBefore() should clone the '+
-       'object that is passed in, even if that object is the item in '+
-       'the list at the index specified.');
-    // [SVGWG issue] not what the spec currently says
+    if (t.item_type != "DOMString") {
+      ok(res !== item &&
+         t.baseVal.getItem(2) !== item,
+         'The method '+t.list_type+'.insertItemBefore() should clone the '+
+         'object that is passed in, even if that object is the item in '+
+         'the list at the index specified.');
+      // [SVGWG issue] not what the spec currently says
 
-    threw = false;
-    try {
-      t.baseVal.insertItemBefore({}, 2);
-    } catch(e) {
-      threw = true;
+      threw = false;
+      try {
+        t.baseVal.insertItemBefore({}, 2);
+      } catch(e) {
+        threw = true;
+      }
+      ok(threw,
+         'The method '+t.list_type+'.insertItemBefore() should throw if passed '+
+         'an object of the wrong type.');
     }
-    ok(threw,
-       'The method '+t.list_type+'.insertItemBefore() should throw if passed '+
-       'an object of the wrong type.');
 
     // Test .replaceItem():
 
     t.element.setAttribute(t.attr_name, t.attr_val_4);
 
     old_items = get_array_of_list_items(t.baseVal);
     item = t.item_constructor();
     res = t.baseVal.replaceItem(item, 2);
 
     is(t.baseVal.numberOfItems, 4,
        'The '+t.list_type+' object should contain four list items.');
-    ok(res === item,
-       'The list item returned by '+t.list_type+'.replaceItem() should be '+
-       'the exact same object as the item that was passed to that method, '+
-       'since the item that was passed to that method did not already belong '+
-       'to a list.');
+    if (t.item_type != "DOMString") {
+      ok(res === item,
+         'The list item returned by '+t.list_type+'.replaceItem() should be '+
+         'the exact same object as the item that was passed to that method, '+
+         'since the item that was passed to that method did not already belong '+
+         'to a list.');
+    }
     ok(t.baseVal.getItem(2) === item,
        'The list item at index 2 should be the exact same object as the '+
        'object that was passed to the '+t.list_type+'.replaceItem() method, '+
        'since the item that was passed to that method did not already belong '+
        'to a list.');
     ok(t.baseVal.getItem(3) === old_items[3],
        'The list item that was at index 3 should still be at index 3 after '+
        'the item at index 2 was replaced using the '+t.list_type+
@@ -672,59 +638,65 @@ function run_baseVal_API_tests()
        'an index that is out of bounds.');
 
     old_items = get_array_of_list_items(t.baseVal);
     item = t.baseVal.getItem(3);
     res = t.baseVal.replaceItem(item, 1);
 
     is(t.baseVal.numberOfItems, 4,
        'The '+t.list_type+' object should contain four list items.');
-    ok(res !== item &&
-       t.baseVal.getItem(1) !== item &&
-       t.baseVal.getItem(1) !== old_items[1] &&
-       res === t.baseVal.getItem(1),
-       'The method '+t.list_type+'.replaceItem() should clone the object '+
-       'that is passed in if that object is already in a list.');
-    // [SVGWG issue] not what the spec currently says
+    if (t.item_type != "DOMString") {
+      ok(res !== item &&
+         t.baseVal.getItem(1) !== item &&
+         t.baseVal.getItem(1) !== old_items[1] &&
+         res === t.baseVal.getItem(1),
+         'The method '+t.list_type+'.replaceItem() should clone the object '+
+         'that is passed in if that object is already in a list.');
+      // [SVGWG issue] not what the spec currently says
+    }
 
     item = t.baseVal.getItem(1);
     res = t.baseVal.replaceItem(item, 1);
 
     is(t.baseVal.numberOfItems, 4,
        'The '+t.list_type+' object should contain four list items.');
-    ok(res !== item &&
-       t.baseVal.getItem(1) !== item,
-       'The method '+t.list_type+'.replaceItem() should clone the object '+
-       'that is passed in, even if the object that object and the object '+
-       'that is being replaced are the exact same objects.');
-    // [SVGWG issue] not what the spec currently says
+    if (t.item_type != "DOMString") {
+      ok(res !== item &&
+         t.baseVal.getItem(1) !== item,
+         'The method '+t.list_type+'.replaceItem() should clone the object '+
+         'that is passed in, even if the object that object and the object '+
+         'that is being replaced are the exact same objects.');
+      // [SVGWG issue] not what the spec currently says
 
-    threw = false;
-    try {
-      t.baseVal.replaceItem({}, 2);
-    } catch(e) {
-      threw = true;
+      threw = false;
+      try {
+        t.baseVal.replaceItem({}, 2);
+      } catch(e) {
+        threw = true;
+      }
+      ok(threw,
+         'The method '+t.list_type+'.replaceItem() should throw if passed '+
+         'an object of the wrong type.');
     }
-    ok(threw,
-       'The method '+t.list_type+'.replaceItem() should throw if passed '+
-       'an object of the wrong type.');
 
     // Test .removeItem():
 
     t.element.setAttribute(t.attr_name, t.attr_val_4);
 
     old_items = get_array_of_list_items(t.baseVal);
     item = t.baseVal.getItem(2);
     res = t.baseVal.removeItem(2);
 
     is(t.baseVal.numberOfItems, 3,
        'The '+t.list_type+' object should contain three list items.');
-    ok(res === item,
-       'The list item returned by '+t.list_type+'.removeItem() should be the '+
-       'exact same object as the item that was at the specified index.');
+    if (t.item_type != "DOMString") {
+      ok(res === item,
+         'The list item returned by '+t.list_type+'.removeItem() should be the '+
+         'exact same object as the item that was at the specified index.');
+    }
     ok(t.baseVal.getItem(1) === old_items[1],
        'The list item that was at index 1 should still be at index 1 after '+
        'the item at index 2 was removed using the '+t.list_type+
        '.replaceItem() method.');
     ok(t.baseVal.getItem(2) === old_items[3],
        'The list item that was at index 3 should still be at index 2 after '+
        'the item at index 2 was removed using the '+t.list_type+
        '.replaceItem() method.');
@@ -764,46 +736,48 @@ function run_baseVal_API_tests()
        'appending a new item using the '+t.list_type+'.appendItem() '+
        'method.');
 
     item = t.baseVal.getItem(2);
     res = t.baseVal.appendItem(item);
 
     is(t.baseVal.numberOfItems, 6,
        'The '+t.list_type+' object should contain six list items.');
-    ok(res !== item &&
-       t.baseVal.getItem(5) !== item &&
-       res === t.baseVal.getItem(5),
-       'The method '+t.list_type+'.appendItem() should clone the object '+
-       'that is passed in if that object is already in a list.');
-    // [SVGWG issue] not what the spec currently says
+    if (t.item_type != "DOMString") {
+      ok(res !== item &&
+         t.baseVal.getItem(5) !== item &&
+         res === t.baseVal.getItem(5),
+         'The method '+t.list_type+'.appendItem() should clone the object '+
+         'that is passed in if that object is already in a list.');
+      // [SVGWG issue] not what the spec currently says
+    }
 
     item = t.baseVal.getItem(5);
     res = t.baseVal.appendItem(item);
 
     is(t.baseVal.numberOfItems, 7,
        'The '+t.list_type+' object should contain seven list items.');
-    ok(res !== item &&
-       t.baseVal.getItem(6) !== item,
-       'The method '+t.list_type+'.appendItem() should clone the object '+
-       'that is passed in, if that object is already the last item in '+
-       'that list.');
-    // [SVGWG issue] not what the spec currently says
-
-
+    if (t.item_type != "DOMString") {
+      ok(res !== item &&
+         t.baseVal.getItem(6) !== item,
+         'The method '+t.list_type+'.appendItem() should clone the object '+
+         'that is passed in, if that object is already the last item in '+
+         'that list.');
+      // [SVGWG issue] not what the spec currently says
 
-    threw = false;
-    try {
-      t.baseVal.appendItem({});
-    } catch(e) {
-      threw = true;
+      threw = false;
+      try {
+        t.baseVal.appendItem({});
+      } catch(e) {
+        threw = true;
+      }
+      ok(threw,
+         'The method '+t.list_type+'.appendItem() should throw if passed '+
+         'an object of the wrong type.');
     }
-    ok(threw,
-       'The method '+t.list_type+'.appendItem() should throw if passed '+
-       'an object of the wrong type.');
   }
 }
 
 
 /**
  * This function tests the SVGXxxList API for the anim val list (see also the
  * comment for test_baseVal_API).
  */
@@ -948,43 +922,47 @@ function run_basic_setAttribute_tests()
          'time the item at a given index in the '+t.list_type+' for '+
          t.av_path+' is accessed, given that the index was not made invalid '+
          'by a change in list length between the successive accesses.');
     }
 
     // Test the effect of setting the attribute to new values:
 
     t.old_baseVal_items = get_array_of_list_items(t.baseVal);
-    t.old_animVal_items = get_array_of_list_items(t.animVal);
+    if (t.animVal) {
+      t.old_animVal_items = get_array_of_list_items(t.animVal);
+    }
 
     t.element.setAttribute(t.attr_name, t.attr_val_3a);
     t.element.setAttribute(t.attr_name, t.attr_val_5a);
 
     ok(t.baseVal.numberOfItems == 5 && t.baseVal.getItem(4) != null,
        'The length of the '+t.list_type+' object for '+t.bv_path+' should '+
        'have been set to 5 by the setAttribute() call.');
 
     if (t.animVal) {
       ok(t.baseVal.numberOfItems == t.animVal.numberOfItems,
          'Since no animations are active, the length of the '+t.list_type+' '+
          'objects for '+t.bv_path+' and '+t.av_path+' should be the same '+
          '(5).');
     }
 
-    ok(t.baseVal.getItem(2) === t.old_baseVal_items[2],
-       'After its attribute changes, list items in the '+t.list_type+' for '+
-       t.bv_path+' that are at indexes that existed prior to the attribute '+
-       'change should be the exact same objects as the objects that were '+
-       'at those indexes prior to the attribute change.');
+    if (t.item_type != "DOMString") {
+      ok(t.baseVal.getItem(2) === t.old_baseVal_items[2],
+         'After its attribute changes, list items in the '+t.list_type+' for '+
+         t.bv_path+' that are at indexes that existed prior to the attribute '+
+         'change should be the exact same objects as the objects that were '+
+         'at those indexes prior to the attribute change.');
 
-    ok(t.baseVal.getItem(3) !== t.old_baseVal_items[3],
-       'After its attribute changes, list items in the '+t.list_type+' for '+
-       t.bv_path+' that are at indexes that did not exist prior to the '+
-       'attribute change should not be the same objects as any objects that '+
-       'were at those indexes at some earlier time.');
+      ok(t.baseVal.getItem(3) !== t.old_baseVal_items[3],
+         'After its attribute changes, list items in the '+t.list_type+' for '+
+         t.bv_path+' that are at indexes that did not exist prior to the '+
+         'attribute change should not be the same objects as any objects that '+
+         'were at those indexes at some earlier time.');
+    }
 
     if (t.animVal) {
       ok(t.animVal.getItem(2) === t.old_animVal_items[2],
          'After its attribute changes, list items in the '+t.list_type+' for '+
          t.av_path+' that are at indexes that existed prior to the attribute '+
          'change should be the exact same objects as the objects that were '+
          'at those indexes prior to the attribute change.');
 
@@ -1345,17 +1323,19 @@ function run_tests()
       t.item_is = function(itemA, itemB, message) {
       ok(typeof(itemA.value) != 'undefined' &&
          typeof(itemB.value) != 'undefined',
          'expecting value property');
         is(itemA.value, itemB.value, message);
       };
     }
 
-    t.element.appendChild(create_animate_elements(t));
+    if (t.animVal) {
+      t.element.appendChild(create_animate_elements(t));
+    }
   }
 
   // Run the major test groups:
 
   run_baseVal_API_tests();
   run_animVal_API_tests();
   run_basic_setAttribute_tests();
   run_list_mutation_tests();
--- a/content/svg/content/test/test_a_href_01.xhtml
+++ b/content/svg/content/test/test_a_href_01.xhtml
@@ -37,17 +37,17 @@ function frameLoaded() {
 
 function doNavigationIfReady() {
   if (didWindowLoad && frameLoadCount == testCount) {
     doNavigation();
   }
 }
 
 function doNavigation() {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserWrite");
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 
   // Test clicking on an unmodified <a>.
   doNavigationTest(1, "a_href_helper_01.svg");
   // Test clicking on an <a> whose xlink:href is modified by assigning to href.baseVal.
   doNavigationTest(2, "a_href_helper_02_03.svg", function(a) { a.href.baseVal = "a_href_destination.svg"; });
   // Test clicking on an <a> whose xlink:href is modified by a setAttributeNS call.
   doNavigationTest(3, "a_href_helper_02_03.svg", function(a) { a.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", "a_href_destination.svg"); });
   // Test clicking on an <a> whose xlink:href is modified by animation.
--- a/content/xml/tests/load/loadauth.html
+++ b/content/xml/tests/load/loadauth.html
@@ -31,17 +31,17 @@ function documentLoaded(e) {
     "Event properties:\n" + 
     eventProperties;
 }
 
 xmlDoc.addEventListener("load", documentLoaded, false);
 
 function execute()
 {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   xmlDoc.load("http://green/heikki/login/data.xml");
 }
 
 </script>
 </head>
 <body onload="execute();">
 <h1>Synchronized document.load() test</h1>
 
--- a/content/xslt/src/base/txExpandedNameMap.h
+++ b/content/xslt/src/base/txExpandedNameMap.h
@@ -97,26 +97,28 @@ protected:
 
         bool next()
         {
             return ++mCurrentPos < mMap.mItems.Length();
         }
 
         const txExpandedName key()
         {
-            NS_ASSERTION(mCurrentPos < mMap.mItems.Length(),
+            NS_ASSERTION(mCurrentPos >= 0 &&
+                         mCurrentPos < mMap.mItems.Length(),
                          "invalid position in txExpandedNameMap::iterator");
             return txExpandedName(mMap.mItems[mCurrentPos].mNamespaceID,
                                   mMap.mItems[mCurrentPos].mLocalName);
         }
 
     protected:
         void* itemValue()
         {
-            NS_ASSERTION(mCurrentPos < mMap.mItems.Length(),
+            NS_ASSERTION(mCurrentPos >= 0 &&
+                         mCurrentPos < mMap.mItems.Length(),
                          "invalid position in txExpandedNameMap::iterator");
             return mMap.mItems[mCurrentPos].mValue;
         }
 
     private:
         txExpandedNameMap_base& mMap;
         PRUint32 mCurrentPos;
     };
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -1376,17 +1376,17 @@ nsXULDocument::IsCapabilityEnabled(const
 }
 
 
 nsresult
 nsXULDocument::Persist(nsIContent* aElement, PRInt32 aNameSpaceID,
                        nsIAtom* aAttribute)
 {
     // For non-chrome documents, persistance is simply broken
-    if (!IsCapabilityEnabled("UniversalBrowserWrite"))
+    if (!IsCapabilityEnabled("UniversalXPConnect"))
         return NS_ERROR_NOT_AVAILABLE;
 
     // First make sure we _have_ a local store to stuff the persisted
     // information into. (We might not have one if profile information
     // hasn't been loaded yet...)
     if (!mLocalStore)
         return NS_OK;
 
@@ -2135,17 +2135,17 @@ nsXULDocument::PrepareToLoadPrototype(ns
     return NS_OK;
 }
 
 
 nsresult
 nsXULDocument::ApplyPersistentAttributes()
 {
     // For non-chrome documents, persistance is simply broken
-    if (!IsCapabilityEnabled("UniversalBrowserRead"))
+    if (!IsCapabilityEnabled("UniversalXPConnect"))
         return NS_ERROR_NOT_AVAILABLE;
 
     // Add all of the 'persisted' attributes into the content
     // model.
     if (!mLocalStore)
         return NS_OK;
 
     mApplyingPersistedAttrs = true;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1621,20 +1621,20 @@ nsDocShell::ValidateOrigin(nsIDocShellTr
     NS_ENSURE_TRUE(securityManager, false);
 
     nsCOMPtr<nsIPrincipal> subjectPrincipal;
     nsresult rv =
         securityManager->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
     NS_ENSURE_SUCCESS(rv, false);
 
     if (subjectPrincipal) {
-        // We're called from JS, check if UniversalBrowserWrite is
+        // We're called from JS, check if UniversalXPConnect is
         // enabled.
         bool ubwEnabled = false;
-        rv = securityManager->IsCapabilityEnabled("UniversalBrowserWrite",
+        rv = securityManager->IsCapabilityEnabled("UniversalXPConnect",
                                                   &ubwEnabled);
         NS_ENSURE_SUCCESS(rv, false);
 
         if (ubwEnabled) {
             return true;
         }
     }
 
@@ -7779,17 +7779,17 @@ nsDocShell::CheckLoadingPermissions()
     // the parent before allowing it to load anything into this
     // docshell.
 
     nsCOMPtr<nsIScriptSecurityManager> securityManager =
         do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     bool ubwEnabled = false;
-    rv = securityManager->IsCapabilityEnabled("UniversalBrowserWrite",
+    rv = securityManager->IsCapabilityEnabled("UniversalXPConnect",
                                               &ubwEnabled);
     if (NS_FAILED(rv) || ubwEnabled) {
         return rv;
     }
 
     nsCOMPtr<nsIPrincipal> subjPrincipal;
     rv = securityManager->GetSubjectPrincipal(getter_AddRefs(subjPrincipal));
     NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && subjPrincipal, rv);
--- a/docshell/test/browser/browser_bug435325.js
+++ b/docshell/test/browser/browser_bug435325.js
@@ -7,18 +7,18 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = gBrowser.addTab();
   window.addEventListener("DOMContentLoaded", checkPage, false);
 
   // Go offline and disable the cache, then try to load the test URL.
   Services.io.offline = true;
-  gPrefService.setBoolPref("browser.cache.disk.enable", false);
-  gPrefService.setBoolPref("browser.cache.memory.enable", false);
+  Services.prefs.setBoolPref("browser.cache.disk.enable", false);
+  Services.prefs.setBoolPref("browser.cache.memory.enable", false);
   content.location = "http://example.com/";
 }
 
 function checkPage() {
   if(content.location == "about:blank") {
     info("got about:blank, which is expected once, so return");
     return;
   }
@@ -37,13 +37,13 @@ function checkPage() {
   ok(!Services.io.offline, "After clicking the Try Again button, we're back "
    +" online. This depends on Components.interfaces.nsIDOMWindowUtils being "
    +"available from untrusted content (bug 435325).");
 
   finish();
 }
 
 registerCleanupFunction(function() {
-  gPrefService.setBoolPref("browser.cache.disk.enable", true);
-  gPrefService.setBoolPref("browser.cache.memory.enable", true);
+  Services.prefs.setBoolPref("browser.cache.disk.enable", true);
+  Services.prefs.setBoolPref("browser.cache.memory.enable", true);
   Services.io.offline = false;
   gBrowser.removeCurrentTab();
 });
--- a/dom/base/nsBarProps.cpp
+++ b/dom/base/nsBarProps.cpp
@@ -101,17 +101,17 @@ nsBarProp::SetVisibleByFlag(bool aVisibl
   nsCOMPtr<nsIWebBrowserChrome> browserChrome = GetBrowserChrome();
   NS_ENSURE_TRUE(browserChrome, NS_OK);
 
   bool enabled = false;
 
   nsCOMPtr<nsIScriptSecurityManager>
            securityManager(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
   if (securityManager)
-    securityManager->IsCapabilityEnabled("UniversalBrowserWrite", &enabled);
+    securityManager->IsCapabilityEnabled("UniversalXPConnect", &enabled);
   if (!enabled)
     return NS_OK;
 
   PRUint32 chromeFlags;
 
   NS_ENSURE_SUCCESS(browserChrome->GetChromeFlags(&chromeFlags),
                     NS_ERROR_FAILURE);
   if (aVisible)
@@ -318,17 +318,17 @@ nsScrollbarsProp::GetVisible(bool *aVisi
 NS_IMETHODIMP
 nsScrollbarsProp::SetVisible(bool aVisible)
 {
   bool     enabled = false;
 
   nsCOMPtr<nsIScriptSecurityManager>
            securityManager(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
   if (securityManager)
-    securityManager->IsCapabilityEnabled("UniversalBrowserWrite", &enabled);
+    securityManager->IsCapabilityEnabled("UniversalXPConnect", &enabled);
   if (!enabled)
     return NS_OK;
 
   /* Scrollbars, unlike the other barprops, implement visibility directly
      rather than handing off to the superclass (and from there to the
      chrome window) because scrollbar visibility uniquely applies only
      to the window making the change (arguably. it does now, anyway.)
      and because embedding apps have no interface for implementing this
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -419,16 +419,17 @@
 #include "nsIDOMSVGRectElement.h"
 #include "nsIDOMSVGScriptElement.h"
 #include "nsIDOMSVGStopElement.h"
 #include "nsIDOMSVGStylable.h"
 #include "nsIDOMSVGStyleElement.h"
 #include "nsIDOMSVGSVGElement.h"
 #include "nsIDOMSVGSwitchElement.h"
 #include "nsIDOMSVGSymbolElement.h"
+#include "nsIDOMSVGTests.h"
 #include "nsIDOMSVGTextElement.h"
 #include "nsIDOMSVGTextPathElement.h"
 #include "nsIDOMSVGTitleElement.h"
 #include "nsIDOMSVGTransform.h"
 #include "nsIDOMSVGTransformable.h"
 #include "nsIDOMSVGTransformList.h"
 #include "nsIDOMSVGTSpanElement.h"
 #include "nsIDOMSVGUnitTypes.h"
@@ -1240,16 +1241,18 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(SVGPoint, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGPointList, nsSVGPointListSH,
                            ARRAY_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGPreserveAspectRatio, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGRect, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(SVGStringList, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)    
   NS_DEFINE_CLASSINFO_DATA(SVGTransform, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGTransformList, nsSVGTransformListSH,
                            ARRAY_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGZoomEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(HTMLCanvasElement, nsElementSH,
@@ -3087,55 +3090,61 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGDocument)
     DOM_CLASSINFO_DOCUMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   // SVG element classes
 
   DOM_CLASSINFO_MAP_BEGIN(SVGAElement, nsIDOMSVGAElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGAltGlyphElement, nsIDOMSVGAltGlyphElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTextPositioningElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTextContentElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGAnimateElement, nsIDOMSVGAnimateElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimationElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimateElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMElementTimeControl)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGAnimateTransformElement,
                           nsIDOMSVGAnimateTransformElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimationElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimateTransformElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMElementTimeControl)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGAnimateMotionElement,
                           nsIDOMSVGAnimateMotionElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimationElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimateMotionElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMElementTimeControl)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGSetElement,
                           nsIDOMSVGSetElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimationElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGSetElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMElementTimeControl)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGMpathElement, nsIDOMSVGMpathElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
@@ -3143,41 +3152,42 @@ nsDOMClassInfo::Init()
 
   DOM_CLASSINFO_MAP_BEGIN(TimeEvent, nsIDOMTimeEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMTimeEvent)
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGCircleElement, nsIDOMSVGCircleElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGCircleElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGClipPathElement, nsIDOMSVGClipPathElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGClipPathElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGLocatable)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTransformable)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGUnitTypes)
-    DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
+    DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGDefsElement, nsIDOMSVGDefsElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGDefsElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGDescElement, nsIDOMSVGDescElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGDescElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGEllipseElement, nsIDOMSVGEllipseElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGEllipseElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGFEBlendElement, nsIDOMSVGFEBlendElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFEBlendElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFilterPrimitiveStandardAttributes)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
@@ -3326,104 +3336,116 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFETurbulenceElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFilterPrimitiveStandardAttributes)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGFilterElement, nsIDOMSVGFilterElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFilterElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGUnitTypes)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGGElement, nsIDOMSVGGElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGGElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGImageElement, nsIDOMSVGImageElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGImageElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGLinearGradientElement, nsIDOMSVGLinearGradientElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGGradientElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGLinearGradientElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGUnitTypes)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGLineElement, nsIDOMSVGLineElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGLineElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGMarkerElement, nsIDOMSVGMarkerElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGMarkerElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFitToViewBox)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGMaskElement, nsIDOMSVGMaskElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGMaskElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGUnitTypes)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGMetadataElement, nsIDOMSVGMetadataElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGMetadataElement)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGPathElement, nsIDOMSVGPathElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGPathElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimatedPathData)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGPatternElement, nsIDOMSVGPatternElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGPatternElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFitToViewBox)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGUnitTypes)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGPolygonElement, nsIDOMSVGPolygonElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGPolygonElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimatedPoints)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGPolylineElement, nsIDOMSVGPolylineElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGPolylineElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimatedPoints)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGRadialGradientElement, nsIDOMSVGRadialGradientElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGGradientElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGRadialGradientElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGUnitTypes)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGRectElement, nsIDOMSVGRectElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGRectElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGScriptElement, nsIDOMSVGScriptElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGScriptElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
@@ -3440,68 +3462,75 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGSVGElement, nsIDOMSVGSVGElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGSVGElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFitToViewBox)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGLocatable)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGZoomAndPan)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGSwitchElement, nsIDOMSVGSwitchElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGSwitchElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGSymbolElement, nsIDOMSVGSymbolElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGSymbolElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFitToViewBox)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGTextElement, nsIDOMSVGTextElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTextPositioningElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTextContentElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGTextPathElement, nsIDOMSVGTextPathElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTextContentElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGTitleElement, nsIDOMSVGTitleElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTitleElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGTSpanElement, nsIDOMSVGTSpanElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTextPositioningElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTextContentElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(SVGUnknownElement, nsIDOMSVGElement)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGUseElement, nsIDOMSVGUseElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGUseElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   // other SVG classes
 
   DOM_CLASSINFO_MAP_BEGIN(SVGAngle, nsIDOMSVGAngle)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAngle)
@@ -3695,16 +3724,20 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(SVGPreserveAspectRatio, nsIDOMSVGPreserveAspectRatio)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGPreserveAspectRatio)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGRect, nsIDOMSVGRect)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGRect)
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(SVGStringList, nsIDOMSVGStringList)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStringList)
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN(SVGTransform, nsIDOMSVGTransform)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTransform)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGTransformList, nsIDOMSVGTransformList)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTransformList)
   DOM_CLASSINFO_MAP_END
 
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -50,30 +50,33 @@
 #include "nsContentUtils.h"
 #include "xpcpublic.h"
 
 namespace mozilla {
 class DOMSVGLengthList;
 class DOMSVGNumberList;
 class DOMSVGPathSegList;
 class DOMSVGPointList;
+class DOMSVGStringList;
 class DOMSVGTransformList;
 }
 class nsGlobalWindow;
 class nsIDOMDocument;
 class nsIDOMHTMLOptionsCollection;
 class nsIDOMNodeList;
 class nsIDOMSVGLength;
 class nsIDOMSVGLengthList;
 class nsIDOMSVGNumber;
 class nsIDOMSVGNumberList;
 class nsIDOMSVGPathSeg;
 class nsIDOMSVGPathSegList;
 class nsIDOMSVGPoint;
 class nsIDOMSVGPointList;
+class nsIDOMSVGStringList;
+class nsIDOMSVGTests;
 class nsIDOMSVGTransform;
 class nsIDOMSVGTransformList;
 class nsIDOMWindow;
 class nsIForm;
 class nsIHTMLDocument;
 class nsNPAPIPluginInstance;
 
 struct nsDOMClassInfoData;
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -336,16 +336,17 @@ DOMCI_CLASS(SVGPathSegLinetoVerticalAbs)
 DOMCI_CLASS(SVGPathSegLinetoVerticalRel)
 DOMCI_CLASS(SVGPathSegList)
 DOMCI_CLASS(SVGPathSegMovetoAbs)
 DOMCI_CLASS(SVGPathSegMovetoRel)
 DOMCI_CLASS(SVGPoint)
 DOMCI_CLASS(SVGPointList)
 DOMCI_CLASS(SVGPreserveAspectRatio)
 DOMCI_CLASS(SVGRect)
+DOMCI_CLASS(SVGStringList)
 DOMCI_CLASS(SVGTransform)
 DOMCI_CLASS(SVGTransformList)
 DOMCI_CLASS(SVGZoomEvent)
 
 // Canvas
 DOMCI_CLASS(HTMLCanvasElement)
 DOMCI_CLASS(CanvasRenderingContext2D)
 DOMCI_CLASS(CanvasGradient)
--- a/dom/base/nsDOMMemoryReporter.cpp
+++ b/dom/base/nsDOMMemoryReporter.cpp
@@ -225,8 +225,17 @@ nsDOMMemoryMultiReporter::CollectReports
   nsRefPtr<nsGlobalWindow> *end = w + windows.Length();
   for (; w != end; ++w) {
     CollectWindowMemoryUsage(*w, aCb, aClosure);
   }
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsDOMMemoryMultiReporter::GetExplicitNonHeap(PRInt64* aAmount)
+{
+  // This reporter only measures heap memory.
+  *aAmount = 0;
+  return NS_OK;
+}
+
+
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2597,17 +2597,17 @@ nsGlobalWindow::DialogOpenAttempted()
     NS_ERROR("DialogOpenAttempted() called without a top window?");
 
     return false;
   }
 
   topWindow = topWindow->GetCurrentInnerWindowInternal();
   if (!topWindow ||
       topWindow->mLastDialogQuitTime.IsNull() ||
-      nsContentUtils::IsCallerTrustedForCapability("UniversalXPConnect")) {
+      nsContentUtils::CallerHasUniversalXPConnect()) {
     return false;
   }
 
   TimeDuration dialogDuration(TimeStamp::Now() -
                               topWindow->mLastDialogQuitTime);
 
   if (dialogDuration.ToSeconds() <
         Preferences::GetInt("dom.successive_dialog_time_limit",
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -124,29 +124,32 @@ static PRLogModuleInfo* gJSDiagnostics;
 #ifdef CompareString
 #undef CompareString
 #endif
 
 // The amount of time we wait between a request to GC (due to leaving
 // a page) and doing the actual GC.
 #define NS_GC_DELAY                 4000 // ms
 
+#define NS_SHRINK_GC_BUFFERS_DELAY  4000 // ms
+
 // The amount of time we wait from the first request to GC to actually
 // doing the first GC.
 #define NS_FIRST_GC_DELAY           10000 // ms
 
 // The amount of time we wait between a request to CC (after GC ran)
 // and doing the actual CC.
 #define NS_CC_DELAY                 5000 // ms
 
 #define JAVASCRIPT nsIProgrammingLanguage::JAVASCRIPT
 
 // if you add statics here, add them to the list in nsJSRuntime::Startup
 
 static nsITimer *sGCTimer;
+static nsITimer *sShrinkGCBuffersTimer;
 static nsITimer *sCCTimer;
 
 static bool sGCHasRun;
 
 // The number of currently pending document loads. This count isn't
 // guaranteed to always reflect reality and can't easily as we don't
 // have an easy place to know when a load ends or is interrupted in
 // all cases. This counter also gets reset if we end up GC'ing while
@@ -1093,34 +1096,35 @@ nsJSContext::~nsJSContext()
     NS_IF_RELEASE(sRuntimeService);
     NS_IF_RELEASE(sSecurityManager);
   }
 }
 
 void
 nsJSContext::DestroyJSContext()
 {
-  if (!mContext)
+  if (!mContext) {
     return;
+  }
 
   // Clear our entry in the JSContext, bugzilla bug 66413
   ::JS_SetContextPrivate(mContext, nsnull);
 
   // Unregister our "javascript.options.*" pref-changed callback.
   Preferences::UnregisterCallback(JSOptionChangedCallback,
                                   js_options_dot_str, this);
 
-  bool do_gc = mGCOnDestruction && !sGCTimer;
-
+  if (mGCOnDestruction) {
+    PokeGC();
+  }
+        
   // Let xpconnect destroy the JSContext when it thinks the time is right.
   nsIXPConnect *xpc = nsContentUtils::XPConnect();
   if (xpc) {
-    xpc->ReleaseJSContext(mContext, !do_gc);
-  } else if (do_gc) {
-    ::JS_DestroyContext(mContext);
+    xpc->ReleaseJSContext(mContext, true);
   } else {
     ::JS_DestroyContextNoGC(mContext);
   }
   mContext = nsnull;
 }
 
 // QueryInterface implementation for nsJSContext
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSContext)
@@ -3219,31 +3223,44 @@ nsJSContext::ScriptExecuted()
 //static
 void
 nsJSContext::GarbageCollectNow(bool shrinkingGC)
 {
   NS_TIME_FUNCTION_MIN(1.0);
   SAMPLE_LABEL("GC", "GarbageCollectNow");
 
   KillGCTimer();
+  KillShrinkGCBuffersTimer();
 
   // Reset sPendingLoadCount in case the timer that fired was a
   // timer we scheduled due to a normal GC timer firing while
   // documents were loading. If this happens we're waiting for a
   // document that is taking a long time to load, and we effectively
   // ignore the fact that the currently loading documents are still
   // loading and move on as if they weren't.
   sPendingLoadCount = 0;
   sLoadingInProgress = false;
 
   if (nsContentUtils::XPConnect()) {
     nsContentUtils::XPConnect()->GarbageCollect(shrinkingGC);
   }
 }
 
+//static
+void
+nsJSContext::ShrinkGCBuffersNow()
+{
+  NS_TIME_FUNCTION_MIN(1.0);
+  SAMPLE_LABEL("GC", "ShrinkGCBuffersNow");
+
+  KillShrinkGCBuffersTimer();
+
+  JS_ShrinkGCBuffers(nsJSRuntime::sRuntime);
+}
+
 //Static
 void
 nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener)
 {
   if (!NS_IsMainThread()) {
     return;
   }
 
@@ -3291,16 +3308,24 @@ nsJSContext::CycleCollectNow(nsICycleCol
 void
 GCTimerFired(nsITimer *aTimer, void *aClosure)
 {
   NS_RELEASE(sGCTimer);
 
   nsJSContext::GarbageCollectNow();
 }
 
+void
+ShrinkGCBuffersTimerFired(nsITimer *aTimer, void *aClosure)
+{
+  NS_RELEASE(sShrinkGCBuffersTimer);
+
+  nsJSContext::ShrinkGCBuffersNow();
+}
+
 // static
 void
 CCTimerFired(nsITimer *aTimer, void *aClosure)
 {
   NS_RELEASE(sCCTimer);
 
   nsJSContext::CycleCollectNow();
 }
@@ -3356,16 +3381,36 @@ nsJSContext::PokeGC()
                                  : NS_GC_DELAY,
                                  nsITimer::TYPE_ONE_SHOT);
 
   first = false;
 }
 
 // static
 void
+nsJSContext::PokeShrinkGCBuffers()
+{
+  if (sShrinkGCBuffersTimer) {
+    return;
+  }
+
+  CallCreateInstance("@mozilla.org/timer;1", &sShrinkGCBuffersTimer);
+
+  if (!sShrinkGCBuffersTimer) {
+    // Failed to create timer (probably because we're in XPCOM shutdown)
+    return;
+  }
+
+  sShrinkGCBuffersTimer->InitWithFuncCallback(ShrinkGCBuffersTimerFired, nsnull,
+                                              NS_SHRINK_GC_BUFFERS_DELAY,
+                                              nsITimer::TYPE_ONE_SHOT);
+}
+
+// static
+void
 nsJSContext::MaybePokeCC()
 {
   if (nsCycleCollector_suspectedCount() > 1000) {
     PokeCC();
   }
 }
 
 // static
@@ -3397,16 +3442,27 @@ nsJSContext::KillGCTimer()
     sGCTimer->Cancel();
 
     NS_RELEASE(sGCTimer);
   }
 }
 
 //static
 void
+nsJSContext::KillShrinkGCBuffersTimer()
+{
+  if (sShrinkGCBuffersTimer) {
+    sShrinkGCBuffersTimer->Cancel();
+
+    NS_RELEASE(sShrinkGCBuffersTimer);
+  }
+}
+
+//static
+void
 nsJSContext::KillCCTimer()
 {
   if (sCCTimer) {
     sCCTimer->Cancel();
 
     NS_RELEASE(sCCTimer);
   }
 }
@@ -3460,20 +3516,21 @@ DOMGCFinishedCallback(JSRuntime *rt, JSC
   } else {
     // If this was a full GC, poke the CC to run soon.
     if (!comp) {
       sGCHasRun = true;
       nsJSContext::PokeCC();
     }
   }
 
-  // If we didn't end up scheduling a GC, and there are unused
-  // chunks waiting to expire, make sure we will GC again soon.
-  if (!sGCTimer && JS_GetGCParameter(rt, JSGC_UNUSED_CHUNKS) > 0) {
-    nsJSContext::PokeGC();
+  // If we didn't end up scheduling a GC, make sure that we release GC buffers
+  // soon after canceling previous shrinking attempt 
+  nsJSContext::KillShrinkGCBuffersTimer();
+  if (!sGCTimer) {
+    nsJSContext::PokeShrinkGCBuffers();
   }
 }
 
 // Script object mananagement - note duplicate implementation
 // in nsJSRuntime below...
 nsresult
 nsJSContext::HoldScriptObject(void* aScriptObject)
 {
@@ -3803,16 +3860,17 @@ nsJSRuntime::GetNameSpaceManager()
   return gNameSpaceManager;
 }
 
 /* static */
 void
 nsJSRuntime::Shutdown()
 {
   nsJSContext::KillGCTimer();
+  nsJSContext::KillShrinkGCBuffersTimer();
   nsJSContext::KillCCTimer();
 
   NS_IF_RELEASE(gNameSpaceManager);
 
   if (!sContextCount) {
     // We're being shutdown, and there are no more contexts
     // alive, release the JS runtime service and the security manager.
 
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -178,21 +178,25 @@ public:
   virtual void LeaveModalState();
 
   NS_DECL_NSIXPCSCRIPTNOTIFY
 
   static void LoadStart();
   static void LoadEnd();
 
   static void GarbageCollectNow(bool shrinkingGC = false);
+  static void ShrinkGCBuffersNow();
   static void CycleCollectNow(nsICycleCollectorListener *aListener = nsnull);
 
   static void PokeGC();
   static void KillGCTimer();
 
+  static void PokeShrinkGCBuffers();
+  static void KillShrinkGCBuffersTimer();
+
   static void PokeCC();
   static void MaybePokeCC();
   static void KillCCTimer();
 
   virtual void GC();
 
 protected:
   nsresult InitializeExternalClasses();
--- a/dom/interfaces/svg/Makefile.in
+++ b/dom/interfaces/svg/Makefile.in
@@ -108,20 +108,22 @@ XPIDLSRCS	= \
 		nsIDOMSVGPolylineElement.idl \
 		nsIDOMSVGPresAspectRatio.idl \
 		nsIDOMSVGRect.idl \
 		nsIDOMSVGRectElement.idl \
 		nsIDOMSVGScriptElement.idl \
 		nsIDOMSVGSetElement.idl \
 		nsIDOMSVGSVGElement.idl \
 		nsIDOMSVGStopElement.idl \
+		nsIDOMSVGStringList.idl \
 		nsIDOMSVGStylable.idl \
 		nsIDOMSVGStyleElement.idl \
 		nsIDOMSVGSwitchElement.idl \
 		nsIDOMSVGSymbolElement.idl \
+		nsIDOMSVGTests.idl \
 		nsIDOMSVGTextContentElement.idl \
 		nsIDOMSVGTextElement.idl \
 		nsIDOMSVGTextPathElement.idl \
 		nsIDOMSVGTextPositionElem.idl \
 		nsIDOMSVGTitleElement.idl \
 		nsIDOMSVGTransform.idl \
 		nsIDOMSVGTransformList.idl \
 		nsIDOMSVGTransformable.idl \
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/svg/nsIDOMSVGStringList.idl
@@ -0,0 +1,59 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * The Initial Developer of the Original Code is
+ * Robert Longson
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "domstubs.idl"
+
+[scriptable, uuid(481f01a5-0bbb-4abf-8623-f3c2fb5642a9)]
+interface nsIDOMSVGStringList : nsISupports
+{ 
+  readonly attribute unsigned long numberOfItems;
+
+  void clear();
+          // raises(nsIDOMDOMException);
+  DOMString initialize(in DOMString newItem);
+                    // raises(nsIDOMDOMException);
+  DOMString getItem(in unsigned long index);
+                    // raises(nsIDOMDOMException);
+  DOMString insertItemBefore(in DOMString newItem, in unsigned long index);
+                    // raises(nsIDOMDOMException);
+  DOMString replaceItem(in DOMString newItem, in unsigned long index);
+                    // raises(nsIDOMDOMException);
+  DOMString removeItem(in unsigned long index);
+                    // raises(nsIDOMDOMException);
+  DOMString appendItem(in DOMString newItem);
+                    // raises(nsIDOMDOMException);
+};
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/svg/nsIDOMSVGTests.idl
@@ -0,0 +1,49 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * The Initial Developer of the Original Code is
+ * Robert Longson
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIDOMSVGStringList.idl"
+
+[scriptable, uuid(b6186ed0-0861-11e1-be50-0800200c9a66)]
+interface nsIDOMSVGTests : nsISupports
+{
+  readonly attribute nsIDOMSVGStringList requiredFeatures;
+  readonly attribute nsIDOMSVGStringList requiredExtensions;
+  readonly attribute nsIDOMSVGStringList systemLanguage;
+
+  boolean hasExtension(in DOMString extension);
+};
+
--- a/dom/locales/en-US/chrome/security/caps.properties
+++ b/dom/locales/en-US/chrome/security/caps.properties
@@ -148,14 +148,9 @@ SetPropertyDeniedOriginsOnlySubject = Pe
 CallMethodDeniedOriginsOnlySubject = Permission denied for <%S> to call method %S.%S
 CreateWrapperDenied = Permission denied to create wrapper for object of class %S
 CreateWrapperDeniedForOrigin = Permission denied for <%2$S> to create wrapper for object of class %1$S
 ExtensionCapability = Unknown: %S
 ProtocolFlagError = Warning: Protocol handler for '%S' doesn't advertise a security policy.  While loading of such protocols is allowed for now, this is deprecated.  Please see the documentation in nsIProtocolHandler.idl.
 #
 # The following descriptions are shown in the EnableCapabilityQuery dialog
 #
-capdesc.UniversalBrowserRead = Read private data from any site or window
-capdesc.UniversalBrowserWrite = Modify any open window
 capdesc.UniversalXPConnect = Run or install software on your machine
-capdesc.UniversalFileRead = Read and upload local files
-capdesc.UniversalPreferencesRead = Read program settings
-capdesc.UniversalPreferencesWrite = Modify program settings
--- a/dom/tests/mochitest/bugs/bug346659-opener-echoer.html
+++ b/dom/tests/mochitest/bugs/bug346659-opener-echoer.html
@@ -1,6 +1,6 @@
 <script>
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect UniversalBrowserRead UniversalBrowserWrite");
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   window.opener.opener.postMessage(window.opener.testNum + " - " + window.x, "http://mochi.test:8888");
   window.opener.close();
   window.close();
 </script>
--- a/dom/tests/mochitest/bugs/bug346659-parent-echoer.html
+++ b/dom/tests/mochitest/bugs/bug346659-parent-echoer.html
@@ -1,5 +1,5 @@
 <script>
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect UniversalBrowserRead UniversalBrowserWrite");
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   window.parent.opener.postMessage(window.parent.testNum + " - " + window.x, "http://mochi.test:8888");
   window.parent.close();
 </script>
--- a/dom/tests/mochitest/bugs/test_bug346659.html
+++ b/dom/tests/mochitest/bugs/test_bug346659.html
@@ -37,17 +37,17 @@ function handleCmd(evt) {
   try {
     cmd = JSON.parse(evt.data);
   } catch (e) {
     // Not json
     return false;
   }  
 
   // Grab privileges so we can access cross-domain windows
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect UniversalBrowserRead UniversalBrowserWrite");
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 
   if ("load" in cmd) {
     var testNum = cmd.load;
     var win = wins[testNum];
     win.childWin.x = testNum;
     if (win.childWin.opener == win) {
       if ("xsite" in cmd) {
         var loc = r(window.location.href, "bug346659-opener-echoer.html");
--- a/dom/tests/mochitest/bugs/test_bug437361.html
+++ b/dom/tests/mochitest/bugs/test_bug437361.html
@@ -1,51 +1,53 @@
 <!DOCTYPE HTML>
 <html>
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=437361
 -->
 <head>
   <title>Test for Bug 437361</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/mozprefs.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   
   <script class="testbody" type="text/javascript">
 
   /** Test for Bug 437361 **/
 
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-
   function testModalDialogBlockedCleanly() {
-    is(true, pref("dom.disable_open_during_load"), "mozprefs sanity check");
+    is(true, SpecialPowers.getBoolPref("dom.disable_open_during_load"), "mozprefs sanity check");
     var rv = window.showModalDialog( // should be blocked without exception
       "data:text/html,<html><body onload='close(); returnValue = 1;' /></html>");
     is(rv, null, "Modal dialog opened unexpectedly.");
   }
   
   function testModalDialogAllowed() {
-    is(false, pref("dom.disable_open_during_load"), "mozprefs sanity check");
+    is(false, SpecialPowers.getBoolPref("dom.disable_open_during_load"), "mozprefs sanity check");
     var rv = window.showModalDialog( // should not be blocked this time
       "data:text/html,<html><body onload='close(); returnValue = 1;' /></html>");
     is(rv, 1, "Problem with modal dialog returnValue.");
   }
 
   function testOtherExceptionsNotTrapped() {
-    is(false, pref("dom.disable_open_during_load"), "mozprefs sanity check");
+    is(false, SpecialPowers.getBoolPref("dom.disable_open_during_load"), "mozprefs sanity check");
     window.showModalDialog('about:config'); // forbidden by SecurityCheckURL
   }
 
   function test(disableOpen, exceptionExpected, testFn, errorMsg) {
+    var oldPrefVal = SpecialPowers.getBoolPref("dom.disable_open_during_load");
     try {
-      pref("dom.disable_open_during_load", disableOpen, testFn);
+      SpecialPowers.setBoolPref("dom.disable_open_during_load", disableOpen);
+      testFn();
       ok(!exceptionExpected, errorMsg);
     } catch (_) {
       ok(exceptionExpected, errorMsg);
     }
+    finally {
+      SpecialPowers.setBoolPref("dom.disable_open_during_load", oldPrefVal);
+    }
   }
 
   test(true, false, testModalDialogBlockedCleanly,
        "Blocked showModalDialog caused an exception.");
        
   test(false, false, testModalDialogAllowed,
        "showModalDialog was blocked even though dom.disable_open_during_load was false.");
 
--- a/dom/tests/mochitest/bugs/test_bug504862.html
+++ b/dom/tests/mochitest/bugs/test_bug504862.html
@@ -15,21 +15,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 /** Test for Bug 504862 **/
 SimpleTest.waitForExplicitFinish();
 function onMsgRcv(event)
 {
   is(event.data, "args: undefined", "Unexpected cross origin dialog arguments.");
 }
 
 function runTest() {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   window.addEventListener("message", onMsgRcv, false);
 
-  var subsequentDlg = "data:text/html,<html><body onload='opener.is(window.dialogArguments, \'my args\', \'subsequent dialog document did not get the right arguments.\'); close();'>";
-
   var result = window.showModalDialog("file_bug504862.html", "my args");
   is(result, null, "window sees previous dialog documents return value.");
 
   result = window.showModalDialog("http://test1.example.com/tests/dom/tests/mochitest/bugs/file_bug504862.html", "my args");
 
   is(result, null, "Able to see return value from cross origin dialog.");
   SimpleTest.finish();
 }
--- a/dom/tests/mochitest/general/Makefile.in
+++ b/dom/tests/mochitest/general/Makefile.in
@@ -53,16 +53,17 @@ include $(topsrcdir)/config/rules.mk
 		test_497898.html \
 		test_bug504220.html \
 		test_bug628069_1.html \
 		test_bug628069_2.html \
 		file_bug628069.html \
 		test_bug631440.html \
 		test_bug653364.html \
 		test_bug629535.html \
+		test_clientRects.html \
 		test_consoleAPI.html \
 		test_domWindowUtils.html \
 		test_domWindowUtils_scrollXY.html \
 		test_offsets.html \
 		test_offsets.js \
 		test_windowProperties.html \
 		test_clipboard_events.html \
 		test_nodesFromRect.html \
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/general/test_clientRects.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML>
+<html id="d9" style="width:800px; height:1000px">
+<head>
+  <title>Tests for getClientRects/getBoundingClientRect</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
+</head>
+<body style="margin:0" onload="doTest()">
+
+<script>
+function isWithinEps(v1, v2, eps, msg) {
+  if (eps) {
+    ok(Math.abs(v1 - v2) < eps, msg + " (within " + eps + "); got " + v1 + ", expected " + v2);
+  } else {
+    is(v1, v2, msg);
+  }
+}
+function checkRect(clientRect, r, eps, exprMsg, restMsg) {
+  isWithinEps(clientRect.left, r[0], eps, exprMsg + ".left" + restMsg);
+  isWithinEps(clientRect.top, r[1], eps, exprMsg + ".top" + restMsg);
+  isWithinEps(clientRect.right, r[2], eps, exprMsg + ".right" + restMsg);
+  isWithinEps(clientRect.bottom, r[3], eps, exprMsg + ".bottom" + restMsg);
+  isWithinEps(clientRect.width, r[2] - r[0], eps, exprMsg + ".width" + restMsg);
+  isWithinEps(clientRect.height, r[3] - r[1], eps, exprMsg + ".height" + restMsg);
+}
+function doc(id) {
+  return document.getElementById(id).contentDocument;
+}
+function checkElement(id, list, eps, doc) {
+  var e = (doc || document).getElementById(id);
+  var clientRects = e.getClientRects();
+  is(clientRects.length, list.length, "getClientRects().length for element '" + id + "'");
+  var bounds = list.length > 0 ? list[0] : [0,0,0,0];
+  for (var i = 0; i < clientRects.length && i < list.length; ++i) {
+    var r = list[i];
+    r[2] += r[0];
+    r[3] += r[1];
+    checkRect(clientRects[i], r, eps, "getClientRects()[" + i + "]", " for element '" + id + "'");
+    if (r[2] != r[0] && r[3] != r[1]) {
+      bounds[0] = Math.min(bounds[0], r[0]);
+      bounds[1] = Math.min(bounds[1], r[1]);
+      bounds[2] = Math.max(bounds[2], r[2]);
+      bounds[3] = Math.max(bounds[3], r[3]);
+    }
+  }
+  checkRect(e.getBoundingClientRect(), bounds, eps, "getBoundingClientRect()", " for element '" + id + "'");
+}
+</script>
+
+<!-- Simple case -->
+<div id="d1" style="position:absolute; left:50px; top:50px; width:20px; height:30px; background:pink;"></div>
+<!-- Multiple boxes -->
+<div style="position:absolute; left:50px; top:100px; width:400px; height:100px; -moz-column-count:2; -moz-column-gap:0; column-count:2; column-gap:0">
+  <div id="d2">
+    <div style="width:200px; height:100px; background:yellow"></div>
+    <div style="width:200px; height:100px; background:lime"></div>
+  </div>
+</div>
+<!-- No boxes -->
+<div id="d3" style="display:none"></div>
+<!-- Element in transform -->
+<div style="-moz-transform:translate(50px, 50px); transform:translate(50px,50px); position:absolute; left:0; top:200px">
+  <div id="d4" style="width:50px; height:50px; background:blue;"></div>  
+</div>
+<svg style="position:absolute; left:50px; top:300px; width:100px; height:100px;">
+  <!-- Element in SVG foreignobject -->
+  <foreignObject x="20" y="30" width="40" height="40">
+    <div id="d5" style="width:40px; height:40px; background:pink;"></div>
+  </foreignObject>
+  <!-- SVG Element -->
+  <circle id="s1" cx="60" cy="60" r="10" fill="yellow"/>
+</svg>
+<!-- Element in transform with bounding-box -->
+<div style="-moz-transform:rotate(45deg); transform:rotate(45deg); position:absolute; left:50px; top:450px; width:100px; height:100px;">
+  <div id="d6" style="width:100px; height:100px; background:orange;"></div>  
+</div>
+<!-- Element in two transforms; we should combine transforms instead of taking bounding-box twice -->
+<div style="-moz-transform:rotate(45deg); transform:rotate(45deg); position:absolute; left:50px; top:550px; width:100px; height:100px;">
+  <div style="-moz-transform:rotate(-45deg); transform:rotate(-45deg); width:100px; height:100px;">
+    <div id="d7" style="width:100px; height:100px; background:lime;"></div>
+  </div>
+</div>
+<!-- Fixed-pos element -->
+<div id="d8" style="position:fixed; left:50px; top:700px; width:100px; height:100px; background:gray;"></div>
+<!-- Root element; see d9 -->
+<!-- Element in iframe -->
+<iframe id="f1" style="position:absolute; left:300px; top:0; width:100px; height:200px; border:none"
+        src="data:text/html,<div id='d10' style='position:absolute; left:0; top:25px; width:100px; height:100px; background:cyan'>">
+</iframe>
+<!-- Root element in iframe -->
+<iframe id="f2" style="position:absolute; left:300px; top:250px; width:100px; height:200px; border:none"
+        src="data:text/html,<html id='d11' style='width:100px; height:100px; background:magenta'>">
+</iframe>
+<!-- Fixed-pos element in iframe -->
+<iframe id="f3" style="position:absolute; left:300px; top:400px; border:none"
+        src="data:text/html,<div id='d12' style='position:fixed; left:0; top:0; width:100px; height:100px;'>"></iframe>
+
+<script>
+function doTest() {
+  checkElement("d1", [[50,50,20,30]]);
+  checkElement("d2", [[50,100,200,100],[250,100,200,100]]);
+  checkElement("d3", []);
+  checkElement("d4", [[50,250,50,50]]);
+  checkElement("d5", [[70,330,40,40]]);
+  checkElement("s1", [[100,350,20,20]]);
+  var sqrt2 = Math.sqrt(2);
+  checkElement("d6", [[100 - 50*sqrt2,500 - 50*sqrt2,100*sqrt2,100*sqrt2]], 0.1);
+  checkElement("d7", [[50,550,100,100]]);
+  checkElement("d8", [[50,700,100,100]]);
+  checkElement("d9", [[0,0,800,1000]]);
+  checkElement("d10", [[0,25,100,100]], 0, doc("f1"));
+  checkElement("d11", [[0,0,100,100]], 0, doc("f2"));
+  checkElement("d12", [[0,0,100,100]], 0, doc("f3"));
+  SimpleTest.finish();
+}
+SimpleTest.waitForExplicitFinish();
+</script>
+
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+
+</body>
+</html>
--- a/dom/tests/mochitest/general/test_focusrings.xul
+++ b/dom/tests/mochitest/general/test_focusrings.xul
@@ -33,17 +33,17 @@ function setOrRestoreTabFocus(newValue) 
     }
   } else {
     prefs.setIntPref("tabfocus", newValue);
   }
 }
 
 function snapShot(element) {
   var rect = element.getBoundingClientRect();
-  netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
+  netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
   var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
   canvas.setAttribute("width", rect.width + 12);
   canvas.setAttribute("height", rect.height + 12);
   var ctx = canvas.getContext("2d");
   ctx.drawWindow(window, rect.left - 6, rect.top - 6, rect.width + 6, rect.height + 6,
                  "transparent");
   return canvas;
 }
--- a/dom/tests/mochitest/storageevent/interOriginFrame.js
+++ b/dom/tests/mochitest/storageevent/interOriginFrame.js
@@ -1,11 +1,11 @@
 function postMsg(message)
 {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   var l = parent.window.location;
   parent.postMessage(message, l.protocol + "//" + l.host);
 }
 
 window.addEventListener("message", onMessageReceived, false);
 
 function onMessageReceived(event)
 {
--- a/dom/tests/mochitest/storageevent/interOriginTest2.js
+++ b/dom/tests/mochitest/storageevent/interOriginTest2.js
@@ -11,17 +11,16 @@ var todoRegExp = new RegExp("^TODO");
 
 const framePath = "/tests/dom/tests/mochitest/storageevent/";
 
 window.addEventListener("message", onMessageReceived, false);
 
 function onMessageReceived(event)
 {
   netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
 
   switch (event.data)
   {
     // Indication of the frame onload event
     case "frame loaded":
       if (--frameLoadsPending)
         break;
 
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -861,22 +861,21 @@ RuntimeService::Init()
   NS_ENSURE_STATE(mIdleThreadTimer);
 
   bool ok = mDomainMap.Init();
   NS_ENSURE_STATE(ok);
 
   ok = mWindowMap.Init();
   NS_ENSURE_STATE(ok);
 
-  nsresult rv;
-  nsCOMPtr<nsIObserverService> obs =
-    do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
+  NS_ENSURE_TRUE(obs, NS_ERROR_FAILURE);
 
-  rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, false);
+  nsresult rv =
+    obs->AddObserver(this, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mObserved = true;
 
   for (PRUint32 index = 0; index < ArrayLength(gPrefsToWatch); index++) {
     if (NS_FAILED(Preferences::RegisterCallback(PrefCallback,
                                                 gPrefsToWatch[index], this))) {
       NS_WARNING("Failed to register pref callback?!");
@@ -911,16 +910,26 @@ RuntimeService::Init()
 
 // This spins the event loop until all workers are finished and their threads
 // have been joined.
 void
 RuntimeService::Cleanup()
 {
   AssertIsOnMainThread();
 
+  nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
+  NS_WARN_IF_FALSE(obs, "Failed to get observer service?!");
+
+  // Tell anyone that cares that they're about to lose worker support.
+  if (obs && NS_FAILED(obs->NotifyObservers(nsnull, WORKERS_SHUTDOWN_TOPIC,
+                                            nsnull))) {
+    NS_WARNING("NotifyObservers failed!");
+  }
+
+  // That's it, no more workers.
   mShuttingDown = true;
 
   if (mIdleThreadTimer) {
     if (NS_FAILED(mIdleThreadTimer->Cancel())) {
       NS_WARNING("Failed to cancel idle timer!");
     }
     mIdleThreadTimer = nsnull;
   }
@@ -990,23 +999,20 @@ RuntimeService::Cleanup()
     NS_ASSERTION(!mWindowMap.Count(), "All windows should have been released!");
   }
 
   if (mObserved) {
     for (PRUint32 index = 0; index < ArrayLength(gPrefsToWatch); index++) {
       Preferences::UnregisterCallback(PrefCallback, gPrefsToWatch[index], this);
     }
 
-    nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
-    NS_WARN_IF_FALSE(obs, "Failed to get observer service?!");
-
     if (obs) {
       nsresult rv =
         obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID);
-      mObserved = !NS_SUCCEEDED(rv);
+      mObserved = NS_FAILED(rv);
     }
   }
 }
 
 // static
 PLDHashOperator
 RuntimeService::AddAllTopLevelWorkersToArray(const nsACString& aKey,
                                              WorkerDomainInfo* aData,
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -181,27 +181,24 @@ public:
     }
 
     mPathPrefix = NS_LITERAL_CSTRING("explicit/dom/workers(") +
                   escapedDomain + NS_LITERAL_CSTRING(")/worker(") +
                   escapedURL + NS_LITERAL_CSTRING(", ") + mAddressString +
                   NS_LITERAL_CSTRING(")/");
   }
 
-  NS_IMETHOD
-  CollectReports(nsIMemoryMultiReporterCallback* aCallback,
-                 nsISupports* aClosure)
+  nsresult
+  CollectForRuntime(bool aIsQuick, void* aData)
   {
     AssertIsOnMainThread();
 
-    IterateData data;
-
     if (mWorkerPrivate) {
       bool disabled;
-      if (!mWorkerPrivate->BlockAndCollectRuntimeStats(&data, &disabled)) {
+      if (!mWorkerPrivate->BlockAndCollectRuntimeStats(aIsQuick, aData, &disabled)) {
         return NS_ERROR_FAILURE;
       }
 
       // Don't ever try to talk to the worker again.
       if (disabled) {
 #ifdef DEBUG
         {
           nsCAutoString message("Unable to report memory for ");
@@ -212,22 +209,45 @@ public:
                      NS_LITERAL_CSTRING(")! It is either using ctypes or is in "
                                         "the process of being destroyed");
           NS_WARNING(message.get());
         }
 #endif
         mWorkerPrivate = nsnull;
       }
     }
+    return NS_OK;
+  }
+
+  NS_IMETHOD
+  CollectReports(nsIMemoryMultiReporterCallback* aCallback,
+                 nsISupports* aClosure)
+  {
+    AssertIsOnMainThread();
+
+    IterateData data;
+    nsresult rv = CollectForRuntime(/* isQuick = */false, &data);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
 
     // Always report, even if we're disabled, so that we at least get an entry
     // in about::memory.
     ReportJSRuntimeStats(data, mPathPrefix, aCallback, aClosure);
+
     return NS_OK;
   }
+
+  NS_IMETHOD
+  GetExplicitNonHeap(PRInt64 *aAmount)
+  {
+    AssertIsOnMainThread();
+
+    return CollectForRuntime(/* isQuick = */true, aAmount);
+  }
 };
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(WorkerMemoryReporter, nsIMemoryMultiReporter)
 
 struct WorkerStructuredCloneCallbacks
 {
   static JSObject*
   Read(JSContext* aCx, JSStructuredCloneReader* aReader, uint32_t aTag,
@@ -876,33 +896,39 @@ public:
 
     bool dummy;
     return events::DispatchEventToTarget(aCx, target, event, &dummy);
   }
 };
 
 class NotifyRunnable : public WorkerControlRunnable
 {
+  bool mFromJSObjectFinalizer;
   Status mStatus;
 
 public:
-  NotifyRunnable(WorkerPrivate* aWorkerPrivate, Status aStatus)
+  NotifyRunnable(WorkerPrivate* aWorkerPrivate, bool aFromJSObjectFinalizer,
+                 Status aStatus)
   : WorkerControlRunnable(aWorkerPrivate, WorkerThread, UnchangedBusyCount),
-    mStatus(aStatus)
+    mFromJSObjectFinalizer(aFromJSObjectFinalizer), mStatus(aStatus)
   {
     NS_ASSERTION(aStatus == Terminating || aStatus == Canceling ||
                  aStatus == Killing, "Bad status!");
   }
 
   bool
   PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
   {
     // Modify here, but not in PostRun! This busy count addition will be matched
-    // by the CloseEventRunnable.
-    return aWorkerPrivate->ModifyBusyCount(aCx, true);
+    // by the CloseEventRunnable. If we're running from a finalizer there is no
+    // need to modify the count because future changes to the busy count will
+    // have no effect.
+    return mFromJSObjectFinalizer ?
+           true :
+           aWorkerPrivate->ModifyBusyCount(aCx, true);
   }
 
   bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
   {
     return aWorkerPrivate->NotifyInternal(aCx, mStatus);
   }
 };
@@ -1373,26 +1399,27 @@ public:
 class CollectRuntimeStatsRunnable : public WorkerControlRunnable
 {
   typedef mozilla::Mutex Mutex;
   typedef mozilla::CondVar CondVar;
 
   Mutex mMutex;
   CondVar mCondVar;
   volatile bool mDone;
-  IterateData* mData;
+  bool mIsQuick;
+  void* mData;
   bool* mSucceeded;
 
 public:
-  CollectRuntimeStatsRunnable(WorkerPrivate* aWorkerPrivate, IterateData* aData,
-                              bool* aSucceeded)
+  CollectRuntimeStatsRunnable(WorkerPrivate* aWorkerPrivate, bool aIsQuick,
+                              void* aData, bool* aSucceeded)
   : WorkerControlRunnable(aWorkerPrivate, WorkerThread, UnchangedBusyCount),
     mMutex("CollectRuntimeStatsRunnable::mMutex"),
     mCondVar(mMutex, "CollectRuntimeStatsRunnable::mCondVar"), mDone(false),
-    mData(aData), mSucceeded(aSucceeded)
+    mIsQuick(aIsQuick), mData(aData), mSucceeded(aSucceeded)
   { }
 
   bool
   PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
   {
     AssertIsOnMainThread();
     return true;
   }
@@ -1424,17 +1451,19 @@ public:
     return true;
   }
 
   bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
   {
     JSAutoSuspendRequest asr(aCx);
 
-    *mSucceeded = CollectCompartmentStatsForRuntime(JS_GetRuntime(aCx), mData);
+    *mSucceeded = mIsQuick ?
+      mozilla::xpconnect::memory::GetExplicitNonHeapForRuntime(JS_GetRuntime(aCx), mData) :
+      mozilla::xpconnect::memory::CollectCompartmentStatsForRuntime(JS_GetRuntime(aCx), mData);
 
     {
       MutexAutoLock lock(mMutex);
       mDone = true;
       mCondVar.Notify();
     }
 
     return true;
@@ -1761,17 +1790,18 @@ WorkerPrivateParent<Derived>::Start()
     }
   }
 
   return false;
 }
 
 template <class Derived>
 bool
-WorkerPrivateParent<Derived>::Notify(JSContext* aCx, Status aStatus)
+WorkerPrivateParent<Derived>::NotifyPrivate(JSContext* aCx, Status aStatus,
+                                            bool aFromJSObjectFinalizer)
 {
   AssertIsOnParentThread();
 
   bool pending;
   {
     MutexAutoLock lock(mMutex);
 
     if (mParentStatus >= aStatus) {
@@ -1802,18 +1832,19 @@ WorkerPrivateParent<Derived>::Notify(JSC
 
   NS_ASSERTION(aStatus != Terminating || mQueuedRunnables.IsEmpty(),
                "Shouldn't have anything queued!");
 
   // Anything queued will be discarded.
   mQueuedRunnables.Clear();
 
   nsRefPtr<NotifyRunnable> runnable =
-    new NotifyRunnable(ParentAsWorkerPrivate(), aStatus);
-  return runnable->Dispatch(aCx);
+    new NotifyRunnable(ParentAsWorkerPrivate(), aFromJSObjectFinalizer,
+                       aStatus);
+  return runnable->Dispatch(aFromJSObjectFinalizer ? nsnull : aCx);
 }
 
 template <class Derived>
 bool
 WorkerPrivateParent<Derived>::Suspend(JSContext* aCx)
 {
   AssertIsOnParentThread();
   NS_ASSERTION(!mParentSuspended, "Suspended more than once!");
@@ -1878,33 +1909,34 @@ WorkerPrivateParent<Derived>::Resume(JSC
 template <class Derived>
 void
 WorkerPrivateParent<Derived>::FinalizeInstance(JSContext* aCx,
                                                bool aFromJSFinalizer)
 {
   AssertIsOnParentThread();
 
   if (mJSObject) {
-    // Make sure we're in the right compartment.
+    // Make sure we're in the right compartment, but only enter one if this is
+    // not running from a finalizer.
     JSAutoEnterCompartment ac;
-    if (!ac.enter(aCx, mJSObject)) {
+    if (!aFromJSFinalizer && !ac.enter(aCx, mJSObject)) {
       NS_ERROR("How can this fail?!");
       return;
     }
 
     // Decouple the object from the private now.
     worker::ClearPrivateSlot(aCx, mJSObject, !aFromJSFinalizer);
 
     // Clear the JS object.
     mJSObject = nsnull;
 
     // Unroot.
     RootJSObject(aCx, false);
 
-    if (!Terminate(aCx)) {
+    if (!TerminatePrivate(aCx, aFromJSFinalizer)) {
       NS_WARNING("Failed to terminate!");
     }
 
     events::EventTarget::FinalizeInstance(aCx);
   }
 }
 
 template <class Derived>
@@ -2564,17 +2596,17 @@ WorkerPrivate::ScheduleDeletion(bool aWa
       new TopLevelWorkerFinishedRunnable(this, currentThread);
     if (NS_FAILED(NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL))) {
       NS_WARNING("Failed to dispatch runnable!");
     }
   }
 }
 
 bool
-WorkerPrivate::BlockAndCollectRuntimeStats(IterateData* aData, bool* aDisabled)
+WorkerPrivate::BlockAndCollectRuntimeStats(bool aIsQuick, void* aData, bool* aDisabled)
 {
   AssertIsOnMainThread();
   NS_ASSERTION(aData, "Null data!");
 
   {
     MutexAutoLock lock(mMutex);
 
     if (mMemoryReporterDisabled) {
@@ -2584,17 +2616,17 @@ WorkerPrivate::BlockAndCollectRuntimeSta
 
     *aDisabled = false;
     mMemoryReporterRunning = true;
   }
 
   bool succeeded;
 
   nsRefPtr<CollectRuntimeStatsRunnable> runnable =
-    new CollectRuntimeStatsRunnable(this, aData, &succeeded);
+    new CollectRuntimeStatsRunnable(this, aIsQuick, aData, &succeeded);
   if (!runnable->Dispatch(nsnull)) {
     NS_WARNING("Failed to dispatch runnable!");
     succeeded = false;
   }
 
   {
     MutexAutoLock lock(mMutex);
     mMemoryReporterRunning = false;
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -236,24 +236,36 @@ protected:
 
 private:
   Derived*
   ParentAsWorkerPrivate() const
   {
     return static_cast<Derived*>(const_cast<WorkerPrivateParent*>(this));
   }
 
+  bool
+  NotifyPrivate(JSContext* aCx, Status aStatus, bool aFromJSFinalizer);
+
+  bool
+  TerminatePrivate(JSContext* aCx, bool aFromJSFinalizer)
+  {
+    return NotifyPrivate(aCx, Terminating, aFromJSFinalizer);
+  }
+
 public:
   // May be called on any thread...
   bool
   Start();
 
   // Called on the parent thread.
   bool
-  Notify(JSContext* aCx, Status aStatus);
+  Notify(JSContext* aCx, Status aStatus)
+  {
+    return NotifyPrivate(aCx, aStatus, false);
+  }
 
   bool
   Cancel(JSContext* aCx)
   {
     return Notify(aCx, Canceling);
   }
 
   bool
@@ -278,17 +290,17 @@ public:
   }
 
   void
   FinalizeInstance(JSContext* aCx, bool aFromJSFinalizer);
 
   bool
   Terminate(JSContext* aCx)
   {
-    return Notify(aCx, Terminating);
+    return TerminatePrivate(aCx, false);
   }
 
   bool
   Close(JSContext* aCx);
 
   bool
   ModifyBusyCount(JSContext* aCx, bool aIncrease);
 
@@ -656,18 +668,17 @@ public:
 
   void
   UpdateJSContextOptionsInternal(JSContext* aCx, PRUint32 aOptions);
 
   void
   ScheduleDeletion(bool aWasPending);
 
   bool
-  BlockAndCollectRuntimeStats(mozilla::xpconnect::memory::IterateData* aData,
-                              bool* aDisabled);
+  BlockAndCollectRuntimeStats(bool isQuick, void* aData, bool* aDisabled);
 
   bool
   DisableMemoryReporter();
 
 #ifdef JS_GC_ZEAL
   void
   UpdateGCZealInternal(JSContext* aCx, PRUint8 aGCZeal);
 #endif
--- a/dom/workers/Workers.h
+++ b/dom/workers/Workers.h
@@ -46,16 +46,18 @@
 
 #define BEGIN_WORKERS_NAMESPACE \
   namespace mozilla { namespace dom { namespace workers {
 #define END_WORKERS_NAMESPACE \
   } /* namespace workers */ } /* namespace dom */ } /* namespace mozilla */
 #define USING_WORKERS_NAMESPACE \
   using namespace mozilla::dom::workers;
 
+#define WORKERS_SHUTDOWN_TOPIC "web-workers-shutdown"
+
 class nsPIDOMWindow;
 
 BEGIN_WORKERS_NAMESPACE
 
 class WorkerPrivate;
 
 struct PrivatizableBase
 { };
--- a/dom/workers/test/Makefile.in
+++ b/dom/workers/test/Makefile.in
@@ -53,16 +53,19 @@ include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES = \
   test_404.html \
   test_atob.html \
   atob_worker.js \
   test_blobWorkers.html \
   test_close.html \
   close_worker.js \
+  test_closeOnGC.html \
+  closeOnGC_worker.js \
+  closeOnGC_server.sjs \
   test_dataURLWorker.html \
   test_errorPropagation.html \
   errorPropagation_iframe.html \
   errorPropagation_worker.js \
   test_eventDispatch.html \
   eventDispatch_worker.js \
   test_importScripts.html \
   importScripts_worker.js \
@@ -153,24 +156,16 @@ include $(topsrcdir)/config/rules.mk
   WorkerTest_subworker.js \
   chromeWorker_worker.js \
   chromeWorker_subworker.js \
   test_workersDisabled.xul \
   workersDisabled_worker.js \
   dom_worker_helper.js \
   $(NULL)
 
-ifneq ($(OS_ARCH),WINNT)
-_TEST_FILES += \
-  test_closeOnGC.html \
-  closeOnGC_worker.js \
-  closeOnGC_server.sjs \
-  $(NULL)
-endif
-
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 
 libs:: $(_SUBDIR_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)/subdir
 
 libs:: $(_CHROME_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -116,16 +116,17 @@
 #include "nsComputedDOMStyle.h"
 #include "nsTextEditUtils.h"
 #include "nsComputedDOMStyle.h"
 
 #include "mozilla/FunctionTimer.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/Element.h"
 #include "nsContentUtils.h"
+#include "nsCCUncollectableMarker.h"
 
 #define NS_ERROR_EDITOR_NO_SELECTION NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_EDITOR,1)
 #define NS_ERROR_EDITOR_NO_TEXTNODE  NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_EDITOR,2)
 
 #ifdef NS_DEBUG_EDITOR
 static bool gNoisy = false;
 #endif
 
@@ -194,16 +195,22 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mActionListeners)
  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mEditorObservers)
  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mDocStateListeners)
  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mEventTarget)
  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mEventListener)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsEditor)
+ nsIDocument* currentDoc =
+   tmp->mRootElement ? tmp->mRootElement->GetCurrentDoc() : nsnull;
+ if (currentDoc &&
+     nsCCUncollectableMarker::InGeneration(cb, currentDoc->GetMarkedCCGeneration())) {
+   return NS_SUCCESS_INTERRUPTED_TRAVERSE;
+ }
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRootElement)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mInlineSpellChecker)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTxnMgr)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mIMETextRangeList)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mIMETextNode)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mActionListeners)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mEditorObservers)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mDocStateListeners)
@@ -988,17 +995,18 @@ nsEditor::EndPlaceHolderTransaction()
         plcTxn->EndPlaceHolderBatch();
       }
       else  
       {
         // in the future we will check to make sure undo is off here,
         // since that is the only known case where the placeholdertxn would disappear on us.
         // For now just removing the assert.
       }
-      // notify editor observers of action unless it is uncommitted IME
+      // notify editor observers of action but if composing, it's done by
+      // text event handler.
       if (!mInIMEMode) NotifyEditorObservers();
     }
   }
   mPlaceHolderBatch--;
   
   return NS_OK;
 }
 
--- a/editor/libeditor/base/nsEditorCommands.cpp
+++ b/editor/libeditor/base/nsEditorCommands.cpp
@@ -315,23 +315,17 @@ nsCutOrDeleteCommand::GetCommandStatePar
 NS_IMETHODIMP
 nsCopyCommand::IsCommandEnabled(const char * aCommandName,
                                 nsISupports *aCommandRefCon,
                                 bool *outCmdEnabled)
 {
   NS_ENSURE_ARG_POINTER(outCmdEnabled);
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
   if (editor)
-  {
-    bool isEditable = false;
-    nsresult rv = editor->GetIsSelectionEditable(&isEditable);
-    NS_ENSURE_SUCCESS(rv, rv);
-    if (isEditable)
-      return editor->CanCopy(outCmdEnabled);
-  }
+    return editor->CanCopy(outCmdEnabled);
 
   *outCmdEnabled = false;
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsCopyCommand::DoCommand(const char *aCommandName, nsISupports *aCommandRefCon)
@@ -658,29 +652,24 @@ NS_IMETHODIMP
 nsSelectAllCommand::IsCommandEnabled(const char * aCommandName,
                                      nsISupports *aCommandRefCon,
                                      bool *outCmdEnabled)
 {
   NS_ENSURE_ARG_POINTER(outCmdEnabled);
 
   nsresult rv = NS_OK;
   *outCmdEnabled = false;
-  bool docIsEmpty, selectionIsEditable;
+  bool docIsEmpty;
  
   // you can select all if there is an editor which is non-empty
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
   if (editor) {
-    rv = editor->GetIsSelectionEditable(&selectionIsEditable);
+    rv = editor->GetDocumentIsEmpty(&docIsEmpty);
     NS_ENSURE_SUCCESS(rv, rv);
-
-    if (selectionIsEditable) {
-      rv = editor->GetDocumentIsEmpty(&docIsEmpty);
-      NS_ENSURE_SUCCESS(rv, rv);
-      *outCmdEnabled = !docIsEmpty;
-    }
+    *outCmdEnabled = !docIsEmpty;
   } 
 
   return rv;
 }
 
 
 NS_IMETHODIMP
 nsSelectAllCommand::DoCommand(const char *aCommandName,
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp
@@ -365,20 +365,16 @@ nsHTMLEditor::DoInsertHTMLWithContext(co
   res = CreateListOfNodesToPaste(fragmentAsNode, nodeList,
                                  streamStartParent, streamStartOffset,
                                  streamEndParent, streamEndOffset);
   NS_ENSURE_SUCCESS(res, res);
 
   if (nodeList.Count() == 0)
     return NS_OK;
 
-  // walk list of nodes; perform surgery on nodes (relativize) with _mozattr
-  res = RelativizeURIInFragmentList(nodeList, aFlavor, aSourceDoc, targetNode);
-  // ignore results from this call, try to paste/insert anyways
- 
   // are there any table elements in the list?  
   // node and offset for insertion
   nsCOMPtr<nsIDOMNode> parentNode;
   PRInt32 offsetOfNewNode;
   
   // check for table cell selection mode
   bool cellSelectionMode = false;
   nsCOMPtr<nsIDOMElement> cell;
@@ -890,102 +886,16 @@ nsHTMLEditor::GetAttributeToModifyOnNode
     aAttr = srcStr;
     return NS_OK;
   }
 
   return NS_OK;
 }
 
 nsresult
-nsHTMLEditor::RelativizeURIForNode(nsIDOMNode *aNode, nsIURL *aDestURL)
-{
-  nsAutoString attributeToModify;
-  GetAttributeToModifyOnNode(aNode, attributeToModify);
-  if (attributeToModify.IsEmpty())
-    return NS_OK;
-
-  nsCOMPtr<nsIDOMNamedNodeMap> attrMap;
-  nsresult rv = aNode->GetAttributes(getter_AddRefs(attrMap));
-  NS_ENSURE_SUCCESS(rv, NS_OK);
-  NS_ENSURE_TRUE(attrMap, NS_OK); // assume errors here shouldn't cancel insertion
-
-  nsCOMPtr<nsIDOMNode> attrNode;
-  rv = attrMap->GetNamedItem(attributeToModify, getter_AddRefs(attrNode));
-  NS_ENSURE_SUCCESS(rv, NS_OK); // assume errors here shouldn't cancel insertion
-
-  if (attrNode)
-  {
-    nsAutoString oldValue;
-    attrNode->GetNodeValue(oldValue);
-    if (!oldValue.IsEmpty())
-    {
-      NS_ConvertUTF16toUTF8 oldCValue(oldValue);
-      nsCOMPtr<nsIURI> currentNodeURI;
-      rv = NS_NewURI(getter_AddRefs(currentNodeURI), oldCValue);
-      if (NS_SUCCEEDED(rv))
-      {
-        nsCAutoString newRelativePath;
-        aDestURL->GetRelativeSpec(currentNodeURI, newRelativePath);
-        if (!newRelativePath.IsEmpty())
-        {
-          NS_ConvertUTF8toUTF16 newCValue(newRelativePath);
-          attrNode->SetNodeValue(newCValue);
-        }
-      }
-    }
-  }
-
-  return NS_OK;
-}
-
-nsresult
-nsHTMLEditor::RelativizeURIInFragmentList(const nsCOMArray<nsIDOMNode> &aNodeList,
-                                          const nsAString &aFlavor,
-                                          nsIDOMDocument *aSourceDoc,
-                                          nsIDOMNode *aTargetNode)
-{
-  // determine destination URL
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  GetDocument(getter_AddRefs(domDoc));
-  NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
-
-  nsCOMPtr<nsIDocument> destDoc = do_QueryInterface(domDoc);
-  NS_ENSURE_TRUE(destDoc, NS_ERROR_FAILURE);
-
-  nsCOMPtr<nsIURL> destURL = do_QueryInterface(destDoc->GetDocBaseURI());
-  NS_ENSURE_TRUE(destURL, NS_ERROR_FAILURE);
-
-  PRInt32 listCount = aNodeList.Count();
-  PRInt32 j;
-  for (j = 0; j < listCount; j++)
-  {
-    nsIDOMNode* somenode = aNodeList[j];
-
-    nsCOMPtr<nsIDOMTreeWalker> walker;
-    nsresult rv = domDoc->CreateTreeWalker(somenode,
-                                           nsIDOMNodeFilter::SHOW_ELEMENT,
-                                           nsnull, true,
-                                           getter_AddRefs(walker));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsCOMPtr<nsIDOMNode> currentNode;
-    walker->GetCurrentNode(getter_AddRefs(currentNode));
-    while (currentNode)
-    {
-      rv = RelativizeURIForNode(currentNode, destURL);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      walker->NextNode(getter_AddRefs(currentNode));
-    }
-  }
-
-  return NS_OK;
-}
-
-nsresult
 nsHTMLEditor::AddInsertionListener(nsIContentFilter *aListener)
 {
   NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER);
 
   // don't let a listener be added more than once
   if (mContentFilters.IndexOfObject(aListener) == -1)
   {
     if (!mContentFilters.AppendObject(aListener))
--- a/editor/libeditor/html/nsHTMLEditor.h
+++ b/editor/libeditor/html/nsHTMLEditor.h
@@ -576,21 +576,16 @@ protected:
                                      nsIDOMNode **aFragmentAsNode,      
                                      nsIDOMNode **aFragStartNode,
                                      PRInt32 *aFragStartOffset,
                                      nsIDOMNode **aFragEndNode,
                                      PRInt32 *aFragEndOffset,
                                      nsIDOMNode **aTargetNode,       
                                      PRInt32 *aTargetOffset,   
                                      bool *aDoContinue);
-  nsresult   RelativizeURIInFragmentList(const nsCOMArray<nsIDOMNode> &aNodeList,
-                                        const nsAString &aFlavor,
-                                        nsIDOMDocument *aSourceDoc,
-                                        nsIDOMNode *aTargetNode);
-  nsresult   RelativizeURIForNode(nsIDOMNode *aNode, nsIURL *aDestURL);
   nsresult   GetAttributeToModifyOnNode(nsIDOMNode *aNode, nsAString &aAttrib);
 
   bool       IsInLink(nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *outLink = nsnull);
   nsresult   StripFormattingNodes(nsIDOMNode *aNode, bool aOnlyList = false);
   nsresult   CreateDOMFragmentFromPaste(const nsAString & aInputString,
                                         const nsAString & aContextStr,
                                         const nsAString & aInfoStr,
                                         nsCOMPtr<nsIDOMNode> *outFragNode,
--- a/editor/libeditor/html/tests/test_bug676401.html
+++ b/editor/libeditor/html/tests/test_bug676401.html
@@ -27,23 +27,23 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script type="application/javascript">
 
 /** Test for Bug 676401 **/
 SimpleTest.waitForExplicitFinish();
 SimpleTest.waitForFocus(runTests);
 
 var gBlock1, gBlock2;
 
-function IsCommandEnabled(command) {
+function IsCommandEnabled(command, alwaysEnabled) {
   var enabled;
 
-  // non-editable div: should return false
+  // non-editable div: should return false unless alwaysEnabled
   window.getSelection().selectAllChildren(gBlock1);
   enabled = document.queryCommandEnabled(command);
-  is(enabled, false, "'" + command + "' should not be enabled on a non-editable block.");
+  is(enabled, alwaysEnabled, "'" + command + "' should not be enabled on a non-editable block.");
 
   // editable div: should return true
   window.getSelection().selectAllChildren(gBlock2);
   enabled = document.queryCommandEnabled(command);
   is(enabled, true, "'" + command + "' should be enabled on an editable block.");
 }
 
 function runTests() {
@@ -62,47 +62,47 @@ function runTests() {
     "heading", "formatBlock",
     "contentReadOnly", "createLink",
     "decreaseFontSize", "increaseFontSize",
     "insertHTML", "insertHorizontalRule", "insertImage",
     "removeFormat", "selectAll", "styleWithCSS"
   ];
   document.execCommand("styleWithCSS", false, false);
   for (i = 0; i < commands.length; i++)
-    IsCommandEnabled(commands[i]);
+    IsCommandEnabled(commands[i], commands[i] == "selectAll");
   document.execCommand("styleWithCSS", false, true);
   for (i = 0; i < commands.length; i++)
-    IsCommandEnabled(commands[i]);
+    IsCommandEnabled(commands[i], commands[i] == "selectAll");
 
   // Mozilla-specific stuff
   commands = ["enableInlineTableEditing", "enableObjectResizing", "insertBrOnReturn"];
   for (i = 0; i < commands.length; i++)
-    IsCommandEnabled(commands[i]);
+    IsCommandEnabled(commands[i], false);
 
   // cut/copy/paste -- SpecialPowers required
   SpecialPowers.setCharPref("capability.policy.policynames",                      "allowclipboard");
   SpecialPowers.setCharPref("capability.policy.allowclipboard.sites",             "http://mochi.test:8888");
   SpecialPowers.setCharPref("capability.policy.allowclipboard.Clipboard.cutcopy", "allAccess");
   SpecialPowers.setCharPref("capability.policy.allowclipboard.Clipboard.paste",   "allAccess");
   commands = ["cut", "paste", "copy"];
   for (i = 0; i < commands.length; i++) {
-    IsCommandEnabled(commands[i]);
+    IsCommandEnabled(commands[i], commands[i] == "copy");
     document.execCommand(commands[i], false, false);
   }
   SpecialPowers.clearUserPref("capability.policy.policynames");
   SpecialPowers.clearUserPref("capability.policy.allowclipboard.sites");
   SpecialPowers.clearUserPref("capability.policy.allowclipboard.Clipboard.cutcopy");
   SpecialPowers.clearUserPref("capability.policy.allowclipboard.Clipboard.paste");
 
   // delete/undo/redo -- we have to execute this commands because:
   //  * there's nothing to undo if we haven't modified the selection first
   //  * there's nothing to redo if we haven't undone something first
   commands = ["delete", "undo", "redo"];
   for (i = 0; i < commands.length; i++) {
-    IsCommandEnabled(commands[i]);
+    IsCommandEnabled(commands[i], false);
     document.execCommand(commands[i], false, false);
   }
 
   // done
   SimpleTest.finish();
 }
 
 </script>
--- a/editor/libeditor/html/tests/test_htmleditor_keyevent_handling.html
+++ b/editor/libeditor/html/tests/test_htmleditor_keyevent_handling.html
@@ -123,34 +123,36 @@ function runTests()
     }
 
     aDescription += ": "
 
     aElement.focus();
     is(fm.focusedElement, aElement, aDescription + "failed to move focus");
 
     // Modifier keys:
-    //   Only when editor is editable, it consumes.
+    //   Basically, modifier keys shouldn't cause keypress event.  However,
+    //   even if it were dispatched by widget's bug, editor should consume
+    //   it when editor is editable.
     reset("");
-    synthesizeKey("VK_META", { });
+    synthesizeKey("VK_META", { type: "keypress" });
     check(aDescription + "Meta", true, true, !aIsReadonly);
 
     reset("");
-    synthesizeKey("VK_SHIFT", { });
+    synthesizeKey("VK_SHIFT", { type: "keypress" });
     check(aDescription + "Shift", true, true, !aIsReadonly);
 
     reset("");
-    synthesizeKey("VK_CONTROL", { });
+    synthesizeKey("VK_CONTROL", { type: "keypress" });
     check(aDescription + "Control", true, true, !aIsReadonly);
 
     // Alt key press event installs menubar key event listener, so,
     // we should pass Alt key testing on Windows and Linux.
     if (!kIsWin && !kIsLinux) {
       reset("");
-      synthesizeKey("VK_ALT", { });
+      synthesizeKey("VK_ALT", { type: "keypress" });
       check(aDescription + "Alt", true, true, !aIsReadonly);
     }
 
     // Backspace key:
     //   If editor is readonly, it doesn't consume.
     //   If editor is editable, it consumes backspace and shift+backspace.
     //   Otherwise, editor doesn't consume the event.
     reset("");
--- a/editor/libeditor/text/nsPlaintextEditor.cpp
+++ b/editor/libeditor/text/nsPlaintextEditor.cpp
@@ -983,16 +983,23 @@ nsPlaintextEditor::UpdateIMEComposition(
     if (caretP) {
       caretP->SetCaretDOMSelection(selection);
     }
 
     // second part of 23558 fix:
     if (aCompositionString.IsEmpty()) {
       mIMETextNode = nsnull;
     }
+
+    // If still composing, we should fire input event via observer.
+    // Note that if committed, we don't need to notify it since it will be
+    // notified at followed compositionend event.
+    if (mIsIMEComposing) {
+      NotifyEditorObservers();
+    }
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsPlaintextEditor::GetDocumentIsEmpty(bool *aDocumentIsEmpty)
 {
--- a/editor/libeditor/text/tests/test_texteditor_keyevent_handling.html
+++ b/editor/libeditor/text/tests/test_texteditor_keyevent_handling.html
@@ -111,34 +111,36 @@ function runTests()
     }
 
     aDescription += ": "
 
     aElement.focus();
     is(fm.focusedElement, aElement, aDescription + "failed to move focus");
 
     // Modifier keys:
-    //   Only when editor is editable, it consumes.
+    //   Basically, modifier keys shouldn't cause keypress event.  However,
+    //   even if it were dispatched by widget's bug, editor should consume
+    //   it when editor is editable.
     reset("");
-    synthesizeKey("VK_META", { });
+    synthesizeKey("VK_META", { type: "keypress" });
     check(aDescription + "Meta", true, true, !aIsReadonly);
 
     reset("");
-    synthesizeKey("VK_SHIFT", { });
+    synthesizeKey("VK_SHIFT", { type: "keypress" });
     check(aDescription + "Shift", true, true, !aIsReadonly);
 
     reset("");
-    synthesizeKey("VK_CONTROL", { });
+    synthesizeKey("VK_CONTROL", { type: "keypress" });
     check(aDescription + "Control", true, true, !aIsReadonly);
 
     // Alt key press event installs menubar key event listener, so,
     // we should pass Alt key testing on Windows and Linux.
     if (!kIsWin && !kIsLinux) {
       reset("");
-      synthesizeKey("VK_ALT", { });
+      synthesizeKey("VK_ALT", { type: "keypress" });
       check(aDescription + "Alt", true, true, !aIsReadonly);
     }
 
     // Backspace key:
     //   If editor is readonly, it doesn't consume.
     //   If editor is editable, it consumes backspace and shift+backspace.
     //   Otherwise, editor doesn't consume the event but the native key
     //   bindings on nsTextControlFrame may consume it.
--- a/editor/txmgr/src/nsTransactionManager.cpp
+++ b/editor/txmgr/src/nsTransactionManager.cpp
@@ -41,33 +41,23 @@
 #include "nsTransactionItem.h"
 #include "nsTransactionStack.h"
 #include "nsVoidArray.h"
 #include "nsTransactionManager.h"
 #include "nsTransactionList.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 
-#define LOCK_TX_MANAGER(mgr)    (mgr)->Lock()
-#define UNLOCK_TX_MANAGER(mgr)  (mgr)->Unlock()
-
-
 nsTransactionManager::nsTransactionManager(PRInt32 aMaxTransactionCount)
   : mMaxTransactionCount(aMaxTransactionCount)
 {
-  mMonitor = ::PR_NewMonitor();
 }
 
 nsTransactionManager::~nsTransactionManager()
 {
-  if (mMonitor)
-  {
-    ::PR_DestroyMonitor(mMonitor);
-    mMonitor = 0;
-  }
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsTransactionManager)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsTransactionManager)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mListeners)
   tmp->mDoStack.DoUnlink();
   tmp->mUndoStack.DoUnlink();
@@ -92,111 +82,95 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTrans
 
 NS_IMETHODIMP
 nsTransactionManager::DoTransaction(nsITransaction *aTransaction)
 {
   nsresult result;
 
   NS_ENSURE_TRUE(aTransaction, NS_ERROR_NULL_POINTER);
 
-  LOCK_TX_MANAGER(this);
-
   bool doInterrupt = false;
 
   result = WillDoNotify(aTransaction, &doInterrupt);
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   if (doInterrupt) {
-    UNLOCK_TX_MANAGER(this);
     return NS_OK;
   }
 
   result = BeginTransaction(aTransaction);
 
   if (NS_FAILED(result)) {
     DidDoNotify(aTransaction, result);
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   result = EndTransaction();
 
   nsresult result2 = DidDoNotify(aTransaction, result);
 
   if (NS_SUCCEEDED(result))
     result = result2;
 
-  UNLOCK_TX_MANAGER(this);
-
   return result;
 }
 
 NS_IMETHODIMP
 nsTransactionManager::UndoTransaction()
 {
   nsresult result       = NS_OK;
   nsRefPtr<nsTransactionItem> tx;
 
-  LOCK_TX_MANAGER(this);
-
   // It is illegal to call UndoTransaction() while the transaction manager is
   // executing a  transaction's DoTransaction() method! If this happens,
   // the UndoTransaction() request is ignored, and we return NS_ERROR_FAILURE.
 
   result = mDoStack.Peek(getter_AddRefs(tx));
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   if (tx) {
-    UNLOCK_TX_MANAGER(this);
     return NS_ERROR_FAILURE;
   }
 
   // Peek at the top of the undo stack. Don't remove the transaction
   // until it has successfully completed.
   result = mUndoStack.Peek(getter_AddRefs(tx));
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   // Bail if there's nothing on the stack.
   if (!tx) {
-    UNLOCK_TX_MANAGER(this);
     return NS_OK;
   }
 
   nsCOMPtr<nsITransaction> t;
 
   result = tx->GetTransaction(getter_AddRefs(t));
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   bool doInterrupt = false;
 
   result = WillUndoNotify(t, &doInterrupt);
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   if (doInterrupt) {
-    UNLOCK_TX_MANAGER(this);
     return NS_OK;
   }
 
   result = tx->UndoTransaction(this);
 
   if (NS_SUCCEEDED(result)) {
     result = mUndoStack.Pop(getter_AddRefs(tx));
 
@@ -204,80 +178,69 @@ nsTransactionManager::UndoTransaction()
       result = mRedoStack.Push(tx);
   }
 
   nsresult result2 = DidUndoNotify(t, result);
 
   if (NS_SUCCEEDED(result))
     result = result2;
 
-  UNLOCK_TX_MANAGER(this);
-
   return result;
 }
 
 NS_IMETHODIMP
 nsTransactionManager::RedoTransaction()
 {
   nsresult result       = NS_OK;
   nsRefPtr<nsTransactionItem> tx;
 
-  LOCK_TX_MANAGER(this);
-
   // It is illegal to call RedoTransaction() while the transaction manager is
   // executing a  transaction's DoTransaction() method! If this happens,
   // the RedoTransaction() request is ignored, and we return NS_ERROR_FAILURE.
 
   result = mDoStack.Peek(getter_AddRefs(tx));
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   if (tx) {
-    UNLOCK_TX_MANAGER(this);
     return NS_ERROR_FAILURE;
   }
 
   // Peek at the top of the redo stack. Don't remove the transaction
   // until it has successfully completed.
   result = mRedoStack.Peek(getter_AddRefs(tx));
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   // Bail if there's nothing on the stack.
   if (!tx) {
-    UNLOCK_TX_MANAGER(this);
     return NS_OK;
   }
 
   nsCOMPtr<nsITransaction> t;
 
   result = tx->GetTransaction(getter_AddRefs(t));
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   bool doInterrupt = false;
 
   result = WillRedoNotify(t, &doInterrupt);
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   if (doInterrupt) {
-    UNLOCK_TX_MANAGER(this);
     return NS_OK;
   }
 
   result = tx->RedoTransaction(this);
 
   if (NS_SUCCEEDED(result)) {
     result = mRedoStack.Pop(getter_AddRefs(tx));
 
@@ -285,323 +248,266 @@ nsTransactionManager::RedoTransaction()
       result = mUndoStack.Push(tx);
   }
 
   nsresult result2 = DidRedoNotify(t, result);
 
   if (NS_SUCCEEDED(result))
     result = result2;
 
-  UNLOCK_TX_MANAGER(this);
-
   return result;
 }
 
 NS_IMETHODIMP
 nsTransactionManager::Clear()
 {
   nsresult result;
 
-  LOCK_TX_MANAGER(this);
-
   result = ClearRedoStack();
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   result = ClearUndoStack();
 
-  UNLOCK_TX_MANAGER(this);
-
   return result;
 }
 
 NS_IMETHODIMP
 nsTransactionManager::BeginBatch()
 {
   nsresult result;
 
   // We can batch independent transactions together by simply pushing
   // a dummy transaction item on the do stack. This dummy transaction item
   // will be popped off the do stack, and then pushed on the undo stack
   // in EndBatch().
 
-  LOCK_TX_MANAGER(this);
-
   bool doInterrupt = false;
 
   result = WillBeginBatchNotify(&doInterrupt);
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   if (doInterrupt) {
-    UNLOCK_TX_MANAGER(this);
     return NS_OK;
   }
 
   result = BeginTransaction(0);
   
   nsresult result2 = DidBeginBatchNotify(result);
 
   if (NS_SUCCEEDED(result))
     result = result2;
 
-  UNLOCK_TX_MANAGER(this);
-
   return result;
 }
 
 NS_IMETHODIMP
 nsTransactionManager::EndBatch()
 {
   nsRefPtr<nsTransactionItem> tx;
   nsCOMPtr<nsITransaction> ti;
   nsresult result;
 
-  LOCK_TX_MANAGER(this);
-
   // XXX: Need to add some mechanism to detect the case where the transaction
   //      at the top of the do stack isn't the dummy transaction, so we can
   //      throw an error!! This can happen if someone calls EndBatch() within
   //      the DoTransaction() method of a transaction.
   //
   //      For now, we can detect this case by checking the value of the
   //      dummy transaction's mTransaction field. If it is our dummy
   //      transaction, it should be NULL. This may not be true in the
   //      future when we allow users to execute a transaction when beginning
   //      a batch!!!!
 
   result = mDoStack.Peek(getter_AddRefs(tx));
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   if (tx)
     tx->GetTransaction(getter_AddRefs(ti));
 
   if (!tx || ti) {
-    UNLOCK_TX_MANAGER(this);
     return NS_ERROR_FAILURE;
   }
 
   bool doInterrupt = false;
 
   result = WillEndBatchNotify(&doInterrupt);
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   if (doInterrupt) {
-    UNLOCK_TX_MANAGER(this);
     return NS_OK;
   }
 
   result = EndTransaction();
 
   nsresult result2 = DidEndBatchNotify(result);
 
   if (NS_SUCCEEDED(result))
     result = result2;
 
-  UNLOCK_TX_MANAGER(this);
-
   return result;
 }
 
 NS_IMETHODIMP
 nsTransactionManager::GetNumberOfUndoItems(PRInt32 *aNumItems)
 {
-  nsresult result;
-
-  LOCK_TX_MANAGER(this);
-  result = mUndoStack.GetSize(aNumItems);
-  UNLOCK_TX_MANAGER(this);
-
-  return result;
+  return mUndoStack.GetSize(aNumItems);
 }
 
 NS_IMETHODIMP
 nsTransactionManager::GetNumberOfRedoItems(PRInt32 *aNumItems)
 {
-  nsresult result;
-
-  LOCK_TX_MANAGER(this);
-  result = mRedoStack.GetSize(aNumItems);
-  UNLOCK_TX_MANAGER(this);
-
-  return result;
+  return mRedoStack.GetSize(aNumItems);
 }
 
 NS_IMETHODIMP
 nsTransactionManager::GetMaxTransactionCount(PRInt32 *aMaxCount)
 {
   NS_ENSURE_TRUE(aMaxCount, NS_ERROR_NULL_POINTER);
 
-  LOCK_TX_MANAGER(this);
   *aMaxCount = mMaxTransactionCount;
-  UNLOCK_TX_MANAGER(this);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTransactionManager::SetMaxTransactionCount(PRInt32 aMaxCount)
 {
   PRInt32 numUndoItems  = 0, numRedoItems = 0, total = 0;
   nsRefPtr<nsTransactionItem> tx;
   nsresult result;
 
-  LOCK_TX_MANAGER(this);
-
   // It is illegal to call SetMaxTransactionCount() while the transaction
   // manager is executing a  transaction's DoTransaction() method because
   // the undo and redo stacks might get pruned! If this happens, the
   // SetMaxTransactionCount() request is ignored, and we return
   // NS_ERROR_FAILURE.
 
   result = mDoStack.Peek(getter_AddRefs(tx));
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   if (tx) {
-    UNLOCK_TX_MANAGER(this);
     return NS_ERROR_FAILURE;
   }
 
   // If aMaxCount is less than zero, the user wants unlimited
   // levels of undo! No need to prune the undo or redo stacks!
 
   if (aMaxCount < 0) {
     mMaxTransactionCount = -1;
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   result = mUndoStack.GetSize(&numUndoItems);
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   result = mRedoStack.GetSize(&numRedoItems);
 
   if (NS_FAILED(result)) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   total = numUndoItems + numRedoItems;
 
   // If aMaxCount is greater than the number of transactions that currently
   // exist on the undo and redo stack, there is no need to prune the
   // undo or redo stacks!
 
   if (aMaxCount > total ) {
     mMaxTransactionCount = aMaxCount;
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   // Try getting rid of some transactions on the undo stack! Start at
   // the bottom of the stack and pop towards the top.
 
   while (numUndoItems > 0 && (numRedoItems + numUndoItems) > aMaxCount) {
     result = mUndoStack.PopBottom(getter_AddRefs(tx));
 
     if (NS_FAILED(result) || !tx) {
-      UNLOCK_TX_MANAGER(this);
       return result;
     }
 
     --numUndoItems;
   }
 
   // If necessary, get rid of some transactions on the redo stack! Start at
   // the bottom of the stack and pop towards the top.
 
   while (numRedoItems > 0 && (numRedoItems + numUndoItems) > aMaxCount) {
     result = mRedoStack.PopBottom(getter_AddRefs(tx));
 
     if (NS_FAILED(result) || !tx) {
-      UNLOCK_TX_MANAGER(this);
       return result;
     }
 
     --numRedoItems;
   }
 
   mMaxTransactionCount = aMaxCount;
 
-  UNLOCK_TX_MANAGER(this);
-
   return result;
 }
 
 NS_IMETHODIMP
 nsTransactionManager::PeekUndoStack(nsITransaction **aTransaction)
 {
   nsRefPtr<nsTransactionItem> tx;
   nsresult result;
 
   NS_ENSURE_TRUE(aTransaction, NS_ERROR_NULL_POINTER);
 
   *aTransaction = 0;
 
-  LOCK_TX_MANAGER(this);
-
   result = mUndoStack.Peek(getter_AddRefs(tx));
 
   if (NS_FAILED(result) || !tx) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   result = tx->GetTransaction(aTransaction);
 
-  UNLOCK_TX_MANAGER(this);
-
   return result;
 }
 
 NS_IMETHODIMP
 nsTransactionManager::PeekRedoStack(nsITransaction **aTransaction)
 {
   nsRefPtr<nsTransactionItem> tx;
   nsresult result;
 
   NS_ENSURE_TRUE(aTransaction, NS_ERROR_NULL_POINTER);
 
   *aTransaction = 0;
 
-  LOCK_TX_MANAGER(this);
-
   result = mRedoStack.Peek(getter_AddRefs(tx));
 
   if (NS_FAILED(result) || !tx) {
-    UNLOCK_TX_MANAGER(this);
     return result;
   }
 
   result = tx->GetTransaction(aTransaction);
 
-  UNLOCK_TX_MANAGER(this);
-
   return result;
 }
 
 NS_IMETHODIMP
 nsTransactionManager::GetUndoList(nsITransactionList **aTransactionList)
 {
   NS_ENSURE_TRUE(aTransactionList, NS_ERROR_NULL_POINTER);
 
@@ -624,61 +530,37 @@ nsTransactionManager::GetRedoList(nsITra
   return (! *aTransactionList) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
 }
 
 NS_IMETHODIMP
 nsTransactionManager::AddListener(nsITransactionListener *aListener)
 {
   NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER);
 
-  LOCK_TX_MANAGER(this);
-
-  nsresult rv = mListeners.AppendObject(aListener) ? NS_OK : NS_ERROR_FAILURE;
-
-  UNLOCK_TX_MANAGER(this);
-
-  return rv;
+  return mListeners.AppendObject(aListener) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsTransactionManager::RemoveListener(nsITransactionListener *aListener)
 {
   NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER);
 
-  LOCK_TX_MANAGER(this);
-
-  nsresult rv = mListeners.RemoveObject(aListener) ? NS_OK : NS_ERROR_FAILURE;
-
-  UNLOCK_TX_MANAGER(this);
-
-  return rv;
+  return mListeners.RemoveObject(aListener) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 nsresult
 nsTransactionManager::ClearUndoStack()
 {
-  nsresult result;
-
-  LOCK_TX_MANAGER(this);
-  result = mUndoStack.Clear();
-  UNLOCK_TX_MANAGER(this);
-
-  return result;
+  return mUndoStack.Clear();
 }
 
 nsresult
 nsTransactionManager::ClearRedoStack()
 {
-  nsresult result;
-
-  LOCK_TX_MANAGER(this);
-  result = mRedoStack.Clear();
-  UNLOCK_TX_MANAGER(this);
-
-  return result;
+  return mRedoStack.Clear();
 }
 
 nsresult
 nsTransactionManager::WillDoNotify(nsITransaction *aTransaction, bool *aInterrupt)
 {
   nsresult result = NS_OK;
   for (PRInt32 i = 0, lcount = mListeners.Count(); i < lcount; i++)
   {
@@ -907,19 +789,16 @@ nsTransactionManager::DidMergeNotify(nsI
   return result;
 }
 
 nsresult
 nsTransactionManager::BeginTransaction(nsITransaction *aTransaction)
 {
   nsresult result = NS_OK;
 
-  // No need for LOCK/UNLOCK_TX_MANAGER() calls since the calling routine
-  // should have done this already!
-
   // XXX: POSSIBLE OPTIMIZATION
   //      We could use a factory that pre-allocates/recycles transaction items.
   nsRefPtr<nsTransactionItem> tx = new nsTransactionItem(aTransaction);
 
   if (!tx) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
@@ -941,19 +820,16 @@ nsTransactionManager::BeginTransaction(n
 
 nsresult
 nsTransactionManager::EndTransaction()
 {
   nsCOMPtr<nsITransaction> tint;
   nsRefPtr<nsTransactionItem> tx;
   nsresult result              = NS_OK;
 
-  // No need for LOCK/UNLOCK_TX_MANAGER() calls since the calling routine
-  // should have done this already!
-
   result = mDoStack.Pop(getter_AddRefs(tx));
 
   if (NS_FAILED(result) || !tx)
     return result;
 
   result = tx->GetTransaction(getter_AddRefs(tint));
 
   if (NS_FAILED(result)) {
@@ -1072,26 +948,8 @@ nsTransactionManager::EndTransaction()
   if (NS_FAILED(result)) {
     // XXX: What do we do in the case where a clear fails?
     //      Remove the transaction from the stack, and release it?
   }
 
   return result;
 }
 
-nsresult
-nsTransactionManager::Lock()
-{
-  if (mMonitor)
-    PR_EnterMonitor(mMonitor);
-
-  return NS_OK;
-}
-
-nsresult
-nsTransactionManager::Unlock()
-{
-  if (mMonitor)
-    PR_ExitMonitor(mMonitor);
-
-  return NS_OK;
-}
-
--- a/editor/txmgr/src/nsTransactionManager.h
+++ b/editor/txmgr/src/nsTransactionManager.h
@@ -33,17 +33,16 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsTransactionManager_h__
 #define nsTransactionManager_h__
 
-#include "prmon.h"
 #include "nsWeakReference.h"
 #include "nsITransactionManager.h"
 #include "nsCOMArray.h"
 #include "nsITransactionListener.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsITransaction;
 class nsITransactionListener;
@@ -60,18 +59,16 @@ class nsTransactionManager : public nsIT
 private:
 
   PRInt32                mMaxTransactionCount;
   nsTransactionStack     mDoStack;
   nsTransactionStack     mUndoStack;
   nsTransactionRedoStack mRedoStack;
   nsCOMArray<nsITransactionListener> mListeners;
 
-  PRMonitor              *mMonitor;
-
 public:
 
   /** The default constructor.
    */
   nsTransactionManager(PRInt32 aMaxTransactionCount=-1);
 
   /** The default destructor.
    */
@@ -107,13 +104,11 @@ public:
                                   bool aDidMerge,
                                   nsresult aMergeResult);
 
 private:
 
   /* nsTransactionManager specific private methods. */
   virtual nsresult BeginTransaction(nsITransaction *aTransaction);
   virtual nsresult EndTransaction(void);
-  virtual nsresult Lock(void);
-  virtual nsresult Unlock(void);
 };
 
 #endif // nsTransactionManager_h__
--- a/editor/txtsvc/public/nsIInlineSpellChecker.idl
+++ b/editor/txtsvc/public/nsIInlineSpellChecker.idl
@@ -38,17 +38,17 @@
 
 #include "nsISupports.idl"
 #include "domstubs.idl"
 
 interface nsISelection;
 interface nsIEditor;
 interface nsIEditorSpellCheck;
 
-[scriptable, uuid(f456dda1-965d-470c-8c55-e51b38e45212)]
+[scriptable, uuid(df635540-d073-47b8-8678-18776130691d)]
 
 interface nsIInlineSpellChecker : nsISupports
 {
   readonly attribute nsIEditorSpellCheck spellChecker;
 
   [noscript] void init(in nsIEditor aEditor);
   [noscript] void cleanup(in boolean aDestroyingFrames);
 
@@ -63,16 +63,17 @@ interface nsIInlineSpellChecker : nsISup
                                    in nsIDOMNode aEndNode,
                                    in long aEndOffset);
 
   void spellCheckRange(in nsIDOMRange aSelection);
 
   nsIDOMRange getMisspelledWord(in nsIDOMNode aNode, in long aOffset);
   void replaceWord(in nsIDOMNode aNode, in long aOffset, in AString aNewword);
   void addWordToDictionary(in AString aWord);
+  void removeWordFromDictionary(in AString aWord);
   
   void ignoreWord(in AString aWord);
   void ignoreWords([array, size_is(aCount)] in wstring aWordsToIgnore, in unsigned long aCount);
   void updateCurrentDictionary();
 };
 
 %{C++
 
--- a/embedding/components/find/src/nsWebBrowserFind.cpp
+++ b/embedding/components/find/src/nsWebBrowserFind.cpp
@@ -734,20 +734,17 @@ nsresult nsWebBrowserFind::SearchInFrame
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (subject) {
         bool subsumes;
         rv = subject->Subsumes(theDoc->NodePrincipal(), &subsumes);
         NS_ENSURE_SUCCESS(rv, rv);
         if (!subsumes) {
             bool hasCap = false;
-            secMan->IsCapabilityEnabled("UniversalBrowserWrite", &hasCap);
-            if (!hasCap) {
-                secMan->IsCapabilityEnabled("UniversalXPConnect", &hasCap);
-            }
+            secMan->IsCapabilityEnabled("UniversalXPConnect", &hasCap);
             if (!hasCap) {
                 return NS_ERROR_DOM_PROP_ACCESS_DENIED;
             }
         }
     }
 
     if (!mFind) {
         mFind = do_CreateInstance(NS_FIND_CONTRACTID, &rv);
--- a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
@@ -1551,17 +1551,17 @@ PRUint32 nsWindowWatcher::CalculateChrom
 
   /* missing
      chromeFlags->copy_history
    */
 
   // Check security state for use in determing window dimensions
   bool enabled;
   nsresult res =
-    securityManager->IsCapabilityEnabled("UniversalBrowserWrite", &enabled);
+    securityManager->IsCapabilityEnabled("UniversalXPConnect", &enabled);
 
   if (NS_FAILED(res) || !enabled || (isChrome && !aHasChromeParent)) {
     // If priv check fails (or if we're called from chrome, but the
     // parent is not a chrome window), set all elements to minimum
     // reqs., else leave them alone.
     chromeFlags |= nsIWebBrowserChrome::CHROME_TITLEBAR;
     chromeFlags |= nsIWebBrowserChrome::CHROME_WINDOW_CLOSE;
     chromeFlags &= ~nsIWebBrowserChrome::CHROME_WINDOW_LOWERED;
@@ -1973,17 +1973,17 @@ nsWindowWatcher::SizeOpenedDocShellItem(
   
   nsresult res;
   bool enabled = false;
 
   // Check security state for use in determing window dimensions
   nsCOMPtr<nsIScriptSecurityManager>
     securityManager(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
   if (securityManager) {
-    res = securityManager->IsCapabilityEnabled("UniversalBrowserWrite",
+    res = securityManager->IsCapabilityEnabled("UniversalXPConnect",
                                                &enabled);
     if (NS_FAILED(res))
       enabled = false;
     else if (enabled && aParent) {
       nsCOMPtr<nsIDOMChromeWindow> chromeWin(do_QueryInterface(aParent));
 
       bool isChrome = false;
       nsresult rv = securityManager->SubjectPrincipalIsSystem(&isChrome);
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -864,16 +864,34 @@ mozInlineSpellChecker::AddWordToDictiona
   NS_ENSURE_SUCCESS(rv, rv); 
 
   mozInlineSpellStatus status(this);
   rv = status.InitForSelection();
   NS_ENSURE_SUCCESS(rv, rv);
   return ScheduleSpellCheck(status);
 }
 
+//  mozInlineSpellChecker::RemoveWordFromDictionary
+
+NS_IMETHODIMP
+mozInlineSpellChecker::RemoveWordFromDictionary(const nsAString &word)
+{
+  NS_ENSURE_TRUE(mSpellCheck, NS_ERROR_NOT_INITIALIZED);
+
+  nsAutoString wordstr(word);
+  nsresult rv = mSpellCheck->RemoveWordFromDictionary(wordstr.get());
+  NS_ENSURE_SUCCESS(rv, rv); 
+  
+  mozInlineSpellStatus status(this);
+  nsCOMPtr<nsIRange> range = do_QueryInterface(NULL); // Check everything
+  rv = status.InitForRange(range);
+  NS_ENSURE_SUCCESS(rv, rv);
+  return ScheduleSpellCheck(status);
+}
+
 // mozInlineSpellChecker::IgnoreWord
 
 NS_IMETHODIMP
 mozInlineSpellChecker::IgnoreWord(const nsAString &word)
 {
   NS_ENSURE_TRUE(mSpellCheck, NS_ERROR_NOT_INITIALIZED);
 
   nsAutoString wordstr(word);
--- a/gfx/thebes/gfxPangoFonts.cpp
+++ b/gfx/thebes/gfxPangoFonts.cpp
@@ -103,17 +103,17 @@ using namespace mozilla;
 #define PANGO_GLYPH_EMPTY           ((PangoGlyph)0)
 #endif
 // For g a PangoGlyph,
 #define IS_MISSING_GLYPH(g) ((g) & PANGO_GLYPH_UNKNOWN_FLAG)
 #define IS_EMPTY_GLYPH(g) ((g) == PANGO_GLYPH_EMPTY)
 
 #define PRINTING_FC_PROPERTY "gfx.printing"
 
-class gfxPangoFcFont;
+struct gfxPangoFcFont;
 
 // Same as pango_units_from_double from Pango 1.16 (but not in older versions)
 int moz_pango_units_from_double(double d) {
     return NS_lround(d * FLOAT_PANGO_SCALE);
 }
 
 static PangoLanguage *GuessPangoLanguage(nsIAtom *aLanguage);
 
deleted file mode 100644
--- a/gfx/ycbcr/QuellGccWarnings.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp
---- a/gfx/ycbcr/yuv_convert.cpp
-+++ b/gfx/ycbcr/yuv_convert.cpp
-@@ -337,16 +337,17 @@ NS_GFX_(void) ScaleYCbCrToRGB32(const ui
-                                          source_dx_uv >> kFractionBits);
-         }
-       }
-       else {
-         ScaleYUVToRGB32Row_C(y_ptr, u_ptr, v_ptr,
-                              dest_pixel, width, source_dx);
-       }
- #else
-+      (void)source_dx_uv;
-       ScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
-                          dest_pixel, width, source_dx);
- #endif
-     }
-   }
-   // MMX used for FastConvertYUVToRGB32Row and FilterRows requires emms.
-   if (has_mmx)
-     EMMS();
-diff --git a/gfx/ycbcr/yuv_row.h b/gfx/ycbcr/yuv_row.h
---- a/gfx/ycbcr/yuv_row.h
-+++ b/gfx/ycbcr/yuv_row.h
-@@ -129,14 +129,14 @@ extern SIMD_ALIGNED(int16 kCoefficientsR
- #if defined(ARCH_CPU_X86) && !defined(ARCH_CPU_X86_64)
- #if defined(_MSC_VER)
- #define EMMS() __asm emms
- #pragma warning(disable: 4799)
- #else
- #define EMMS() asm("emms")
- #endif
- #else
--#define EMMS()
-+#define EMMS() ((void)0)
- #endif
- 
- }  // extern "C"
- 
- #endif  // MEDIA_BASE_YUV_ROW_H_
--- a/gfx/ycbcr/README
+++ b/gfx/ycbcr/README
@@ -20,10 +20,8 @@ convert.patch contains the following cha
   * Add YCbCr 4:4:4 support
   * Bug 619178 - Update CPU detection in yuv_convert to new SSE.h interface.
   * Bug 616778 - Split yuv_convert FilterRows vectorized code into separate files so it can
     be properly guarded with cpuid() calls.
 
 win64.patch: SSE2 optimization for Microsoft Visual C++ x64 version
 
 TypeFromSize.patch: Bug 656185 - Add a method to detect YUVType from plane sizes.
-
-QuellGccWarnings.patch: Bug 711895 - Avoid some GCC compilation warnings.
--- a/gfx/ycbcr/update.sh
+++ b/gfx/ycbcr/update.sh
@@ -4,9 +4,8 @@ cp $1/media/base/yuv_convert.cc yuv_conv
 cp $1/media/base/yuv_row.h .
 cp $1/media/base/yuv_row_table.cc yuv_row_table.cpp
 cp $1/media/base/yuv_row_posix.cc yuv_row_posix.cpp
 cp $1/media/base/yuv_row_win.cc yuv_row_win.cpp
 cp $1/media/base/yuv_row_posix.cc yuv_row_c.cpp
 patch -p3 <convert.patch
 patch -p3 <win64.patch
 patch -p3 <TypeFromSize.patch
-patch -p3 <QuellGccWarnings.patch
--- a/gfx/ycbcr/yuv_convert.cpp
+++ b/gfx/ycbcr/yuv_convert.cpp
@@ -337,17 +337,16 @@ NS_GFX_(void) ScaleYCbCrToRGB32(const ui
                                          source_dx_uv >> kFractionBits);
         }
       }
       else {
         ScaleYUVToRGB32Row_C(y_ptr, u_ptr, v_ptr,
                              dest_pixel, width, source_dx);
       }
 #else
-      (void)source_dx_uv;
       ScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
                          dest_pixel, width, source_dx);
 #endif
     }
   }
   // MMX used for FastConvertYUVToRGB32Row and FilterRows requires emms.
   if (has_mmx)
     EMMS();
--- a/gfx/ycbcr/yuv_row.h
+++ b/gfx/ycbcr/yuv_row.h
@@ -129,14 +129,14 @@ extern SIMD_ALIGNED(int16 kCoefficientsR
 #if defined(ARCH_CPU_X86) && !defined(ARCH_CPU_X86_64)
 #if defined(_MSC_VER)
 #define EMMS() __asm emms
 #pragma warning(disable: 4799)
 #else
 #define EMMS() asm("emms")
 #endif
 #else
-#define EMMS() ((void)0)
+#define EMMS()
 #endif
 
 }  // extern "C"
 
 #endif  // MEDIA_BASE_YUV_ROW_H_
--- a/image/test/mochitest/test_bug490949.html
+++ b/image/test/mochitest/test_bug490949.html
@@ -49,17 +49,17 @@ RemoteCanvas.prototype.load = function(c
 };
 
 RemoteCanvas.prototype.reload = function(cb, force) {
     this.cb = cb;
     window.frames[0].location.reload(force);
 }
 
 RemoteCanvas.prototype.handleEvent = function() {
-    netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 
     // Look back up the iframe by id
     var ldrFrame = document.getElementById("test-iframe");
     // Get a reference to the window object you need for the canvas
     // drawWindow method
     var remoteWindow = ldrFrame.contentWindow;
 
     //Draw canvas
--- a/image/test/mochitest/test_bug496292.html
+++ b/image/test/mochitest/test_bug496292.html
@@ -54,17 +54,17 @@ RemoteCanvas.prototype.load = function(c
 };
 
 RemoteCanvas.prototype.reload = function(cb, force) {
     this.cb = cb;
     window.frames[0].location.reload(force);
 }
 
 RemoteCanvas.prototype.handleEvent = function() {
-    netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 
     // Look back up the iframe by id
     var ldrFrame = document.getElementById("test-iframe-" + this.url);
     // Get a reference to the window object you need for the canvas
     // drawWindow method
     var remoteWindow = ldrFrame.contentWindow;
 
     //Draw canvas
--- a/image/test/mochitest/test_bug497665.html
+++ b/image/test/mochitest/test_bug497665.html
@@ -16,17 +16,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script type="application/javascript">
 
 var image1first, image2first, image1second, image2second, image1third, image2third;
 
 SimpleTest.waitForExplicitFinish();
 
 function checkFirst()
 {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 
   var iframeelem = document.getElementById('test-iframe');
   var canvas = document.getElementById('canvas');
   var ctx = canvas.getContext('2d');
 
   var firstimg = iframeelem.contentDocument.getElementById('image1');
   var secondimg = iframeelem.contentDocument.getElementById('image2');
   ctx.drawImage(firstimg, 0, 0);
--- a/ipc/chromium/src/base/process_util.h
+++ b/ipc/chromium/src/base/process_util.h
@@ -60,17 +60,17 @@ namespace base {
 // These can be used in a 32-bit bitmask.
 enum ProcessArchitecture {
   PROCESS_ARCH_I386 = 0x1,
   PROCESS_ARCH_X86_64 = 0x2,
   PROCESS_ARCH_PPC = 0x4,
   PROCESS_ARCH_ARM = 0x8
 };
 
-static inline ProcessArchitecture GetCurrentProcessArchitecture()
+inline ProcessArchitecture GetCurrentProcessArchitecture()
 {
   base::ProcessArchitecture currentArchitecture;
 #if defined(ARCH_CPU_X86)
   currentArchitecture = base::PROCESS_ARCH_I386;
 #elif defined(ARCH_CPU_X86_64)
   currentArchitecture = base::PROCESS_ARCH_X86_64;
 #elif defined(ARCH_CPU_PPC)
   currentArchitecture = base::PROCESS_ARCH_PPC;
--- a/ipc/chromium/src/build/build_config.h
+++ b/ipc/chromium/src/build/build_config.h
@@ -81,16 +81,19 @@
 #define ARCH_CPU_IA64 1