Merging m-c into GECKO20b7pre_20101029_RELBRANCH per stuart/aki a=me GECKO20b7pre_20101029_RELBRANCH FENNEC_4_0b2_BUILD3 FENNEC_4_0b2_BUILD4 FENNEC_4_0b2_RELEASE
authorDoug Turner <dougt@dougt.org>
Tue, 02 Nov 2010 15:40:17 -0700
branchGECKO20b7pre_20101029_RELBRANCH
changeset 56838 ec75218656605002ad8ee4218c88feff81f0f38a
parent 56808 6f1663a7e25ed4636d8f952200625caaaa1a7183 (current diff)
parent 56837 48ae242466f0d193f08a9657eeb0476c5a547c97 (diff)
child 56840 97410b48df68623fb690c0a355f8a41150488599
push idunknown
push userunknown
push dateunknown
reviewersme
milestone2.0b7pre
Merging m-c into GECKO20b7pre_20101029_RELBRANCH per stuart/aki a=me
testing/mozmill/tests/firefox/testPrivateBrowsing/testStartStopPBMode.js
--- a/browser/base/content/aboutHome.css
+++ b/browser/base/content/aboutHome.css
@@ -99,16 +99,17 @@ body[dir="rtl"] #searchEngineLinks {
   float: left;
 }
 
 #searchEngineLogo {
   margin: 5px;
 }
 
 #searchText {
+  margin-bottom: 10px;
   width: 100%;
 }
 
 #aboutMozilla {
   text-align: center;
 }
 
 #defaultSnippets {
--- a/browser/base/content/aboutHome.xhtml
+++ b/browser/base/content/aboutHome.xhtml
@@ -67,17 +67,16 @@
       <div id="topSection">
         <div id="brandStart">
           &abouthome.brandStart;
         </div>
         <div id ="searchContainer">
           <img id="searchEngineLogo"/>
           <form name="searchForm" onsubmit="onSearchSubmit(event)">
             <input type="text" name="searchText" value="" id="searchText" maxLength="256"/>
-            <br/>
             <input type="submit" value="&abouthome.searchEngineButton.label;"/>
             <span id="searchEngineLinks">
               <a hidden="true" id="searchEngineAdvancedLink">&abouthome.searchEngineLinks.advanced;</a>
               <a hidden="true" id="searchEngineAdvancedPreferences">&abouthome.searchEngineLinks.preferences;</a>
             </span>
           </form>
         </div>
       </div>
new file mode 100644
--- /dev/null
+++ b/browser/base/content/browser-appmenu.inc
@@ -0,0 +1,409 @@
+# -*- Mode: HTML -*-
+# ***** 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 Application Menu.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Dão Gottwald <dao@mozilla.com>
+#   Joshua M. <soapyhamhocks@gmail.com>
+#   Margaret Leibovic <margaret.leibovic@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 *****
+
+<menupopup id="appmenu-popup"
+#ifdef MOZ_SERVICES_SYNC
+           onpopupshowing="updateEditUIVisibility();gSyncUI.updateUI();">
+#else
+           onpopupshowing="updateEditUIVisibility();">
+#endif
+  <hbox>
+    <vbox id="appmenuPrimaryPane">
+      <hbox flex="1"
+            class="split-menuitem">
+        <menuitem id="appmenu_newTab"
+                  class="menuitem-tooltip split-menuitem-item"
+                  flex="1"
+                  label="&tabCmd.label;"
+                  command="cmd_newNavigatorTab"
+                  key="key_newNavigatorTab"/>
+        <menu class="split-menuitem-menu">
+          <menupopup>
+            <menuitem id="appmenu_newTab_popup"
+                      label="&tabCmd.label;"
+                      command="cmd_newNavigatorTab"
+                      key="key_newNavigatorTab"/>
+            <menuitem id="appmenu_newNavigator"
+                      label="&newNavigatorCmd.label;"
+                      command="cmd_newNavigator"
+                      key="key_newNavigator"/>
+            <menuseparator/>
+            <menuitem id="appmenu_openFile"
+                      label="&openFileCmd.label;"
+                      command="Browser:OpenFile"
+                      key="openFileKb"/>
+          </menupopup>
+        </menu>
+      </hbox>
+      <menuitem id="appmenu_privateBrowsing"
+                class="menuitem-iconic menuitem-iconic-tooltip"
+                label="&privateBrowsingCmd.start.label;"
+                startlabel="&privateBrowsingCmd.start.label;"
+                stoplabel="&privateBrowsingCmd.stop.label;"
+                command="Tools:PrivateBrowsing"
+                key="key_privatebrowsing"/>
+      <menuitem label="&goOfflineCmd.label;"
+                id="appmenu_offlineModeRecovery"
+                type="checkbox"
+                observes="workOfflineMenuitemState"
+                oncommand="BrowserOffline.toggleOfflineStatus();"/>
+      <menuseparator class="appmenu-menuseparator"/>
+      <hbox>
+        <menuitem id="appmenu-edit-label"
+                  label="&appMenuEdit.label;"
+                  disabled="true"/>
+        <toolbarbutton id="appmenu-cut"
+                       class="appmenu-edit-button"
+                       command="cmd_cut"
+                       onclick="if (!this.disabled) hidePopup();"
+                       tooltiptext="&cutButton.tooltip;"/>
+        <toolbarbutton id="appmenu-copy"
+                       class="appmenu-edit-button"
+                       command="cmd_copy"
+                       onclick="if (!this.disabled) hidePopup();"
+                       tooltiptext="&copyButton.tooltip;"/>
+        <toolbarbutton id="appmenu-paste"
+                       class="appmenu-edit-button"
+                       command="cmd_paste"
+                       onclick="if (!this.disabled) hidePopup();"
+                       tooltiptext="&pasteButton.tooltip;"/>
+      </hbox>
+      <menuitem id="appmenu_find"
+                class="menuitem-tooltip"
+                label="&appMenuFind.label;"
+                command="cmd_find"
+                key="key_find"/>
+      <menuseparator class="appmenu-menuseparator"/>
+      <menuitem id="appmenu_savePage"
+                class="menuitem-tooltip"
+                label="&savePageCmd.label;"
+                command="Browser:SavePage"
+                key="key_savePage"/>
+      <menuitem id="appmenu_sendLink"
+                label="&sendPageCmd.label;"
+                command="Browser:SendLink"/>
+      <hbox flex="1"
+            class="split-menuitem">
+        <menuitem id="appmenu_print"
+                  class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
+                  flex="1"
+                  label="&printCmd.label;"
+                  command="cmd_print"
+                  key="printKb"/>
+        <menu class="split-menuitem-menu">
+          <menupopup>
+            <menuitem id="appmenu_print_popup"
+                      class="menuitem-iconic"
+                      label="&printCmd.label;"
+                      command="cmd_print"
+                      key="printKb"/>
+            <menuitem id="appmenu_printPreview"
+                      label="&printPreviewCmd.label;"
+                      command="cmd_printPreview"/>
+            <menuitem id="appmenu_printSetup"
+                      label="&printSetupCmd.label;"
+                      command="cmd_pageSetup"/>
+          </menupopup>
+        </menu>
+      </hbox>
+      <menuseparator class="appmenu-menuseparator"/>
+      <menu id="appmenu_webDeveloper"
+            label="&appMenuWebDeveloper.label;">
+        <menupopup id="appmenu_webDeveloper_popup">
+          <menuitem id="appmenu_webConsole"
+                    label="&webConsoleCmd.label;"
+                    oncommand="HUDConsoleUI.toggleHUD();"
+                    key="key_webConsole"/>
+          <menuitem id="appmenu_pageInspect"
+                    hidden="true"
+                    label="&inspectMenu.label;"
+                    type="checkbox"
+                    command="Tools:Inspect"
+                    key="key_inspect"/>
+          <menuseparator/>
+          <menuitem id="appmenu_pageSource"
+                    label="&viewPageSourceCmd.label;"
+                    command="View:PageSource"
+                    key="key_viewSource"/>
+          <menuseparator/>
+#define ID_PREFIX appmenu_developer_
+#include browser-charsetmenu.inc
+#undef ID_PREFIX
+          <menuseparator/>
+          <menuitem label="&goOfflineCmd.label;"
+                    type="checkbox"
+                    observes="workOfflineMenuitemState"
+                    oncommand="BrowserOffline.toggleOfflineStatus();"/>
+        </menupopup>
+      </menu>
+      <menuseparator class="appmenu-menuseparator"/>
+#define ID_PREFIX appmenu_
+#include browser-charsetmenu.inc
+#undef ID_PREFIX
+      <menuitem id="appmenu_fullScreen"
+                class="menuitem-tooltip"
+                label="&fullScreenCmd.label;"
+                type="checkbox"
+                observes="View:FullScreen"
+                key="key_fullScreen"/>
+      <menuitem id="appmenu-quit"
+                class="menuitem-iconic"
+#ifdef XP_WIN
+                label="&quitApplicationCmdWin.label;"
+#else
+                label="&quitApplicationCmd.label;"
+#endif
+                command="cmd_quitApplication"/>
+    </vbox>
+    <vbox id="appmenuSecondaryPane">
+      <hbox class="split-menuitem">
+        <menuitem id="appmenu_bookmarks"
+                  class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
+                  flex="1"
+                  label="&bookmarksMenu.label;"
+                  command="Browser:ShowAllBookmarks"
+                  key="manBookmarkKb"/>
+        <menu id="appmenu_bookmarksMenu"
+              class="split-menuitem-menu">
+          <menupopup id="appmenu_bookmarksPopup"
+                     placespopup="true"
+                     context="placesContext"
+                     openInTabs="children"
+                     oncommand="BookmarksEventHandler.onCommand(event);"
+                     onclick="BookmarksEventHandler.onClick(event);"
+                     onpopupshowing="BookmarksMenuButton.onPopupShowing(event);
+                                     if (!this.parentNode._placesView)
+                                       new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
+                     tooltip="bhTooltip"
+                     popupsinherittooltip="true">
+            <menuitem id="appmenu_showAllBookmarks"
+                      label="&showAllBookmarks.label;"
+                      command="Browser:ShowAllBookmarks"
+                      context=""
+                      key="manBookmarkKb"/>
+            <menuseparator/>
+            <menuitem id="appmenu_bookmarkThisPage"
+                      class="menuitem-iconic"
+                      label="&bookmarkThisPageCmd.label;"
+                      command="Browser:AddBookmarkAs"
+                      key="addBookmarkAsKb"/>
+            <menuitem id="appmenu_subscribeToPage"
+                      class="menuitem-iconic"
+                      label="&subscribeToPageMenuitem.label;"
+                      oncommand="return FeedHandler.subscribeToFeed(null, event);"
+                      onclick="checkForMiddleClick(this, event);"
+                      observes="singleFeedMenuitemState"/>
+            <menu id="appmenu_subscribeToPageMenu"
+                  class="menu-iconic"
+                  label="&subscribeToPageMenupopup.label;"
+                  observes="multipleFeedsMenuState">
+              <menupopup id="appmenu_subscribeToPageMenupopup"
+                         onpopupshowing="return FeedHandler.buildFeedList(event.target);"
+                         oncommand="return FeedHandler.subscribeToFeed(null, event);"
+                         onclick="checkForMiddleClick(this, event);"/>
+            </menu>
+            <menuseparator/>
+            <menu id="appmenu_bookmarksToolbar"
+                  placesanonid="toolbar-autohide"
+                  class="menu-iconic bookmark-item"
+                  label="&personalbarCmd.label;"
+                  container="true">
+              <menupopup id="appmenu_bookmarksToolbarPopup"
+                         placespopup="true"
+                         context="placesContext"
+                         onpopupshowing="if (!this.parentNode._placesView)
+                                           new PlacesMenu(event, 'place:folder=TOOLBAR');"/>
+            </menu>
+            <menuseparator/>
+            <!-- Bookmarks menu items -->
+            <menuseparator builder="end"
+                           class="hide-if-empty-places-result"/>
+            <menuitem id="appmenu_unsortedBookmarks"
+                      label="&appMenuUnsorted.label;"
+                      oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"
+                      class="menuitem-iconic"/>
+          </menupopup>
+        </menu>
+      </hbox>
+      <hbox class="split-menuitem">
+        <menuitem id="appmenu_history"
+                  class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
+                  flex="1"
+                  label="&historyMenu.label;"
+                  command="Browser:ShowAllHistory"
+                  key="showAllHistoryKb"/>
+        <menu id="appmenu_historyMenu"
+              class="split-menuitem-menu">
+          <menupopup id="appmenu_historyMenupopup"
+                     placespopup="true"
+                     oncommand="this.parentNode._placesView._onCommand(event);"
+                     onclick="checkForMiddleClick(this, event);"
+                     onpopupshowing="if (!this.parentNode._placesView)
+                                       new HistoryMenu(event);"
+                     tooltip="bhTooltip"
+                     popupsinherittooltip="true">
+            <menuitem id="appmenu_showAllHistory"
+                      label="&showAllHistoryCmd2.label;"
+                      command="Browser:ShowAllHistory"
+                      key="showAllHistoryKb"/>
+            <menuseparator/>
+            <menuitem id="appmenu_sanitizeHistory"
+                      label="&clearRecentHistory.label;"
+                      key="key_sanitize"
+                      command="Tools:Sanitize"/>
+            <menuseparator class="hide-if-empty-places-result"/>
+            <menuitem id="appmenu_restoreLastSession"
+                      class="restoreLastSession"
+                      label="&historyRestoreLastSession.label;"
+                      oncommand="restoreLastSession();"
+                      disabled="true"/>
+            <menu id="appmenu_recentlyClosedTabsMenu"
+                  class="recentlyClosedTabsMenu"
+                  label="&historyUndoMenu.label;"
+                  disabled="true">
+              <menupopup id="appmenu_recentlyClosedTabsMenupopup"
+                         onpopupshowing="document.getElementById('appmenu_historyMenu')._placesView.populateUndoSubmenu();"/>
+            </menu>
+            <menu id="appmenu_recentlyClosedWindowsMenu"
+                  class="recentlyClosedWindowsMenu"
+                  label="&historyUndoWindowMenu.label;"
+                  disabled="true">
+              <menupopup id="appmenu_recentlyClosedWindowsMenupopup"
+                         onpopupshowing="document.getElementById('appmenu_historyMenu')._placesView.populateUndoWindowSubmenu();"/>
+            </menu>
+            <menuseparator/>
+          </menupopup>
+        </menu>
+      </hbox>
+      <menuitem id="appmenu_downloads"
+                class="menuitem-tooltip"
+                label="&downloads.label;"
+                command="Tools:Downloads"
+                key="key_openDownloads"/>
+      <spacer id="appmenuSecondaryPane-spacer"/>
+      <menuitem id="appmenu_addons"
+                class="menuitem-iconic menuitem-iconic-tooltip"
+                label="&addons.label;"
+                command="Tools:Addons"
+                key="key_openAddons"/>
+      <hbox class="split-menuitem">
+        <menuitem id="appmenu_customize"
+#ifdef XP_UNIX
+                  label="&preferencesCmdUnix.label;"
+#else
+                  label="&preferencesCmd.label;"
+#endif
+                  class="split-menuitem-item"
+                  flex="1"
+                  oncommand="openPreferences();"/>
+        <menu class="split-menuitem-menu"
+              label="&preferencesCmd.label;">
+          <menupopup id="appmenu_customizeMenu"
+                     onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleTabsOnTop').previousSibling);">
+            <menuitem id="appmenu_preferences"
+#ifdef XP_UNIX
+                      label="&preferencesCmdUnix.label;"
+#else
+                      label="&preferencesCmd.label;"
+#endif
+                      oncommand="openPreferences();"/>
+            <menuseparator/>
+            <menuseparator/>
+            <menuitem id="appmenu_toggleTabsOnTop"
+                      label="&viewTabsOnTop.label;"
+                      type="checkbox"
+                      command="cmd_ToggleTabsOnTop"/>
+            <menuitem id="appmenu_toolbarLayout"
+                      label="&appMenuToolbarLayout.label;"
+                      command="cmd_CustomizeToolbars"/>
+          </menupopup>
+        </menu>
+      </hbox>
+      <hbox class="split-menuitem">
+        <menuitem id="appmenu_help"
+                  class="split-menuitem-item"
+                  flex="1"
+                  label="&helpMenu.label;"
+                  oncommand="openHelpLink('firefox-help')"/>
+        <menu class="split-menuitem-menu">
+          <menupopup id="appmenu_helpMenupopup">
+            <menuitem id="appmenu_openHelp"
+                      label="&helpMenu.label;"
+                      oncommand="openHelpLink('firefox-help')"
+                      onclick="checkForMiddleClick(this, event);"/>
+            <menuitem id="appmenu_gettingStarted"
+                      label="&appMenuGettingStarted.label;"
+                      oncommand="gBrowser.loadOneTab('http://www.mozilla.com/firefox/central/', {inBackground: false});"
+                      onclick="checkForMiddleClick(this, event);"/>
+            <menuitem id="appmenu_troubleshootingInfo"
+                      label="&helpTroubleshootingInfo.label;"
+                      oncommand="openTroubleshootingPage()"
+                      onclick="checkForMiddleClick(this,event);"/>
+            <menuitem id="appmenu_feedbackPage"
+                      label="&helpFeedbackPage.label;"
+                      oncommand="openFeedbackPage()"
+                      onclick="checkForMiddleClick(this, event);"/>
+            <menuseparator/>
+            <menuitem id="appmenu_safeMode"
+                      accesskey="&appMenuSafeMode.accesskey;"
+                      label="&appMenuSafeMode.label;"
+                      oncommand="safeModeRestart();"/>
+            <menuseparator/>
+            <menuitem id="appmenu_about"
+                      label="&aboutProduct.label;"
+                      oncommand="openAboutDialog();"/>
+          </menupopup>
+        </menu>
+      </hbox>
+#ifdef MOZ_SERVICES_SYNC
+      <spacer flex="1"/>
+      <!-- only one of sync-setup or sync-syncnow will be showing at once -->
+      <menuitem id="sync-setup-appmenu"
+                label="&syncSetup.label;"
+                observes="sync-setup-state"
+                oncommand="gSyncUI.openSetup()"/>
+      <menuitem id="sync-syncnowitem-appmenu"
+                label="&syncSyncNowItem.label;"
+                observes="sync-syncnow-state"
+                oncommand="gSyncUI.doSync(event);"/>
+#endif
+    </vbox>
+  </hbox>
+</menupopup>
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -436,381 +436,17 @@
   <button id="appmenu-button"
           type="menu"
 #ifdef XP_WIN
           label="&brandShortName;"
 #else
           label="&appMenuButton.label;"
 #endif
           style="-moz-user-focus: ignore;">
-    <menupopup id="appmenu-popup"
-#ifdef MOZ_SERVICES_SYNC
-               onpopupshowing="updateEditUIVisibility();gSyncUI.updateUI();">
-#else
-               onpopupshowing="updateEditUIVisibility();">
-#endif
-      <hbox>
-        <vbox id="appmenuPrimaryPane">
-          <hbox flex="1"
-                class="split-menuitem">
-            <menuitem id="appmenu_newTab"
-                      class="menuitem-tooltip split-menuitem-item"
-                      flex="1"
-                      label="&tabCmd.label;"
-                      command="cmd_newNavigatorTab"
-                      key="key_newNavigatorTab"/>
-              <menu class="split-menuitem-menu">
-                <menupopup>
-                  <menuitem id="appmenu_newTab_popup"
-                            label="&tabCmd.label;"
-                            command="cmd_newNavigatorTab"
-                            key="key_newNavigatorTab"/>
-                  <menuitem id="appmenu_newNavigator"
-                            label="&newNavigatorCmd.label;"
-                            command="cmd_newNavigator"
-                            key="key_newNavigator"/>
-                  <menuseparator/>
-                  <menuitem id="appmenu_openFile"
-                            label="&openFileCmd.label;"
-                            command="Browser:OpenFile"
-                            key="openFileKb"/>
-                </menupopup>
-               </menu>
-          </hbox>
-          <menuitem id="appmenu_privateBrowsing"
-                    class="menuitem-iconic menuitem-iconic-tooltip"
-                    label="&privateBrowsingCmd.start.label;"
-                    startlabel="&privateBrowsingCmd.start.label;"
-                    stoplabel="&privateBrowsingCmd.stop.label;"
-                    command="Tools:PrivateBrowsing"
-                    key="key_privatebrowsing"/>
-          <menuitem label="&goOfflineCmd.label;"
-                    id="appmenu_offlineModeRecovery"
-                    type="checkbox"
-                    observes="workOfflineMenuitemState"
-                    oncommand="BrowserOffline.toggleOfflineStatus();"/>
-          <menuseparator class="appmenu-menuseparator"/>
-          <hbox>
-            <menuitem id="appmenu-edit-label"
-                      label="&appMenuEdit.label;"
-                      disabled="true"/>
-            <toolbarbutton id="appmenu-cut"
-                           class="appmenu-edit-button"
-                           command="cmd_cut"
-                           onclick="if (!this.disabled) hidePopup();"
-                           tooltiptext="&cutButton.tooltip;"/>
-            <toolbarbutton id="appmenu-copy"
-                           class="appmenu-edit-button"
-                           command="cmd_copy"
-                           onclick="if (!this.disabled) hidePopup();"
-                           tooltiptext="&copyButton.tooltip;"/>
-            <toolbarbutton id="appmenu-paste"
-                           class="appmenu-edit-button"
-                           command="cmd_paste"
-                           onclick="if (!this.disabled) hidePopup();"
-                           tooltiptext="&pasteButton.tooltip;"/>
-          </hbox>
-          <menuitem id="appmenu_find"
-                    class="menuitem-tooltip"
-                    label="&appMenuFind.label;"
-                    command="cmd_find"
-                    key="key_find"/>
-          <menuseparator class="appmenu-menuseparator"/>
-          <menuitem id="appmenu_savePage"
-                    class="menuitem-tooltip"
-                    label="&savePageCmd.label;"
-                    command="Browser:SavePage"
-                    key="key_savePage"/>
-          <menuitem id="appmenu_sendLink"
-                    label="&sendPageCmd.label;"
-                    command="Browser:SendLink"/>
-          <hbox flex="1"
-                class="split-menuitem">
-            <menuitem id="appmenu_print"
-                      class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
-                      flex="1"
-                      label="&printCmd.label;"
-                      command="cmd_print"
-                      key="printKb"/>
-            <menu class="split-menuitem-menu">
-              <menupopup>
-                <menuitem id="appmenu_print_popup"
-                          class="menuitem-iconic"
-                          label="&printCmd.label;"
-                          command="cmd_print"
-                          key="printKb"/>
-                <menuitem id="appmenu_printPreview"
-                          label="&printPreviewCmd.label;"
-                          command="cmd_printPreview"/>
-                <menuitem id="appmenu_printSetup"
-                          label="&printSetupCmd.label;"
-                          command="cmd_pageSetup"/>
-              </menupopup>
-            </menu>
-          </hbox>
-          <menuseparator class="appmenu-menuseparator"/>
-          <menu id="appmenu_webDeveloper"
-                label="&appMenuWebDeveloper.label;">
-            <menupopup id="appmenu_webDeveloper_popup">
-              <menuitem id="appmenu_webConsole"
-                        label="&webConsoleCmd.label;"
-                        oncommand="HUDConsoleUI.toggleHUD();"
-                        key="key_webConsole"/>
-              <menuitem id="appmenu_pageInspect"
-                        hidden="true"
-                        label="&inspectMenu.label;"
-                        type="checkbox"
-                        command="Tools:Inspect"
-                        key="key_inspect"/>
-              <menuseparator/>
-              <menuitem id="appmenu_pageSource"
-                        label="&viewPageSourceCmd.label;"
-                        command="View:PageSource"
-                        key="key_viewSource"/>
-              <menuseparator/>
-#define ID_PREFIX appmenu_developer_
-#include browser-charsetmenu.inc
-#undef ID_PREFIX
-              <menuseparator/>
-              <menuitem label="&goOfflineCmd.label;"
-                        type="checkbox"
-                        observes="workOfflineMenuitemState"
-                        oncommand="BrowserOffline.toggleOfflineStatus();"/>
-            </menupopup>
-          </menu>
-          <menuseparator class="appmenu-menuseparator"/>
-#define ID_PREFIX appmenu_
-#include browser-charsetmenu.inc
-#undef ID_PREFIX
-          <menuitem id="appmenu_fullScreen"
-                    class="menuitem-tooltip"
-                    label="&fullScreenCmd.label;"
-                    type="checkbox"
-                    observes="View:FullScreen"
-                    key="key_fullScreen"/>
-          <menuitem id="appmenu-quit"
-                    class="menuitem-iconic"
-#ifdef XP_WIN
-                    label="&quitApplicationCmdWin.label;"
-#else
-                    label="&quitApplicationCmd.label;"
-#endif
-                    command="cmd_quitApplication"/>
-        </vbox>
-        <vbox id="appmenuSecondaryPane">
-          <hbox class="split-menuitem">
-            <menuitem id="appmenu_bookmarks"
-                      class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
-                      flex="1"
-                      label="&bookmarksMenu.label;"
-                      command="Browser:ShowAllBookmarks"
-                      key="manBookmarkKb"/>
-            <menu id="appmenu_bookmarksMenu"
-                  class="split-menuitem-menu">
-              <menupopup id="appmenu_bookmarksPopup"
-                         placespopup="true"
-                         context="placesContext"
-                         openInTabs="children"
-                         oncommand="BookmarksEventHandler.onCommand(event);"
-                         onclick="BookmarksEventHandler.onClick(event);"
-                         onpopupshowing="BookmarksMenuButton.onPopupShowing(event);
-                                         if (!this.parentNode._placesView)
-                                           new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
-                         tooltip="bhTooltip"
-                         popupsinherittooltip="true">
-                <menuitem id="appmenu_showAllBookmarks"
-                          label="&showAllBookmarks.label;"
-                          command="Browser:ShowAllBookmarks"
-                          context=""
-                          key="manBookmarkKb"/>
-                <menuseparator/>
-                <menuitem id="appmenu_bookmarkThisPage"
-                          class="menuitem-iconic"
-                          label="&bookmarkThisPageCmd.label;"
-                          command="Browser:AddBookmarkAs"
-                          key="addBookmarkAsKb"/>
-                <menuitem id="appmenu_subscribeToPage"
-                          class="menuitem-iconic"
-                          label="&subscribeToPageMenuitem.label;"
-                          oncommand="return FeedHandler.subscribeToFeed(null, event);"
-                          onclick="checkForMiddleClick(this, event);"
-                          observes="singleFeedMenuitemState"/>
-                <menu id="appmenu_subscribeToPageMenu"
-                      class="menu-iconic"
-                      label="&subscribeToPageMenupopup.label;"
-                      observes="multipleFeedsMenuState">
-                  <menupopup id="appmenu_subscribeToPageMenupopup"
-                             onpopupshowing="return FeedHandler.buildFeedList(event.target);"
-                             oncommand="return FeedHandler.subscribeToFeed(null, event);"
-                             onclick="checkForMiddleClick(this, event);"/>
-                </menu>
-                <menuseparator/>
-                <menu id="appmenu_bookmarksToolbar"
-                      placesanonid="toolbar-autohide"
-                      class="menu-iconic bookmark-item"
-                      label="&personalbarCmd.label;"
-                      container="true">
-                  <menupopup id="appmenu_bookmarksToolbarPopup"
-                             placespopup="true"
-                             context="placesContext"
-                             onpopupshowing="if (!this.parentNode._placesView)
-                                               new PlacesMenu(event, 'place:folder=TOOLBAR');"/>
-                </menu>
-                <menuseparator/>
-                <!-- Bookmarks menu items -->
-                <menuseparator builder="end"
-                               class="hide-if-empty-places-result"/>
-                <menuitem id="appmenu_unsortedBookmarks"
-                          label="&appMenuUnsorted.label;"
-                          oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"
-                          class="menuitem-iconic"/>
-              </menupopup>
-            </menu>
-          </hbox>
-          <hbox class="split-menuitem">
-            <menuitem id="appmenu_history"
-                      class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
-                      flex="1"
-                      label="&historyMenu.label;"
-                      command="Browser:ShowAllHistory"
-                      key="showAllHistoryKb"/>
-            <menu id="appmenu_historyMenu"
-                  class="split-menuitem-menu">
-              <menupopup id="appmenu_historyMenupopup"
-                         placespopup="true"
-                         oncommand="this.parentNode._placesView._onCommand(event);"
-                         onclick="checkForMiddleClick(this, event);"
-                         onpopupshowing="if (!this.parentNode._placesView)
-                                           new HistoryMenu(event);"
-                         tooltip="bhTooltip"
-                         popupsinherittooltip="true">
-                <menuitem id="appmenu_showAllHistory"
-                          label="&showAllHistoryCmd2.label;"
-                          command="Browser:ShowAllHistory"
-                          key="showAllHistoryKb"/>
-                <menuseparator/>
-                <menuitem id="appmenu_sanitizeHistory"
-                          label="&clearRecentHistory.label;"
-                          key="key_sanitize"
-                          command="Tools:Sanitize"/>
-                <menuseparator class="hide-if-empty-places-result"/>
-                <menuitem id="appmenu_restoreLastSession"
-                          class="restoreLastSession"
-                          label="&historyRestoreLastSession.label;"
-                          oncommand="restoreLastSession();"
-                          disabled="true"/>
-                <menu id="appmenu_recentlyClosedTabsMenu"
-                      class="recentlyClosedTabsMenu"
-                      label="&historyUndoMenu.label;"
-                      disabled="true">
-                  <menupopup id="appmenu_recentlyClosedTabsMenupopup"
-                             onpopupshowing="document.getElementById('appmenu_historyMenu')._placesView.populateUndoSubmenu();"/>
-                </menu>
-                <menu id="appmenu_recentlyClosedWindowsMenu"
-                      class="recentlyClosedWindowsMenu"
-                      label="&historyUndoWindowMenu.label;"
-                      disabled="true">
-                  <menupopup id="appmenu_recentlyClosedWindowsMenupopup"
-                             onpopupshowing="document.getElementById('appmenu_historyMenu')._placesView.populateUndoWindowSubmenu();"/>
-                </menu>
-                <menuseparator/>
-              </menupopup>
-            </menu>
-          </hbox>
-            <menuitem id="appmenu_downloads"
-                      class="menuitem-tooltip"
-                      label="&downloads.label;"
-                      command="Tools:Downloads"
-                      key="key_openDownloads"/>
-            <spacer id="appmenuSecondaryPane-spacer"/>
-            <menuitem id="appmenu_addons"
-                      class="menuitem-iconic menuitem-iconic-tooltip"
-                      label="&addons.label;"
-                      command="Tools:Addons"
-                      key="key_openAddons"/>
-            <hbox class="split-menuitem">
-              <menuitem id="appmenu_customize"
-                        label="&preferencesCmd.label;"
-                        class="split-menuitem-item"
-                        flex="1"
-                        oncommand="openPreferences();"/>
-              <menu class="split-menuitem-menu"
-                    label="&preferencesCmd.label;">
-                <menupopup id="appmenu_customizeMenu"
-                           onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleTabsOnTop').previousSibling);">
-                  <menuitem id="appmenu_preferences"
-#ifdef XP_UNIX
-                            label="&preferencesCmdUnix.label;"
-#else
-                            label="&preferencesCmd.label;"
-#endif
-                            oncommand="openPreferences();"/>
-                  <menuseparator/>
-                  <menuseparator/>
-                  <menuitem id="appmenu_toggleTabsOnTop"
-                            label="&viewTabsOnTop.label;"
-                            type="checkbox"
-                            command="cmd_ToggleTabsOnTop"/>
-                  <menuitem id="appmenu_toolbarLayout"
-                            label="&appMenuToolbarLayout.label;"
-                            command="cmd_CustomizeToolbars"/>
-                </menupopup>
-              </menu>
-            </hbox>
-            <hbox class="split-menuitem">
-              <menuitem id="appmenu_help"
-                        class="split-menuitem-item"
-                        flex="1"
-                        label="&helpMenu.label;"
-                        oncommand="openHelpLink('firefox-help')"/>
-              <menu class="split-menuitem-menu">
-                <menupopup id="appmenu_helpMenupopup">
-                  <menuitem id="appmenu_openHelp"
-                            label="&helpMenu.label;"
-                            oncommand="openHelpLink('firefox-help')"
-                            onclick="checkForMiddleClick(this, event);"/>
-                  <menuitem id="appmenu_gettingStarted"
-                            label="&appMenuGettingStarted.label;"
-                            oncommand="gBrowser.loadOneTab('http://www.mozilla.com/firefox/central/', {inBackground: false});"
-                            onclick="checkForMiddleClick(this, event);"/>
-                  <menuitem id="appmenu_troubleshootingInfo"
-                            label="&helpTroubleshootingInfo.label;"
-                            oncommand="openTroubleshootingPage()"
-                            onclick="checkForMiddleClick(this,event);"/>
-                  <menuitem id="appmenu_feedbackPage"
-                            label="&helpFeedbackPage.label;"
-                            oncommand="openFeedbackPage()"
-                            onclick="checkForMiddleClick(this, event);"/>
-                  <menuseparator/>
-                  <menuitem id="appmenu_safeMode"
-                            accesskey="&appMenuSafeMode.accesskey;"
-                            label="&appMenuSafeMode.label;"
-                            oncommand="safeModeRestart();"/>
-                  <menuseparator/>
-                  <menuitem id="appmenu_about"
-                            label="&aboutProduct.label;"
-                            oncommand="openAboutDialog();"/>
-                </menupopup>
-              </menu>
-            </hbox>
-#ifdef MOZ_SERVICES_SYNC
-            <spacer flex="1"/>
-            <!-- only one of sync-setup or sync-syncnow will be showing at once -->
-            <menuitem id="sync-setup-appmenu"
-                      label="&syncSetup.label;"
-                      observes="sync-setup-state"
-                      oncommand="gSyncUI.openSetup()"/>
-            <menuitem id="sync-syncnowitem-appmenu"
-                      label="&syncSyncNowItem.label;"
-                      observes="sync-syncnow-state"
-                      oncommand="gSyncUI.doSync(event);"/>
-#endif
-        </vbox>
-      </hbox>
-    </menupopup>
+#include browser-appmenu.inc
   </button>
   </hbox>
   <spacer id="titlebar-spacer" flex="1"/>
   <hbox id="titlebar-buttonbox">
     <toolbarbutton class="titlebar-button" id="titlebar-min" oncommand="window.minimize();"/>
     <toolbarbutton class="titlebar-button" id="titlebar-max" oncommand="onTitlebarMaxClick();"/>
     <toolbarbutton class="titlebar-button" id="titlebar-close" command="cmd_closeWindow"/>
   </hbox>
--- a/browser/base/content/test/browser_bug553455.js
+++ b/browser/base/content/test/browser_bug553455.js
@@ -592,17 +592,17 @@ var XPInstallObserver = {
     info("Observed " + aTopic + " for " + installInfo.installs.length + " installs");
     installInfo.installs.forEach(function(aInstall) {
       info("Install of " + aInstall.sourceURI.spec + " was in state " + aInstall.state);
     });
   }
 };
 
 function test() {
-  requestLongerTimeout(2);
+  requestLongerTimeout(4);
   waitForExplicitFinish();
 
   Services.prefs.setBoolPref("extensions.logging.enabled", true);
 
   Services.obs.addObserver(XPInstallObserver, "addon-install-started", false);
   Services.obs.addObserver(XPInstallObserver, "addon-install-blocked", false);
   Services.obs.addObserver(XPInstallObserver, "addon-install-failed", false);
   Services.obs.addObserver(XPInstallObserver, "addon-install-complete", false);
--- a/browser/base/content/test/tabview/browser_tabview_launch.js
+++ b/browser/base/content/test/tabview/browser_tabview_launch.js
@@ -50,23 +50,38 @@ function test() {
   ok(button, "Tab View button exists");
   button.doCommand();
 }
 
 // ----------
 function onTabViewLoadedAndShown() {
   window.removeEventListener("tabviewshown", onTabViewLoadedAndShown, false);
   
-  ok(TabView.isVisible(), "Tab View is visible. Count: " + tabViewShownCount);
-  tabViewShownCount++;
+  // Evidently sometimes isVisible (which is based on the selectedIndex of the
+  // tabview deck) isn't updated immediately when called from button.doCommand,
+  // so we add a little timeout here to get outside of the doCommand call.
+  // If the initial timeout isn't enough, we keep waiting in case it's taking
+  // longer than expected.
+  // See bug 594909.
+  let deck = document.getElementById("tab-view-deck");
+  function waitForSwitch() {
+    if (deck.selectedIndex == 1) {
+      ok(TabView.isVisible(), "Tab View is visible. Count: " + tabViewShownCount);
+      tabViewShownCount++;
+      
+      // kick off the series
+      window.addEventListener("tabviewshown", onTabViewShown, false);
+      window.addEventListener("tabviewhidden", onTabViewHidden, false);
+      TabView.toggle();
+    } else {
+      setTimeout(waitForSwitch, 10);
+    }
+  }
   
-  // kick off the series
-  window.addEventListener("tabviewshown", onTabViewShown, false);
-  window.addEventListener("tabviewhidden", onTabViewHidden, false);
-  TabView.toggle();
+  setTimeout(waitForSwitch, 1);
 }
 
 // ----------
 function onTabViewShown() {
   // add the count to the message so we can track things more easily.
   ok(TabView.isVisible(), "Tab View is visible. Count: " + tabViewShownCount);
   tabViewShownCount++;
   TabView.toggle();
--- a/browser/locales/all-locales
+++ b/browser/locales/all-locales
@@ -1,56 +1,61 @@
 af
 ak
 ar
 as
+ast
 be
 bg
 bn-BD
 bn-IN
 br
 bs
 ca
 cs
 cy
 da
 de
 el
 en-GB
 en-ZA
 eo
 es-AR
+es-CL
 es-ES
 es-MX
 et
 eu
 fa
 fi
 fr
 fy-NL
 ga-IE
+gd
 gl
 gu-IN
 he
 hi-IN
 hr
 hu
 hy-AM
 id
 is
 it
 ja
 ja-JP-mac
 ka
+km
 kn
 ko
 ku
 lg
 lt
 lv
+mai
 mk
 ml
 mn
 mr
 nb-NO
 nl
 nn-NO
 nso
@@ -66,15 +71,16 @@ ru
 si
 sk
 sl
 son
 sq
 sr
 sv-SE
 ta
+ta-LK
 te
 th
 tr
 uk
 vi
 zh-CN
 zh-TW
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -66,17 +66,17 @@ can reach it easily. -->
 <!ENTITY menubarCmd.label "Menu Bar">
 <!ENTITY menubarCmd.accesskey "M">
 <!ENTITY navbarCmd.label "Navigation Toolbar">
 <!ENTITY navbarCmd.accesskey "N">
 <!ENTITY personalbarCmd.label "Bookmarks Toolbar">
 <!ENTITY personalbarCmd.accesskey "B">
 <!ENTITY bookmarksToolbarItem.label "Bookmarks Toolbar Items">
 <!ENTITY addonBarCmd.label "Add-on Bar">
-<!ENTITY addonBarCmd.accesskey "B">
+<!ENTITY addonBarCmd.accesskey "A">
 
 <!ENTITY pageSourceCmd.label "Page Source">
 <!ENTITY pageSourceCmd.accesskey "o">
 <!ENTITY pageSourceCmd.commandkey "u">
 <!ENTITY pageInfoCmd.label "Page Info">
 <!ENTITY pageInfoCmd.accesskey "I">
 <!ENTITY pageInfoCmd.commandkey "i">
 <!ENTITY fullScreenCmd.label "Full Screen">
--- a/browser/locales/shipped-locales
+++ b/browser/locales/shipped-locales
@@ -12,41 +12,45 @@ de
 el
 en-GB
 en-US
 en-ZA
 eo
 es-AR
 es-ES
 et
+eu
 fi
 fr
 fy-NL
 ga-IE
+gd
 he
 hu
 hy-AM
 id
 is
 it
 ja linux win32
 ja-JP-mac osx
 ko
 ku
 lg
 lt
 lv
+mk
 nb-NO
 nl
 nn-NO
 nso
 pa-IN
 pl
 pt-BR
 pt-PT
+rm
 ro
 ru
 sk
 son
 sq
 sv-SE
 tr
 uk
--- a/build/mobile/sutagent/android/AndroidManifest.xml
+++ b/build/mobile/sutagent/android/AndroidManifest.xml
@@ -60,9 +60,12 @@
 
 <uses-permission android:name="android.permission.VIBRATE"></uses-permission>
 
 
 
 <uses-permission android:name="android.permission.SET_TIME"></uses-permission>
 
 
+
+<uses-permission android:name="android.permission.SET_TIME_ZONE"></uses-permission>
+
 </manifest> 
\ No newline at end of file
--- a/build/mobile/sutagent/android/DoCommand.java
+++ b/build/mobile/sutagent/android/DoCommand.java
@@ -46,27 +46,31 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintWriter;
+import java.lang.reflect.Field;
 import java.net.Socket;
 import java.net.SocketException;
 import java.net.UnknownHostException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Collections;
 import java.util.Date;
 import java.util.GregorianCalendar;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.TimeZone;
 import java.util.Timer;
 import java.util.zip.Adler32;
 import java.util.zip.CheckedInputStream;
 import java.util.zip.CheckedOutputStream;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import java.util.zip.ZipInputStream;
@@ -82,30 +86,33 @@ import org.apache.http.client.ClientProt
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.DefaultHttpClient;
 
 import com.mozilla.SUTAgentAndroid.SUTAgentAndroid;
 
 import android.app.Activity;
 import android.app.ActivityManager;
+import android.app.AlarmManager;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Configuration;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Debug;
 import android.os.Environment;
 import android.os.StatFs;
 import android.os.SystemClock;
+import android.provider.Settings;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.WindowManager;
 
 public class DoCommand {
 	
 	String lineSep = System.getProperty("line.separator");
 	Process	pProc;
@@ -113,23 +120,23 @@ public class DoCommand {
 	InputStream	sutErr;
 	InputStream	sutOut;
 	AlertLooperThread alrt = null;
 	ContextWrapper	contextWrapper = null;
 	
 	String	currentDir = "/";
 	String	sErrorPrefix = "##AGENT-WARNING## ";
 	
-	private final String prgVersion = "SUTAgentAndroid Version 0.85";
+	private final String prgVersion = "SUTAgentAndroid Version 0.87";
 	
 	public enum Command
 		{
 		RUN ("run"),
 		EXEC ("exec"),
-		ARUN ("arun"),
+		ENVRUN ("envrun"),
 		KILL ("kill"),
 		PS ("ps"),
 		DEVINFO ("info"),
 		OS ("os"),
 		ID ("id"),
 		UPTIME ("uptime"),
 		SETTIME ("settime"),
 		SYSTIME ("systime"),
@@ -168,16 +175,18 @@ public class DoCommand {
 		HELP ("help"),
 		FTPG ("ftpg"),
 		FTPP ("ftpp"),
 		INST ("inst"),
 		UPDT ("updt"),
 		UNINST ("uninst"),
 		TEST ("test"),
 		VER ("ver"),
+		TZGET ("tzget"),
+		TZSET ("tzset"),
 		UNKNOWN ("unknown");
 		
 		private final String theCmd;
 		
 		Command(String theCmd) { this.theCmd = theCmd; }
 
 		public String theCmd() {return theCmd;}
 		
@@ -202,32 +211,43 @@ public class DoCommand {
 		}
 	
 	public String processCommand(String theCmdLine, PrintWriter out, BufferedInputStream in, OutputStream cmdOut)
 		{
 		String 	strReturn = "";
 		Command	cCmd = null;
 		Command cSubCmd = null;
 		
-		String [] Argv = parseCmdLine(theCmdLine);
+		String [] Argv = parseCmdLine2(theCmdLine);
 		
 		int Argc = Argv.length;
 		
 		cCmd = Command.getCmd(Argv[0]);
 		
 		switch(cCmd)
 			{
 			case VER:
 				strReturn = prgVersion;
 				break;
 				
 			case CLOK:
 				strReturn = GetClok();
 				break;
 				
+			case TZGET:
+				strReturn = GetTimeZone();
+				break;
+				
+			case TZSET:
+				if (Argc == 2)
+					strReturn = SetTimeZone(Argv[1]);
+				else
+					strReturn = sErrorPrefix + "Wrong number of arguments for settz command!";
+				break;
+				
 			case UPDT:
 				strReturn = StartUpdateOMatic(Argv[1], Argv[2]);
 				break;
 			
 			case SETTIME:
 				strReturn = SetSystemTime(Argv[1], Argv[2], cmdOut);
 				break;
 			
@@ -322,26 +342,16 @@ public class DoCommand {
 					}
 				else
 					{
 					strReturn = sErrorPrefix + "Wrong number of arguments for alrt command!";
 					}
 				break;
 				
 			case REBT:
-//				try {
-//					reboot(null);
-//					Power.reboot(null);
-//					Power.shutdown();
-//					}
-//				catch (IOException e)
-//					{
-					// TODO Auto-generated catch block
-//					e.printStackTrace();
-//					}
 				RunReboot(cmdOut);
 				break;
 				
 			case TMPD:
 				strReturn = GetTmpDir();
 				break;
 				
 			case DEVINFO:
@@ -493,16 +503,35 @@ public class DoCommand {
 			case QUIT:
 			case EXIT:
 				strReturn = Argv[0];
 				break;
 				
 			case TEST:
 //				boolean bRet = false;
 /*				
+				Configuration userConfig = new Configuration();
+				Settings.System.getConfiguration( contextWrapper.getContentResolver(), userConfig );
+				Calendar cal = Calendar.getInstance( userConfig.locale);
+				TimeZone ctz = cal.getTimeZone();
+				String sctzLongName = ctz.getDisplayName();
+				String pstzName = TimeZone.getDefault().getDisplayName();
+*/
+				String sTimeZoneName = GetTimeZone();
+				
+				TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
+				TimeZone tz2 = TimeZone.getTimeZone("GMT-08:00");
+				int	nOffset = (-8 * 3600000);
+				String [] zoneNames = TimeZone.getAvailableIDs(nOffset);
+				int nNumMatches = zoneNames.length;
+				TimeZone.setDefault(tz);
+				
+				String sOldTZ = System.setProperty("persist.sys.timezone", "America/Los_Angeles");
+				
+/*				
 				byte[] buffer = new byte [4096];
 				int	nRead = 0;
 				long lTotalRead = 0;
 
 				Context ctx = SUTAgentAndroid.me.getApplicationContext();
 
 				FTPClient ftp = new FTPClient();
 				try 
@@ -586,17 +615,17 @@ public class DoCommand {
 				catch (IOException e)
 					{
 					// TODO Auto-generated catch block
 					strReturn = e.getMessage();
 					e.printStackTrace();
 					}
 */				
 //				strReturn = InstallApplication();
-				strReturn = InstallApp(Argv[1], cmdOut);
+//				strReturn = InstallApp(Argv[1], cmdOut);
 				
 //				strReturn = UninstallApplication();
 //				String sPingCheck = SendPing("www.mozilla.org",null);
 //				if (sPingCheck.contains("3 received"))
 //					strReturn = sPingCheck;
 //				RunReboot(cmdOut);
 /*
 				try 
@@ -648,16 +677,34 @@ public class DoCommand {
 				catch (IOException e) 
 					{
 					// TODO Auto-generated catch block
 					e.printStackTrace();
 					}
 */
 				break;
 				
+			case ENVRUN:
+				if (Argc >= 2)
+					{
+					String [] theArgs = new String [Argc - 1];
+			
+					for (int lcv = 1; lcv < Argc; lcv++)
+						{
+						theArgs[lcv - 1] = Argv[lcv];
+						}
+			
+					strReturn = StartPrg2(theArgs, cmdOut);
+					}
+				else
+					{
+					strReturn = sErrorPrefix + "Wrong number of arguments for " + Argv[0] + " command!";
+					}
+				break;
+				
 			case EXEC:
 			case RUN:
 				if (Argc >= 2)
 					{
 					String [] theArgs = new String [Argc - 1];
 				
 					for (int lcv = 1; lcv < Argc; lcv++)
 						{
@@ -823,32 +870,175 @@ public class DoCommand {
 				}
 			// Kill the thread
 			alrt.quit();
 			alrt = null;
 			System.gc();
 			}
 		}
 
-	public String [] parseCmdLine(String theCmdLine) {
+	public String [] parseCmdLine2(String theCmdLine)
+		{
+		String	cmdString;
 		String	workingString;
 		String	workingString2;
+		String	workingString3;
 		List<String> lst = new ArrayList<String>();
-		int nLength = theCmdLine.length();
-		int nFirstSpace = theCmdLine.indexOf(' ');
+		int nLength = 0;
+		int nFirstSpace = -1;
+		
+		// Null cmd line
+		if (theCmdLine == null)
+			{
+			String [] theArgs = new String [1];
+			theArgs[0] = new String("");
+			return(theArgs);
+			}
+		else
+			{
+			nLength = theCmdLine.length();
+			nFirstSpace = theCmdLine.indexOf(' ');
+			}
 		
 		if (nFirstSpace == -1)
 			{
 			String [] theArgs = new String [1];
 			theArgs[0] = new String(theCmdLine);
 			return(theArgs);
 			}
 		
 		// Get the command
-		lst.add(new String(theCmdLine.substring(0, nFirstSpace)));
+		cmdString = new String(theCmdLine.substring(0, nFirstSpace)); 
+		lst.add(cmdString);
+		
+		// Jump past the command and trim
+		workingString = (theCmdLine.substring(nFirstSpace + 1, nLength)).trim();
+		
+		while ((nLength = workingString.length()) > 0)
+			{
+			int nEnd = 0;
+			int	nStart = 0;
+			
+			// if we have a quote
+			if (workingString.startsWith("\""))
+				{
+				// point to the first non quote char
+				nStart = 1;
+				// find the matching quote
+				nEnd = workingString.indexOf('"', nStart);
+				
+				char prevChar;
+				
+				while(nEnd != -1)
+					{
+					// check to see if the quotation mark has been escaped
+					prevChar = workingString.charAt(nEnd - 1);
+					if (prevChar == '\\')
+						{
+						// if escaped, point past this quotation mark and find the next
+						nEnd++;
+						if (nEnd < nLength)
+							nEnd = workingString.indexOf('"', nEnd);
+						else
+							nEnd = -1;
+						}
+					else
+						break;
+					}
+				
+				// there isn't one
+				if (nEnd == -1)
+					{
+					// point at the quote
+					nStart = 0;
+					// so find the next space
+					nEnd = workingString.indexOf(' ', nStart);
+					// there isn't one of those either
+					if (nEnd == -1)
+						nEnd = nLength;	// Just grab the rest of the cmdline
+					}
+				}
+			else // no quote so find the next space
+				{
+				nEnd = workingString.indexOf(' ', nStart);
+				// there isn't one of those
+				if (nEnd == -1)
+					nEnd = nLength;	// Just grab the rest of the cmdline
+				}
+			
+			// get the substring
+			workingString2 = workingString.substring(nStart, nEnd);
+
+			// if we have escaped quotes
+			if (workingString2.contains("\\\""))
+				{
+				do
+					{
+					// replace escaped quote with embedded quote
+					workingString3 = workingString2.replace("\\\"", "\"");
+					workingString2 = workingString3;
+					}
+				while(workingString2.contains("\\\""));
+				}
+
+			// add it to the list
+			lst.add(new String(workingString2));
+			
+			// if we are dealing with a quote
+			if (nStart > 0)
+				nEnd++; //  point past the end one
+			
+			// jump past the substring and trim it
+			workingString = (workingString.substring(nEnd)).trim();
+			}
+		
+		// ok we're done package up the results
+		int nItems = lst.size();
+		
+		String [] theArgs = new String [nItems];
+		
+		for (int lcv = 0; lcv < nItems; lcv++)
+			{
+			theArgs[lcv] = lst.get(lcv);
+			}
+	
+		return(theArgs);
+		}
+	
+	public String [] parseCmdLine(String theCmdLine) {
+		String	cmdString;
+		String	workingString;
+		String	workingString2;
+		List<String> lst = new ArrayList<String>();
+		int nLength = 0;
+		int nFirstSpace = -1;
+		
+		// Null cmd line
+		if (theCmdLine == null)
+			{
+			String [] theArgs = new String [1];
+			theArgs[0] = new String("");
+			return(theArgs);
+			}
+		else
+			{
+			nLength = theCmdLine.length();
+			nFirstSpace = theCmdLine.indexOf(' ');
+			}
+		
+		if (nFirstSpace == -1)
+			{
+			String [] theArgs = new String [1];
+			theArgs[0] = new String(theCmdLine);
+			return(theArgs);
+			}
+		
+		// Get the command
+		cmdString = new String(theCmdLine.substring(0, nFirstSpace)); 
+		lst.add(cmdString);
 		
 		// Jump past the command and trim
 		workingString = (theCmdLine.substring(nFirstSpace + 1, nLength)).trim();
 		
 		while ((nLength = workingString.length()) > 0)
 			{
 			int nEnd = 0;
 			int	nStart = 0;
@@ -866,34 +1056,39 @@ public class DoCommand {
 					// point at the quote
 					nStart = 0;
 					// so find the next space
 					nEnd = workingString.indexOf(' ', nStart);
 					// there isn't one of those either
 					if (nEnd == -1)
 						nEnd = nLength;	// Just grab the rest of the cmdline
 					}
+				else
+					{
+					nStart = 0;
+					nEnd++;
+					}
 				}
 			else // no quote so find the next space
 				{
 				nEnd = workingString.indexOf(' ', nStart);
 				// there isn't one of those
 				if (nEnd == -1)
 					nEnd = nLength;	// Just grab the rest of the cmdline
 				}
 			
 			// get the substring
 			workingString2 = workingString.substring(nStart, nEnd);
 			
 			// add it to the list
 			lst.add(new String(workingString2));
 			
 			// if we are dealing with a quote
-			if (nStart > 0)
-				nEnd++; //  point past the end one
+//			if (nStart > 0)
+//				nEnd++; //  point past the end one
 			
 			// jump past the substring and trim it
 			workingString = (workingString.substring(nEnd)).trim();
 			}
 		
 		int nItems = lst.size();
 		
 		String [] theArgs = new String [nItems];
@@ -1111,17 +1306,16 @@ public class DoCommand {
 			}
 		
 		return(sRet);
 		}
 	
 	public String StatProcess(String string)
 		{
 		String sRet = "";
-//		ActivityManager aMgr = (ActivityManager) SUTAgentAndroid.me.getSystemService(Activity.ACTIVITY_SERVICE);
 		ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
 		int	[] nPids = new int [1];
 		
 		nPids[0] = Integer.parseInt(string);
 		
 		android.os.Debug.MemoryInfo[] mi = aMgr.getProcessMemoryInfo(nPids);
 		
 		sRet  = "Dalvik Private Dirty pages         " + mi[0].dalvikPrivateDirty     + " kb\n";
@@ -1155,17 +1349,16 @@ public class DoCommand {
 			}
 		
 		return(sRet);
 		}
 	
 	public String GetAppRoot(String AppName)
 		{
 		String sRet = "";
-//		Context ctx = SUTAgentAndroid.me.getApplicationContext();
 		Context ctx = contextWrapper.getApplicationContext();
 		
 		if (ctx != null)
 			{
 			try {
 				Context appCtx = ctx.createPackageContext(AppName, 0);
 				ContextWrapper appCtxW = new ContextWrapper(appCtx);
 				sRet = appCtxW.getPackageResourcePath();
@@ -1229,18 +1422,18 @@ public class DoCommand {
 		byte[] 			buffer 		= new byte [4096];
 		int				nRead 		= 0;
 		long 			lTotalRead 	= 0;
 		MessageDigest	digest 		= null;
 		
 		try {
 			digest = java.security.MessageDigest.getInstance("MD5");
 			}
-		catch (NoSuchAlgorithmException e) {
-			// TODO Auto-generated catch block
+		catch (NoSuchAlgorithmException e)
+			{
 			e.printStackTrace();
 			}
 		
 		try {
 			FileInputStream srcFile  = new FileInputStream(sTmpFileName);
 			while((nRead = srcFile.read(buffer)) != -1)
 				{
 				digest.update(buffer, 0, nRead);
@@ -1415,22 +1608,20 @@ public class DoCommand {
 
 			if (lTotalWritten == lTotalRead)
 				sRet = sTmpSrcFileName + " copied to " + sTmpDstFileName;
 			else
 				sRet = sErrorPrefix + "Failed to copy " + sTmpSrcFileName + " [length = " + lTotalWritten + "] to " + sTmpDstFileName + " [length = " + lTotalRead + "]";
 			}
 		catch (FileNotFoundException e)
 			{
-			// TODO Auto-generated catch block
 			e.printStackTrace();
 			} 
 		catch (IOException e)
 			{
-			// TODO Auto-generated catch block
 			e.printStackTrace();
 			}
 
 		return (sRet);
 		}
 	
 	public String IsDirWritable(String sDir)
 		{
@@ -1529,22 +1720,16 @@ public class DoCommand {
 							strRet = "\r" + lTotalRead + " of " + lFtpSize + " bytes received " + ((lTotalRead * 100) / lFtpSize) + "% completed";
 							out.write(strRet.getBytes());
 							out.flush();
 							}
 						ftpIn.close();
 						@SuppressWarnings("unused")
 						boolean bRet = ftp.completePendingCommand();
 						outStream.flush();
-				    	/*				    	
-				    	if (ftp.retrieveFile("pub/mozilla.org/firefox/releases/3.6b4/wince-arm/en-US/firefox-3.6b4.cab", outStream))
-				    		{
-				    		outStream.flush();
-				    		}
-				    	 */				    		
 			    		outStream.close();
 						strRet = ftp.getReplyString();
 						reply = ftp.getReplyCode();
 				    	}
 					strRet = ftp.getReplyString();
 					reply = ftp.getReplyCode();
 				    ftp.logout();
 				    ftp.disconnect();
@@ -1559,26 +1744,24 @@ public class DoCommand {
 		    else
 		    	{
 		        ftp.disconnect();
 		        System.err.println("FTP server refused connection.");
 		        }
 			}
 		catch (SocketException e)
 			{
-			// TODO Auto-generated catch block
 			sRet = e.getMessage();
 			strRet = ftp.getReplyString();
 			reply = ftp.getReplyCode();
 			sRet += "\n" + strRet;
 			e.printStackTrace();
 			}
 		catch (IOException e)
 			{
-			// TODO Auto-generated catch block
 			sRet = e.getMessage();
 			strRet = ftp.getReplyString();
 			reply = ftp.getReplyCode();
 			sRet += "\n" + strRet;
 			e.printStackTrace();
 			}
 		return (sRet);
 	}
@@ -1647,26 +1830,24 @@ public class DoCommand {
 		{
 		String [] theArgs = new String [3];
 		
 		theArgs[0] = "su";
 		theArgs[1] = "-c";
 		theArgs[2] = "kill";
 
 		String sRet = sErrorPrefix + "Unable to kill " + sProcName + "\n";
-//		ActivityManager aMgr = (ActivityManager) SUTAgentAndroid.me.getSystemService(Activity.ACTIVITY_SERVICE);
 		ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
 		List <ActivityManager.RunningAppProcessInfo> lProcesses = aMgr.getRunningAppProcesses();
 		int lcv = 0;
 		String strProcName = "";
 		int	nPID = 0;
 		
 		for (lcv = 0; lcv < lProcesses.size(); lcv++)
 			{
-//			if (lProcesses.get(lcv).processName.contentEquals(sProcName))
 			if (lProcesses.get(lcv).processName.contains(sProcName))
 				{
 				strProcName = lProcesses.get(lcv).processName;
 				nPID = lProcesses.get(lcv).pid;
 				sRet = sErrorPrefix + "Failed to kill " + nPID + " " + strProcName + "\n";
 
 				theArgs[2] += " " + nPID;
 				
@@ -1679,85 +1860,74 @@ public class DoCommand {
 					}
 				catch (IOException e) 
 					{
 					sRet = e.getMessage();
 					e.printStackTrace();
 					} 
 				catch (InterruptedException e)
 					{
-					// TODO Auto-generated catch block
 					e.printStackTrace();
 					}
 
-//				SUTAgentAndroid.me.finishActivity(SUTAgentAndroid.START_PRG);
-
 				// Give the messages a chance to be processed
 				try {
 					Thread.sleep(2000);
 					}
 				catch (InterruptedException e)
 					{
 					e.printStackTrace();
 					}
-//				aMgr.restartPackage(strProcName);
 				break;
 				}
 			}
 		
 		if (nPID > 0)
 			{
 			sRet = "Successfully killed " + nPID + " " + strProcName + "\n";
 			lProcesses = aMgr.getRunningAppProcesses();
 			for (lcv = 0; lcv < lProcesses.size(); lcv++)
 				{
-//				if (lProcesses.get(lcv).processName.contentEquals(sProcName))
 				if (lProcesses.get(lcv).processName.contains(sProcName))
 					{
 					sRet = sErrorPrefix + "Unable to kill " + nPID + " " + strProcName + "\n";
 					break;
 					}
 				}
 			}
 		
 		return (sRet);
 		}
 
 	public boolean IsProcessDead(String sProcName)
 		{
 		boolean bRet = false;
-//		ActivityManager aMgr = (ActivityManager) SUTAgentAndroid.me.getSystemService(Activity.ACTIVITY_SERVICE);
 		ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
 		List <ActivityManager.ProcessErrorStateInfo> lProcesses = aMgr.getProcessesInErrorState();
 		int lcv = 0;
-//		String strProcName = "";
-//		int	nPID = 0;
 		
 		if (lProcesses != null)
 			{
 			for (lcv = 0; lcv < lProcesses.size(); lcv++)
 				{
 				if (lProcesses.get(lcv).processName.contentEquals(sProcName) && 
 					lProcesses.get(lcv).condition != ActivityManager.ProcessErrorStateInfo.NO_ERROR)
 					{
-//					strProcName = lProcesses.get(lcv).processName;
-//					nPID = lProcesses.get(lcv).pid;
 					bRet = true;
 					break;
 					}
 				}
 			}
 	
 		return (bRet);
 		}
 
 	public String GetProcessInfo()
 		{
 		String sRet = "";
-//		ActivityManager aMgr = (ActivityManager) SUTAgentAndroid.me.getSystemService(Activity.ACTIVITY_SERVICE);
 		ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
 		List <ActivityManager.RunningAppProcessInfo> lProcesses = aMgr.getRunningAppProcesses();
 		int	nProcs = lProcesses.size();
 		int lcv = 0;
 		String strProcName = "";
 		int	nPID = 0;
 		int nUser = 0;
 		
@@ -1812,22 +1982,20 @@ public class DoCommand {
 	public String GetMemoryInfo()
 		{
 		String sRet = "PA:" + GetMemoryConfig();
 		return (sRet);
 		}
 
 	public long GetMemoryConfig()
 		{
-//		ActivityManager aMgr = (ActivityManager) SUTAgentAndroid.me.getSystemService(Activity.ACTIVITY_SERVICE);
 		ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
 		ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo();
 		aMgr.getMemoryInfo(outInfo);
 		long lMem = outInfo.availMem;
-//		float fMem = (float) lMem / (float)(1024.0 * 1024.0);
 
 		return (lMem);
 		}
 	
 	public String RegisterTheDevice(String sSrvr, String sPort, String sData)
 		{
 		String sRet = "";
 		String line = "";
@@ -1861,22 +2029,20 @@ public class DoCommand {
 				socket.close();
 				}
 			catch(NumberFormatException e)
 				{
 				e.printStackTrace();
 				} 
 			catch (UnknownHostException e)
 				{
-				// TODO Auto-generated catch block
 				e.printStackTrace();
 				}
 			catch (IOException e)
 				{
-				// TODO Auto-generated catch block
 				sRet += "reg exception thrown";
 				e.printStackTrace();
 				}
 			}
 		return(sRet);
 		}
 	
 	public String GetInternetData(String sHost, String sPort, String sURL)
@@ -1906,79 +2072,118 @@ public class DoCommand {
 			    byte [] data = new byte [2048];
 			    int nRead = content.read(data);
 			    sRet = new String(data, 0, nRead);
 			    content.close(); // this will also close the connection
 				}
 			}
 		catch (IllegalArgumentException e)
 			{
-			// TODO Auto-generated catch block
 			sRet = e.getLocalizedMessage();
 			e.printStackTrace();
 			}
 		catch (ClientProtocolException e)
 			{
-			// TODO Auto-generated catch block
 			sRet = e.getLocalizedMessage();
 			e.printStackTrace();
 			}
 		catch (IOException e)
 			{
-			// TODO Auto-generated catch block
 			sRet = e.getLocalizedMessage();
 			e.printStackTrace();
 			}
 		
 		return(sRet);
 		}
+	
+	public String GetTimeZone()
+		{
+		String	sRet = "";
+		TimeZone tz;
+		
+		tz = TimeZone.getDefault();
+		Date now = new Date();
+		sRet = tz.getDisplayName(tz.inDaylightTime(now), TimeZone.LONG);
+		
+		return(sRet);
+		}
+	
+	public String SetTimeZone(String sTimeZone)
+		{
+		String			sRet = "Unable to set timezone to " + sTimeZone;
+		TimeZone 		tz = null;
+		AlarmManager 	amgr = null;
+		
+		if ((sTimeZone.length() > 0) && (sTimeZone.startsWith("GMT")))
+			{
+			amgr = (AlarmManager) contextWrapper.getSystemService(Context.ALARM_SERVICE);
+			if (amgr != null)
+				amgr.setTimeZone(sTimeZone);
+			}
+		else
+			{
+			String [] zoneNames = TimeZone.getAvailableIDs();
+			int nNumMatches = zoneNames.length;
+			int	lcv = 0;
+			
+			for (lcv = 0; lcv < nNumMatches; lcv++)
+				{
+				if (zoneNames[lcv].equalsIgnoreCase(sTimeZone))
+					break;
+				}
+
+			if (lcv < nNumMatches)
+				{
+				amgr = (AlarmManager) contextWrapper.getSystemService(Context.ALARM_SERVICE);
+				if (amgr != null)
+					amgr.setTimeZone(zoneNames[lcv]);
+				}
+			}
+		
+		if (amgr != null)
+			{
+			tz = TimeZone.getDefault();
+			Date now = new Date();
+			sRet = tz.getDisplayName(tz.inDaylightTime(now), TimeZone.LONG);
+			}
+		
+		return(sRet);
+		}
 
 	public String GetSystemTime()
 		{
 		String sRet = "";
 		Calendar cal = Calendar.getInstance();
 		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss:SSS");
 		sRet = sdf.format(cal.getTime());
 	
 		return (sRet);
 		}
 	
 	public String SetSystemTime(String sDate, String sTime, OutputStream out)
 		{
-//		Debug.waitForDebugger();
 		String sRet = "";
 		
-//		Intent	prgIntent = new Intent(android.provider.Settings.ACTION_DATE_SETTINGS);
-//		prgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-//		contextWrapper.startActivity(prgIntent);
-		
-		// 2010/09/22 
-		// 15:41:00
-		// 0123456789012345678
-		
 		if (((sDate != null) && (sTime != null)) && 
 			(sDate.contains("/") || sDate.contains(".")) &&
 			(sTime.contains(":")))
 			{
 			int year = Integer.parseInt(sDate.substring(0,4));
 			int month = Integer.parseInt(sDate.substring(5,7));
 			int day = Integer.parseInt(sDate.substring(8,10));
 			
 			int hour = Integer.parseInt(sTime.substring(0,2));
 			int mins = Integer.parseInt(sTime.substring(3,5));
 			int secs = Integer.parseInt(sTime.substring(6,8));
 
-			Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+			Calendar cal = new GregorianCalendar(TimeZone.getDefault());
 			cal.set(year, month - 1, day, hour, mins, secs);
 			long lMillisecs = cal.getTime().getTime();
 			
-//			boolean bRet = SystemClock.setCurrentTimeMillis(lMillisecs);
 			String sM = Long.toString(lMillisecs);
-//			long lm = 1285175618316L;
-			String sTest = cal.getTime().toGMTString();
 			String sMillis = sM.substring(0, sM.length() - 3) + "." + sM.substring(sM.length() - 3);
 			String [] theArgs = new String [3];
 		
 			theArgs[0] = "su";
 			theArgs[1] = "-c";
 			theArgs[2] = "date -u " + sMillis;
 		
 			try 
@@ -1991,17 +2196,16 @@ public class DoCommand {
 				}
 			catch (IOException e) 
 				{
 				sRet = e.getMessage();
 				e.printStackTrace();
 				} 
 			catch (InterruptedException e)
 				{
-				// TODO Auto-generated catch block
 				e.printStackTrace();
 				}
 			}
 		else
 			{
 			sRet = "Invalid argument(s)";
 			}
 
@@ -2040,34 +2244,16 @@ public class DoCommand {
 			lHold %= 60L * 1000L;
 			nSecs = (int)(lHold / 1000L);
 			nMilliseconds = (int)(lHold % 1000);
 			sRet = "" + nDays + " days " + nHours + " hours " + nMinutes + " minutes " + nSecs + " seconds " + nMilliseconds + " ms";
 			}
 
 		return (sRet);
 		}
-/*	
-	private boolean IsProcRunning(Process pProc)
-		{
-		boolean bRet = false;
-		int nExitCode = 0;
-		
-		try
-			{
-			nExitCode = pProc.exitValue();
-			}
-		catch (IllegalThreadStateException z)
-			{	
-			bRet = true;
-			}
-
-		return(bRet);
-		}
-*/
 
 	public String NewKillProc(String sProcId, OutputStream out)
 		{
 		String sRet = "";
 		String [] theArgs = new String [3];
 		
 		theArgs[0] = "su";
 		theArgs[1] = "-c";
@@ -2102,43 +2288,38 @@ public class DoCommand {
 		theArgs[0] = "ping";
 		theArgs[1] = "-c";
 		theArgs[2] = "3";
 		theArgs[3] = sIPAddr;
 		
 		try 
 			{
 			pProc = Runtime.getRuntime().exec(theArgs);
-//			sutErr = pProc.getErrorStream(); // Stderr
-//			sutIn = pProc.getOutputStream(); // Stdin
-//			sutOut = pProc.getInputStream(); // Stdout
 			RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
 			outThrd.start();
 			outThrd.join(5000);
 			if (out == null)
 				sRet = outThrd.strOutput;
 			}
 		catch (IOException e) 
 			{
 			sRet = e.getMessage();
 			e.printStackTrace();
 			} 
 		catch (InterruptedException e)
 			{
-			// TODO Auto-generated catch block
 			e.printStackTrace();
 			}
 	
 		return (sRet);
 		}
 	
 	public String GetTmpDir()
 	{
 		String 	sRet = "";
-//		Context ctx = SUTAgentAndroid.me.getApplicationContext();
 		Context ctx = contextWrapper.getApplicationContext();
         File dir = ctx.getFilesDir();
         ctx = null;
         try {
 			sRet = dir.getCanonicalPath();
 			} 
         catch (IOException e)
         	{
@@ -2240,17 +2421,16 @@ public class DoCommand {
 			}
 		catch (IOException e) 
 			{
 			sRet = e.getMessage();
 			e.printStackTrace();
 			} 
 		catch (InterruptedException e)
 			{
-			// TODO Auto-generated catch block
 			e.printStackTrace();
 			}
 
 		return (sRet);
 		}
 	
 	public String UnInstallApp(String sApp, OutputStream out)
 		{
@@ -2264,17 +2444,16 @@ public class DoCommand {
 		try 
 			{
 			pProc = Runtime.getRuntime().exec(theArgs);
 		
 			RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
 			outThrd.start();
 			outThrd.join(60000);
 			int nRet = pProc.exitValue();
-//			boolean bRet = outThrd.isAlive();
 			sRet = "\nuninst complete [" + nRet + "]";
 			}
 		catch (IOException e) 
 			{
 			sRet = e.getMessage();
 			e.printStackTrace();
 			} 
 		catch (InterruptedException e)
@@ -2398,17 +2577,16 @@ public class DoCommand {
 
 		return (sRet);
 		}
 
 	public String StartUpdateOMatic(String sPkgName, String sPkgFileName)
 		{
 		String sRet = "";
 	
-//		Context ctx = SUTAgentAndroid.me.getApplicationContext();
 		Context ctx = contextWrapper.getApplicationContext();
 		PackageManager pm = ctx.getPackageManager();
 
 		Intent prgIntent = new Intent();
 		prgIntent.setPackage("com.mozilla.UpdateOMatic");
 		prgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
 		try {
@@ -2430,40 +2608,34 @@ public class DoCommand {
 			}
 		
 		prgIntent.putExtra("pkgName", sPkgName);
 		prgIntent.putExtra("pkgFileName", sPkgFileName);
 
 		try 
 			{
 			contextWrapper.startActivity(prgIntent);
-//			Thread.sleep(5000);
 			sRet = "exit";
 			}
 		catch(ActivityNotFoundException anf)
 			{
 			anf.printStackTrace();
 			} 
-//		catch (InterruptedException e)
-//			{
-//			e.printStackTrace();
-//			}
 	
 		ctx = null;
 		return (sRet);
 		}
 
 	public String StartJavaPrg(String [] sArgs)
 		{
 		String sRet = "";
 		String sArgList = "";
 		String sUrl = "";
 		String sRedirFileName = "";
 		
-//		Context ctx = SUTAgentAndroid.me.getApplicationContext();
 		Context ctx = contextWrapper.getApplicationContext();
 		PackageManager pm = ctx.getPackageManager();
 
 		Intent prgIntent = new Intent();
 		prgIntent.setPackage(sArgs[0]);
 		prgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
 		try {
@@ -2481,17 +2653,17 @@ public class DoCommand {
 			}
 		catch (NameNotFoundException e)
 			{
 			e.printStackTrace();
 			}
 		
 		if (sArgs.length > 1)
 			{
-			if (sArgs[0].contains("android.browser"))
+//			if (sArgs[0].contains("android.browser"))
 				prgIntent.setAction(Intent.ACTION_VIEW);
 			
 			if (sArgs[0].contains("fennec"))
 				{
 				sArgList = "";
 				sUrl = "";
 				
 				for (int lcv = 1; lcv < sArgs.length; lcv++)
@@ -2525,20 +2697,17 @@ public class DoCommand {
 				prgIntent.setData(Uri.parse(sArgList.trim()));
 				}
 			}
 		else
 			prgIntent.setData(Uri.parse("about:blank"));
 
 		try 
 			{
-//			ctx.startActivity(prgIntent);
 			contextWrapper.startActivity(prgIntent);
-//			SUTAgentAndroid.me.startActivity(prgIntent);
-//			SUTAgentAndroid.me.startActivityForResult(prgIntent, SUTAgentAndroid.START_PRG);
 			}
 		catch(ActivityNotFoundException anf)
 			{
 			anf.printStackTrace();
 			}
 		
 		ctx = null;
 		return (sRet);
@@ -2546,31 +2715,169 @@ public class DoCommand {
 
 	public String StartPrg(String [] progArray, OutputStream out)
 		{
 		String sRet = "";
 		
 		try 
 			{
 			pProc = Runtime.getRuntime().exec(progArray);
-			sutErr = pProc.getErrorStream(); // Stderr
-			sutIn = pProc.getOutputStream(); // Stdin
-			sutOut = pProc.getInputStream(); // Stdout
 			RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
 			outThrd.start();
 			outThrd.join(10000);
+			int nRetCode = pProc.exitValue();
+			sRet = "return code [" + nRetCode + "]";
 			}
 		catch (IOException e) 
 			{
 			e.printStackTrace();
 			}
 		catch (InterruptedException e)
 			{
-			// TODO Auto-generated catch block
 			e.printStackTrace();
+			sRet = "Timed out!";
+			}
+
+		return (sRet);
+		}
+/*	
+	@SuppressWarnings("unchecked")
+	public static void set(String key, String value) throws Exception
+		{
+	    Class[] classes = Collections.class.getDeclaredClasses();
+	    Map env = System.getenv();
+	    for(Class cl : classes)
+	    	{
+	        if("java.util.Collections$UnmodifiableMap".equals(cl.getName()))
+	        	{
+	            Field field = cl.getDeclaredField("m");
+	            field.setAccessible(true);
+	            Object obj = field.get(env);
+	            Map<String, String> map = (Map<String, String>) obj;
+	            map.put(key, value);
+	        	}
+	    	}
+		}
+
+*/	
+	public String StartPrg2(String [] progArray, OutputStream out)
+		{
+		String sRet = "";
+		
+		int	nArraySize = 0;
+		int	nArgs = progArray.length - 1; // 1st arg is the environment string
+		int	lcv	= 0;
+		int	temp = 0;
+
+		String sEnvString = progArray[0];
+
+		// Set up command line args stripping off the environment string
+		String [] theArgs = new String [nArgs];
+		for (lcv = 0; lcv < nArgs; lcv++)
+			{
+			theArgs[lcv] = progArray[lcv + 1];
+			}
+		
+		try 
+			{
+			String [] envStrings = sEnvString.split(",");
+			Map<String, String> newEnv = new HashMap<String, String>();
+			
+			for (lcv = 0; lcv < envStrings.length; lcv++)
+				{
+				temp = envStrings[lcv].indexOf("=");
+				if (temp > 0)
+					{
+					newEnv.put(	envStrings[lcv].substring(0, temp), 
+								envStrings[lcv].substring(temp + 1, envStrings[lcv].length()));
+					}
+				}
+			
+			Map<String, String> sysEnv = System.getenv();
+			
+			nArraySize = sysEnv.size();
+			
+			for (Map.Entry<String, String> entry : newEnv.entrySet())
+				{
+				if (!sysEnv.containsKey(entry.getKey()))
+					{
+					nArraySize++;
+					}
+				}
+			
+			String[] envArray = new String[nArraySize];
+				
+			int		i = 0;
+			int		offset;
+			String	sKey = "";
+			String 	sValue = "";
+			
+	        for (Map.Entry<String, String> entry : sysEnv.entrySet())
+	        	{
+	        	sKey = entry.getKey();
+	        	if (newEnv.containsKey(sKey))
+	        		{
+	        		sValue = newEnv.get(sKey);
+	        		if ((offset = sValue.indexOf("$" + sKey)) != -1)
+	        			{
+	        			envArray[i++] = sKey + 
+	        							"=" + 
+	        							sValue.substring(0, offset) + 
+	        							entry.getValue() + 
+	        							sValue.substring(offset + sKey.length() + 1);
+	        			}
+	        		else
+	        			envArray[i++] = sKey + "=" + sValue;
+	        		newEnv.remove(sKey);
+	        		}
+	        	else
+	        		envArray[i++] = entry.getKey() + "=" + entry.getValue();
+	        	}
+	        
+			for (Map.Entry<String, String> entry : newEnv.entrySet())
+				{
+        		envArray[i++] = entry.getKey() + "=" + entry.getValue();
+				}
+	        
+			pProc = Runtime.getRuntime().exec(theArgs, envArray);
+
+			RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
+			outThrd.start();
+			outThrd.join(10000);
+			int nRetCode = pProc.exitValue();
+			sRet = "return code [" + nRetCode + "]";
+			}
+		catch(UnsupportedOperationException e)
+			{
+			if (e != null)
+				e.printStackTrace();
+			}
+		catch(ClassCastException e)
+			{
+			if (e != null)
+				e.printStackTrace();
+			}
+		catch(IllegalArgumentException e)
+			{
+			if (e != null)
+				e.printStackTrace();
+			}
+		catch(NullPointerException e)
+			{
+			if (e != null)
+				e.printStackTrace();
+			}
+		catch (IOException e) 
+			{
+			e.printStackTrace();
+			}
+		catch (InterruptedException e)
+			{
+			e.printStackTrace();
+			sRet = "Timed out!";
 			}
 
 		return (sRet);
 		}
 /*	
 	public String InstallApplication()
 		{
 		String sRet = "";
@@ -2598,60 +2905,63 @@ public class DoCommand {
 	
 		SUTAgentAndroid.me.startActivity(unInstIntent);
 
 		return(sRet);
 		}
 */
 	private String PrintUsage()
 		{
-		String sRet = "run [executable] [args]  - start program no wait\n" +
-			"exec [executable] [args] - start program wait\n" +
-			"fire [executable] [args] - start program no wait\n" +
-			"arun [executable] [args] - start program no wait\n" +
-			"kill [program name]      - kill program no path\n" +
-			"killall                  - kill all processes started\n" +
-			"ps                       - list of running processes\n" +
-			"info                     - list of device info\n" +
-			"        [os]             - os version for device\n" +
-			"        [id]             - unique identifier for device\n" +
-			"        [uptime]         - uptime for device\n" +
-			"        [systime]        - current system time on device\n" +
-			"        [screen]         - width, height and bits per pixel for device\n" +
-			"        [memory]         - physical, free, available, storage memory for device\n" +
-			"        [processes]      - list of running processes see 'ps'\n" +
-			"deadman timeout          - set the duration for the deadman timer\n" +
-			"alrt [on/off]            - start or stop sysalert behavior\n" +
-			"disk [arg]               - prints disk space info\n" +
-			"cp file1 file2           - copy file1 to file2 on device\n" +
-			"time file                - timestamp for file on device\n" +
-			"hash file                - generate hash for file on device\n" +
-			"cd directory             - change cwd on device\n" +
-			"cat file                 - cat file on device\n" +
-			"cwd                      - display cwd on device\n" +
-			"mv file1 file2           - move file1 to file2 on device\n" +
-			"push filename            - push file to device\n" +
-			"rm file                  - delete file on device\n" +
-			"rmdr directory           - delete directory on device even if not empty\n" +
-			"mkdr directory           - create directory on device\n" +
-			"dirw directory           - tests whether the directory is writable on the device\n" +
-			"stat processid           - stat process on device\n" +
-			"dead processid           - print whether the process is alive or hung on device\n" +
-			"mems                     - dump memory stats on device\n" +
-			"ls                       - print directory on device\n" +
-			"tmpd                     - print temp directory on device\n" +
-			"ping [hostname/ipaddr]   - ping a network device\n" +
-			"unzp zipfile destdir     - unzip the zipfile into the destination dir\n" +
-			"zip zipfile src          - zip the source file/dir into zipfile\n" +
-			"rebt                     - reboot device\n" +
-			"inst /path/filename.apk  - install the referenced apk file\n" +
-			"uninst packagename       - uninstall the referenced package\n" +
-			"updt pkgname pkgfile     - unpdate the referenced package\n" +
-			"clok                     - the current device time expressed as the number of millisecs since epoch\n" +
-			"settime date time        - sets the device date and time (YYYY/MM/DD HH:MM:SS)\n" +
-			"rebt                     - reboot device\n" +
-			"quit                     - disconnect SUTAgent\n" +
-			"exit                     - close SUTAgent\n" +
-			"ver                      - SUTAgent version\n" +
-			"help                     - you're reading it";
+		String sRet = 
+			"run [executable] [args]      - start program no wait\n" +
+			"exec [executable] [args]     - start program wait\n" +
+			"fire [executable] [args]     - start program no wait\n" +
+			"envrun [env pairs] [cmdline] - start program no wait\n" +
+			"kill [program name]          - kill program no path\n" +
+			"killall                      - kill all processes started\n" +
+			"ps                           - list of running processes\n" +
+			"info                         - list of device info\n" +
+			"        [os]                 - os version for device\n" +
+			"        [id]                 - unique identifier for device\n" +
+			"        [uptime]             - uptime for device\n" +
+			"        [systime]            - current system time on device\n" +
+			"        [screen]             - width, height and bits per pixel for device\n" +
+			"        [memory]             - physical, free, available, storage memory for device\n" +
+			"        [processes]          - list of running processes see 'ps'\n" +
+			"deadman timeout              - set the duration for the deadman timer\n" +
+			"alrt [on/off]                - start or stop sysalert behavior\n" +
+			"disk [arg]                   - prints disk space info\n" +
+			"cp file1 file2               - copy file1 to file2 on device\n" +
+			"time file                    - timestamp for file on device\n" +
+			"hash file                    - generate hash for file on device\n" +
+			"cd directory                 - change cwd on device\n" +
+			"cat file                     - cat file on device\n" +
+			"cwd                          - display cwd on device\n" +
+			"mv file1 file2               - move file1 to file2 on device\n" +
+			"push filename                - push file to device\n" +
+			"rm file                      - delete file on device\n" +
+			"rmdr directory               - delete directory on device even if not empty\n" +
+			"mkdr directory               - create directory on device\n" +
+			"dirw directory               - tests whether the directory is writable on the device\n" +
+			"stat processid               - stat process on device\n" +
+			"dead processid               - print whether the process is alive or hung on device\n" +
+			"mems                         - dump memory stats on device\n" +
+			"ls                           - print directory on device\n" +
+			"tmpd                         - print temp directory on device\n" +
+			"ping [hostname/ipaddr]       - ping a network device\n" +
+			"unzp zipfile destdir         - unzip the zipfile into the destination dir\n" +
+			"zip zipfile src              - zip the source file/dir into zipfile\n" +
+			"rebt                         - reboot device\n" +
+			"inst /path/filename.apk      - install the referenced apk file\n" +
+			"uninst packagename           - uninstall the referenced package\n" +
+			"updt pkgname pkgfile         - unpdate the referenced package\n" +
+			"clok                         - the current device time expressed as the number of millisecs since epoch\n" +
+			"settime date time            - sets the device date and time (YYYY/MM/DD HH:MM:SS)\n" +
+			"tzset timezone               - sets the device timezone format is GMTxhh:mm x = +/- or a recognized Olsen string\n" +
+			"tzget                        - returns the current timezone set on the device\n" +
+			"rebt                         - reboot device\n" +
+			"quit                         - disconnect SUTAgent\n" +
+			"exit                         - close SUTAgent\n" +
+			"ver                          - SUTAgent version\n" +
+			"help                         - you're reading it";
 		return (sRet);
 		}
 }
--- a/build/mobile/sutagent/android/SUTAgentAndroid.java
+++ b/build/mobile/sutagent/android/SUTAgentAndroid.java
@@ -386,17 +386,17 @@ public class SUTAgentAndroid extends Act
 					else if (nChargeLevel > 80)
 						sb.append("HIGH");
 					}
 				
 				if (BatteryManager.BATTERY_HEALTH_OVERHEAT == health)
 					{
 					sb.append("Overheated ");
 					sb.append((((float)(nBatteryTemp))/10));
-					sb.append("(C)");
+					sb.append("(C)");
 					}
 				else
 					{
 					switch(status)
 						{
 						case BatteryManager.BATTERY_STATUS_UNKNOWN:
 							// old emulator; maybe also when plugged in with no battery
 							if (present == true)
--- a/client.mk
+++ b/client.mk
@@ -64,18 +64,17 @@
 #   MOZ_PREFLIGHT      }   MOZ_BUILD_PROJECTS, before each project, after
 #   MOZ_POSTFLIGHT     }   each project, and after all projects; these
 #   MOZ_POSTFLIGHT_ALL }   variables contain space-separated lists
 #   MOZ_UNIFY_BDATE      - Set to use the same bdate for each project in
 #                          MOZ_BUILD_PROJECTS
 #
 #######################################################################
 # Defines
-#
-CVS = cvs
+
 comma := ,
 
 CWD := $(CURDIR)
 ifneq (1,$(words $(CWD)))
 $(error The mozilla directory cannot be located in a path with spaces.)
 endif
 
 ifeq "$(CWD)" "/"
@@ -102,17 +101,16 @@ endif
 MKDIR := mkdir
 SH := /bin/sh
 ifndef MAKE
 MAKE := gmake
 endif
 PERL ?= perl
 PYTHON ?= python
 
-RUN_AUTOCONF_LOCALLY = 1
 CONFIG_GUESS_SCRIPT := $(wildcard $(TOPSRCDIR)/build/autoconf/config.guess)
 ifdef CONFIG_GUESS_SCRIPT
   CONFIG_GUESS = $(shell $(CONFIG_GUESS_SCRIPT))
 endif
 
 
 ####################################
 # Sanity checks
@@ -165,17 +163,16 @@ MOZ_MAKE = $(MAKE) $(MOZ_MAKE_FLAGS) -C 
 endif # MOZ_BUILD_PROJECTS
 
 # 'configure' scripts generated by autoconf.
 CONFIGURES := $(TOPSRCDIR)/configure
 CONFIGURES += $(TOPSRCDIR)/js/src/configure
 
 #######################################################################
 # Rules
-# 
 
 # The default rule is build
 build::
 
 # Print out any options loaded from mozconfig.
 all build clean depend distclean export libs install realclean::
 	@if test -f .mozconfig.out; then \
 	  cat .mozconfig.out; \
@@ -267,51 +264,44 @@ else
 # individual project in a multi-project build.
 
 ####################################
 # Configure
 
 CONFIG_STATUS = $(wildcard $(OBJDIR)/config.status)
 CONFIG_CACHE  = $(wildcard $(OBJDIR)/config.cache)
 
-ifdef RUN_AUTOCONF_LOCALLY
 EXTRA_CONFIG_DEPS := \
 	$(TOPSRCDIR)/aclocal.m4 \
 	$(wildcard $(TOPSRCDIR)/build/autoconf/*.m4) \
 	$(TOPSRCDIR)/js/src/aclocal.m4 \
 	$(NULL)
 
 $(CONFIGURES): %: %.in $(EXTRA_CONFIG_DEPS)
 	@echo Generating $@ using autoconf
 	cd $(@D); $(AUTOCONF)
-endif
 
 CONFIG_STATUS_DEPS := \
 	$(wildcard $(CONFIGURES)) \
 	$(TOPSRCDIR)/allmakefiles.sh \
 	$(TOPSRCDIR)/.mozconfig.mk \
 	$(wildcard $(TOPSRCDIR)/nsprpub/configure) \
 	$(wildcard $(TOPSRCDIR)/config/milestone.txt) \
-	$(wildcard $(TOPSRCDIR)/config/chrome-versions.sh) \
-  $(wildcard $(addsuffix confvars.sh,$(wildcard $(TOPSRCDIR)/*/))) \
+	$(wildcard $(addsuffix confvars.sh,$(wildcard $(TOPSRCDIR)/*/))) \
 	$(NULL)
 
 # configure uses the program name to determine @srcdir@. Calling it without
 #   $(TOPSRCDIR) will set @srcdir@ to "."; otherwise, it is set to the full
 #   path of $(TOPSRCDIR).
 ifeq ($(TOPSRCDIR),$(OBJDIR))
   CONFIGURE = ./configure
 else
   CONFIGURE = $(TOPSRCDIR)/configure
 endif
 
-ifdef MOZ_TOOLS
-  CONFIGURE = $(TOPSRCDIR)/configure
-endif
-
 configure-files: $(CONFIGURES)
 
 configure:: configure-files
 ifdef MOZ_BUILD_PROJECTS
 	@if test ! -d $(MOZ_OBJDIR); then $(MKDIR) $(MOZ_OBJDIR); else true; fi
 endif
 	@if test ! -d $(OBJDIR); then $(MKDIR) $(OBJDIR); else true; fi
 	@echo cd $(OBJDIR);
@@ -412,9 +402,9 @@ cleansrcdir:
 echo-variable-%:
 	@echo $($*)
 
 # This makefile doesn't support parallel execution. It does pass
 # MOZ_MAKE_FLAGS to sub-make processes, so they will correctly execute
 # in parallel.
 .NOTPARALLEL:
 
-.PHONY: checkout real_checkout depend build profiledbuild maybe_clobber_profiledbuild export libs alldep install clean realclean distclean cleansrcdir pull_all build_all clobber clobber_all pull_and_build_all everything configure preflight_all preflight postflight postflight_all
+.PHONY: checkout real_checkout depend build profiledbuild maybe_clobber_profiledbuild export libs alldep install clean realclean distclean cleansrcdir pull_all build_all clobber clobber_all pull_and_build_all everything configure preflight_all preflight postflight postflight_all upload sdk
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -691,8 +691,21 @@ MOZ_APP_EXTRA_LIBS = @MOZ_APP_EXTRA_LIBS
 ANDROID_NDK       = @ANDROID_NDK@
 ANDROID_TOOLCHAIN = @ANDROID_TOOLCHAIN@
 ANDROID_PLATFORM  = @ANDROID_PLATFORM@
 ANDROID_SDK       = @ANDROID_SDK@
 ANDROID_TOOLS     = @ANDROID_TOOLS@
 ANDROID_VERSION   = @ANDROID_VERSION@
 
 JS_SHARED_LIBRARY = @JS_SHARED_LIBRARY@
+
+# We only want to do the pymake sanity on Windows, other os's can cope
+ifeq (,$(filter-out WINNT WINCE,$(HOST_OS_ARCH)))
+# Ensure invariants between GNU Make and pymake
+# Checked here since we want the sane error in a file that
+# actually can be found regardless of path-style.
+ifeq (_:,$(.PYMAKE)_$(findstring :,$(srcdir)))
+$(error Windows-style srcdir being used with GNU make. Did you mean to run $(topsrcdir)/build/pymake/make.py instead? [see-also: https://developer.mozilla.org/en/Gmake_vs._Pymake])
+endif
+ifeq (1_a,$(.PYMAKE)_$(firstword a$(subst /, ,$(srcdir))))
+$(error MSYS-style srcdir being used with Pymake. Did you mean to run GNU Make instead? [see-also: https://developer.mozilla.org/en/Gmake_vs._Pymake])
+endif
+endif # Windows
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -166,58 +166,58 @@ define _INSTALL_TESTS
 
 endef # do not remove the blank line!
 
 SOLO_FILE ?= $(error Specify a test filename in SOLO_FILE when using check-interactive or check-one)
 
 libs::
 	$(foreach dir,$(XPCSHELL_TESTS),$(_INSTALL_TESTS))
 	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py \
-          $(testxpcobjdir)/all-test-dirs.list \
-          $(addprefix $(relativesrcdir)/,$(XPCSHELL_TESTS))
+	  $(testxpcobjdir)/all-test-dirs.list \
+	  $(addprefix $(relativesrcdir)/,$(XPCSHELL_TESTS))
 
 testxpcsrcdir = $(topsrcdir)/testing/xpcshell
 
 # Execute all tests in the $(XPCSHELL_TESTS) directories.
 # See also testsuite-targets.mk 'xpcshell-tests' target for global execution.
 xpcshell-tests:
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-          -I$(topsrcdir)/build \
-          $(testxpcsrcdir)/runxpcshelltests.py \
-          --symbols-path=$(DIST)/crashreporter-symbols \
-          $(EXTRA_TEST_ARGS) \
-          $(DIST)/bin/xpcshell \
-          $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+	  -I$(topsrcdir)/build \
+	  $(testxpcsrcdir)/runxpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  $(EXTRA_TEST_ARGS) \
+	  $(DIST)/bin/xpcshell \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
 
 # Execute a single test, specified in $(SOLO_FILE), but don't automatically
 # start the test. Instead, present the xpcshell prompt so the user can
 # attach a debugger and then start the test.
 check-interactive:
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-          -I$(topsrcdir)/build \
-          $(testxpcsrcdir)/runxpcshelltests.py \
-          --symbols-path=$(DIST)/crashreporter-symbols \
-          --test-path=$(SOLO_FILE) \
-          --profile-name=$(MOZ_APP_NAME) \
-          --interactive \
-          $(DIST)/bin/xpcshell \
-          $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+	  -I$(topsrcdir)/build \
+	  $(testxpcsrcdir)/runxpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --test-path=$(SOLO_FILE) \
+	  --profile-name=$(MOZ_APP_NAME) \
+	  --interactive \
+	  $(DIST)/bin/xpcshell \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
 
 # Execute a single test, specified in $(SOLO_FILE)
 check-one:
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-          -I$(topsrcdir)/build \
-          $(testxpcsrcdir)/runxpcshelltests.py \
-          --symbols-path=$(DIST)/crashreporter-symbols \
-          --test-path=$(SOLO_FILE) \
-          --profile-name=$(MOZ_APP_NAME) \
-          --verbose \
-          $(EXTRA_TEST_ARGS) \
-          $(DIST)/bin/xpcshell \
-          $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+	  -I$(topsrcdir)/build \
+	  $(testxpcsrcdir)/runxpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --test-path=$(SOLO_FILE) \
+	  --profile-name=$(MOZ_APP_NAME) \
+	  --verbose \
+	  $(EXTRA_TEST_ARGS) \
+	  $(DIST)/bin/xpcshell \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
 
 endif # XPCSHELL_TESTS
 
 ifdef CPP_UNIT_TESTS
 
 # Compile the tests to $(DIST)/bin.  Make lots of niceties available by default
 # through TestHarness.h, by modifying the list of includes and the libs against
 # which stuff links.
@@ -841,17 +841,17 @@ ifdef LIBRARY_NAME
 ifdef EXPORT_LIBRARY
 ifdef IS_COMPONENT
 ifdef BUILD_STATIC_LIBS
 	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_COMPS) $(STATIC_LIBRARY_NAME)
 ifdef MODULE_NAME
 	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_COMP_NAMES) $(MODULE_NAME)
 endif
 endif # BUILD_STATIC_LIBS
-else  # !IS_COMPONENT
+else # !IS_COMPONENT
 	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
 endif # IS_COMPONENT
 endif # EXPORT_LIBRARY
 endif # LIBRARY_NAME
 
 # Create dependencies on static (and shared EXTRA_DSO_LIBS) libraries
 LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(LIBS))
 HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(HOST_LIBS))
@@ -869,17 +869,17 @@ vpath $(LIB_PREFIX)%.$(LIB_SUFFIX) $(_LI
 ifdef IMPORT_LIB_SUFFIX
 vpath $(LIB_PREFIX)%.$(IMPORT_LIB_SUFFIX) $(_LIBDIRS)
 endif # IMPORT_LIB_SUFFIX
 vpath $(DLL_PREFIX)%$(DLL_SUFFIX) $(_LIBDIRS)
 endif # _LIBDIRS
 
 endif # _LIBNAME_RELATIVE_PATHS
 
-# Dependancies which, if modified, should cause everything to rebuild
+# Dependencies which, if modified, should cause everything to rebuild
 GLOBAL_DEPS += Makefile Makefile.in $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
 
 ##############################################
 ifdef PARALLEL_DIRS
 libs:: $(PARALLEL_DIRS_libs)
 
 $(PARALLEL_DIRS_libs): %_libs: %/Makefile
 	+@$(call SUBMAKE,libs,$*)
@@ -1193,17 +1193,17 @@ else
 ifneq (,$(filter OSF1 BSD_OS FreeBSD NetBSD OpenBSD SunOS Darwin,$(OS_ARCH)))
 CLEANUP1	:= | egrep -v '(________64ELEL_|__.SYMDEF)'
 CLEANUP2	:= rm -f ________64ELEL_ __.SYMDEF
 else
 CLEANUP2	:= true
 endif
 SUB_LOBJS	= $(shell for lib in $(SHARED_LIBRARY_LIBS); do $(AR_LIST) $${lib} $(CLEANUP1); done;)
 endif # EXPAND_FAKELIBS
-endif # SHARED_LIBARY_LIBS
+endif # SHARED_LIBRARY_LIBS
 endif
 ifdef MOZILLA_PROBE_LIBS
 PROBE_LOBJS	= $(shell for lib in $(MOZILLA_PROBE_LIBS); do $(AR_LIST) $${lib} $(CLEANUP1); done;)
 endif
 ifdef DTRACE_PROBE_OBJ
 EXTRA_DEPS += $(DTRACE_PROBE_OBJ)
 endif
 
@@ -1573,17 +1573,17 @@ SPACE := $(EMPTY) $(EMPTY)
 # and class paths to be in the DOS form (i.e. e:/builds/...).  This function
 # does the appropriate conversion on Windows, but is a noop on other systems.
 ifeq (,$(filter-out WINNT WINCE, $(HOST_OS_ARCH)))
 ifdef CYGWIN_WRAPPER
 normalizepath = $(foreach p,$(1),$(shell cygpath -m $(p)))
 else
 # assume MSYS
 #  We use 'pwd -W' to get DOS form of the path.  However, since the given path
-#  could be a file or a nonexistent path, we cannot call 'pwd -W' directly
+#  could be a file or a non-existent path, we cannot call 'pwd -W' directly
 #  on the path.  Instead, we extract the root path (i.e. "c:/"), call 'pwd -W'
 #  on it, then merge with the rest of the path.
 root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\1|")
 non-root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\2|")
 normalizepath = $(foreach p,$(1),$(if $(filter /%,$(1)),$(patsubst %/,%,$(shell cd $(call root-path,$(1)) && pwd -W))/$(call non-root-path,$(1)),$(1)))
 endif
 else
 normalizepath = $(1)
new file mode 100644
--- /dev/null
+++ b/content/base/public/FromParser.h
@@ -0,0 +1,57 @@
+/* ***** 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
+ * Ms2ger <Ms2ger@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * 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_dom_FromParser_h
+#define mozilla_dom_FromParser_h
+
+namespace mozilla {
+namespace dom {
+
+/**
+ * Constants for passing as aFromParser
+ */
+enum FromParser {
+  NOT_FROM_PARSER = 0,
+  FROM_PARSER_NETWORK = 1,
+  FROM_PARSER_DOCUMENT_WRITE = 1 << 1,
+  FROM_PARSER_FRAGMENT = 1 << 2,
+  FROM_PARSER_XSLT = 1 << 3
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_FromParser_h
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -79,18 +79,19 @@ nsLineBreaker.h \
 nsReferencedElement.h \
 nsXMLNameSpaceMap.h \
 nsDOMEventTargetWrapperCache.h \
 $(NULL)
 
 EXPORTS_NAMESPACES = mozilla/dom
 
 EXPORTS_mozilla/dom = \
-Element.h \
-$(NULL)
+		Element.h \
+		FromParser.h \
+		$(NULL)
 
 ifndef DISABLE_XFORMS_HOOKS
 EXPORTS += nsIXFormsUtilityService.h
 endif
 
 SDK_XPIDLSRCS   = \
 		nsISelection.idl  \
 		$(NULL)
--- a/content/base/public/nsContentCreatorFunctions.h
+++ b/content/base/public/nsContentCreatorFunctions.h
@@ -37,41 +37,35 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsContentCreatorFunctions_h__
 #define nsContentCreatorFunctions_h__
 
 #include "nscore.h"
 #include "nsCOMPtr.h"
+#include "mozilla/dom/FromParser.h"
 
 /**
  * Functions to create content, to be used only inside Gecko
  * (mozilla/content and mozilla/layout).
  */
 
 class nsAString;
 class nsIContent;
 class nsIDocument;
 class nsINodeInfo;
 class imgIRequest;
 class nsNodeInfoManager;
 class nsGenericHTMLElement;
 
-/**
- * Constants for passing as aFromParser
- */
-#define NS_NOT_FROM_PARSER 0
-#define NS_FROM_PARSER_NETWORK 1
-#define NS_FROM_PARSER_DOCUMENT_WRITE (1 << 1)
-#define NS_FROM_PARSER_FRAGMENT (1 << 2)
-
 nsresult
 NS_NewElement(nsIContent** aResult, PRInt32 aElementType,
-              already_AddRefed<nsINodeInfo> aNodeInfo, PRUint32 aFromParser);
+              already_AddRefed<nsINodeInfo> aNodeInfo,
+              mozilla::dom::FromParser aFromParser);
 
 nsresult
 NS_NewXMLElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo);
 
 /**
  * aNodeInfoManager must not be null.
  */
 nsresult
@@ -104,23 +98,23 @@ NS_NewXMLStylesheetProcessingInstruction
  * aNodeInfoManager must not be null.
  */
 nsresult
 NS_NewXMLCDATASection(nsIContent** aInstancePtrResult,
                       nsNodeInfoManager *aNodeInfoManager);
 
 nsresult
 NS_NewHTMLElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo,
-                  PRUint32 aFromParser);
+                  mozilla::dom::FromParser aFromParser);
 
 // First argument should be nsHTMLTag, but that adds dependency to parser
 // for a bunch of files.
 already_AddRefed<nsGenericHTMLElement>
 CreateHTMLElement(PRUint32 aNodeType, already_AddRefed<nsINodeInfo> aNodeInfo,
-                  PRUint32 aFromParser);
+                  mozilla::dom::FromParser aFromParser);
 
 #ifdef MOZ_MATHML
 nsresult
 NS_NewMathMLElement(nsIContent** aResult,
                      already_AddRefed<nsINodeInfo> aNodeInfo);
 #endif
 
 #ifdef MOZ_XUL
@@ -129,17 +123,17 @@ NS_NewXULElement(nsIContent** aResult, a
 
 void
 NS_TrustedNewXULElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo);
 #endif
 
 #ifdef MOZ_SVG
 nsresult
 NS_NewSVGElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo,
-                 PRUint32 aFromParser);
+                 mozilla::dom::FromParser aFromParser);
 #endif
 
 nsresult
 NS_NewGenConImageContent(nsIContent** aResult,
                          already_AddRefed<nsINodeInfo> aNodeInfo,
                          imgIRequest* aImageRequest);
 
 nsresult
--- a/content/base/public/nsIScriptElement.h
+++ b/content/base/public/nsIScriptElement.h
@@ -53,25 +53,28 @@
 
 /**
  * Internal interface implemented by script elements
  */
 class nsIScriptElement : public nsIScriptLoaderObserver {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTELEMENT_IID)
 
-  nsIScriptElement(PRUint32 aFromParser)
+  nsIScriptElement(mozilla::dom::FromParser aFromParser)
     : mLineNumber(0),
       mAlreadyStarted(PR_FALSE),
       mMalformed(PR_FALSE),
       mDoneAddingChildren(PR_TRUE),
       mFrozen(PR_FALSE),
       mDefer(PR_FALSE),
       mAsync(PR_FALSE),
-      mParserCreated((PRUint8)aFromParser),
+      mParserCreated(aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT ?
+                     mozilla::dom::NOT_FROM_PARSER : aFromParser),
+                     // Fragment parser-created scripts (if executable)
+                     // behave like script-created scripts.
       mCreatorParser(nsnull)
   {
   }
 
   /**
    * Content type identifying the scripting language. Can be empty, in
    * which case javascript will be assumed.
    */
@@ -115,20 +118,19 @@ public:
    */
   PRBool GetScriptAsync()
   {
     NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
     return mAsync;  
   }
 
   /**
-   * Returns a constant defined in nsContentCreatorFunctions.h. Non-zero
-   * values mean parser-created and zero means not parser-created.
+   * Returns how the element was created.
    */
-  PRUint32 GetParserCreated()
+  mozilla::dom::FromParser GetParserCreated()
   {
     return mParserCreated;
   }
 
   void SetScriptLineNumber(PRUint32 aLineNumber)
   {
     mLineNumber = aLineNumber;
   }
@@ -151,17 +153,17 @@ public:
     mAlreadyStarted = PR_TRUE;
   }
 
   void LoseParserInsertedness()
   {
     mFrozen = PR_FALSE;
     mUri = nsnull;
     mCreatorParser = nsnull;
-    mParserCreated = NS_NOT_FROM_PARSER;
+    mParserCreated = mozilla::dom::NOT_FROM_PARSER;
   }
 
   void SetCreatorParser(nsIParser* aParser)
   {
     mCreatorParser = getter_AddRefs(NS_GetWeakReference(aParser));
   }
 
   /**
@@ -229,17 +231,17 @@ protected:
   /**
    * The effective asyncness.
    */
   PRPackedBool mAsync;
   
   /**
    * Whether this element was parser-created.
    */
-  PRUint8 mParserCreated;
+  mozilla::dom::FromParser mParserCreated;
 
   /**
    * The effective src (or null if no src).
    */
   nsCOMPtr<nsIURI> mUri;
   
   /**
    * The creator parser of a non-defer, non-async parser-inserted script.
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -4366,17 +4366,18 @@ nsDocument::CreateElementNS(const nsAStr
   nsresult rv = nsContentUtils::GetNodeInfoFromQName(aNamespaceURI,
                                                      aQualifiedName,
                                                      mNodeInfoManager,
                                                      getter_AddRefs(nodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIContent> content;
   PRInt32 ns = nodeInfo->NamespaceID();
-  rv = NS_NewElement(getter_AddRefs(content), ns, nodeInfo.forget(), PR_FALSE);
+  rv = NS_NewElement(getter_AddRefs(content), ns, nodeInfo.forget(),
+                     NOT_FROM_PARSER);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return CallQueryInterface(content, aReturn);
 }
 
 NS_IMETHODIMP
 nsDocument::CreateTextNode(const nsAString& aData, nsIDOMText** aReturn)
 {
@@ -6843,17 +6844,18 @@ nsDocument::CreateElem(const nsAString& 
   PRInt32 elementType = aDocumentDefaultType ? mDefaultElementType :
     aNamespaceID;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   mNodeInfoManager->GetNodeInfo(aName, aPrefix, aNamespaceID,
                                 getter_AddRefs(nodeInfo));
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
-  return NS_NewElement(aResult, elementType, nodeInfo.forget(), PR_FALSE);
+  return NS_NewElement(aResult, elementType, nodeInfo.forget(),
+                       NOT_FROM_PARSER);
 }
 
 PRBool
 nsDocument::IsSafeToFlush() const
 {
   nsCOMPtr<nsIPresShell> shell = GetShell();
   if (!shell)
     return PR_TRUE;
--- a/content/base/src/nsInProcessTabChildGlobal.cpp
+++ b/content/base/src/nsInProcessTabChildGlobal.cpp
@@ -310,17 +310,17 @@ nsInProcessTabChildGlobal::InitTabChildG
 
   nsISupports* scopeSupports =
     NS_ISUPPORTS_CAST(nsPIDOMEventTarget*, this);
   JS_SetContextPrivate(cx, scopeSupports);
 
   nsresult rv =
     xpc->InitClassesWithNewWrappedGlobal(cx, scopeSupports,
                                          NS_GET_IID(nsISupports),
-                                         GetPrincipal(), EmptyCString(),
+                                         GetPrincipal(), nsnull,
                                          flags, getter_AddRefs(mGlobal));
   NS_ENSURE_SUCCESS(rv, false);
 
   JSObject* global = nsnull;
   rv = mGlobal->GetJSObject(&global);
   NS_ENSURE_SUCCESS(rv, false);
 
   JS_SetGlobalObject(cx, global);
--- a/content/base/src/nsNameSpaceManager.cpp
+++ b/content/base/src/nsNameSpaceManager.cpp
@@ -52,16 +52,18 @@
 
 #ifdef MOZ_XTF
 #include "nsIServiceManager.h"
 #include "nsIXTFService.h"
 #include "nsContentUtils.h"
 static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
 #endif
 
+using namespace mozilla::dom;
+
 #ifdef MOZ_SVG
 PRBool NS_SVGEnabled();
 #endif
 
 #define kXMLNSNameSpaceURI "http://www.w3.org/2000/xmlns/"
 #define kXMLNameSpaceURI "http://www.w3.org/XML/1998/namespace"
 #define kXHTMLNameSpaceURI "http://www.w3.org/1999/xhtml"
 #define kXLinkNameSpaceURI "http://www.w3.org/1999/xlink"
@@ -222,17 +224,17 @@ NameSpaceManagerImpl::GetNameSpaceID(con
     return nameSpaceID;
   }
 
   return kNameSpaceID_Unknown;
 }
 
 nsresult
 NS_NewElement(nsIContent** aResult, PRInt32 aElementType,
-              already_AddRefed<nsINodeInfo> aNodeInfo, PRUint32 aFromParser)
+              already_AddRefed<nsINodeInfo> aNodeInfo, FromParser aFromParser)
 {
   if (aElementType == kNameSpaceID_XHTML) {
     return NS_NewHTMLElement(aResult, aNodeInfo, aFromParser);
   }
 #ifdef MOZ_XUL
   if (aElementType == kNameSpaceID_XUL) {
     return NS_NewXULElement(aResult, aNodeInfo);
   }
--- a/content/base/src/nsScriptElement.h
+++ b/content/base/src/nsScriptElement.h
@@ -54,17 +54,17 @@ public:
   NS_DECL_NSISCRIPTLOADEROBSERVER
 
   // nsIMutationObserver
   NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
 
-  nsScriptElement(PRUint32 aFromParser)
+  nsScriptElement(mozilla::dom::FromParser aFromParser)
     : nsIScriptElement(aFromParser)
   {
   }
 
 protected:
   // Internal methods
 
   /**
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -152,16 +152,20 @@ nsScriptLoader::nsScriptLoader(nsIDocume
 nsScriptLoader::~nsScriptLoader()
 {
   mObservers.Clear();
 
   if (mParserBlockingRequest) {
     mParserBlockingRequest->FireScriptAvailable(NS_ERROR_ABORT);
   }
 
+  for (PRUint32 i = 0; i < mXSLTRequests.Length(); i++) {
+    mXSLTRequests[i]->FireScriptAvailable(NS_ERROR_ABORT);
+  }
+
   for (PRUint32 i = 0; i < mDeferRequests.Length(); i++) {
     mDeferRequests[i]->FireScriptAvailable(NS_ERROR_ABORT);
   }
 
   for (PRUint32 i = 0; i < mAsyncRequests.Length(); i++) {
     mAsyncRequests[i]->FireScriptAvailable(NS_ERROR_ABORT);
   }
 
@@ -572,50 +576,68 @@ nsScriptLoader::ProcessScriptElement(nsI
     // we now have a request that may or may not be still loading
     if (!async && aElement->GetScriptDeferred()) {
       // We don't want to run this yet.
       // If we come here, the script is a parser-created script and it has
       // the defer attribute but not the async attribute. Since a
       // a parser-inserted script is being run, we came here by the parser
       // running the script, which means the parser is still alive and the
       // parse is ongoing.
-      NS_ASSERTION(mDocument->GetCurrentContentSink(),
-          "Defer script on a document without an active parser; bug 592366.");
+      NS_ASSERTION(mDocument->GetCurrentContentSink() ||
+                   aElement->GetParserCreated() == FROM_PARSER_XSLT,
+          "Non-XSLT Defer script on a document without an active parser; bug 592366.");
       mDeferRequests.AppendElement(request);
       return NS_OK;
     }
     if (async) {
       mAsyncRequests.AppendElement(request);
       if (!request->mLoading) {
         // The script is available already. Run it ASAP when the event
         // loop gets a chance to spin.
         ProcessPendingRequestsAsync();
       }
       return NS_OK;
     }
-    if (!request->mLoading) {
-      // The request has already been loaded. If the script comes from the
-      // network stream, cheat for performance reasons and avoid a trip
-      // through the event loop.
-      if (aElement->GetParserCreated() == NS_FROM_PARSER_NETWORK) {
+
+    if (aElement->GetParserCreated() == FROM_PARSER_XSLT) {
+      // Need to maintain order for XSLT-inserted scripts
+      NS_ASSERTION(!mParserBlockingRequest,
+          "Parser-blocking scripts and XSLT scripts in the same doc!");
+      mXSLTRequests.AppendElement(request);
+      if (!request->mLoading) {
+        // The script is available already. Run it ASAP when the event
+        // loop gets a chance to spin.
+        ProcessPendingRequestsAsync();
+      }
+      return NS_ERROR_HTMLPARSER_BLOCK;
+    }
+    if (!request->mLoading && ReadyToExecuteScripts()) {
+      // The request has already been loaded and there are no pending style
+      // sheets. If the script comes from the network stream, cheat for
+      // performance reasons and avoid a trip through the event loop.
+      if (aElement->GetParserCreated() == FROM_PARSER_NETWORK) {
         return ProcessRequest(request);
       }
       // Otherwise, we've got a document.written script, make a trip through
       // the event loop to hide the preload effects from the scripts on the
       // Web page.
       NS_ASSERTION(!mParserBlockingRequest,
           "There can be only one parser-blocking script at a time");
+      NS_ASSERTION(mXSLTRequests.IsEmpty(),
+          "Parser-blocking scripts and XSLT scripts in the same doc!");
       mParserBlockingRequest = request;
       ProcessPendingRequestsAsync();
       return NS_ERROR_HTMLPARSER_BLOCK;
     }
-    // The script hasn't loaded yet and is parser-inserted and non-async.
-    // It'll be executed when it has loaded.
+    // The script hasn't loaded yet or there's a style sheet blocking it.
+    // The script will be run when it loads or the style sheet loads.
     NS_ASSERTION(!mParserBlockingRequest,
         "There can be only one parser-blocking script at a time");
+    NS_ASSERTION(mXSLTRequests.IsEmpty(),
+        "Parser-blocking scripts and XSLT scripts in the same doc!");
     mParserBlockingRequest = request;
     return NS_ERROR_HTMLPARSER_BLOCK;
   }
 
   // inline script
   nsCOMPtr<nsIContentSecurityPolicy> csp;
   rv = mDocument->NodePrincipal()->GetCsp(getter_AddRefs(csp));
   NS_ENSURE_SUCCESS(rv, rv);
@@ -636,28 +658,38 @@ nsScriptLoader::ProcessScriptElement(nsI
   request = new nsScriptLoadRequest(aElement, version);
   NS_ENSURE_TRUE(request, NS_ERROR_OUT_OF_MEMORY);
   request->mJSVersion = version;
   request->mLoading = PR_FALSE;
   request->mIsInline = PR_TRUE;
   request->mURI = mDocument->GetDocumentURI();
   request->mLineNo = aElement->GetScriptLineNumber();
 
-  if (aElement->GetParserCreated() == NS_NOT_FROM_PARSER) {
+  if (aElement->GetParserCreated() == FROM_PARSER_XSLT &&
+      (!ReadyToExecuteScripts() || !mXSLTRequests.IsEmpty())) {
+    // Need to maintain order for XSLT-inserted scripts
+    NS_ASSERTION(!mParserBlockingRequest,
+        "Parser-blocking scripts and XSLT scripts in the same doc!");
+    mXSLTRequests.AppendElement(request);
+    return NS_ERROR_HTMLPARSER_BLOCK;
+  }
+  if (aElement->GetParserCreated() == NOT_FROM_PARSER) {
     NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
         "A script-inserted script is inserted without an update batch?");
     nsContentUtils::AddScriptRunner(new nsScriptRequestProcessor(this,
                                                                  request));
     return NS_OK;
   }
-  if (aElement->GetParserCreated() == NS_FROM_PARSER_NETWORK &&
+  if (aElement->GetParserCreated() == FROM_PARSER_NETWORK &&
       !ReadyToExecuteScripts()) {
     NS_ASSERTION(!mParserBlockingRequest,
         "There can be only one parser-blocking script at a time");
     mParserBlockingRequest = request;
+    NS_ASSERTION(mXSLTRequests.IsEmpty(),
+        "Parser-blocking scripts and XSLT scripts in the same doc!");
     return NS_ERROR_HTMLPARSER_BLOCK;
   }
   // We now have a document.written inline script or we have an inline script
   // from the network but there is no style sheet that is blocking scripts.
   // Don't check for style sheets blocking scripts in the document.write
   // case to avoid style sheet network activity affecting when
   // document.write returns. It's not really necessary to do this if
   // there's no document.write currently on the call stack. However,
@@ -851,44 +883,52 @@ nsScriptLoader::ProcessPendingRequests()
   if (mParserBlockingRequest &&
       !mParserBlockingRequest->mLoading &&
       ReadyToExecuteScripts()) {
     request.swap(mParserBlockingRequest);
     // nsContentSink::ScriptAvailable unblocks the parser
     ProcessRequest(request);
   }
 
+  while (ReadyToExecuteScripts() && 
+         !mXSLTRequests.IsEmpty() && 
+         !mXSLTRequests[0]->mLoading) {
+    request.swap(mXSLTRequests[0]);
+    mXSLTRequests.RemoveElementAt(0);
+    ProcessRequest(request);
+  }
+
   PRUint32 i = 0;
   while (mEnabled && i < mAsyncRequests.Length()) {
     if (!mAsyncRequests[i]->mLoading) {
       request.swap(mAsyncRequests[i]);
       mAsyncRequests.RemoveElementAt(i);
       ProcessRequest(request);
       continue;
     }
     ++i;
   }
 
-  if (mDocumentParsingDone) {
+  if (mDocumentParsingDone && mXSLTRequests.IsEmpty()) {
     while (!mDeferRequests.IsEmpty() && !mDeferRequests[0]->mLoading) {
       request.swap(mDeferRequests[0]);
       mDeferRequests.RemoveElementAt(0);
       ProcessRequest(request);
     }
   }
 
   while (!mPendingChildLoaders.IsEmpty() && ReadyToExecuteScripts()) {
     nsRefPtr<nsScriptLoader> child = mPendingChildLoaders[0];
     mPendingChildLoaders.RemoveElementAt(0);
     child->RemoveExecuteBlocker();
   }
 
   if (mDocumentParsingDone && mDocument &&
       !mParserBlockingRequest && mAsyncRequests.IsEmpty() &&
-      mDeferRequests.IsEmpty()) {
+      mXSLTRequests.IsEmpty() && mDeferRequests.IsEmpty()) {
     // No more pending scripts; time to unblock onload.
     // OK to unblock onload synchronously here, since callers must be
     // prepared for the world changing anyway.
     mDocumentParsingDone = PR_FALSE;
     mDocument->UnblockOnload(PR_TRUE);
   }
 }
 
@@ -1048,17 +1088,18 @@ nsScriptLoader::OnStreamComplete(nsIStre
   nsScriptLoadRequest* request = static_cast<nsScriptLoadRequest*>(aContext);
   NS_ASSERTION(request, "null request in stream complete handler");
   NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
 
   nsresult rv = PrepareLoadedRequest(request, aLoader, aStatus, aStringLen,
                                      aString);
   if (NS_FAILED(rv)) {
     if (mDeferRequests.RemoveElement(request) ||
-        mAsyncRequests.RemoveElement(request)) {
+        mAsyncRequests.RemoveElement(request) ||
+        mXSLTRequests.RemoveElement(request)) {
       FireScriptAvailable(rv, request);
     } else if (mParserBlockingRequest == request) {
       mParserBlockingRequest = nsnull;
       // nsContentSink::ScriptAvailable unblocks the parser
       FireScriptAvailable(rv, request);
     } else {
       mPreloads.RemoveElement(request, PreloadRequestComparator());
     }
@@ -1126,16 +1167,17 @@ nsScriptLoader::PrepareLoadedRequest(nsS
   }
 
   // This assertion could fire errorously if we ran out of memory when
   // inserting the request in the array. However it's an unlikely case
   // so if you see this assertion it is likely something else that is
   // wrong, especially if you see it more than once.
   NS_ASSERTION(mDeferRequests.IndexOf(aRequest) >= 0 ||
                mAsyncRequests.IndexOf(aRequest) >= 0 ||
+               mXSLTRequests.IndexOf(aRequest) >= 0 ||
                mPreloads.Contains(aRequest, PreloadRequestComparator()) ||
                mParserBlockingRequest,
                "aRequest should be pending!");
 
   // Mark this as loaded
   aRequest->mLoading = PR_FALSE;
 
   return NS_OK;
@@ -1178,16 +1220,17 @@ nsScriptLoader::ParsingComplete(PRBool a
     // Have to check because we apparently get ParsingComplete
     // without BeginDeferringScripts in some cases
     mDocumentParsingDone = PR_TRUE;
   }
   mDeferEnabled = PR_FALSE;
   if (aTerminated) {
     mDeferRequests.Clear();
     mAsyncRequests.Clear();
+    mXSLTRequests.Clear();
     mParserBlockingRequest = nsnull;
   }
 
   // Have to call this even if aTerminated so we'll correctly unblock
   // onload and all.
   ProcessPendingRequests();
 }
 
--- a/content/base/src/nsScriptLoader.h
+++ b/content/base/src/nsScriptLoader.h
@@ -294,16 +294,17 @@ private:
                                 nsresult aStatus,
                                 PRUint32 aStringLen,
                                 const PRUint8* aString);
 
   nsIDocument* mDocument;                   // [WEAK]
   nsCOMArray<nsIScriptLoaderObserver> mObservers;
   nsTArray<nsRefPtr<nsScriptLoadRequest> > mAsyncRequests;
   nsTArray<nsRefPtr<nsScriptLoadRequest> > mDeferRequests;
+  nsTArray<nsRefPtr<nsScriptLoadRequest> > mXSLTRequests;
   nsRefPtr<nsScriptLoadRequest> mParserBlockingRequest;
 
   // In mRequests, the additional information here is stored by the element.
   struct PreloadInfo {
     nsRefPtr<nsScriptLoadRequest> mRequest;
     nsString mCharset;
   };
 
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -426,16 +426,23 @@ include $(topsrcdir)/config/rules.mk
 		test_bug578096.html \
 		test_bug598877.html \
 		test_bug600466.html \
 		test_bug600468.html \
 		test_bug600471.html \
 		test_bug601803.html \
 		file_bug601803a.html \
 		file_bug601803b.html \
+		test_bug604660.html \
+		file_bug604660-1.xml \
+		file_bug604660-2.xsl \
+		file_bug604660-3.js \
+		file_bug604660-4.js \
+		file_bug604660-5.xml \
+		file_bug604660-6.xsl \
 		test_bug605982.html \
 		$(NULL)
 
 # This test fails on the Mac for some reason
 ifneq (,$(filter gtk2 windows,$(MOZ_WIDGET_TOOLKIT)))
 _TEST_FILES2 += 	test_copyimage.html \
 		$(NULL)
 endif
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_bug604660-1.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="file_bug604660-2.xsl" ?>
+<placeholder/>
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_bug604660-2.xsl
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
+  <xsl:template match="/">
+    <html>
+      <head>
+        <title>XSLT script execution test</title>
+      </head>
+      <body>
+        <script defer="" src="data:text/javascript,parent.scriptRan(5);"></script>
+        <script>parent.scriptRan(1);</script>
+        <script async="" src="data:text/javascript,parent.asyncRan();"></script>
+        <script src="file_bug604660-3.js"></script>
+        <script>parent.scriptRan(3);</script>
+        <script src="file_bug604660-4.js"></script>        
+      </body>
+    </html>
+  </xsl:template>
+</xsl:stylesheet>
+
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_bug604660-3.js
@@ -0,0 +1,1 @@
+parent.scriptRan(2);
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_bug604660-4.js
@@ -0,0 +1,1 @@
+parent.scriptRan(4);
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_bug604660-5.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<placeholder/>
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_bug604660-6.xsl
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
+  <xsl:template match="/">
+    <html>
+      <script>xsltProcessorCreatedScriptRan();</script>
+    </html>
+  </xsl:template>
+</xsl:stylesheet>
+
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug604660.html
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=604660
+-->
+<head>
+  <title>Test for Bug 604660</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=604660">Mozilla Bug 604660</a>
+<script>
+SimpleTest.waitForExplicitFinish();
+var asyncState = false;
+var scriptState = 0;
+
+function scriptRan(num) {
+  ++scriptState;
+  is(scriptState, num, "Scripts ran in the wrong sequence.");
+}
+
+function asyncRan() {
+  asyncState = true;
+}
+
+</script>
+<p id="display"><iframe src="file_bug604660-1.xml" onload="iframeloaded()";></iframe></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+var xlstProcessorState = false;
+
+function xsltProcessorCreatedScriptRan() {
+  xlstProcessorState = true;
+}
+
+function iframeloaded() {
+  ok(asyncState, "Async script should have run.");
+  is(scriptState, 5, "Five scripts should have run.");
+
+  var processor = new XSLTProcessor();
+
+  var xhr = new XMLHttpRequest();
+  xhr.onreadystatechange = function() {
+    if (this.readyState == 4) {
+      processor.importStylesheet(this.responseXML);
+      xhr.onreadystatechange = function() {
+        if (this.readyState == 4) {
+          var doc = processor.transformToDocument(this.responseXML);
+          var target = document.getElementById("display");
+          target.appendChild(doc.documentElement.firstChild);
+          ok(!xlstProcessorState, "Scripts created by transformToDocument should not run.");
+
+          var fragment = processor.transformToFragment(this.responseXML, document);
+          target.appendChild(fragment.firstChild.firstChild);
+          ok(xlstProcessorState, "Scripts created by transformToFragment should run.");
+
+          SimpleTest.finish();
+        }
+      }
+      xhr.open("GET", "file_bug604660-5.xml");
+      xhr.send();
+    }
+  }
+  xhr.open("GET", "file_bug604660-6.xsl");
+  xhr.send();
+}
+</script>
+</pre>
+</body>
+</html>
+
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -1634,17 +1634,17 @@ WebGLContext::GetParameter(PRUint32 pnam
             wrval->SetAsArray(nsIDataType::VTYPE_INT32, nsnull,
                               2, static_cast<void*>(iv));
         }
             break;
 
         case LOCAL_GL_SCISSOR_BOX: // 4 ints
         case LOCAL_GL_VIEWPORT: // 4 ints
         {
-            GLint iv[2] = { 0 };
+            GLint iv[4] = { 0 };
             gl->fGetIntegerv(pname, iv);
             wrval->SetAsArray(nsIDataType::VTYPE_INT32, nsnull,
                               4, static_cast<void*>(iv));
         }
             break;
 
         case LOCAL_GL_COLOR_WRITEMASK: // 4 bools
         {
--- a/content/html/content/public/nsHTMLAudioElement.h
+++ b/content/html/content/public/nsHTMLAudioElement.h
@@ -46,17 +46,17 @@ typedef PRUint16 nsMediaNetworkState;
 typedef PRUint16 nsMediaReadyState;
 
 class nsHTMLAudioElement : public nsHTMLMediaElement,
                            public nsIDOMHTMLAudioElement,
                            public nsIJSNativeInitializer
 {
 public:
   nsHTMLAudioElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                     PRUint32 aFromParser = 0);
+                     mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
   virtual ~nsHTMLAudioElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE(nsHTMLMediaElement::)
 
--- a/content/html/content/public/nsHTMLMediaElement.h
+++ b/content/html/content/public/nsHTMLMediaElement.h
@@ -66,17 +66,17 @@ class nsHTMLMediaElement : public nsGene
 public:
   enum CanPlayStatus {
     CANPLAY_NO,
     CANPLAY_MAYBE,
     CANPLAY_YES
   };
 
   nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                     PRUint32 aFromParser = 0);
+                     mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
   virtual ~nsHTMLMediaElement();
 
   /**
    * This is used when the browser is constructing a video element to play
    * a channel that we've already started loading. The src attribute and
    * <source> children are ignored.
    * @param aChannel the channel to use
    * @param aListener returns a stream listener that should receive
--- a/content/html/content/public/nsHTMLVideoElement.h
+++ b/content/html/content/public/nsHTMLVideoElement.h
@@ -41,17 +41,17 @@
 #include "nsIDOMHTMLVideoElement.h"
 #include "nsHTMLMediaElement.h"
 
 class nsHTMLVideoElement : public nsHTMLMediaElement,
                            public nsIDOMHTMLVideoElement
 {
 public:
   nsHTMLVideoElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                     PRUint32 aFromParser = 0);
+                     mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
   virtual ~nsHTMLVideoElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE(nsHTMLMediaElement::)
 
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -982,20 +982,20 @@ PR_STATIC_ASSERT(ELEMENT_TYPE_SPECIFIC_B
  */
 
 class nsGenericHTMLFrameElement : public nsGenericHTMLElement,
                                   public nsIDOMNSHTMLFrameElement,
                                   public nsIFrameLoaderOwner
 {
 public:
   nsGenericHTMLFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                            PRUint32 aFromParser)
+                            mozilla::dom::FromParser aFromParser)
     : nsGenericHTMLElement(aNodeInfo)
   {
-    mNetworkCreated = aFromParser == NS_FROM_PARSER_NETWORK;
+    mNetworkCreated = aFromParser == mozilla::dom::FROM_PARSER_NETWORK;
   }
   virtual ~nsGenericHTMLFrameElement();
 
   // nsISupports
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
 
   // nsIDOMNSHTMLFrameElement
   NS_DECL_NSIDOMNSHTMLFRAMEELEMENT
@@ -1041,49 +1041,30 @@ protected:
   // using NS_FROM_PARSER_NETWORK flag.
   // If the element is modified, it may lose the flag.
   PRPackedBool            mNetworkCreated;
 };
 
 //----------------------------------------------------------------------
 
 /**
- * A macro to implement the NS_NewHTMLXXXElement() functions.
- */
-#define NS_IMPL_NS_NEW_HTML_ELEMENT(_elementName)                            \
-nsGenericHTMLElement*                                                        \
-NS_NewHTML##_elementName##Element(already_AddRefed<nsINodeInfo> aNodeInfo,   \
-                                  PRUint32 aFromParser)                      \
-{                                                                            \
-  return new nsHTML##_elementName##Element(aNodeInfo);                       \
-}
-
-#define NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(_elementName)               \
-nsGenericHTMLElement*                                                        \
-NS_NewHTML##_elementName##Element(already_AddRefed<nsINodeInfo> aNodeInfo,   \
-                                  PRUint32 aFromParser)                      \
-{                                                                            \
-  return new nsHTML##_elementName##Element(aNodeInfo, aFromParser);          \
-}
-
-/**
  * A macro to implement the getter and setter for a given string
  * valued content property. The method uses the generic GetAttr and
  * SetAttr methods.
  */
 #define NS_IMPL_STRING_ATTR(_class, _method, _atom)                  \
   NS_IMETHODIMP                                                      \
   _class::Get##_method(nsAString& aValue)                            \
   {                                                                  \
-    return GetAttrHelper(nsGkAtoms::_atom, aValue);                \
+    return GetAttrHelper(nsGkAtoms::_atom, aValue);                  \
   }                                                                  \
   NS_IMETHODIMP                                                      \
   _class::Set##_method(const nsAString& aValue)                      \
   {                                                                  \
-    return SetAttrHelper(nsGkAtoms::_atom, aValue);                \
+    return SetAttrHelper(nsGkAtoms::_atom, aValue);                  \
   }
 
 /**
  * A macro to implement the getter and setter for a given string
  * valued content property with a default value.
  * The method uses the generic GetAttr and SetAttr methods.
  */
 #define NS_IMPL_STRING_ATTR_DEFAULT_VALUE(_class, _method, _atom, _default) \
@@ -1425,36 +1406,56 @@ NS_NewHTML##_elementName##Element(alread
     NS_INTERFACE_TABLE_ENTRY(_class, _i6)                                     \
     NS_INTERFACE_TABLE_ENTRY(_class, _i7)                                     \
     NS_INTERFACE_TABLE_ENTRY(_class, _i8)                                     \
     NS_INTERFACE_TABLE_ENTRY(_class, _i9)                                     \
     NS_INTERFACE_TABLE_ENTRY(_class, _i10)                                    \
   NS_OFFSET_AND_INTERFACE_TABLE_END
 
 
-// Element class factory methods
-
+/**
+ * A macro to declare the NS_NewHTMLXXXElement() functions.
+ */
 #define NS_DECLARE_NS_NEW_HTML_ELEMENT(_elementName)                       \
 nsGenericHTMLElement*                                                      \
 NS_NewHTML##_elementName##Element(already_AddRefed<nsINodeInfo> aNodeInfo, \
-                                  PRUint32 aFromParser = 0);
+                                  mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
 
 #define NS_DECLARE_NS_NEW_HTML_ELEMENT_AS_SHARED(_elementName)             \
 inline nsGenericHTMLElement*                                               \
 NS_NewHTML##_elementName##Element(already_AddRefed<nsINodeInfo> aNodeInfo, \
-                                  PRUint32 aFromParser = 0)                \
+                                  mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER) \
 {                                                                          \
   return NS_NewHTMLSharedElement(aNodeInfo, aFromParser);                  \
 }
 
+/**
+ * A macro to implement the NS_NewHTMLXXXElement() functions.
+ */
+#define NS_IMPL_NS_NEW_HTML_ELEMENT(_elementName)                            \
+nsGenericHTMLElement*                                                        \
+NS_NewHTML##_elementName##Element(already_AddRefed<nsINodeInfo> aNodeInfo,   \
+                                  mozilla::dom::FromParser aFromParser)      \
+{                                                                            \
+  return new nsHTML##_elementName##Element(aNodeInfo);                       \
+}
+
+#define NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(_elementName)               \
+nsGenericHTMLElement*                                                        \
+NS_NewHTML##_elementName##Element(already_AddRefed<nsINodeInfo> aNodeInfo,   \
+                                  mozilla::dom::FromParser aFromParser)      \
+{                                                                            \
+  return new nsHTML##_elementName##Element(aNodeInfo, aFromParser);          \
+}
+
 // Here, we expand 'NS_DECLARE_NS_NEW_HTML_ELEMENT()' by hand.
 // (Calling the macro directly (with no args) produces compiler warnings.)
 nsGenericHTMLElement*
 NS_NewHTMLElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                  PRUint32 aFromParser = 0);
+                  mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
 
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Shared)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(SharedList)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(SharedObject)
 
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Anchor)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Area)
 #if defined(MOZ_MEDIA)
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/nsHTMLAudioElement.cpp
@@ -63,19 +63,21 @@
 
 #include "nsIRenderingContext.h"
 #include "nsITimer.h"
 
 #include "nsEventDispatcher.h"
 #include "nsIDOMDocumentEvent.h"
 #include "nsIDOMProgressEvent.h"
 
+using namespace mozilla::dom;
+
 nsGenericHTMLElement*
 NS_NewHTMLAudioElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                       PRUint32 aFromParser)
+                       FromParser aFromParser)
 {
   /*
    * nsHTMLAudioElement's will be created without a nsINodeInfo passed in
    * if someone says "var audio = new Audio();" in JavaScript, in a case like
    * that we request the nsINodeInfo from the document's nodeinfo list.
    */
   nsCOMPtr<nsINodeInfo> nodeInfo(aNodeInfo);
   if (!nodeInfo) {
@@ -102,17 +104,17 @@ NS_HTML_CONTENT_INTERFACE_TABLE3(nsHTMLA
 NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLAudioElement,
                                                nsHTMLMediaElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLAudioElement)
 
 NS_IMPL_ELEMENT_CLONE(nsHTMLAudioElement)
 
 
 nsHTMLAudioElement::nsHTMLAudioElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                       PRUint32 aFromParser)
+                                       FromParser aFromParser)
   : nsHTMLMediaElement(aNodeInfo, aFromParser)
 {
 }
 
 nsHTMLAudioElement::~nsHTMLAudioElement()
 {
 }
 
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -51,21 +51,22 @@
 #include "nsDisplayList.h"
 #include "ImageLayers.h"
 #include "BasicLayers.h"
 
 #define DEFAULT_CANVAS_WIDTH 300
 #define DEFAULT_CANVAS_HEIGHT 150
 
 using namespace mozilla;
+using namespace mozilla::dom;
 using namespace mozilla::layers;
 
 nsGenericHTMLElement*
 NS_NewHTMLCanvasElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                        PRUint32 aFromParser)
+                        FromParser aFromParser)
 {
   return new nsHTMLCanvasElement(aNodeInfo);
 }
 
 nsHTMLCanvasElement::nsHTMLCanvasElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo), mWriteOnly(PR_FALSE)
 {
 }
--- a/content/html/content/src/nsHTMLElement.cpp
+++ b/content/html/content/src/nsHTMLElement.cpp
@@ -33,16 +33,17 @@
  * 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 "nsGenericHTMLElement.h"
 #include "nsIDOMHTMLElement.h"
 
+using namespace mozilla::dom;
 
 class nsHTMLElement : public nsGenericHTMLElement,
                       public nsIDOMHTMLElement
 {
 public:
   nsHTMLElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLElement();
 
@@ -64,17 +65,17 @@ public:
 
   virtual nsXPCClassInfo* GetClassInfo();
 };
 
 // Here, we expand 'NS_IMPL_NS_NEW_HTML_ELEMENT()' by hand.
 // (Calling the macro directly (with no args) produces compiler warnings.)
 nsGenericHTMLElement*
 NS_NewHTMLElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                  PRUint32 aFromParser)
+                  FromParser aFromParser)
 {
   return new nsHTMLElement(aNodeInfo);
 }
 
 nsHTMLElement::nsHTMLElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo)
 {
 }
--- a/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -80,16 +80,18 @@
 #include "mozAutoDocUpdate.h"
 #include "nsIHTMLCollection.h"
 
 #include "nsIConstraintValidation.h"
 #include "nsIEventStateManager.h"
 
 #include "nsIDOMHTMLButtonElement.h"
 
+using namespace mozilla::dom;
+
 static const int NS_FORM_CONTROL_LIST_HASHTABLE_SIZE = 16;
 
 static const PRUint8 NS_FORM_AUTOCOMPLETE_ON  = 1;
 static const PRUint8 NS_FORM_AUTOCOMPLETE_OFF = 0;
 
 static const nsAttrValue::EnumTable kFormAutocompleteTable[] = {
   { "on",  NS_FORM_AUTOCOMPLETE_ON },
   { "off", NS_FORM_AUTOCOMPLETE_OFF },
@@ -229,22 +231,19 @@ ShouldBeInElements(nsIFormControl* aForm
   return PR_FALSE;
 }
 
 // nsHTMLFormElement implementation
 
 // construction, destruction
 nsGenericHTMLElement*
 NS_NewHTMLFormElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                      PRUint32 aFromParser)
+                      FromParser aFromParser)
 {
   nsHTMLFormElement* it = new nsHTMLFormElement(aNodeInfo);
-  if (!it) {
-    return nsnull;
-  }
 
   nsresult rv = it->Init();
 
   if (NS_FAILED(rv)) {
     delete it;
     return nsnull;
   }
 
--- a/content/html/content/src/nsHTMLFrameElement.cpp
+++ b/content/html/content/src/nsHTMLFrameElement.cpp
@@ -36,23 +36,24 @@
  * ***** END LICENSE BLOCK ***** */
 #include "nsIDOMHTMLFrameElement.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsDOMError.h"
 
+using namespace mozilla::dom;
 
 class nsHTMLFrameElement : public nsGenericHTMLFrameElement,
                            public nsIDOMHTMLFrameElement
 {
 public:
   nsHTMLFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                     PRUint32 aFromParser = NS_NOT_FROM_PARSER);
+                     mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
   virtual ~nsHTMLFrameElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE(nsGenericHTMLFrameElement::)
 
@@ -76,17 +77,17 @@ public:
   virtual nsXPCClassInfo* GetClassInfo();
 };
 
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Frame)
 
 
 nsHTMLFrameElement::nsHTMLFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                       PRUint32 aFromParser)
+                                       FromParser aFromParser)
   : nsGenericHTMLFrameElement(aNodeInfo, aFromParser)
 {
 }
 
 nsHTMLFrameElement::~nsHTMLFrameElement()
 {
 }
 
--- a/content/html/content/src/nsHTMLIFrameElement.cpp
+++ b/content/html/content/src/nsHTMLIFrameElement.cpp
@@ -43,25 +43,27 @@
 #endif
 #include "nsGkAtoms.h"
 #include "nsIDocument.h"
 #include "nsMappedAttributes.h"
 #include "nsDOMError.h"
 #include "nsRuleData.h"
 #include "nsStyleConsts.h"
 
-class nsHTMLIFrameElement : public nsGenericHTMLFrameElement,
-                            public nsIDOMHTMLIFrameElement
+using namespace mozilla::dom;
+
+class nsHTMLIFrameElement : public nsGenericHTMLFrameElement
+                          , public nsIDOMHTMLIFrameElement
 #ifdef MOZ_SVG
-                            , public nsIDOMGetSVGDocument
+                          , public nsIDOMGetSVGDocument
 #endif
 {
 public:
   nsHTMLIFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                      PRUint32 aFromParser = NS_NOT_FROM_PARSER);
+                      mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
   virtual ~nsHTMLIFrameElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE(nsGenericHTMLFrameElement::)
 
@@ -91,17 +93,17 @@ public:
   virtual nsXPCClassInfo* GetClassInfo();
 };
 
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(IFrame)
 
 
 nsHTMLIFrameElement::nsHTMLIFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                         PRUint32 aFromParser)
+                                         FromParser aFromParser)
   : nsGenericHTMLFrameElement(aNodeInfo, aFromParser)
 {
 }
 
 nsHTMLIFrameElement::~nsHTMLIFrameElement()
 {
 }
 
--- a/content/html/content/src/nsHTMLImageElement.cpp
+++ b/content/html/content/src/nsHTMLImageElement.cpp
@@ -71,16 +71,18 @@
 
 #include "nsIJSContextStack.h"
 #include "nsImageMapUtils.h"
 #include "nsIDOMHTMLMapElement.h"
 #include "nsEventDispatcher.h"
 
 #include "nsLayoutUtils.h"
 
+using namespace mozilla::dom;
+
 // XXX nav attrs: suppress
 
 class nsHTMLImageElement : public nsGenericHTMLElement,
                            public nsImageLoadingContent,
                            public nsIDOMHTMLImageElement,
                            public nsIJSNativeInitializer
 {
 public:
@@ -149,17 +151,17 @@ public:
   virtual nsXPCClassInfo* GetClassInfo();
 protected:
   nsPoint GetXY();
   nsSize GetWidthHeight();
 };
 
 nsGenericHTMLElement*
 NS_NewHTMLImageElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                       PRUint32 aFromParser)
+                       FromParser aFromParser)
 {
   /*
    * nsHTMLImageElement's will be created without a nsINodeInfo passed in
    * if someone says "var img = new Image();" in JavaScript, in a case like
    * that we request the nsINodeInfo from the document's nodeinfo list.
    */
   nsCOMPtr<nsINodeInfo> nodeInfo(aNodeInfo);
   if (!nodeInfo) {
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -122,16 +122,18 @@
 #include "nsTextEditRules.h"
 
 // JS headers are needed for the pattern attribute.
 #include "jsapi.h"
 #include "jscntxt.h"
 
 #include "nsHTMLInputElement.h"
 
+using namespace mozilla::dom;
+
 // XXX align=left, hspace, vspace, border? other nav4 attrs
 
 static NS_DEFINE_CID(kXULControllersCID,  NS_XULCONTROLLERS_CID);
 static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
 
 // First bits are needed for the control type.
 #define NS_OUTER_ACTIVATE_EVENT   (1 << 9)
 #define NS_ORIGINAL_CHECKED_VALUE (1 << 10)
@@ -607,24 +609,24 @@ static nsresult FireEventForAccessibilit
 
 //
 // construction, destruction
 //
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Input)
 
 nsHTMLInputElement::nsHTMLInputElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                       PRUint32 aFromParser)
+                                       FromParser aFromParser)
   : nsGenericHTMLFormElement(aNodeInfo),
     mType(kInputDefaultType->value),
     mBitField(0)
 {
   SET_BOOLBIT(mBitField, BF_PARSER_CREATING, aFromParser);
   SET_BOOLBIT(mBitField, BF_INHIBIT_RESTORATION,
-      aFromParser & NS_FROM_PARSER_FRAGMENT);
+      aFromParser & mozilla::dom::FROM_PARSER_FRAGMENT);
   mInputData.mState = new nsTextEditorState(this);
   NS_ADDREF(mInputData.mState);
   
   if (!gUploadLastDir)
     nsHTMLInputElement::InitUploadLastDir();
 }
 
 nsHTMLInputElement::~nsHTMLInputElement()
@@ -697,20 +699,17 @@ NS_IMPL_NSICONSTRAINTVALIDATION_EXCEPT_S
 // nsIDOMNode
 
 nsresult
 nsHTMLInputElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
 {
   *aResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
-  nsHTMLInputElement *it = new nsHTMLInputElement(ni.forget(), PR_FALSE);
-  if (!it) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
+  nsHTMLInputElement *it = new nsHTMLInputElement(ni.forget(), NOT_FROM_PARSER);
 
   nsCOMPtr<nsINode> kungFuDeathGrip = it;
   nsresult rv = CopyInnerTo(it);
   NS_ENSURE_SUCCESS(rv, rv);
 
   switch (mType) {
     case NS_FORM_INPUT_EMAIL:
     case NS_FORM_INPUT_SEARCH:
--- a/content/html/content/src/nsHTMLInputElement.h
+++ b/content/html/content/src/nsHTMLInputElement.h
@@ -118,17 +118,17 @@ class nsHTMLInputElement : public nsGene
                            public nsIPhonetic,
                            public nsIDOMNSEditableElement,
                            public nsIConstraintValidation
 {
 public:
   using nsIConstraintValidation::GetValidationMessage;
 
   nsHTMLInputElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                     PRUint32 aFromParser);
+                     mozilla::dom::FromParser aFromParser);
   virtual ~nsHTMLInputElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
 
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -116,16 +116,17 @@ static PRLogModuleInfo* gMediaElementEve
 #define LOG(type, msg)
 #define LOG_EVENT(type, msg)
 #endif
 
 #include "nsIContentSecurityPolicy.h"
 #include "nsIChannelPolicy.h"
 #include "nsChannelPolicy.h"
 
+using namespace mozilla::dom;
 using namespace mozilla::layers;
 
 // Under certain conditions there may be no-one holding references to
 // a media element from script, DOM parent, etc, but the element may still
 // fire meaningful events in the future so we can't destroy it yet:
 // 1) If the element is delaying the load event (or would be, if it were
 // in a document), then events up to loadeddata or error could be fired,
 // so we need to stay alive.
@@ -1260,17 +1261,17 @@ NS_IMETHODIMP nsHTMLMediaElement::SetMut
   }
 
   DispatchAsyncEvent(NS_LITERAL_STRING("volumechange"));
 
   return NS_OK;
 }
 
 nsHTMLMediaElement::nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                       PRUint32 aFromParser)
+                                       FromParser aFromParser)
   : nsGenericHTMLElement(aNodeInfo),
     mCurrentLoadID(0),
     mNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY),
     mReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING),
     mLoadWaitStatus(NOT_WAITING),
     mVolume(1.0),
     mChannels(0),
     mRate(0),
--- a/content/html/content/src/nsHTMLObjectElement.cpp
+++ b/content/html/content/src/nsHTMLObjectElement.cpp
@@ -47,30 +47,31 @@
 #include "nsIDOMGetSVGDocument.h"
 #endif
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsFormSubmission.h"
 #include "nsIObjectFrame.h"
 #include "nsIPluginInstance.h"
 #include "nsIConstraintValidation.h"
 
+using namespace mozilla::dom;
 
-class nsHTMLObjectElement : public nsGenericHTMLFormElement,
-                            public nsObjectLoadingContent,
-                            public nsIDOMHTMLObjectElement,
-                            public nsIConstraintValidation
+class nsHTMLObjectElement : public nsGenericHTMLFormElement
+                          , public nsObjectLoadingContent
+                          , public nsIDOMHTMLObjectElement
+                          , public nsIConstraintValidation
 #ifdef MOZ_SVG
-                            , public nsIDOMGetSVGDocument
+                          , public nsIDOMGetSVGDocument
 #endif
 {
 public:
   using nsIConstraintValidation::GetValidationMessage;
 
   nsHTMLObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                      PRUint32 aFromParser = 0);
+                      mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
   virtual ~nsHTMLObjectElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
 
@@ -153,22 +154,22 @@ private:
   PRPackedBool mIsDoneAddingChildren;
 };
 
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Object)
 
 
 nsHTMLObjectElement::nsHTMLObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                         PRUint32 aFromParser)
+                                         FromParser aFromParser)
   : nsGenericHTMLFormElement(aNodeInfo),
     mIsDoneAddingChildren(!aFromParser)
 {
   RegisterFreezableElement();
-  SetIsNetworkCreated(aFromParser == NS_FROM_PARSER_NETWORK);
+  SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK);
 
   // <object> is always barred from constraint validation.
   SetBarredFromConstraintValidation(PR_TRUE);
 }
 
 nsHTMLObjectElement::~nsHTMLObjectElement()
 {
   UnregisterFreezableElement();
--- a/content/html/content/src/nsHTMLOptionElement.cpp
+++ b/content/html/content/src/nsHTMLOptionElement.cpp
@@ -61,23 +61,25 @@
 #include "nsNodeInfoManager.h"
 #include "nsCOMPtr.h"
 #include "nsIEventStateManager.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsContentCreatorFunctions.h"
 #include "mozAutoDocUpdate.h"
 
+using namespace mozilla::dom;
+
 /**
  * Implementation of &lt;option&gt;
  */
 
 nsGenericHTMLElement*
 NS_NewHTMLOptionElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                        PRUint32 aFromParser)
+                        FromParser aFromParser)
 {
   /*
    * nsHTMLOptionElement's will be created without a nsINodeInfo passed in
    * if someone says "var opt = new Option();" in JavaScript, in a case like
    * that we request the nsINodeInfo from the document's nodeinfo list.
    */
   nsCOMPtr<nsINodeInfo> nodeInfo(aNodeInfo);
   if (!nodeInfo) {
--- a/content/html/content/src/nsHTMLScriptElement.cpp
+++ b/content/html/content/src/nsHTMLScriptElement.cpp
@@ -53,16 +53,18 @@
 #include "nsServiceManagerUtils.h"
 #include "nsIScriptEventHandler.h"
 #include "nsIDOMDocument.h"
 #include "nsContentErrors.h"
 #include "nsIArray.h"
 #include "nsTArray.h"
 #include "nsDOMJSUtils.h"
 
+using namespace mozilla::dom;
+
 //
 // Helper class used to support <SCRIPT FOR=object EVENT=handler ...>
 // style script tags...
 //
 class nsHTMLScriptEventHandler : public nsIScriptEventHandler
 {
 public:
   nsHTMLScriptEventHandler(nsIDOMHTMLScriptElement *aOuter);
@@ -303,17 +305,17 @@ nsHTMLScriptEventHandler::Invoke(nsISupp
 
 
 class nsHTMLScriptElement : public nsGenericHTMLElement,
                             public nsIDOMHTMLScriptElement,
                             public nsScriptElement
 {
 public:
   nsHTMLScriptElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                      PRUint32 aFromParser);
+                      FromParser aFromParser);
   virtual ~nsHTMLScriptElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
 
@@ -356,17 +358,17 @@ protected:
   virtual nsresult MaybeProcessScript();
 };
 
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Script)
 
 
 nsHTMLScriptElement::nsHTMLScriptElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                         PRUint32 aFromParser)
+                                         FromParser aFromParser)
   : nsGenericHTMLElement(aNodeInfo)
   , nsScriptElement(aFromParser)
 {
   mDoneAddingChildren = !aFromParser;
   AddMutationObserver(this);
 }
 
 nsHTMLScriptElement::~nsHTMLScriptElement()
@@ -414,20 +416,18 @@ nsHTMLScriptElement::BindToTree(nsIDocum
 }
 
 nsresult
 nsHTMLScriptElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
 {
   *aResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
-  nsHTMLScriptElement* it = new nsHTMLScriptElement(ni.forget(), PR_FALSE);
-  if (!it) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
+  nsHTMLScriptElement* it =
+    new nsHTMLScriptElement(ni.forget(), NOT_FROM_PARSER);
 
   nsCOMPtr<nsINode> kungFuDeathGrip = it;
   nsresult rv = CopyInnerTo(it);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // The clone should be marked evaluated if we are.
   it->mAlreadyStarted = mAlreadyStarted;
   it->mLineNumber = mLineNumber;
--- a/content/html/content/src/nsHTMLSelectElement.cpp
+++ b/content/html/content/src/nsHTMLSelectElement.cpp
@@ -135,23 +135,23 @@ nsSafeOptionListMutation::~nsSafeOptionL
 //
 
 // construction, destruction
 
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Select)
 
 nsHTMLSelectElement::nsHTMLSelectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                         PRUint32 aFromParser)
+                                         FromParser aFromParser)
   : nsGenericHTMLFormElement(aNodeInfo),
     mOptions(new nsHTMLOptionCollection(this)),
     mIsDoneAddingChildren(!aFromParser),
     mDisabledChanged(PR_FALSE),
     mMutating(PR_FALSE),
-    mInhibitStateRestoration(!!(aFromParser & NS_FROM_PARSER_FRAGMENT)),
+    mInhibitStateRestoration(!!(aFromParser & FROM_PARSER_FRAGMENT)),
     mNonOptionChildren(0),
     mOptGroupCount(0),
     mSelectedIndex(-1)
 {
   // FIXME: Bug 328908, set mOptions in an Init function and get rid of null
   // checks.
 
   // DoneAddingChildren() will be called later if it's from the parser,
--- a/content/html/content/src/nsHTMLSelectElement.h
+++ b/content/html/content/src/nsHTMLSelectElement.h
@@ -239,17 +239,17 @@ class nsHTMLSelectElement : public nsGen
                             public nsIDOMHTMLSelectElement,
                             public nsISelectElement,
                             public nsIConstraintValidation
 {
 public:
   using nsIConstraintValidation::GetValidationMessage;
 
   nsHTMLSelectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                      PRUint32 aFromParser = 0);
+                      mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
   virtual ~nsHTMLSelectElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
 
--- a/content/html/content/src/nsHTMLSharedObjectElement.cpp
+++ b/content/html/content/src/nsHTMLSharedObjectElement.cpp
@@ -52,27 +52,29 @@
 
 // XXX this is to get around conflicts with windows.h defines
 // introduced through jni.h
 #ifdef XP_WIN
 #undef GetClassName
 #undef GetObject
 #endif
 
-class nsHTMLSharedObjectElement : public nsGenericHTMLElement,
-                                  public nsObjectLoadingContent,
-                                  public nsIDOMHTMLAppletElement,
-                                  public nsIDOMHTMLEmbedElement
+using namespace mozilla::dom;
+
+class nsHTMLSharedObjectElement : public nsGenericHTMLElement
+                                , public nsObjectLoadingContent
+                                , public nsIDOMHTMLAppletElement
+                                , public nsIDOMHTMLEmbedElement
 #ifdef MOZ_SVG
-                                  , public nsIDOMGetSVGDocument
+                                , public nsIDOMGetSVGDocument
 #endif
 {
 public:
   nsHTMLSharedObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                            PRUint32 aFromParser = 0);
+                            mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
   virtual ~nsHTMLSharedObjectElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
 
@@ -173,17 +175,17 @@ private:
   PRPackedBool mIsDoneAddingChildren;
 };
 
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(SharedObject)
 
 
 nsHTMLSharedObjectElement::nsHTMLSharedObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                                     PRUint32 aFromParser)
+                                                     FromParser aFromParser)
   : nsGenericHTMLElement(aNodeInfo),
     mIsDoneAddingChildren(mNodeInfo->Equals(nsGkAtoms::embed) || !aFromParser)
 {
   RegisterFreezableElement();
 }
 
 nsHTMLSharedObjectElement::~nsHTMLSharedObjectElement()
 {
--- a/content/html/content/src/nsHTMLTextAreaElement.cpp
+++ b/content/html/content/src/nsHTMLTextAreaElement.cpp
@@ -76,33 +76,35 @@
 #include "nsDOMError.h"
 #include "mozAutoDocUpdate.h"
 #include "nsISupportsPrimitives.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsIConstraintValidation.h"
 
 #include "nsTextEditorState.h"
 
+using namespace mozilla::dom;
+
 static NS_DEFINE_CID(kXULControllersCID,  NS_XULCONTROLLERS_CID);
 
 #define NS_NO_CONTENT_DISPATCH (1 << 0)
 
 class nsHTMLTextAreaElement : public nsGenericHTMLFormElement,
                               public nsIDOMHTMLTextAreaElement,
                               public nsIDOMNSHTMLTextAreaElement,
                               public nsITextControlElement,
                               public nsIDOMNSEditableElement,
                               public nsStubMutationObserver,
                               public nsIConstraintValidation
 {
 public:
   using nsIConstraintValidation::GetValidationMessage;
 
   nsHTMLTextAreaElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                        PRUint32 aFromParser = 0);
+                        mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
 
   // nsIDOMElement
@@ -273,22 +275,22 @@ protected:
   PRBool IsMutable() const;
 };
 
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(TextArea)
 
 
 nsHTMLTextAreaElement::nsHTMLTextAreaElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                             PRUint32 aFromParser)
+                                             FromParser aFromParser)
   : nsGenericHTMLFormElement(aNodeInfo),
     mValueChanged(PR_FALSE),
     mHandlingSelect(PR_FALSE),
     mDoneAddingChildren(!aFromParser),
-    mInhibitStateRestoration(!!(aFromParser & NS_FROM_PARSER_FRAGMENT)),
+    mInhibitStateRestoration(!!(aFromParser & FROM_PARSER_FRAGMENT)),
     mDisabledChanged(PR_FALSE),
     mState(new nsTextEditorState(this))
 {
   AddMutationObserver(this);
 }
 
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLTextAreaElement)
--- a/content/html/content/src/nsHTMLVideoElement.cpp
+++ b/content/html/content/src/nsHTMLVideoElement.cpp
@@ -61,16 +61,18 @@
 #include "nsIRenderingContext.h"
 #include "nsITimer.h"
 
 #include "nsEventDispatcher.h"
 #include "nsIDOMDocumentEvent.h"
 #include "nsIDOMProgressEvent.h"
 #include "nsMediaError.h"
 
+using namespace mozilla::dom;
+
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Video)
 
 NS_IMPL_ADDREF_INHERITED(nsHTMLVideoElement, nsHTMLMediaElement)
 NS_IMPL_RELEASE_INHERITED(nsHTMLVideoElement, nsHTMLMediaElement)
 
 DOMCI_NODE_DATA(HTMLVideoElement, nsHTMLVideoElement)
 
 NS_INTERFACE_TABLE_HEAD(nsHTMLVideoElement)
@@ -96,17 +98,17 @@ NS_IMETHODIMP nsHTMLVideoElement::GetVid
 /* readonly attribute unsigned long videoHeight; */
 NS_IMETHODIMP nsHTMLVideoElement::GetVideoHeight(PRUint32 *aVideoHeight)
 {
   *aVideoHeight = mMediaSize.height == -1 ? 0 : mMediaSize.height;
   return NS_OK;
 }
 
 nsHTMLVideoElement::nsHTMLVideoElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                       PRUint32 aFromParser)
+                                       FromParser aFromParser)
   : nsHTMLMediaElement(aNodeInfo, aFromParser)
 {
 }
 
 nsHTMLVideoElement::~nsHTMLVideoElement()
 {
 }
 
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -62,16 +62,18 @@
 #include "nsPIDOMWindow.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIDOMEventGroup.h"
 #include "nsIEditor.h"
 #include "nsTextEditRules.h"
 
 #include "nsTextEditorState.h"
 
+using namespace mozilla::dom;
+
 static NS_DEFINE_CID(kTextEditorCID, NS_TEXTEDITOR_CID);
 static NS_DEFINE_CID(kFrameSelectionCID, NS_FRAMESELECTION_CID);
 
 static nsINativeKeyBindings *sNativeInputBindings = nsnull;
 static nsINativeKeyBindings *sNativeTextAreaBindings = nsnull;
 
 struct SelectionState {
   PRInt32 mStart;
@@ -1515,17 +1517,17 @@ nsTextEditorState::CreateRootNode()
 
   // Now create a DIV and add it to the anonymous content child list.
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::div, nsnull,
                                                  kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   nsresult rv = NS_NewHTMLElement(getter_AddRefs(mRootNode), nodeInfo.forget(),
-                                  PR_FALSE);
+                                  NOT_FROM_PARSER);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Set the necessary classes on the text control. We use class values
   // instead of a 'style' attribute so that the style comes from a user-agent
   // style sheet and is still applied even if author styles are disabled.
   nsAutoString classValue;
   classValue.AppendLiteral("anonymous-div");
   PRInt32 wrapCols = GetWrapCols();
@@ -1592,17 +1594,17 @@ be called if @placeholder is the empty s
   // Create a DIV for the placeholder
   // and add it to the anonymous content child list
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = pNodeInfoManager->GetNodeInfo(nsGkAtoms::div, nsnull,
                                            kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   rv = NS_NewHTMLElement(getter_AddRefs(mPlaceholderDiv), nodeInfo.forget(),
-                         PR_FALSE);
+                         NOT_FROM_PARSER);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Create the text node for the placeholder text before doing anything else
   rv = NS_NewTextNode(getter_AddRefs(placeholderText), pNodeInfoManager);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = mPlaceholderDiv->AppendChildTo(placeholderText, PR_FALSE);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/content/html/document/src/nsHTMLContentSink.cpp
+++ b/content/html/document/src/nsHTMLContentSink.cpp
@@ -134,21 +134,22 @@ static PRLogModuleInfo* gSinkLogModuleIn
 
 #else
 #define SINK_TRACE_NODE(_bit, _msg, _tag, _sp, _obj)
 #endif
 
 //----------------------------------------------------------------------
 
 typedef nsGenericHTMLElement*
-  (*contentCreatorCallback)(already_AddRefed<nsINodeInfo>, PRUint32 aFromParser);
+  (*contentCreatorCallback)(already_AddRefed<nsINodeInfo>,
+                            FromParser aFromParser);
 
 nsGenericHTMLElement*
 NS_NewHTMLNOTUSEDElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                         PRUint32 aFromParser)
+                         FromParser aFromParser)
 {
   NS_NOTREACHED("The element ctor should never be called");
   return nsnull;
 }
 
 #define HTML_TAG(_tag, _classname) NS_NewHTML##_classname##Element,
 #define HTML_HTMLELEMENT_TAG(_tag) NS_NewHTMLElement,
 #define HTML_OTHER(_tag) NS_NewHTMLNOTUSEDElement,
@@ -550,22 +551,22 @@ HTMLContentSink::CreateContentObject(con
 
     nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull, kNameSpaceID_XHTML);
     NS_IF_ADDREF(mNodeInfoCache[aNodeType] = nodeInfo);
   }
 
   NS_ENSURE_TRUE(nodeInfo, nsnull);
 
   // Make the content object
-  return CreateHTMLElement(aNodeType, nodeInfo.forget(), PR_TRUE);
+  return CreateHTMLElement(aNodeType, nodeInfo.forget(), FROM_PARSER_NETWORK);
 }
 
 nsresult
 NS_NewHTMLElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo,
-                  PRUint32 aFromParser)
+                  FromParser aFromParser)
 {
   *aResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> nodeInfo = aNodeInfo;
 
   nsIParserService* parserService = nsContentUtils::GetParserService();
   if (!parserService)
     return NS_ERROR_OUT_OF_MEMORY;
@@ -578,17 +579,17 @@ NS_NewHTMLElement(nsIContent** aResult, 
   *aResult = CreateHTMLElement(parserService->
                                  HTMLCaseSensitiveAtomTagToId(name),
                                nodeInfo.forget(), aFromParser).get();
   return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 already_AddRefed<nsGenericHTMLElement>
 CreateHTMLElement(PRUint32 aNodeType, already_AddRefed<nsINodeInfo> aNodeInfo,
-                  PRUint32 aFromParser)
+                  FromParser aFromParser)
 {
   NS_ASSERTION(aNodeType <= NS_HTML_TAG_MAX ||
                aNodeType == eHTMLTag_userdefined,
                "aNodeType is out of bounds");
 
   contentCreatorCallback cb = sContentCreatorCallbacks[aNodeType];
 
   NS_ASSERTION(cb != NS_NewHTMLNOTUSEDElement,
@@ -2614,17 +2615,18 @@ HTMLContentSink::ProcessLINKTag(const ns
   nsresult  result = NS_OK;
 
   if (mCurrentContext) {
     // Create content object
     nsCOMPtr<nsIContent> element;
     nsCOMPtr<nsINodeInfo> nodeInfo;
     nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::link, nsnull, kNameSpaceID_XHTML);
 
-    result = NS_NewHTMLElement(getter_AddRefs(element), nodeInfo.forget(), PR_FALSE);
+    result = NS_NewHTMLElement(getter_AddRefs(element), nodeInfo.forget(),
+                               NOT_FROM_PARSER);
     NS_ENSURE_SUCCESS(result, result);
 
     nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(element));
 
     if (ssle) {
       // XXX need prefs. check here.
       if (!mInsideNoXXXTag) {
         ssle->InitStyleLinkElement(PR_FALSE);
--- a/content/html/document/src/nsHTMLFragmentContentSink.cpp
+++ b/content/html/document/src/nsHTMLFragmentContentSink.cpp
@@ -70,16 +70,17 @@
 #include "nsCSSProperty.h"
 #include "mozilla/css/Declaration.h"
 #include "nsICSSStyleRule.h"
 #include "nsUnicharInputStream.h"
 #include "nsCSSStyleSheet.h"
 #include "nsICSSRuleList.h"
 #include "nsIDOMCSSRule.h"
 
+using namespace mozilla::dom;
 namespace css = mozilla::css;
 
 //
 // XXX THIS IS TEMPORARY CODE
 // There's a considerable amount of copied code from the
 // regular nsHTMLContentSink. All of it will be factored
 // at some pointe really soon!
 //
@@ -385,17 +386,18 @@ nsHTMLFragmentContentSink::OpenContainer
       nodeInfo = mNodeInfoManager->GetNodeInfo(name, 
                                                nsnull, 
                                                kNameSpaceID_XHTML);
       NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
       NS_ADDREF(mNodeInfoCache[nodeType] = nodeInfo);
     }
 
-    content = CreateHTMLElement(nodeType, nodeInfo.forget(), PR_FALSE).get();
+    content =
+      CreateHTMLElement(nodeType, nodeInfo.forget(), NOT_FROM_PARSER).get();
     NS_ENSURE_TRUE(content, NS_ERROR_OUT_OF_MEMORY);
 
     result = AddAttributes(aNode, content);
     if (NS_FAILED(result)) {
       NS_RELEASE(content);
       return result;
     }
 
@@ -472,17 +474,18 @@ nsHTMLFragmentContentSink::AddLeaf(const
           NS_ASSERTION(name, "This should not happen!");
 
           nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull,
                                                    kNameSpaceID_XHTML);
           NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
           NS_ADDREF(mNodeInfoCache[nodeType] = nodeInfo);
         }
 
-        content = CreateHTMLElement(nodeType, nodeInfo.forget(), PR_FALSE);
+        content =
+          CreateHTMLElement(nodeType, nodeInfo.forget(), NOT_FROM_PARSER);
         NS_ENSURE_TRUE(content, NS_ERROR_OUT_OF_MEMORY);
 
         result = AddAttributes(aNode, content);
         NS_ENSURE_SUCCESS(result, result);
 
         nsIContent *parent = GetCurrentContent();
         if (!parent) {
           parent = mRoot;
--- a/content/html/document/src/nsPluginDocument.cpp
+++ b/content/html/document/src/nsPluginDocument.cpp
@@ -290,17 +290,17 @@ nsPluginDocument::CreateSyntheticPluginD
 
 
   // make plugin content
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::embed, nsnull,
                                            kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
   rv = NS_NewHTMLElement(getter_AddRefs(mPluginContent), nodeInfo.forget(),
-                         PR_FALSE);
+                         NOT_FROM_PARSER);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // make it a named element
   mPluginContent->SetAttr(kNameSpaceID_None, nsGkAtoms::name,
                           NS_LITERAL_STRING("plugin"), PR_FALSE);
 
   // fill viewport and auto-resize
   NS_NAMED_LITERAL_STRING(percent100, "100%");
--- a/content/html/document/src/nsVideoDocument.cpp
+++ b/content/html/document/src/nsVideoDocument.cpp
@@ -112,17 +112,17 @@ nsVideoDocument::CreateSyntheticVideoDoc
   // make content
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::video, nsnull,
                                            kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_FAILURE);
 
   nsRefPtr<nsHTMLMediaElement> element =
     static_cast<nsHTMLMediaElement*>(NS_NewHTMLVideoElement(nodeInfo.forget(),
-                                     PR_FALSE));
+                                                            NOT_FROM_PARSER));
   if (!element)
     return NS_ERROR_OUT_OF_MEMORY;
   element->SetAutoplay(PR_TRUE);
   element->SetControls(PR_TRUE);
   element->LoadWithChannel(aChannel, aListener);
   UpdateTitle(aChannel);
 
   if (nsContentUtils::IsChildOfSameType(this)) {
--- a/content/html/document/test/test_bug404320.html
+++ b/content/html/document/test/test_bug404320.html
@@ -15,16 +15,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="content">
   <iframe id="testIframe"></iframe>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 404320 **/
 
+SimpleTest.waitForExplicitFinish();
+
 var win = document.getElementById("testIframe").contentWindow;
 var doc = document.getElementById("testIframe").contentDocument;
 
 function testFormatBlock(tag, withAngleBrackets, shouldSucceed)
 {
   win.getSelection().selectAllChildren(doc.body.firstChild);
   doc.execCommand("FormatBlock", false,
                   withAngleBrackets ? tag : "<" + tag + ">");
@@ -71,15 +73,20 @@ var goodTags = [ "address",
                  "h6",
                  "p",
                  "pre" ];
 var badTags =  [ "b",
                  "i",
                  "span",
                  "foo" ];
 
-formatBlockTests(goodTags, true);
-formatBlockTests(badTags, false);
+function runTests() {
+  formatBlockTests(goodTags, true);
+  formatBlockTests(badTags, false);
+  SimpleTest.finish();
+}
+
+addLoadEvent(runTests);
 
 </script>
 </pre>
 </body>
 </html>
--- a/content/media/test/test_error_in_video_document.html
+++ b/content/media/test/test_error_in_video_document.html
@@ -21,16 +21,21 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script type="application/javascript">
 
 /** Test for Bug 604067 **/
 
 var f = document.createElement("iframe");
 
 function check() {
   var v = document.body.getElementsByTagName("iframe")[0].contentDocument.body.getElementsByTagName("video")[0];
+  
+  // Debug info for Bug 608634
+  ok(true, "iframe src=" + document.body.getElementsByTagName("iframe")[0].src);
+  ok(true, "video src=" + v.src);
+  
   ok(v.error && v.error.code == MediaError.MEDIA_ERR_DECODE, "Must have error set to MEDIA_ERR_DECODE");
   SimpleTest.finish();
 }
 
 // Find an error test that we'd think we should be able to play (if it
 // wasn't already known to fail).
 var t = getPlayableVideo(gErrorTests);
 if (t != null) {
--- a/content/svg/content/src/nsSVGElement.h
+++ b/content/svg/content/src/nsSVGElement.h
@@ -463,17 +463,17 @@ NS_NewSVG##_elementName##Element(nsICont
                                                                              \
   return rv;                                                                 \
 }
 
 #define NS_IMPL_NS_NEW_SVG_ELEMENT_CHECK_PARSER(_elementName)                \
 nsresult                                                                     \
 NS_NewSVG##_elementName##Element(nsIContent **aResult,                       \
                                  already_AddRefed<nsINodeInfo> aNodeInfo,    \
-                                 PRUint32 aFromParser)                       \
+                                 FromParser aFromParser)                     \
 {                                                                            \
   nsRefPtr<nsSVG##_elementName##Element> it =                                \
     new nsSVG##_elementName##Element(aNodeInfo, aFromParser);                \
   if (!it)                                                                   \
     return NS_ERROR_OUT_OF_MEMORY;                                           \
                                                                              \
   nsresult rv = it->Init();                                                  \
                                                                              \
--- a/content/svg/content/src/nsSVGElementFactory.cpp
+++ b/content/svg/content/src/nsSVGElementFactory.cpp
@@ -42,16 +42,18 @@
 #include "nsIAtom.h"
 #include "nsINodeInfo.h"
 #include "nsGkAtoms.h"
 #include "nsContentDLF.h"
 #include "nsContentUtils.h"
 #include "nsSVGUtils.h"
 #include "nsDebug.h"
 
+using namespace mozilla::dom;
+
 nsresult
 NS_NewSVGAElement(nsIContent **aResult,
                   already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGAltGlyphElement(nsIContent **aResult,
                          already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGPolylineElement(nsIContent **aResult,
@@ -72,17 +74,17 @@ nsresult
 NS_NewSVGRectElement(nsIContent **aResult,
                      already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGGElement(nsIContent **aResult,
                   already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGSVGElement(nsIContent **aResult,
                     already_AddRefed<nsINodeInfo> aNodeInfo,
-                    PRUint32 aFromParser);
+                    FromParser aFromParser);
 nsresult
 NS_NewSVGForeignObjectElement(nsIContent **aResult,
                               already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGPathElement(nsIContent **aResult,
                      already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGTextElement(nsIContent **aResult,
@@ -112,17 +114,17 @@ nsresult
 NS_NewSVGDefsElement(nsIContent **aResult,
                      already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGDescElement(nsIContent **aResult,
                      already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGScriptElement(nsIContent **aResult,
                        already_AddRefed<nsINodeInfo> aNodeInfo,
-                       PRUint32 aFromParser);
+                       FromParser aFromParser);
 nsresult
 NS_NewSVGUseElement(nsIContent **aResult,
                     already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGSymbolElement(nsIContent **aResult,
                        already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGMarkerElement(nsIContent **aResult,
@@ -236,17 +238,17 @@ NS_NewSVGMpathElement(nsIContent **aResu
                       already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGSetElement(nsIContent **aResult,
                     already_AddRefed<nsINodeInfo> aNodeInfo);
 #endif // MOZ_SMIL
 
 nsresult
 NS_NewSVGElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo,
-                 PRUint32 aFromParser)
+                 FromParser aFromParser)
 {
   NS_PRECONDITION(NS_SVGEnabled(),
                   "creating an SVG element while SVG disabled");
 
   static const char kSVGStyleSheetURI[] = "resource://gre/res/svg.css";
 
   // this bit of code is to load svg.css on demand
   nsIDocument *doc = aNodeInfo.get()->GetDocument();
--- a/content/svg/content/src/nsSVGSVGElement.cpp
+++ b/content/svg/content/src/nsSVGSVGElement.cpp
@@ -67,16 +67,17 @@
 #include "nsSMILAnimationController.h"
 #include "nsSMILTypes.h"
 #include "nsIContentIterator.h"
 
 nsresult NS_NewContentIterator(nsIContentIterator** aInstancePtrResult);
 #endif // MOZ_SMIL
 
 using namespace mozilla;
+using namespace mozilla::dom;
 
 NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGTranslatePoint::DOMVal, mElement)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGTranslatePoint::DOMVal)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGTranslatePoint::DOMVal)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGTranslatePoint::DOMVal)
   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGPoint)
@@ -191,45 +192,42 @@ NS_INTERFACE_TABLE_HEAD(nsSVGSVGElement)
                            nsIDOMSVGZoomAndPan)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGSVGElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGSVGElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGSVGElement::nsSVGSVGElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                 PRUint32 aFromParser)
+                                 FromParser aFromParser)
   : nsSVGSVGElementBase(aNodeInfo),
     mCoordCtx(nsnull),
     mViewportWidth(0),
     mViewportHeight(0),
     mCurrentTranslate(0.0f, 0.0f),
     mCurrentScale(1.0f),
     mPreviousTranslate(0.0f, 0.0f),
     mPreviousScale(1.0f),
     mRedrawSuspendCount(0)
 #ifdef MOZ_SMIL
-    ,mStartAnimationOnBindToTree(!aFromParser)
+  , mStartAnimationOnBindToTree(!aFromParser)
 #endif // MOZ_SMIL
 {
 }
 
 //----------------------------------------------------------------------
 // nsIDOMNode methods
 
 // From NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGSVGElement)
 nsresult
 nsSVGSVGElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
 {
   *aResult = nsnull;
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
-  nsSVGSVGElement *it = new nsSVGSVGElement(ni.forget(), PR_FALSE);
-  if (!it) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
+  nsSVGSVGElement *it = new nsSVGSVGElement(ni.forget(), NOT_FROM_PARSER);
 
   nsCOMPtr<nsINode> kungFuDeathGrip = it;
   nsresult rv = it->Init();
   rv |= CopyInnerTo(it);
   if (NS_SUCCEEDED(rv)) {
     kungFuDeathGrip.swap(*aResult);
   }
 
--- a/content/svg/content/src/nsSVGSVGElement.h
+++ b/content/svg/content/src/nsSVGSVGElement.h
@@ -46,16 +46,17 @@
 #include "nsIDOMSVGLocatable.h"
 #include "nsIDOMSVGZoomAndPan.h"
 #include "nsIDOMSVGMatrix.h"
 #include "nsIDOMSVGPoint.h"
 #include "nsSVGLength2.h"
 #include "nsSVGEnum.h"
 #include "nsSVGViewBox.h"
 #include "nsSVGPreserveAspectRatio.h"
+#include "mozilla/dom/FromParser.h"
 
 #ifdef MOZ_SMIL
 class nsSMILTimeContainer;
 #endif // MOZ_SMIL
 
 #define QI_AND_CAST_TO_NSSVGSVGELEMENT(base)                                  \
   (nsCOMPtr<nsIDOMSVGSVGElement>(do_QueryInterface(base)) ?                   \
    static_cast<nsSVGSVGElement*>(base.get()) : nsnull)
@@ -128,18 +129,19 @@ class nsSVGSVGElement : public nsSVGSVGE
                         public nsIDOMSVGZoomAndPan
 {
   friend class nsSVGOuterSVGFrame;
   friend class nsSVGInnerSVGFrame;
 
 protected:
   friend nsresult NS_NewSVGSVGElement(nsIContent **aResult,
                                       already_AddRefed<nsINodeInfo> aNodeInfo,
-                                      PRUint32 aFromParser);
-  nsSVGSVGElement(already_AddRefed<nsINodeInfo> aNodeInfo, PRUint32 aFromParser);
+                                      mozilla::dom::FromParser aFromParser);
+  nsSVGSVGElement(already_AddRefed<nsINodeInfo> aNodeInfo,
+                  mozilla::dom::FromParser aFromParser);
   
 public:
 
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
 #ifdef MOZ_SMIL
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsSVGSVGElement, nsSVGSVGElementBase)
 #endif // MOZ_SMIL
--- a/content/svg/content/src/nsSVGScriptElement.cpp
+++ b/content/svg/content/src/nsSVGScriptElement.cpp
@@ -44,29 +44,31 @@
 #include "nsCOMPtr.h"
 #include "nsSVGString.h"
 #include "nsIDocument.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "nsScriptElement.h"
 #include "nsIDOMText.h"
 
+using namespace mozilla::dom;
+
 typedef nsSVGElement nsSVGScriptElementBase;
 
 class nsSVGScriptElement : public nsSVGScriptElementBase,
                            public nsIDOMSVGScriptElement, 
                            public nsIDOMSVGURIReference,
                            public nsScriptElement
 {
 protected:
   friend nsresult NS_NewSVGScriptElement(nsIContent **aResult,
                                          already_AddRefed<nsINodeInfo> aNodeInfo,
-                                         PRUint32 aFromParser);
+                                         FromParser aFromParser);
   nsSVGScriptElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                     PRUint32 aFromParser);
+                     FromParser aFromParser);
   
 public:
   // interfaces:
   
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGSCRIPTELEMENT
   NS_DECL_NSIDOMSVGURIREFERENCE
 
@@ -128,37 +130,34 @@ NS_INTERFACE_TABLE_HEAD(nsSVGScriptEleme
                            nsIScriptElement, nsIMutationObserver)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGScriptElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGScriptElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGScriptElement::nsSVGScriptElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                       PRUint32 aFromParser)
+                                       FromParser aFromParser)
   : nsSVGScriptElementBase(aNodeInfo)
   , nsScriptElement(aFromParser)
 {
   mDoneAddingChildren = !aFromParser;
   AddMutationObserver(this);
 }
 
 //----------------------------------------------------------------------
 // nsIDOMNode methods
 
 nsresult
 nsSVGScriptElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
 {
   *aResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
-  nsSVGScriptElement* it = new nsSVGScriptElement(ni.forget(), PR_FALSE);
-  if (!it) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
+  nsSVGScriptElement* it = new nsSVGScriptElement(ni.forget(), NOT_FROM_PARSER);
 
   nsCOMPtr<nsINode> kungFuDeathGrip = it;
   nsresult rv = it->Init();
   rv |= CopyInnerTo(it);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // The clone should be marked evaluated if we are.
   it->mAlreadyStarted = mAlreadyStarted;
--- a/content/svg/content/src/nsSVGUseElement.cpp
+++ b/content/svg/content/src/nsSVGUseElement.cpp
@@ -339,17 +339,18 @@ nsSVGUseElement::CreateAnonymousContent(
       return nsnull;
 
     nsCOMPtr<nsINodeInfo> nodeInfo;
     nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::svg, nsnull, kNameSpaceID_SVG);
     if (!nodeInfo)
       return nsnull;
 
     nsCOMPtr<nsIContent> svgNode;
-    NS_NewSVGSVGElement(getter_AddRefs(svgNode), nodeInfo.forget(), PR_FALSE);
+    NS_NewSVGSVGElement(getter_AddRefs(svgNode), nodeInfo.forget(),
+                        NOT_FROM_PARSER);
 
     if (!svgNode)
       return nsnull;
     
     if (newcontent->HasAttr(kNameSpaceID_None, nsGkAtoms::viewBox)) {
       nsAutoString viewbox;
       newcontent->GetAttr(kNameSpaceID_None, nsGkAtoms::viewBox, viewbox);
       svgNode->SetAttr(kNameSpaceID_None, nsGkAtoms::viewBox, viewbox, PR_FALSE);
--- a/content/svg/content/src/nsSVGUseElement.h
+++ b/content/svg/content/src/nsSVGUseElement.h
@@ -41,28 +41,29 @@
 #include "nsIDOMSVGURIReference.h"
 #include "nsIDOMSVGUseElement.h"
 #include "nsStubMutationObserver.h"
 #include "nsSVGGraphicElement.h"
 #include "nsSVGLength2.h"
 #include "nsSVGString.h"
 #include "nsTArray.h"
 #include "nsReferencedElement.h"
+#include "mozilla/dom/FromParser.h"
 
 class nsIContent;
 class nsINodeInfo;
 
 #define NS_SVG_USE_ELEMENT_IMPL_CID \
 { 0x55fb86fe, 0xd81f, 0x4ae4, \
   { 0x80, 0x3f, 0xeb, 0x90, 0xfe, 0xe0, 0x7a, 0xe9 } }
 
 nsresult
 NS_NewSVGSVGElement(nsIContent **aResult,
                     already_AddRefed<nsINodeInfo> aNodeInfo,
-                    PRUint32 aFromParser);
+                    mozilla::dom::FromParser aFromParser);
 
 typedef nsSVGGraphicElement nsSVGUseElementBase;
 
 class nsSVGUseElement : public nsSVGUseElementBase,
                         public nsIDOMSVGURIReference,
                         public nsIDOMSVGUseElement,
                         public nsStubMutationObserver
 {
--- a/content/xbl/src/nsXBLContentSink.cpp
+++ b/content/xbl/src/nsXBLContentSink.cpp
@@ -865,17 +865,17 @@ nsXBLContentSink::ConstructParameter(con
     mMethod->AddParameter(nsDependentString(name));
   }
 }
 
 nsresult
 nsXBLContentSink::CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
                                 nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
                                 nsIContent** aResult, PRBool* aAppendContent,
-                                PRUint32 aFromParser)
+                                FromParser aFromParser)
 {
 #ifdef MOZ_XUL
   if (!aNodeInfo->NamespaceEquals(kNameSpaceID_XUL)) {
 #endif
     return nsXMLContentSink::CreateElement(aAtts, aAttsCount, aNodeInfo,
                                            aLineNumber, aResult,
                                            aAppendContent, aFromParser);
 #ifdef MOZ_XUL
--- a/content/xbl/src/nsXBLContentSink.h
+++ b/content/xbl/src/nsXBLContentSink.h
@@ -119,17 +119,17 @@ protected:
                            nsIAtom* aTagName,
                            PRUint32 aLineNumber);
 
     PRBool NotifyForDocElement() { return PR_FALSE; }
 
     nsresult CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
                            nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
                            nsIContent** aResult, PRBool* aAppendContent,
-                           PRUint32 aFromParser);
+                           mozilla::dom::FromParser aFromParser);
     
     nsresult AddAttributes(const PRUnichar** aAtts, 
                            nsIContent* aContent);
 
 #ifdef MOZ_XUL    
     nsresult AddAttributesToXULPrototype(const PRUnichar **aAtts, 
                                          PRUint32 aAttsCount, 
                                          nsXULPrototypeElement* aElement);
--- a/content/xbl/src/nsXBLDocumentInfo.cpp
+++ b/content/xbl/src/nsXBLDocumentInfo.cpp
@@ -322,21 +322,19 @@ nsXBLDocGlobalObject::EnsureScriptEnviro
   JSAutoRequest ar(cx);
 
   // nsJSEnvironment set the error reporter to NS_ScriptErrorReporter so
   // we must apparently override that with our own (although it isn't clear 
   // why - see bug 339647)
   JS_SetErrorReporter(cx, XBL_ProtoErrorReporter);
 
   nsIPrincipal *principal = GetPrincipal();
-  nsCString origin;
   JSCompartment *compartment;
 
-  principal->GetOrigin(getter_Copies(origin));
-  rv = xpc_CreateGlobalObject(cx, &gSharedGlobalClass, origin, principal,
+  rv = xpc_CreateGlobalObject(cx, &gSharedGlobalClass, principal, nsnull,
                               false, &mJSObject, &compartment);
   NS_ENSURE_SUCCESS(rv, nsnull);
 
   ::JS_SetGlobalObject(cx, mJSObject);
 
   // Add an owning reference from JS back to us. This'll be
   // released when the JSObject is finalized.
   ::JS_SetPrivate(cx, mJSObject, this);
--- a/content/xml/document/src/nsXMLContentSink.cpp
+++ b/content/xml/document/src/nsXMLContentSink.cpp
@@ -97,16 +97,18 @@
 #include "nsIHTMLDocument.h"
 #include "mozAutoDocUpdate.h"
 #include "nsMimeTypes.h"
 
 #ifdef MOZ_SVG
 #include "nsHtml5SVGLoadDispatcher.h"
 #endif
 
+using namespace mozilla::dom;
+
 // XXX Open Issues:
 // 1) what's not allowed - We need to figure out which HTML tags
 //    (prefixed with a HTML namespace qualifier) are explicitly not
 //    allowed (if any).
 // 2) factoring code with nsHTMLContentSink - There's some amount of
 //    common code between this and the HTML content sink. This will
 //    increase as we support more and more HTML elements. How can code
 //    from the code be factored?
@@ -486,17 +488,17 @@ nsXMLContentSink::SetParser(nsIParser* a
   mParser = aParser;
   return NS_OK;
 }
 
 nsresult
 nsXMLContentSink::CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
                                 nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
                                 nsIContent** aResult, PRBool* aAppendContent,
-                                PRUint32 aFromParser)
+                                FromParser aFromParser)
 {
   NS_ASSERTION(aNodeInfo, "can't create element without nodeinfo");
 
   *aResult = nsnull;
   *aAppendContent = PR_TRUE;
   nsresult rv = NS_OK;
 
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
@@ -1015,17 +1017,18 @@ nsXMLContentSink::HandleStartElement(con
     return NS_OK;
   }
   
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   result = CreateElement(aAtts, aAttsCount, nodeInfo, aLineNumber,
-                         getter_AddRefs(content), &appendContent, PR_TRUE);
+                         getter_AddRefs(content), &appendContent,
+                         FROM_PARSER_NETWORK);
   NS_ENSURE_SUCCESS(result, result);
 
   // Have to do this before we push the new content on the stack... and have to
   // do that before we set attributes, call BindToTree, etc.  Ideally we'd push
   // on the stack inside CreateElement (which is effectively what the HTML sink
   // does), but that's hard with all the subclass overrides going on.
   nsCOMPtr<nsIContent> parent = GetCurrentContent();
   
--- a/content/xml/document/src/nsXMLContentSink.h
+++ b/content/xml/document/src/nsXMLContentSink.h
@@ -42,16 +42,17 @@
 #include "nsIXMLContentSink.h"
 #include "nsIExpatSink.h"
 #include "nsIDocumentTransformer.h"
 #include "nsTArray.h"
 #include "nsCOMPtr.h"
 #include "nsCRT.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDTD.h"
+#include "mozilla/dom/FromParser.h"
 
 class nsIDocument;
 class nsIURI;
 class nsIContent;
 class nsINodeInfo;
 class nsIParser;
 class nsIViewManager;
 
@@ -132,17 +133,17 @@ protected:
   //  return TRUE if this call set the root element
   virtual PRBool SetDocElement(PRInt32 aNameSpaceID, 
                                nsIAtom *aTagName,
                                nsIContent *aContent);
   virtual PRBool NotifyForDocElement() { return PR_TRUE; }
   virtual nsresult CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
                                  nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
                                  nsIContent** aResult, PRBool* aAppendContent,
-                                 PRUint32 aFromParser);
+                                 mozilla::dom::FromParser aFromParser);
 
   // aParent is allowed to be null here if this is the root content
   // being closed
   virtual nsresult CloseElement(nsIContent* aContent);
 
   virtual nsresult FlushText(PRBool aReleaseTextNode = PR_TRUE);
 
   nsresult AddContentAsLeaf(nsIContent *aContent);
--- a/content/xml/document/src/nsXMLFragmentContentSink.cpp
+++ b/content/xml/document/src/nsXMLFragmentContentSink.cpp
@@ -58,16 +58,18 @@
 #include "nsContentUtils.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsNetUtil.h"
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
 #include "nsTArray.h"
 #include "nsCycleCollectionParticipant.h"
 
+using namespace mozilla::dom;
+
 class nsXMLFragmentContentSink : public nsXMLContentSink,
                                  public nsIFragmentContentSink
 {
 public:
   nsXMLFragmentContentSink(PRBool aAllContent = PR_FALSE);
   virtual ~nsXMLFragmentContentSink();
 
   NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
@@ -112,17 +114,17 @@ public:
 
 protected:
   virtual PRBool SetDocElement(PRInt32 aNameSpaceID, 
                                nsIAtom *aTagName,
                                nsIContent *aContent);
   virtual nsresult CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
                                  nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
                                  nsIContent** aResult, PRBool* aAppendContent,
-                                 PRUint32 aFromParser);
+                                 mozilla::dom::FromParser aFromParser);
   virtual nsresult CloseElement(nsIContent* aContent);
 
   virtual void MaybeStartLayout(PRBool aIgnorePendingSheets);
 
   // nsContentSink overrides
   virtual nsresult ProcessStyleLink(nsIContent* aElement,
                                     const nsSubstring& aHref,
                                     PRBool aAlternate,
@@ -254,24 +256,24 @@ nsXMLFragmentContentSink::SetDocElement(
   // this is a fragment, not a document
   return PR_FALSE;
 }
 
 nsresult
 nsXMLFragmentContentSink::CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
                                         nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
                                         nsIContent** aResult, PRBool* aAppendContent,
-                                        PRUint32 aFromParser)
+                                        FromParser /*aFromParser*/)
 {
   // Claim to not be coming from parser, since we don't do any of the
   // fancy CloseElement stuff.
   nsresult rv = nsXMLContentSink::CreateElement(aAtts, aAttsCount,
                                                 aNodeInfo, aLineNumber,
                                                 aResult, aAppendContent,
-                                                PR_FALSE);
+                                                NOT_FROM_PARSER);
 
   // When we aren't grabbing all of the content we, never open a doc
   // element, we run into trouble on the first element, so we don't append,
   // and simply push this onto the content stack.
   if (!mAllContent && mContentStack.Length() == 0) {
     *aAppendContent = PR_FALSE;
   }
 
--- a/content/xslt/src/xslt/txMozillaTextOutput.cpp
+++ b/content/xslt/src/xslt/txMozillaTextOutput.cpp
@@ -51,16 +51,18 @@
 #include "nsIParser.h"
 #include "nsICharsetAlias.h"
 #include "nsIPrincipal.h"
 #include "txURIUtils.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentUtils.h"
 #include "nsGkAtoms.h"
 
+using namespace mozilla::dom;
+
 txMozillaTextOutput::txMozillaTextOutput(nsIDOMDocument* aSourceDocument,
                                          nsIDOMDocument* aResultDocument,
                                          nsITransformObserver* aObserver)
 {
     mObserver = do_GetWeakReference(aObserver);
     createResultDocument(aSourceDocument, aResultDocument);
 }
 
@@ -288,11 +290,10 @@ txMozillaTextOutput::createXHTMLElement(
 {
     *aResult = nsnull;
 
     nsCOMPtr<nsINodeInfo> ni;
     ni = mDocument->NodeInfoManager()->
         GetNodeInfo(aName, nsnull, kNameSpaceID_XHTML);
     NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
-    return NS_NewHTMLElement(aResult, ni.forget(), PR_FALSE);
+    return NS_NewHTMLElement(aResult, ni.forget(), NOT_FROM_PARSER);
 }
-
--- a/content/xslt/src/xslt/txMozillaXMLOutput.cpp
+++ b/content/xslt/src/xslt/txMozillaXMLOutput.cpp
@@ -68,16 +68,18 @@
 #include "nsIHTMLContentSink.h"
 #include "nsContentUtils.h"
 #include "txXMLUtils.h"
 #include "nsContentSink.h"
 #include "nsINode.h"
 #include "nsContentCreatorFunctions.h"
 #include "txError.h"
 
+using namespace mozilla::dom;
+
 #define TX_ENSURE_CURRENTNODE                           \
     NS_ASSERTION(mCurrentNode, "mCurrentNode is NULL"); \
     if (!mCurrentNode)                                  \
         return NS_ERROR_UNEXPECTED
 
 txMozillaXMLOutput::txMozillaXMLOutput(const nsSubstring& aRootName,
                                        PRInt32 aRootNsID,
                                        txOutputFormat* aFormat,
@@ -252,18 +254,25 @@ txMozillaXMLOutput::endDocument(nsresult
     nsresult rv = closePrevious(PR_TRUE);
     if (NS_FAILED(rv)) {
         if (mNotifier) {
             mNotifier->OnTransformEnd(rv);
         }
         
         return rv;
     }
-    // This should really be handled by nsIDocument::EndLoad
-    mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE);
+
+    if (mCreatingNewDocument) {
+        // This should really be handled by nsIDocument::EndLoad
+        mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE);
+        nsScriptLoader* loader = mDocument->ScriptLoader();
+        if (loader) {
+            loader->ParsingComplete(PR_FALSE);
+        }
+    }
 
     if (!mRefreshString.IsEmpty()) {
         nsPIDOMWindow *win = mDocument->GetWindow();
         if (win) {
             nsCOMPtr<nsIRefreshURI> refURI =
                 do_QueryInterface(win->GetDocShell());
             if (refURI) {
                 refURI->SetupRefreshURIFromHeader(mDocument->GetDocBaseURI(),
@@ -305,30 +314,42 @@ txMozillaXMLOutput::endElement()
 
     // Handle html-elements
     if (!mNoFixup) {
         if (element->IsHTML()) {
             rv = endHTMLElement(element);
             NS_ENSURE_SUCCESS(rv, rv);
         }
 
-        // Handle script elements
-        if (element->Tag() == nsGkAtoms::script &&
-            (element->IsHTML() ||
-            element->GetNameSpaceID() == kNameSpaceID_SVG)) {
+        // Handle elements that are different when parser-created
+        PRInt32 ns = element->GetNameSpaceID();
+        nsIAtom* localName = element->Tag();
+
+        if ((ns == kNameSpaceID_XHTML && (localName == nsGkAtoms::script ||
+                                          localName == nsGkAtoms::title ||
+                                          localName == nsGkAtoms::object ||
+                                          localName == nsGkAtoms::applet ||
+                                          localName == nsGkAtoms::select ||
+                                          localName == nsGkAtoms::textarea)) ||
+            (ns == kNameSpaceID_SVG && (localName == nsGkAtoms::script ||
+                                        localName == nsGkAtoms::title))) {
 
             rv = element->DoneAddingChildren(PR_TRUE);
 
             // If the act of insertion evaluated the script, we're fine.
             // Else, add this script element to the array of loading scripts.
             if (rv == NS_ERROR_HTMLPARSER_BLOCK) {
                 nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(element);
                 rv = mNotifier->AddScriptElement(sele);
                 NS_ENSURE_SUCCESS(rv, rv);
             }
+        } else if (ns == kNameSpaceID_XHTML &&
+                   (localName == nsGkAtoms::input ||
+                    localName == nsGkAtoms::button)) {
+          element->DoneCreatingElement();
         }
     }
 
     if (mCreatingNewDocument) {
         // Handle all sorts of stylesheets
         nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
             do_QueryInterface(mCurrentNode);
         if (ssle) {
@@ -426,16 +447,23 @@ txMozillaXMLOutput::processingInstructio
 
 nsresult
 txMozillaXMLOutput::startDocument()
 {
     if (mNotifier) {
         mNotifier->OnTransformStart();
     }
 
+    if (mCreatingNewDocument) {
+        nsScriptLoader* loader = mDocument->ScriptLoader();
+        if (loader) {
+            loader->BeginDeferringScripts();
+        }
+    }
+
     return NS_OK;
 }
 
 nsresult
 txMozillaXMLOutput::startElement(nsIAtom* aPrefix, nsIAtom* aLocalName,
                                  nsIAtom* aLowercaseLocalName,
                                  const PRInt32 aNsID)
 {
@@ -531,17 +559,19 @@ txMozillaXMLOutput::startElementInternal
     mTableState = NORMAL;
     mOpenedElementIsHTML = PR_FALSE;
 
     // Create the element
     nsCOMPtr<nsINodeInfo> ni;
     ni = mNodeInfoManager->GetNodeInfo(aLocalName, aPrefix, aNsID);
     NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
-    NS_NewElement(getter_AddRefs(mOpenedElement), aNsID, ni.forget(), PR_FALSE);
+    NS_NewElement(getter_AddRefs(mOpenedElement), aNsID, ni.forget(),
+                  mCreatingNewDocument ?
+                  FROM_PARSER_XSLT : FROM_PARSER_FRAGMENT);
 
     // Set up the element and adjust state
     if (!mNoFixup) {
         if (aNsID == kNameSpaceID_XHTML) {
             mOpenedElementIsHTML = (mOutputFormat.mMethod == eHTMLOutput);
             rv = startHTMLElement(mOpenedElement, mOpenedElementIsHTML);
             NS_ENSURE_SUCCESS(rv, rv);
 
@@ -942,17 +972,19 @@ txMozillaXMLOutput::createHTMLElement(ns
 
     *aResult = nsnull;
 
     nsCOMPtr<nsINodeInfo> ni;
     ni = mNodeInfoManager->GetNodeInfo(aName, nsnull,
                                        kNameSpaceID_XHTML);
     NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
-    return NS_NewHTMLElement(aResult, ni.forget(), PR_FALSE);
+    return NS_NewHTMLElement(aResult, ni.forget(), mCreatingNewDocument ?
+        FROM_PARSER_XSLT : FROM_PARSER_FRAGMENT);
+
 }
 
 txTransformNotifier::txTransformNotifier()
     : mPendingStylesheetCount(0),
       mInTransform(PR_FALSE)      
 {
 }
 
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -3691,18 +3691,19 @@ nsXULDocument::CreateElementFromPrototyp
         newNodeInfo = mNodeInfoManager->GetNodeInfo(aPrototype->mNodeInfo->NameAtom(),
                                                     aPrototype->mNodeInfo->GetPrefixAtom(),
                                                     aPrototype->mNodeInfo->NamespaceID());
         if (!newNodeInfo) return NS_ERROR_OUT_OF_MEMORY;
         nsCOMPtr<nsIContent> content;
         PRInt32 ns = newNodeInfo->NamespaceID();
         nsCOMPtr<nsINodeInfo> xtfNi = newNodeInfo;
         rv = NS_NewElement(getter_AddRefs(content), ns, newNodeInfo.forget(),
-                           PR_FALSE);
-        if (NS_FAILED(rv)) return rv;
+                           NOT_FROM_PARSER);
+        if (NS_FAILED(rv))
+            return rv;
 
         result = content->AsElement();
 
 #ifdef MOZ_XTF
         if (result && xtfNi->NamespaceID() > kNameSpaceID_LastBuiltin) {
             result->BeginAddingChildren();
         }
 #endif
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -727,22 +727,20 @@ nsXULPDGlobalObject::EnsureScriptEnviron
     // attach it as the global for this context.  Then, ::SetScriptContext
     // will re-fetch the global and set it up in our language globals array.
     if (lang_id == nsIProgrammingLanguage::JAVASCRIPT) {
       // some special JS specific code we should abstract
       JSContext *cx = (JSContext *)ctxNew->GetNativeContext();
       JSAutoRequest ar(cx);
 
       nsIPrincipal *principal = GetPrincipal();
-      nsCString origin;
       JSObject *newGlob;
       JSCompartment *compartment;
 
-      principal->GetOrigin(getter_Copies(origin));
-      rv = xpc_CreateGlobalObject(cx, &gSharedGlobalClass, origin, principal,
+      rv = xpc_CreateGlobalObject(cx, &gSharedGlobalClass, principal, nsnull,
                                   false, &newGlob, &compartment);
       NS_ENSURE_SUCCESS(rv, nsnull);
 
       ::JS_SetGlobalObject(cx, newGlob);
 
       // Add an owning reference from JS back to us. This'll be
       // released when the JSObject is finalized.
       ::JS_SetPrivate(cx, newGlob, this);
--- a/content/xul/templates/src/nsXULContentBuilder.cpp
+++ b/content/xul/templates/src/nsXULContentBuilder.cpp
@@ -1399,17 +1399,17 @@ nsXULContentBuilder::CreateElement(PRInt
 
     nsresult rv;
     nsCOMPtr<nsIContent> result;
 
     nsCOMPtr<nsINodeInfo> nodeInfo;
     nodeInfo = doc->NodeInfoManager()->GetNodeInfo(aTag, nsnull, aNameSpaceID);
 
     rv = NS_NewElement(getter_AddRefs(result), aNameSpaceID, nodeInfo.forget(),
-                       PR_FALSE);
+                       NOT_FROM_PARSER);
     if (NS_FAILED(rv))
         return rv;
 
     *aResult = result;
     NS_ADDREF(*aResult);
     return NS_OK;
 }
 
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -69,16 +69,17 @@
 #include "nsTArray.h"
 #include "nsCSSValue.h"
 #include "nsIRunnable.h"
 #include "nsThreadUtils.h"
 #include "nsDOMEventTargetWrapperCache.h"
 
 // General helper includes
 #include "nsGlobalWindow.h"
+#include "nsHistory.h"
 #include "nsIContent.h"
 #include "nsIAttribute.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOM3Document.h"
 #include "nsIDOMXMLDocument.h"
 #include "nsIDOMNSDocument.h"
 #include "nsIDOMEvent.h"
@@ -656,17 +657,18 @@ static nsDOMClassInfoData sClassInfoData
                            ARRAY_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MimeType, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MimeTypeArray, nsMimeTypeArraySH,
                            ARRAY_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(BarProp, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(History, nsHistorySH,
-                           ARRAY_SCRIPTABLE_FLAGS)
+                           ARRAY_SCRIPTABLE_FLAGS |
+                           nsIXPCScriptable::WANT_PRECREATE)
   NS_DEFINE_CLASSINFO_DATA(Screen, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(DOMPrototype, nsDOMConstructorSH,
                            DOM_BASE_SCRIPTABLE_FLAGS |
                            nsIXPCScriptable::WANT_HASINSTANCE |
                            nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE)
   NS_DEFINE_CLASSINFO_DATA(DOMConstructor, nsDOMConstructorSH,
                            DOM_BASE_SCRIPTABLE_FLAGS |
@@ -4577,25 +4579,16 @@ NS_IMETHODIMP
 nsDOMClassInfo::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
                             JSObject * obj, JSObject * *_retval)
 {
   NS_WARNING("nsDOMClassInfo::OuterObject Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
 }
 
-NS_IMETHODIMP
-nsDOMClassInfo::InnerObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
-                            JSObject * obj, JSObject * *_retval)
-{
-  NS_WARNING("nsDOMClassInfo::InnerObject Don't call me!");
-
-  return NS_ERROR_UNEXPECTED;
-}
-
 static nsresult
 GetExternalClassInfo(nsScriptNameSpaceManager *aNameSpaceManager,
                      const nsString &aName,
                      const nsGlobalNameStruct *aStruct,
                      const nsGlobalNameStruct **aResult)
 {
   NS_ASSERTION(aStruct->mType ==
                  nsGlobalNameStruct::eTypeExternalClassInfoCreator,
@@ -6182,26 +6175,26 @@ ResolvePrototype(nsIXPConnect *aXPConnec
         }
       }
     }
   }
 
   {
     JSObject *winobj = aWin->FastGetGlobalJSObject();
 
-    JSAutoEnterCompartment ac;
-    if (!ac.enter(cx, winobj)) {
-      return NS_ERROR_UNEXPECTED;
-    }
-
     JSObject *proto = nsnull;
 
     if (class_parent_name) {
       jsval val;
 
+      JSAutoEnterCompartment ac;
+      if (!ac.enter(cx, winobj)) {
+        return NS_ERROR_UNEXPECTED;
+      }
+
       if (!::JS_LookupProperty(cx, winobj, CutPrefix(class_parent_name), &val)) {
         return NS_ERROR_UNEXPECTED;
       }
 
       JSObject *tmp = JSVAL_IS_OBJECT(val) ? JSVAL_TO_OBJECT(val) : nsnull;
 
       if (tmp) {
         if (!::JS_LookupProperty(cx, tmp, "prototype", &val)) {
@@ -6215,17 +6208,18 @@ ResolvePrototype(nsIXPConnect *aXPConnec
     }
 
     if (dot_prototype) {
       JSObject *xpc_proto_proto = ::JS_GetPrototype(cx, dot_prototype);
 
       if (proto &&
           (!xpc_proto_proto ||
            JS_GET_CLASS(cx, xpc_proto_proto) == sObjectClass)) {
-        if (!::JS_SetPrototype(cx, dot_prototype, proto)) {
+        if (!JS_WrapObject(cx, &proto) ||
+            !JS_SetPrototype(cx, dot_prototype, proto)) {
           return NS_ERROR_UNEXPECTED;
         }
       }
     } else {
       dot_prototype = ::JS_NewObject(cx, &sDOMConstructorProtoClass, proto,
                                      winobj);
       NS_ENSURE_TRUE(dot_prototype, NS_ERROR_OUT_OF_MEMORY);
     }
@@ -7092,17 +7086,17 @@ nsLocationSH::PreCreate(nsISupports *nat
   if (!ds) {
     NS_WARNING("Refusing to create a location in the wrong scope");
     return NS_ERROR_UNEXPECTED;
   }
 
   nsCOMPtr<nsIScriptGlobalObject> sgo = do_GetInterface(ds);
   if (!sgo) {
     NS_WARNING("Refusing to create a location in the wrong scope because the "
-	       "docshell is being destroyed");
+               "docshell is being destroyed");
     return NS_ERROR_UNEXPECTED;
   }
 
   *parentObj = sgo->GetGlobalJSObject();
   return NS_OK;
 }
 
 // DOM Navigator helper
@@ -9910,39 +9904,48 @@ nsStringArraySH::GetProperty(nsIXPConnec
 
   return NS_SUCCESS_I_DID_SOMETHING;
 }
 
 
 // History helper
 
 NS_IMETHODIMP
+nsHistorySH::PreCreate(nsISupports *nativeObj, JSContext *cx,
+                       JSObject *globalObj, JSObject **parentObj)
+{
+  nsHistory *history = (nsHistory *)nativeObj;
+  nsIDocShell *ds = history->GetDocShell();
+  if (!ds) {
+    NS_WARNING("Refusing to create a history object in the wrong scope");
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  nsCOMPtr<nsIScriptGlobalObject> sgo = do_GetInterface(ds);
+  if (!sgo) {
+    NS_WARNING("Refusing to create a history object in the wrong scope because the "
+               "docshell is being destroyed");
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  *parentObj = sgo->GetGlobalJSObject();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsHistorySH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                          JSObject *obj, jsid id, jsval *vp, PRBool *_retval)
 {
   PRBool is_number = PR_FALSE;
   GetArrayIndexFromId(cx, id, &is_number);
 
   if (!is_number) {
     return NS_OK;
   }
 
-  nsresult rv =
-    sSecMan->CheckPropertyAccess(cx, obj, mData->mName, sItem_id,
-                                 nsIXPCSecurityManager::ACCESS_CALL_METHOD);
-
-  if (NS_FAILED(rv)) {
-    // Let XPConnect know that the access was not granted.
-    *_retval = PR_FALSE;
-
-    return NS_OK;
-  }
-
-  // sec check
-
   return nsStringArraySH::GetProperty(wrapper, cx, obj, id, vp, _retval);
 }
 
 nsresult
 nsHistorySH::GetStringAt(nsISupports *aNative, PRInt32 aIndex,
                          nsAString& aResult)
 {
   if (aIndex < 0) {
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -1265,16 +1265,18 @@ protected:
   virtual ~nsHistorySH()
   {
   }
 
   virtual nsresult GetStringAt(nsISupports *aNative, PRInt32 aIndex,
                                nsAString& aResult);
 
 public:
+  NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
+                       JSObject *globalObj, JSObject **parentObj);
   NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                          JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
 
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsHistorySH(aData);
   }
 };
--- a/dom/base/nsHistory.h
+++ b/dom/base/nsHistory.h
@@ -53,16 +53,17 @@ public:
   virtual ~nsHistory();
 
   // nsISupports
   NS_DECL_ISUPPORTS
 
   // nsIDOMHistory
   NS_DECL_NSIDOMHISTORY
 
+  nsIDocShell *GetDocShell() { return mDocShell; }
   void SetDocShell(nsIDocShell *aDocShell);
 
 protected:
   nsresult GetSessionHistoryFromDocShell(nsIDocShell * aDocShell,
                                          nsISHistory ** aReturn);
 
   nsIDocShell* mDocShell;
 };
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -988,20 +988,16 @@ nsJSContext::DOMOperationCallback(JSCont
     const char jsdServiceCtrID[] = "@mozilla.org/js/jsd/debugger-service;1";
     nsCOMPtr<jsdIExecutionHook> jsdHook;
     nsCOMPtr<jsdIDebuggerService> jsds = do_GetService(jsdServiceCtrID, &rv);
 
     // Check if there's a user for the debugger service that's 'on' for us
     if (NS_SUCCEEDED(rv)) {
       jsds->GetDebuggerHook(getter_AddRefs(jsdHook));
       jsds->GetIsOn(&jsds_IsOn);
-      if (jsds_IsOn) { // If this is not true, the next call would start jsd...
-        rv = jsds->OnForRuntime(cx->runtime);
-        jsds_IsOn = NS_SUCCEEDED(rv);
-      }
     }
 
     // If there is a debug handler registered for this runtime AND
     // ((jsd is on AND has a hook) OR (jsd isn't on (something else debugs)))
     // then something useful will be done with our request to debug.
     debugPossible = ((jsds_IsOn && (jsdHook != nsnull)) || !jsds_IsOn);
   }
 #endif
@@ -2529,17 +2525,17 @@ nsJSContext::CreateNativeGlobalForInner(
     nsIScriptSecurityManager *ssm = nsContentUtils::GetSecurityManager();
     ssm->GetSystemPrincipal(getter_AddRefs(systemPrincipal));
   }
 
   nsresult rv = xpc->
           InitClassesWithNewWrappedGlobal(mContext,
                                           aNewInner, NS_GET_IID(nsISupports),
                                           aIsChrome ? systemPrincipal.get() : aPrincipal,
-                                          EmptyCString(), flags,
+                                          nsnull, flags,
                                           getter_AddRefs(jsholder));
   if (NS_FAILED(rv))
     return rv;
   jsholder->GetJSObject(reinterpret_cast<JSObject **>(aNativeGlobal));
   *aHolder = jsholder.get();
   NS_ADDREF(*aHolder);
   return NS_OK;
 }
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -845,17 +845,17 @@ TabChild::InitTabChildGlobal()
 
   nsISupports* scopeSupports =
     NS_ISUPPORTS_CAST(nsPIDOMEventTarget*, scope);
   JS_SetContextPrivate(cx, scopeSupports);
 
   nsresult rv =
     xpc->InitClassesWithNewWrappedGlobal(cx, scopeSupports,
                                          NS_GET_IID(nsISupports),
-                                         scope->GetPrincipal(), EmptyCString(),
+                                         scope->GetPrincipal(), nsnull,
                                          flags, getter_AddRefs(mGlobal));
   NS_ENSURE_SUCCESS(rv, false);
 
   nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(chromeHandler);
   NS_ENSURE_TRUE(root, false);
   root->SetParentTarget(scope);
   
   JSObject* global = nsnull;
--- a/dom/plugins/PluginInstanceParent.cpp
+++ b/dom/plugins/PluginInstanceParent.cpp
@@ -1436,12 +1436,12 @@ PluginInstanceParent::AnswerPluginFocusC
     return false;
 #endif
 }
 
 #ifdef OS_MACOSX
 void
 PluginInstanceParent::Invalidate()
 {
-    NPRect windowRect = {0, 0, mShWidth, mShHeight};
+    NPRect windowRect = {0, 0, mShHeight, mShWidth};
     RecvNPN_InvalidateRect(windowRect);
 }
 #endif
--- a/dom/plugins/PluginModuleParent.cpp
+++ b/dom/plugins/PluginModuleParent.cpp
@@ -122,16 +122,22 @@ PluginModuleParent::PluginModuleParent(c
 
     nsContentUtils::RegisterPrefCallback(kTimeoutPref, TimeoutChanged, this);
 }
 
 PluginModuleParent::~PluginModuleParent()
 {
     NS_ASSERTION(OkToCleanup(), "unsafe destruction");
 
+#ifdef OS_MACOSX
+    if (mCATimer) {
+        mCATimer->Cancel();
+    }
+#endif
+
     if (!mShutdown) {
         NS_WARNING("Plugin host deleted the module without shutting down.");
         NPError err;
         NP_Shutdown(&err);
     }
     NS_ASSERTION(mShutdown, "NP_Shutdown didn't");
 
     if (mSubprocess) {
@@ -906,37 +912,49 @@ PluginModuleParent::RecvPluginHideWindow
     NS_NOTREACHED(
         "PluginInstanceParent::RecvPluginHideWindow not implemented!");
     return false;
 #endif
 }
 
 #ifdef OS_MACOSX
 #define DEFAULT_REFRESH_MS 20 // CoreAnimation: 50 FPS
+
+void
+CAUpdate(nsITimer *aTimer, void *aClosure) {
+    nsTObserverArray<PluginInstanceParent*> *ips =
+        static_cast<nsTObserverArray<PluginInstanceParent*> *>(aClosure);
+    nsTObserverArray<PluginInstanceParent*>::ForwardIterator iter(*ips);
+    while (iter.HasMore()) {
+        iter.GetNext()->Invalidate();
+    }
+}
+
 void
 PluginModuleParent::AddToRefreshTimer(PluginInstanceParent *aInstance) {
     if (mCATimerTargets.Contains(aInstance)) {
         return;
     }
 
     mCATimerTargets.AppendElement(aInstance);
     if (mCATimerTargets.Length() == 1) {
-        mCATimer.Start(base::TimeDelta::FromMilliseconds(DEFAULT_REFRESH_MS),
-                       this, &PluginModuleParent::CAUpdate);
+        if (!mCATimer) {
+            nsresult rv;
+            nsCOMPtr<nsITimer> xpcomTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
+            if (NS_FAILED(rv)) {
+                NS_WARNING("Could not create Core Animation timer for plugin.");
+                return;
+            }
+            mCATimer = xpcomTimer;
+        }
+        mCATimer->InitWithFuncCallback(CAUpdate, &mCATimerTargets, DEFAULT_REFRESH_MS,
+                                       nsITimer::TYPE_REPEATING_SLACK);
     }
 }
 
 void
 PluginModuleParent::RemoveFromRefreshTimer(PluginInstanceParent *aInstance) {
     PRBool visibleRemoved = mCATimerTargets.RemoveElement(aInstance);
     if (visibleRemoved && mCATimerTargets.IsEmpty()) {
-        mCATimer.Stop();
-    }
-}
-
-void
-PluginModuleParent::CAUpdate() {
-    nsTObserverArray<PluginInstanceParent*>::ForwardIterator iter(mCATimerTargets);
-    while (iter.HasMore()) {
-        iter.GetNext()->Invalidate();
+        mCATimer->Cancel();
     }
 }
 #endif
--- a/dom/plugins/PluginModuleParent.h
+++ b/dom/plugins/PluginModuleParent.h
@@ -56,16 +56,17 @@
 #include "mozilla/plugins/PluginProcessParent.h"
 #include "mozilla/plugins/PluginIdentifierParent.h"
 
 #include "nsAutoPtr.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsIFileStreams.h"
 #include "nsTObserverArray.h"
+#include "nsITimer.h"
 
 namespace mozilla {
 namespace plugins {
 //-----------------------------------------------------------------------------
 
 class BrowserStreamParent;
 
 /**
@@ -259,18 +260,17 @@ private:
     nsNPAPIPlugin* mPlugin;
     time_t mProcessStartTime;
     ScopedRunnableMethodFactory<PluginModuleParent> mTaskFactory;
     nsString mPluginDumpID;
     nsString mBrowserDumpID;
     nsString mHangID;
 
 #ifdef OS_MACOSX
-    void CAUpdate();
-    base::RepeatingTimer<PluginModuleParent> mCATimer;
+    nsCOMPtr<nsITimer> mCATimer;
     nsTObserverArray<PluginInstanceParent*> mCATimerTargets;
 #endif
 };
 
 } // namespace plugins
 } // namespace mozilla
 
 #endif  // ifndef dom_plugins_PluginModuleParent_h
--- a/dom/src/threads/nsDOMWorker.cpp
+++ b/dom/src/threads/nsDOMWorker.cpp
@@ -1636,25 +1636,22 @@ nsDOMWorker::CompileGlobalObject(JSConte
 
   nsISupports* scopeSupports = NS_ISUPPORTS_CAST(nsIWorkerScope*, scope);
 
   nsIXPConnect* xpc = nsContentUtils::XPConnect();
 
   const PRUint32 flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES |
                          nsIXPConnect::OMIT_COMPONENTS_OBJECT;
 
-  nsCAutoString origin("DOM worker: ");
-  origin.AppendInt((PRUint64)this);
-
   nsCOMPtr<nsIXPConnectJSObjectHolder> globalWrapper;
   nsresult rv =
     xpc->InitClassesWithNewWrappedGlobal(aCx, scopeSupports,
                                          NS_GET_IID(nsISupports), nsnull,
-                                         origin, flags,
-                                         getter_AddRefs(globalWrapper));
+                                         NS_ISUPPORTS_CAST(nsIWorker*, this),
+                                         flags, getter_AddRefs(globalWrapper));
   NS_ENSURE_SUCCESS(rv, PR_FALSE);
 
   JSObject* global;
   rv = globalWrapper->GetJSObject(&global);
   NS_ENSURE_SUCCESS(rv, PR_FALSE);
 
   NS_ASSERTION(JS_GetGlobalObject(aCx) == global, "Global object mismatch!");
 
--- a/extensions/jssh/nsJSSh.cpp
+++ b/extensions/jssh/nsJSSh.cpp
@@ -613,17 +613,17 @@ NS_IMETHODIMP nsJSSh::Init()
     return NS_ERROR_FAILURE;
   }
   
   JS_SetErrorReporter(mJSContext, my_ErrorReporter);
 
   nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
   xpc->InitClassesWithNewWrappedGlobal(mJSContext, (nsIJSSh*)this,
                                        NS_GET_IID(nsISupports),
-                                       PR_TRUE,
+                                       mPrincipal, nsnull, PR_TRUE,
                                        getter_AddRefs(holder));
   if (!holder) {
     NS_ERROR("global initialization failed");
     return NS_ERROR_FAILURE;
   }
   
   holder->GetJSObject(&mGlobal);
   if (!mGlobal) {
--- a/gfx/thebes/GLContext.h
+++ b/gfx/thebes/GLContext.h
@@ -290,20 +290,21 @@ struct THEBES_API ContextFormat
         StrictBasicRGBA32,
         BasicRGB24,
         StrictBasicRGB24,
         BasicRGB16_565,
         StrictBasicRGB16_565
     };
 
     ContextFormat() {
-        memset(this, 0, sizeof(this));
+        memset(this, 0, sizeof(*this));
     }
 
     ContextFormat(const StandardContextFormat cf) {
+        memset(this, 0, sizeof(*this));
         switch (cf) {
         case BasicRGBA32:
             red = green = blue = alpha = 8;
             minRed = minGreen = minBlue = minAlpha = 1;
             break;
 
         case StrictBasicRGBA32:
             red = green = blue = alpha = 8;
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -1159,17 +1159,17 @@ XPCShellEnvironment::Init()
         NS_ERROR("Failed to get backstage pass from rtsvc!");
         return false;
     }
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = xpc->InitClassesWithNewWrappedGlobal(cx, backstagePass,
                                               NS_GET_IID(nsISupports),
                                               principal,
-                                              EmptyCString(),
+                                              nsnull,
                                               nsIXPConnect::
                                                   FLAG_SYSTEM_GLOBAL_OBJECT,
                                               getter_AddRefs(holder));
     if (NS_FAILED(rv)) {
         NS_ERROR("InitClassesWithNewWrappedGlobal failed!");
         return false;
     }
 
--- a/js/jsd/idl/jsdIDebuggerService.idl
+++ b/js/jsd/idl/jsdIDebuggerService.idl
@@ -67,22 +67,23 @@ interface jsdIExecutionHook;
 interface jsdICallHook;
 interface jsdIEphemeral;
 interface jsdIContext;
 interface jsdIStackFrame;
 interface jsdIScript;
 interface jsdIValue;
 interface jsdIObject;
 interface jsdIProperty;
+interface jsdIActivationCallback;
 
 /**
  * Debugger service.  It's not a good idea to have more than one active client of
  * the debugger service.
  */
-[scriptable, uuid(dc0a24db-f8ac-4889-80d0-6016545a2dda)]
+[scriptable, uuid(01769775-c77c-47f9-8848-0abbab404215)]
 interface jsdIDebuggerService : nsISupports
 {
     /** Internal use only. */
     [noscript] readonly attribute JSDContext        JSDContext;
 
     /**
      * Called when an error or warning occurs.
      */
@@ -211,29 +212,44 @@ interface jsdIDebuggerService : nsISuppo
     
     /**
      * |true| if the debugger service has been turned on.  This does not
      * necessarily mean another app is actively using the service, as the 
      * autostart pref may have turned the service on.
      */
     readonly attribute boolean isOn;
 
+
+    /**
+     * Synchronous activation of the debugger is no longer supported,
+     * and will throw an exception.
+     */
+    void on ();
+
     /**
      * Turn on the debugger.  This function should only be called from JavaScript
      * code.  The debugger will be enabled on the runtime the call is made on,
      * as determined by nsIXPCNativeCallContext.
+     *
+     * The debugger will be activated asynchronously, because there can be no JS
+     * on the stack when code is to be re-compiled for debug mode.
      */
-    void on ();
+    void asyncOn (in jsdIActivationCallback callback);
+    
     /**
-     * Turn on the debugger for a given runtime.
-     *
-     * @param rt The runtime you want to debug.  You cannot turn the debugger
-     *           on for multiple runtimes.
+     * Called by nsIXPConnect after it's had a chance to recompile for
+     * debug mode.
      */
-    [noscript] void onForRuntime (in JSRuntime rt);
+    [noscript] void activateDebugger(in JSRuntime rt);
+
+    /**
+     * Recompile all active scripts in the runtime for debugMode.
+     */
+    [noscript] void recompileForDebugMode(in JSRuntime rt, in PRBool mode);
+
     /**
      * Turn the debugger off.  This will invalidate all of your jsdIEphemeral
      * derived objects, and clear all of your breakpoints.  In theory you
      * should be able to turn the debugger back on at some later time without
      * any problems.
      */
     void off ();
 
@@ -453,16 +469,25 @@ interface jsdIFilter : nsISupports
      * Line number for the end of this filter.  Line numbers are one based.
      * Assigning a 0 to this attribute will tell the debugger to ignore from
      * |startLine| to the end of the file.
      */
     attribute unsigned long endLine;
 };
 
 /**
+ * Notify client code that debugMode has been activated.
+ */
+[scriptable, uuid(6da7f5fb-3a84-4abe-9e23-8b2045960732)]
+interface jsdIActivationCallback : nsISupports
+{
+    void onDebuggerActivated ();
+};
+
+/**
  * Pass an instance of one of these to jsdIDebuggerService::enterNestedEventLoop.
  */
 [scriptable, uuid(88bea60f-9b5d-4b39-b08b-1c3a278782c6)]
 interface jsdINestCallback : nsISupports
 {
     /**
      * This method will be called after pre-nesting work has completed, such
      * as pushing the js context and network event queue, but before the new
--- a/js/jsd/jsd_scpt.c
+++ b/js/jsd/jsd_scpt.c
@@ -580,21 +580,16 @@ jsd_NewScriptHookProc(
     JSD_ScriptHookProc      hook;
     void*                   hookData;
     
     JSD_ASSERT_VALID_CONTEXT(jsdc);
 
     if( JSD_IS_DANGEROUS_THREAD(jsdc) )
         return;
     
-#ifdef LIVEWIRE
-    if( 1 == lineno )
-        jsdlw_PreLoadSource(jsdc, LWDBG_GetCurrentApp(), filename, JS_TRUE );
-#endif
-    
     JSD_LOCK_SCRIPTS(jsdc);
     jsdscript = _newJSDScript(jsdc, cx, script, fun);
     JSD_UNLOCK_SCRIPTS(jsdc);
     if( ! jsdscript )
         return;
 
 #ifdef JSD_DUMP
     JSD_LOCK_SCRIPTS(jsdc);
@@ -606,17 +601,17 @@ jsd_NewScriptHookProc(
     /* local in case jsdc->scriptHook gets cleared on another thread */
     JSD_LOCK();
     hook = jsdc->scriptHook;
     hookData = jsdc->scriptHookData;
     JSD_UNLOCK();
 
     if( hook )
         hook(jsdc, jsdscript, JS_TRUE, hookData);
-}                
+}
 
 void
 jsd_DestroyScriptHookProc( 
                 JSContext   *cx,
                 JSScript    *script,
                 void*       callerdata )
 {
     JSDScript* jsdscript = NULL;
--- a/js/jsd/jsd_val.c
+++ b/js/jsd/jsd_val.c
@@ -784,16 +784,17 @@ jsd_GetScriptForValue(JSDContext* jsdc, 
 
     JS_BeginRequest(cx);
     call = JS_EnterCrossCompartmentCall(cx, JSVAL_TO_OBJECT(val));
     if (!call) {
         JS_EndRequest(cx);
 
         return NULL;
     }
+
     exceptionState = JS_SaveExceptionState(cx);
     fun = JS_ValueToFunction(cx, val);
     JS_RestoreExceptionState(cx, exceptionState);
     if (fun)
         script = JS_GetFunctionScript(cx, fun);
     JS_LeaveCrossCompartmentCall(call);
     JS_EndRequest(cx);
 
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -33,16 +33,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "jsdbgapi.h"
+#include "jslock.h"
 #include "jsd_xpc.h"
 
 #include "nsIXPConnect.h"
 #include "mozilla/ModuleUtils.h"
 #include "nsIServiceManager.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
@@ -2311,17 +2312,23 @@ jsdValue::GetWrappedValue()
 
     jsval *result;
     rv = cc->GetRetValPtr(&result);
     if (NS_FAILED(rv))
         return rv;
 
     if (result)
     {
+        JSContext *cx;
+        rv = cc->GetJSContext(&cx);
+        if (NS_FAILED(rv))
+            return rv;
         *result = JSD_GetValueWrappedJSVal (mCx, mValue);
+        if (!JS_WrapValue(cx, result))
+            return NS_ERROR_FAILURE;
         cc->SetReturnValueWasSet(PR_TRUE);
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 jsdValue::GetScript(jsdIScript **_rval)
@@ -2386,41 +2393,67 @@ jsdService::GetIsOn (PRBool *_rval)
 {
     *_rval = mOn;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 jsdService::On (void)
 {
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+jsdService::AsyncOn (jsdIActivationCallback *activationCallback)
+{
     nsresult  rv;
 
     /* get JS things from the CallContext */
     nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
     if (NS_FAILED(rv)) return rv;
 
     nsAXPCNativeCallContext *cc = nsnull;
     rv = xpc->GetCurrentNativeCallContext(&cc);
     if (NS_FAILED(rv)) return rv;
 
     JSContext *cx;
     rv = cc->GetJSContext (&cx);
     if (NS_FAILED(rv)) return rv;
+
+    mActivationCallback = activationCallback;
     
-    return OnForRuntime(JS_GetRuntime (cx));
-    
+    return xpc->SetDebugModeWhenPossible(PR_TRUE);
 }
 
 NS_IMETHODIMP
-jsdService::OnForRuntime (JSRuntime *rt)
+jsdService::RecompileForDebugMode (JSRuntime *rt, JSBool mode) {
+  NS_ASSERTION(NS_IsMainThread(), "wrong thread");
+
+  JSContext *cx;
+  JSContext *iter = NULL;
+
+  jsword currentThreadId = reinterpret_cast<jsword>(js_CurrentThreadId());
+
+  while ((cx = JS_ContextIterator (rt, &iter))) {
+    if (JS_GetContextThread(cx) == currentThreadId) {
+      JS_SetDebugMode(cx, mode);
+    }
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+jsdService::ActivateDebugger (JSRuntime *rt)
 {
     if (mOn)
         return (rt == mRuntime) ? NS_OK : NS_ERROR_ALREADY_INITIALIZED;
 
     mRuntime = rt;
+    RecompileForDebugMode(rt, JS_TRUE);
 
     if (gLastGCProc == jsds_GCCallbackProc)
         /* condition indicates that the callback proc has not been set yet */
         gLastGCProc = JS_SetGCCallbackRT (rt, jsds_GCCallbackProc);
 
     mCx = JSD_DebuggerOnForUser (rt, NULL, NULL);
     if (!mCx)
         return NS_ERROR_FAILURE;
@@ -2460,16 +2493,20 @@ jsdService::OnForRuntime (JSRuntime *rt)
         JSD_SetFunctionHook (mCx, jsds_CallHookProc, NULL);
     else
         JSD_ClearFunctionHook (mCx);
     mOn = PR_TRUE;
 
 #ifdef DEBUG
     printf ("+++ JavaScript debugging hooks installed.\n");
 #endif
+
+    if (mActivationCallback)
+        return mActivationCallback->OnDebuggerActivated();
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 jsdService::Off (void)
 {
     if (!mOn)
         return NS_OK;
@@ -2510,16 +2547,23 @@ jsdService::Off (void)
     mCx = nsnull;
     mRuntime = nsnull;
     mOn = PR_FALSE;
 
 #ifdef DEBUG
     printf ("+++ JavaScript debugging hooks removed.\n");
 #endif
 
+    nsresult rv;
+    nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
+    if (NS_FAILED(rv))
+        return rv;
+
+    xpc->SetDebugModeWhenPossible(PR_FALSE);
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 jsdService::GetPauseDepth(PRUint32 *_rval)
 {
     NS_ENSURE_ARG_POINTER(_rval);
     *_rval = mPauseLevel;
@@ -2958,17 +3002,17 @@ jsdService::ExitNestedEventLoop (PRUint3
 /* hook attribute get/set functions */
 
 NS_IMETHODIMP
 jsdService::SetErrorHook (jsdIErrorHook *aHook)
 {
     mErrorHook = aHook;
 
     /* if the debugger isn't initialized, that's all we can do for now.  The
-     * OnForRuntime() method will do the rest when the coast is clear.
+     * ActivateDebugger() method will do the rest when the coast is clear.
      */
     if (!mCx || mPauseLevel)
         return NS_OK;
 
     if (aHook)
         JSD_SetErrorReporter (mCx, jsds_ErrorHookProc, NULL);
     else
         JSD_SetErrorReporter (mCx, NULL, NULL);
@@ -3002,17 +3046,17 @@ jsdService::GetBreakpointHook (jsdIExecu
 }
 
 NS_IMETHODIMP
 jsdService::SetDebugHook (jsdIExecutionHook *aHook)
 {    
     mDebugHook = aHook;
 
     /* if the debugger isn't initialized, that's all we can do for now.  The
-     * OnForRuntime() method will do the rest when the coast is clear.
+     * ActivateDebugger() method will do the rest when the coast is clear.
      */
     if (!mCx || mPauseLevel)
         return NS_OK;
 
     if (aHook)
         JSD_SetDebugBreakHook (mCx, jsds_ExecutionHookProc, NULL);
     else
         JSD_ClearDebugBreakHook (mCx);
@@ -3030,17 +3074,17 @@ jsdService::GetDebugHook (jsdIExecutionH
 }
 
 NS_IMETHODIMP
 jsdService::SetDebuggerHook (jsdIExecutionHook *aHook)
 {    
     mDebuggerHook = aHook;
 
     /* if the debugger isn't initialized, that's all we can do for now.  The
-     * OnForRuntime() method will do the rest when the coast is clear.
+     * ActivateDebugger() method will do the rest when the coast is clear.
      */
     if (!mCx || mPauseLevel)
         return NS_OK;
 
     if (aHook)
         JSD_SetDebuggerHook (mCx, jsds_ExecutionHookProc, NULL);
     else
         JSD_ClearDebuggerHook (mCx);
@@ -3058,17 +3102,17 @@ jsdService::GetDebuggerHook (jsdIExecuti
 }
 
 NS_IMETHODIMP
 jsdService::SetInterruptHook (jsdIExecutionHook *aHook)
 {    
     mInterruptHook = aHook;
 
     /* if the debugger isn't initialized, that's all we can do for now.  The
-     * OnForRuntime() method will do the rest when the coast is clear.
+     * ActivateDebugger() method will do the rest when the coast is clear.
      */
     if (!mCx || mPauseLevel)
         return NS_OK;
 
     if (aHook)
         JSD_SetInterruptHook (mCx, jsds_ExecutionHookProc, NULL);
     else
         JSD_ClearInterruptHook (mCx);
@@ -3086,17 +3130,17 @@ jsdService::GetInterruptHook (jsdIExecut
 }
 
 NS_IMETHODIMP
 jsdService::SetScriptHook (jsdIScriptHook *aHook)
 {    
     mScriptHook = aHook;
 
     /* if the debugger isn't initialized, that's all we can do for now.  The
-     * OnForRuntime() method will do the rest when the coast is clear.
+     * ActivateDebugger() method will do the rest when the coast is clear.
      */
     if (!mCx || mPauseLevel)
         return NS_OK;
     
     if (aHook)
         JSD_SetScriptHook (mCx, jsds_ScriptHookProc, NULL);
     /* we can't unset it if !aHook, because we still need to see script
      * deletes in order to Release the jsdIScripts held in JSDScript
@@ -3114,17 +3158,17 @@ jsdService::GetScriptHook (jsdIScriptHoo
 }
 
 NS_IMETHODIMP
 jsdService::SetThrowHook (jsdIExecutionHook *aHook)
 {    
     mThrowHook = aHook;
 
     /* if the debugger isn't initialized, that's all we can do for now.  The
-     * OnForRuntime() method will do the rest when the coast is clear.
+     * ActivateDebugger() method will do the rest when the coast is clear.
      */
     if (!mCx || mPauseLevel)
         return NS_OK;
 
     if (aHook)
         JSD_SetThrowHook (mCx, jsds_ExecutionHookProc, NULL);
     else
         JSD_ClearThrowHook (mCx);
@@ -3142,17 +3186,17 @@ jsdService::GetThrowHook (jsdIExecutionH
 }
 
 NS_IMETHODIMP
 jsdService::SetTopLevelHook (jsdICallHook *aHook)
 {    
     mTopLevelHook = aHook;
 
     /* if the debugger isn't initialized, that's all we can do for now.  The
-     * OnForRuntime() method will do the rest when the coast is clear.
+     * ActivateDebugger() method will do the rest when the coast is clear.
      */
     if (!mCx || mPauseLevel)
         return NS_OK;
 
     if (aHook)
         JSD_SetTopLevelHook (mCx, jsds_CallHookProc, NULL);
     else
         JSD_ClearTopLevelHook (mCx);
@@ -3170,17 +3214,17 @@ jsdService::GetTopLevelHook (jsdICallHoo
 }
 
 NS_IMETHODIMP
 jsdService::SetFunctionHook (jsdICallHook *aHook)
 {    
     mFunctionHook = aHook;
 
     /* if the debugger isn't initialized, that's all we can do for now.  The
-     * OnForRuntime() method will do the rest when the coast is clear.
+     * ActivateDebugger() method will do the rest when the coast is clear.
      */
     if (!mCx || mPauseLevel)
         return NS_OK;
 
     if (aHook)
         JSD_SetFunctionHook (mCx, jsds_CallHookProc, NULL);
     else
         JSD_ClearFunctionHook (mCx);
@@ -3263,17 +3307,17 @@ jsdASObserver::Observe (nsISupports *aSu
     if (NS_FAILED(rv))
         return rv;    
 
     JSRuntime *rt;
     rts->GetRuntime (&rt);
     if (NS_FAILED(rv))
         return rv;
 
-    rv = jsds->OnForRuntime(rt);
+    rv = jsds->ActivateDebugger(rt);
     if (NS_FAILED(rv))
         return rv;
     
     return NS_OK;
 }
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(jsdASObserver)
 NS_DEFINE_NAMED_CID(JSDSERVICE_CID);
--- a/js/jsd/jsd_xpc.h
+++ b/js/jsd/jsd_xpc.h
@@ -300,17 +300,17 @@ class jsdService : public jsdIDebuggerSe
     nsCOMPtr<jsdIExecutionHook> mBreakpointHook;
     nsCOMPtr<jsdIExecutionHook> mDebugHook;
     nsCOMPtr<jsdIExecutionHook> mDebuggerHook;
     nsCOMPtr<jsdIExecutionHook> mInterruptHook;
     nsCOMPtr<jsdIScriptHook>    mScriptHook;
     nsCOMPtr<jsdIExecutionHook> mThrowHook;
     nsCOMPtr<jsdICallHook>      mTopLevelHook;
     nsCOMPtr<jsdICallHook>      mFunctionHook;
-
+    nsCOMPtr<jsdIActivationCallback> mActivationCallback;
 };
 
 #endif /* JSDSERVICE_H___ */
 
 
 /* graveyard */
 
 #if 0
--- a/js/jsd/test/Makefile.in
+++ b/js/jsd/test/Makefile.in
@@ -43,12 +43,13 @@ relativesrcdir  = js/jsd/test
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = jsdebug
 
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES = 	test_bug507448.html \
+		bug507448.js \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/js/jsd/test/bug507448.js
@@ -0,0 +1,25 @@
+netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+
+function f() {}
+function g(a,b) {}
+function h(me, too, here) { var x = 1; }
+function annoying(a, b, a, b, b, a) {}
+function manyLocals(a, b, c, d, e, f, g, h, i, j, k, l, m) {
+  var n, o, p, q, r, s, t, u, v, w, x, y, z;
+}
+
+assertArraysEqual(jsd.wrapValue(f).script.getParameterNames(), []);
+assertArraysEqual(jsd.wrapValue(g).script.getParameterNames(), ["a", "b"]);
+assertArraysEqual(jsd.wrapValue(h).script.getParameterNames(), ["me", "too", "here"]);
+assertArraysEqual(jsd.wrapValue(annoying).script.getParameterNames(),
+                  ["a", "b", "a", "b", "b", "a"]);
+assertArraysEqual(jsd.wrapValue(manyLocals).script.getParameterNames(),
+                  "abcdefghijklm".split(""));
+
+if (!jsdOnAtStart) {
+  // turn JSD off if it wasn't on when this test started
+  jsd.off();
+  ok(!jsd.isOn, "JSD shouldn't be running at the end of this test.");
+}
+
+SimpleTest.finish();
\ No newline at end of file
--- a/js/jsd/test/test_bug507448.html
+++ b/js/jsd/test/test_bug507448.html
@@ -12,58 +12,99 @@ https://bugzilla.mozilla.org/show_bug.cg
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=507448">Mozilla Bug 507448</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script type="application/javascript">
+function f() {}
+function g(a,b) {}
+function h(me, too, here) { var x = 1; }
+function annoying(a, b, a, b, b, a) {}
+function manyLocals(a, b, c, d, e, f, g, h, i, j, k, l, m) {
+  var n, o, p, q, r, s, t, u, v, w, x, y, z;
+}
+</script>
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+function loadScript(url) {
+    var d = new MochiKit.Async.Deferred();
+    var head = document.getElementsByTagName("head")[0];
+    var script = MochiKit.DOM.createDOM("script", { type: "text/javascript", src: url });
+    script.onload = function() {
+        script.onload = null;
+        script.onerror = null;
+        script.onreadystatechange = null;
+        d.callback();
+    };
+    script.onerror = function(msg) {
+        script.onload = null;
+        script.onerror = null;
+        script.onreadystatechange = null;
+        msg = "Failed to load script at " + url + ": " + msg;
+        d.errback(new URIError(msg, url));
+    }
+    script.onreadystatechange = function() {
+        if (script.readyState == "loaded" || script.readyState == "complete") {
+            script.onload();
+        } else {
+            // IE doesn't bother to report errors...
+            MochiKit.Async.callLater(10, script.onerror, "Script loading timed out")
+        }
+    };
+    head.appendChild(script);
+    return d;
+}
 
 /** Test for Bug 507448 **/
 function assertArraysEqual(arr1, arr2) {
   is(arr1.length, arr2.length, "Lengths not equal");
   for (var i = 0 ; i < arr1.length; ++i) {
     is(arr1[i], arr2[i], "Element " + i + " not equal");
   }
 }
 
-// This is somewhat unfortunate: jsd only deals with scripts that have a
-// nonzero line number, so we can't just createElement a script here.
-// So break the test up into three <script>s, of which the middle one has our test functions.
-
 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 var jsdIDebuggerService = Components.interfaces.jsdIDebuggerService;
 var jsd = Components.classes['@mozilla.org/js/jsd/debugger-service;1']
                     .getService(jsdIDebuggerService);
-var jsdOn = jsd.isOn;
-if (!jsdOn) {
-  jsd.on();
-  ok(jsd.isOn, "JSD should be running.");
+var jsdOnAtStart = false;
+
+function setupJSD() {
+  // This is somewhat unfortunate: jsd only deals with scripts that have a
+  // nonzero line number, so we can't just createElement a script here.
+  // So break the test up into three <script>s, of which the middle one has our test functions.
+
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+
+  jsdOnAtStart = jsd.isOn;
+  if (jsdOnAtStart) {
+    testJSD();
+  } else {
+    jsd.asyncOn(
+      {
+        onDebuggerActivated: function() {
+            testJSD();
+        }
+      }  
+    );
+  }
 }
+
+addLoadEvent(setupJSD);
+
 </script>
 <script>
-  function f() {}
-  function g(a,b) {}
-  function h(me, too, here) { var x = 1; }
-  function annoying(a, b, a, b, b, a) {}
-  function manyLocals(a, b, c, d, e, f, g, h, i, j, k, l, m) {
-    var n, o, p, q, r, s, t, u, v, w, x, y, z;
-  }
-</script>
-<script>
+function testJSD() {
   netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  assertArraysEqual(jsd.wrapValue(f).script.getParameterNames(), []);
-  assertArraysEqual(jsd.wrapValue(g).script.getParameterNames(), ["a", "b"]);
-  assertArraysEqual(jsd.wrapValue(h).script.getParameterNames(), ["me", "too", "here"]);
-  assertArraysEqual(jsd.wrapValue(annoying).script.getParameterNames(),
-                    ["a", "b", "a", "b", "b", "a"]);
-  assertArraysEqual(jsd.wrapValue(manyLocals).script.getParameterNames(),
-                    "abcdefghijklm".split(""));
+
+  ok(jsd.isOn, "JSD needs to be running for this test.");
 
-  if (!jsdOn) {
-    jsd.off();
-    ok(!jsd.isOn, "JSD shouldn't be running anymore.");
-  }
+  var deferred = loadScript("bug507448.js");
+}
 </script>
 </pre>
 </body>
 </html>
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -249,50 +249,56 @@ INSTALLED_HEADERS = \
 		jsxdrapi.h \
 		jsxml.h \
 		jsval.h \
 		jsvalue.h \
 		prmjtime.h \
 		$(NULL)
 
 ifdef ENABLE_TRACEJIT
-VPATH		+= $(srcdir)/nanojit
+VPATH		+= \
+		$(srcdir)/tracejit \
+		$(srcdir)/nanojit \
 
 INSTALLED_HEADERS += \
 		jsbuiltins.h    \
 		Assembler.h     \
 		Allocator.h     \
 		CodeAlloc.h     \
 		Containers.h    \
 		LIR.h		\
+		LIRopcode.tbl \
 		avmplus.h	\
 		Fragmento.h	\
 		Native.h	\
 		NativeCommon.h	\
 		Native$(NANOJIT_ARCH).h \
-		njconfig.h  \
+		njconfig.h      \
+		njcpudetect.h   \
 		RegAlloc.h	\
 		nanojit.h	\
 		VMPI.h		\
+		Writer.h	\
 		$(NULL)
 
 CPPSRCS += \
 		jstracer.cpp \
 		Assembler.cpp  \
 		Allocator.cpp  \
 		CodeAlloc.cpp  \
 		Containers.cpp \
 		Fragmento.cpp  \
 		LIR.cpp        \
 		njconfig.cpp   \
 		RegAlloc.cpp   \
 		avmplus.cpp    \
 		Native$(NANOJIT_ARCH).cpp \
-		jsbuiltins.cpp         \
+		jsbuiltins.cpp \
 		VMPI.cpp       \
+		Writer.cpp     \
 		$(NULL)
 
 ifdef WINCE
 # don't need -c
 AS_DASH_C_FLAG =
 ASFLAGS += -arch 6
 ASFILES += jswince.asm
 endif
--- a/js/src/config/autoconf.mk.in
+++ b/js/src/config/autoconf.mk.in
@@ -340,8 +340,21 @@ WRAP_SYSTEM_INCLUDES = @WRAP_SYSTEM_INCL
 
 ENABLE_TRACEJIT = @ENABLE_TRACEJIT@
 ENABLE_METHODJIT = @ENABLE_METHODJIT@
 NANOJIT_ARCH = @NANOJIT_ARCH@
 HAVE_ARM_SIMD= @HAVE_ARM_SIMD@
 
 JS_SHARED_LIBRARY = @JS_SHARED_LIBRARY@
 HAVE_LINUX_PERF_EVENT_H = @HAVE_LINUX_PERF_EVENT_H@
+
+# We only want to do the pymake sanity on Windows, other os's can cope
+ifeq (,$(filter-out WINNT WINCE,$(HOST_OS_ARCH)))
+# Ensure invariants between GNU Make and pymake
+# Checked here since we want the sane error in a file that
+# actually can be found regardless of path-style.
+ifeq (_:,$(.PYMAKE)_$(findstring :,$(srcdir)))
+$(error Windows-style srcdir being used with GNU make. Did you mean to run $(topsrcdir)/build/pymake/make.py instead? [see-also: https://developer.mozilla.org/en/Gmake_vs._Pymake])
+endif
+ifeq (1_a,$(.PYMAKE)_$(firstword a$(subst /, ,$(srcdir))))
+$(error MSYS-style srcdir being used with Pymake. Did you mean to run GNU Make instead? [see-also: https://developer.mozilla.org/en/Gmake_vs._Pymake])
+endif
+endif # Windows
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -166,58 +166,58 @@ define _INSTALL_TESTS
 
 endef # do not remove the blank line!
 
 SOLO_FILE ?= $(error Specify a test filename in SOLO_FILE when using check-interactive or check-one)
 
 libs::
 	$(foreach dir,$(XPCSHELL_TESTS),$(_INSTALL_TESTS))
 	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py \
-          $(testxpcobjdir)/all-test-dirs.list \
-          $(addprefix $(relativesrcdir)/,$(XPCSHELL_TESTS))
+	  $(testxpcobjdir)/all-test-dirs.list \
+	  $(addprefix $(relativesrcdir)/,$(XPCSHELL_TESTS))
 
 testxpcsrcdir = $(topsrcdir)/testing/xpcshell
 
 # Execute all tests in the $(XPCSHELL_TESTS) directories.
 # See also testsuite-targets.mk 'xpcshell-tests' target for global execution.
 xpcshell-tests:
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-          -I$(topsrcdir)/build \
-          $(testxpcsrcdir)/runxpcshelltests.py \
-          --symbols-path=$(DIST)/crashreporter-symbols \
-          $(EXTRA_TEST_ARGS) \
-          $(DIST)/bin/xpcshell \
-          $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+	  -I$(topsrcdir)/build \
+	  $(testxpcsrcdir)/runxpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  $(EXTRA_TEST_ARGS) \
+	  $(DIST)/bin/xpcshell \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
 
 # Execute a single test, specified in $(SOLO_FILE), but don't automatically
 # start the test. Instead, present the xpcshell prompt so the user can
 # attach a debugger and then start the test.
 check-interactive:
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-          -I$(topsrcdir)/build \
-          $(testxpcsrcdir)/runxpcshelltests.py \
-          --symbols-path=$(DIST)/crashreporter-symbols \
-          --test-path=$(SOLO_FILE) \
-          --profile-name=$(MOZ_APP_NAME) \
-          --interactive \
-          $(DIST)/bin/xpcshell \
-          $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+	  -I$(topsrcdir)/build \
+	  $(testxpcsrcdir)/runxpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --test-path=$(SOLO_FILE) \
+	  --profile-name=$(MOZ_APP_NAME) \
+	  --interactive \
+	  $(DIST)/bin/xpcshell \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
 
 # Execute a single test, specified in $(SOLO_FILE)
 check-one:
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-          -I$(topsrcdir)/build \
-          $(testxpcsrcdir)/runxpcshelltests.py \
-          --symbols-path=$(DIST)/crashreporter-symbols \
-          --test-path=$(SOLO_FILE) \
-          --profile-name=$(MOZ_APP_NAME) \
-          --verbose \
-          $(EXTRA_TEST_ARGS) \
-          $(DIST)/bin/xpcshell \
-          $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+	  -I$(topsrcdir)/build \
+	  $(testxpcsrcdir)/runxpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --test-path=$(SOLO_FILE) \
+	  --profile-name=$(MOZ_APP_NAME) \
+	  --verbose \
+	  $(EXTRA_TEST_ARGS) \
+	  $(DIST)/bin/xpcshell \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
 
 endif # XPCSHELL_TESTS
 
 ifdef CPP_UNIT_TESTS
 
 # Compile the tests to $(DIST)/bin.  Make lots of niceties available by default
 # through TestHarness.h, by modifying the list of includes and the libs against
 # which stuff links.
@@ -841,17 +841,17 @@ ifdef LIBRARY_NAME
 ifdef EXPORT_LIBRARY
 ifdef IS_COMPONENT
 ifdef BUILD_STATIC_LIBS
 	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_COMPS) $(STATIC_LIBRARY_NAME)
 ifdef MODULE_NAME
 	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_COMP_NAMES) $(MODULE_NAME)
 endif
 endif # BUILD_STATIC_LIBS
-else  # !IS_COMPONENT
+else # !IS_COMPONENT
 	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
 endif # IS_COMPONENT
 endif # EXPORT_LIBRARY
 endif # LIBRARY_NAME
 
 # Create dependencies on static (and shared EXTRA_DSO_LIBS) libraries
 LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(LIBS))
 HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(HOST_LIBS))
@@ -869,17 +869,17 @@ vpath $(LIB_PREFIX)%.$(LIB_SUFFIX) $(_LI
 ifdef IMPORT_LIB_SUFFIX
 vpath $(LIB_PREFIX)%.$(IMPORT_LIB_SUFFIX) $(_LIBDIRS)
 endif # IMPORT_LIB_SUFFIX
 vpath $(DLL_PREFIX)%$(DLL_SUFFIX) $(_LIBDIRS)
 endif # _LIBDIRS
 
 endif # _LIBNAME_RELATIVE_PATHS
 
-# Dependancies which, if modified, should cause everything to rebuild
+# Dependencies which, if modified, should cause everything to rebuild
 GLOBAL_DEPS += Makefile Makefile.in $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
 
 ##############################################
 ifdef PARALLEL_DIRS
 libs:: $(PARALLEL_DIRS_libs)
 
 $(PARALLEL_DIRS_libs): %_libs: %/Makefile
 	+@$(call SUBMAKE,libs,$*)
@@ -1193,17 +1193,17 @@ else
 ifneq (,$(filter OSF1 BSD_OS FreeBSD NetBSD OpenBSD SunOS Darwin,$(OS_ARCH)))
 CLEANUP1	:= | egrep -v '(________64ELEL_|__.SYMDEF)'
 CLEANUP2	:= rm -f ________64ELEL_ __.SYMDEF
 else
 CLEANUP2	:= true
 endif
 SUB_LOBJS	= $(shell for lib in $(SHARED_LIBRARY_LIBS); do $(AR_LIST) $${lib} $(CLEANUP1); done;)
 endif # EXPAND_FAKELIBS
-endif # SHARED_LIBARY_LIBS
+endif # SHARED_LIBRARY_LIBS
 endif
 ifdef MOZILLA_PROBE_LIBS
 PROBE_LOBJS	= $(shell for lib in $(MOZILLA_PROBE_LIBS); do $(AR_LIST) $${lib} $(CLEANUP1); done;)
 endif
 ifdef DTRACE_PROBE_OBJ
 EXTRA_DEPS += $(DTRACE_PROBE_OBJ)
 endif
 
@@ -1573,17 +1573,17 @@ SPACE := $(EMPTY) $(EMPTY)
 # and class paths to be in the DOS form (i.e. e:/builds/...).  This function
 # does the appropriate conversion on Windows, but is a noop on other systems.
 ifeq (,$(filter-out WINNT WINCE, $(HOST_OS_ARCH)))
 ifdef CYGWIN_WRAPPER
 normalizepath = $(foreach p,$(1),$(shell cygpath -m $(p)))
 else
 # assume MSYS
 #  We use 'pwd -W' to get DOS form of the path.  However, since the given path
-#  could be a file or a nonexistent path, we cannot call 'pwd -W' directly
+#  could be a file or a non-existent path, we cannot call 'pwd -W' directly
 #  on the path.  Instead, we extract the root path (i.e. "c:/"), call 'pwd -W'
 #  on it, then merge with the rest of the path.
 root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\1|")
 non-root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\2|")
 normalizepath = $(foreach p,$(1),$(if $(filter /%,$(1)),$(patsubst %/,%,$(shell cd $(call root-path,$(1)) && pwd -W))/$(call non-root-path,$(1)),$(1)))
 endif
 else
 normalizepath = $(1)
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/testBug606138.js
@@ -0,0 +1,3 @@
+// The proxy is going to mutate thisv in place. InvokeSessionGuard should be
+// cool with that
+with(evalcx(''))[7, 8].map(Int16Array, [])
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/testReplaceMap.js
@@ -0,0 +1,27 @@
+
+// String.replace on functions returning hashmap elements.
+
+function first() {
+  var arr = {a: "hello", b: "there"};
+  var s = 'a|b';
+  return s.replace(/[a-z]/g, function(a) { return arr[a]; }, 'g');
+}
+assertEq(first(), "hello|there");
+
+function second() {
+  var arr = {a: "hello", c: "there"};
+  var s = 'a|b|c';
+  return s.replace(/[a-z]/g, function(a) { return arr[a]; }, 'g');
+}
+assertEq(second(), "hello|undefined|there");
+
+Object.defineProperty(Object.prototype, "b", {get: function() { return "what"; }});
+
+assertEq(second(), "hello|what|there");
+
+function third() {
+  var arr = {a: "hello", b: {toString: function() { arr = {}; return "three"; }}, c: "there"};
+  var s = 'a|b|c';
+  return s.replace(/[a-z]/g, function(a) { return arr[a]; }, 'g');
+}
+assertEq(third(), "hello|three|undefined");
--- a/js/src/jsapi-tests/testBug604087.cpp
+++ b/js/src/jsapi-tests/testBug604087.cpp
@@ -39,17 +39,17 @@ PreWrap(JSContext *cx, JSObject *scope, 
 {
     JS_GC(cx);
     return obj;
 }
 
 static JSObject *
 Wrap(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent, uintN flags)
 {
-    return JSWrapper::New(cx, obj, proto, NULL, &JSCrossCompartmentWrapper::singleton);
+    return JSWrapper::New(cx, obj, proto, parent, &JSCrossCompartmentWrapper::singleton);
 }
 
 BEGIN_TEST(testBug604087)
 {
     JSObject *outerObj = JSWrapper::New(cx, global, global->getProto(), global,
                                         &OuterWrapper::singleton);
     JSObject *compartment2 = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL);
     JSObject *compartment3 = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -648,16 +648,19 @@ JSRuntime::init(uint32 maxbytes)
         return false;
     stateChange = JS_NEW_CONDVAR(gcLock);
     if (!stateChange)
         return false;
     debuggerLock = JS_NEW_LOCK();
     if (!debuggerLock)
         return false;
 #endif
+
+    debugMode = JS_FALSE;
+
     return propertyTree.init() && js_InitThreads(this);
 }
 
 JSRuntime::~JSRuntime()
 {
 #ifdef DEBUG
     /* Don't hurt everyone in leaky ol' Mozilla with a fatal JS_ASSERT! */
     if (!JS_CLIST_IS_EMPTY(&contextList)) {
@@ -1876,73 +1879,32 @@ JS_GetClassObject(JSContext *cx, JSObjec
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
     return js_GetClassObject(cx, obj, key, objp);
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetScopeChain(JSContext *cx)
 {
-    JSStackFrame *fp;
-
     CHECK_REQUEST(cx);
-    fp = js_GetTopStackFrame(cx);
-    if (!fp) {
-        /*
-         * There is no code active on this context. In place of an actual
-         * scope chain, use the context's global object, which is set in
-         * js_InitFunctionAndObjectClasses, and which represents the default
-         * scope chain for the embedding. See also js_FindClassObject.
-         *
-         * For embeddings that use the inner and outer object hooks, the inner
-         * object represents the ultimate global object, with the outer object
-         * acting as a stand-in.
-         */
-        JSObject *obj = cx->globalObject;
-        if (!obj) {
-            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INACTIVE);
-            return NULL;
-        }
-
-        OBJ_TO_INNER_OBJECT(cx, obj);
-        return obj;
-    }
-    return js_GetScopeChain(cx, fp);
+    return GetScopeChain(cx);
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetGlobalForObject(JSContext *cx, JSObject *obj)
 {
     assertSameCompartment(cx, obj);
     return obj->getGlobal();
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetGlobalForScopeChain(JSContext *cx)
 {
-    /*
-     * This is essentially JS_GetScopeChain(cx)->getGlobal(), but without
-     * falling off trace.
-     *
-     * This use of cx->fp, possibly on trace, is deliberate:
-     * cx->fp->scopeChain->getGlobal() returns the same object whether we're on
-     * trace or not, since we do not trace calls across global objects.
-     */
-    VOUCH_DOES_NOT_REQUIRE_STACK();
-
-    if (cx->hasfp())
-        return cx->fp()->scopeChain().getGlobal();
-
-    JSObject *scope = cx->globalObject;
-    if (!scope) {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INACTIVE);
-        return NULL;
-    }
-    OBJ_TO_INNER_OBJECT(cx, scope);
-    return scope;
+    CHECK_REQUEST(cx);
+    return GetGlobalForScopeChain(cx);
 }
 
 JS_PUBLIC_API(jsval)
 JS_ComputeThis(JSContext *cx, jsval *vp)
 {
     assertSameCompartment(cx, JSValueArray(vp, 2));
     if (!ComputeThisFromVp(cx, Valueify(vp)))
         return JSVAL_NULL;
@@ -4167,17 +4129,17 @@ JS_NewFunction(JSContext *cx, JSNative n
 
 JS_PUBLIC_API(JSObject *)
 JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent)
 {
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, parent);  // XXX no funobj for now
     if (!parent) {
         if (cx->hasfp())
-            parent = js_GetScopeChain(cx, cx->fp());
+            parent = GetScopeChain(cx, cx->fp());
         if (!parent)
             parent = cx->globalObject;
         JS_ASSERT(parent);
     }
 
     if (funobj->getClass() != &js_FunctionClass) {
         /*
          * We cannot clone this object, so fail (we used to return funobj, bad
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2628,20 +2628,20 @@ Call(JSContext *cx, JSObject *thisObj, j
 extern JS_PUBLIC_API(bool)
 Call(JSContext *cx, jsval thisv, jsval fun, uintN argc, jsval *argv, jsval *rval);
 
 static inline bool
 Call(JSContext *cx, jsval thisv, JSObject *funObj, uintN argc, jsval *argv, jsval *rval) {
     return Call(cx, thisv, OBJECT_TO_JSVAL(funObj), argc, argv, rval);
 }
 
-} // namespace JS
+} /* namespace JS */
 
 JS_BEGIN_EXTERN_C
-#endif // __cplusplus
+#endif /* __cplusplus */
 
 /*
  * These functions allow setting an operation callback that will be called
  * from the thread the context is associated with some time after any thread
  * triggered the callback using JS_TriggerOperationCallback(cx).
  *
  * In a threadsafe build the engine internally triggers operation callbacks
  * under certain circumstances (i.e. GC and title transfer) to force the
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -446,17 +446,17 @@ js_EnsureDenseArrayCapacity(JSContext *c
     JSBool ret = obj->ensureDenseArrayElements(cx, u + 1);
 
     /* Partially check the CallInfo's storeAccSet is correct. */
     JS_ASSERT(obj->clasp == origObjClasp);
     return ret;
 }
 /* This function and its callees do not touch any object's .clasp field. */
 JS_DEFINE_CALLINFO_3(extern, BOOL, js_EnsureDenseArrayCapacity, CONTEXT, OBJECT, INT32,
-                     0, nanojit::ACCSET_STORE_ANY & ~ACCSET_OBJ_CLASP)
+                     0, nanojit::ACCSET_STORE_ANY & ~tjit::ACCSET_OBJ_CLASP)
 #endif
 
 static JSBool
 DeleteArrayElement(JSContext *cx, JSObject *obj, jsdouble index, JSBool strict)
 {
     JS_ASSERT(index >= 0);
     if (obj->isDenseArray()) {
         if (index <= jsuint(-1)) {
@@ -683,17 +683,17 @@ js_GetDenseArrayElementValue(JSContext *
         vp->setNumber(obj->getArrayLength());
         return JS_TRUE;
     }
     *vp = obj->getDenseArrayElement(i);
     return JS_TRUE;
 }
 
 static JSBool
-array_getProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
+array_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
 {
     uint32 i;
 
     if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
         vp->setNumber(obj->getArrayLength());
         return JS_TRUE;
     }
 
@@ -823,17 +823,17 @@ js_Array_dense_setelem_hole(JSContext* c
 
     jsuint u = jsuint(i);
     if (u >= obj->getArrayLength())
         obj->setArrayLength(u + 1);
     return true;
 }
 /* storeAccSet == ACCSET_OBJ_PRIVATE: because it can set 'length'. */
 JS_DEFINE_CALLINFO_3(extern, BOOL, js_Array_dense_setelem_hole, CONTEXT, OBJECT, INT32,
-                     0, ACCSET_OBJ_PRIVATE)
+                     0, tjit::ACCSET_OBJ_PRIVATE)
 #endif
 
 static JSBool
 array_defineProperty(JSContext *cx, JSObject *obj, jsid id, const Value *value,
                      PropertyOp getter, PropertyOp setter, uintN attrs)
 {
     uint32 i = 0;       // init to shut GCC up
     JSBool isIndex;
--- a/js/src/jsatom.cpp
+++ b/js/src/jsatom.cpp
@@ -458,52 +458,23 @@ JSAtom *
 js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
 {
     JS_ASSERT(!(flags & ~(ATOM_PINNED|ATOM_INTERNED|ATOM_TMPSTR|ATOM_NOCOPY)));
     JS_ASSERT_IF(flags & ATOM_NOCOPY, flags & ATOM_TMPSTR);
 
     if (str->isAtomized())
         return STRING_TO_ATOM(str);
 
-    size_t length = str->length();
-    if (length == 1) {
-        jschar c = str->chars()[0];
-        if (c < UNIT_STRING_LIMIT)
-            return STRING_TO_ATOM(JSString::unitString(c));
-    }
-
-    if (length == 2) {
-        jschar *chars = str->chars();
-        if (JSString::fitsInSmallChar(chars[0]) &&
-            JSString::fitsInSmallChar(chars[1])) {
-            return STRING_TO_ATOM(JSString::length2String(chars[0], chars[1]));
-        }
-    }
+    const jschar *chars;
+    size_t length;
+    str->getCharsAndLength(chars, length);
 
-    /*
-     * Here we know that JSString::intStringTable covers only 256 (or at least
-     * not 1000 or more) chars. We rely on order here to resolve the unit vs.
-     * int string/length-2 string atom identity issue by giving priority to unit
-     * strings for "0" through "9" and length-2 strings for "10" through "99".
-     */
-    JS_STATIC_ASSERT(INT_STRING_LIMIT <= 999);
-    if (length == 3) {
-        const jschar *chars = str->chars();
-
-        if ('1' <= chars[0] && chars[0] <= '9' &&
-            '0' <= chars[1] && chars[1] <= '9' &&
-            '0' <= chars[2] && chars[2] <= '9') {
-            jsint i = (chars[0] - '0') * 100 +
-                      (chars[1] - '0') * 10 +
-                      (chars[2] - '0');
-
-            if (jsuint(i) < INT_STRING_LIMIT)
-                return STRING_TO_ATOM(JSString::intString(i));
-        }
-    }
+    JSString *staticStr = JSString::lookupStaticString(chars, length);
+    if (staticStr)
+        return STRING_TO_ATOM(staticStr);
 
     JSAtomState *state = &cx->runtime->atomState;
     AtomSet &atoms = state->atoms;
 
     AutoLockDefaultCompartment lock(cx);
     AtomSet::AddPtr p = atoms.lookupForAdd(str);
 
     /* Hashing the string should have flattened it if it was a rope. */
--- a/js/src/jsbuiltins.h
+++ b/js/src/jsbuiltins.h
@@ -44,107 +44,16 @@
 
 #include "nanojit/nanojit.h"
 #include "jsvalue.h"
 
 #ifdef THIS
 #undef THIS
 #endif
 
-namespace js {
-
-/*
- * See ValidateWriter::checkAccSet() for what each of these access regions
- * mean.
- *
- * *** WARNING WARNING WARNING ***
- *
- * Any incorrect access region annotations on loads/stores/calls could lead to
- * subtle bugs that manifest rarely, eg. when two loads are CSE'd that
- * shouldn't be.
- *
- * If you add a new access region you will need to add some sanity checking to
- * ValidateWriter::checkAccSet().  Do not skimp on this checking!  Make it as
- * strong as you can.  Look at the existing cases for inspiration.  This
- * checking helps prevent these subtle bugs.
- *
- * Furthermore, do not add a "catch-all" region such as "ACCSET_OTHER".  There
- * are two reasons for this.  First, no checking could be done on loads/stores
- * bearing it.  Second, it would be too easy for someone in the future who
- * doesn't understand how AccSets work to use it inappropriately.  Only
- * ACCSET_ALL (the union of all access regions) should be used as a catch-all,
- * it can always be used safely, but it reduces optimization possibilities.
- *
- * Most of the access regions are type-based, ie. all structs of a particular
- * type combined together form a region.  This is less precise than
- * considering each struct separately, but also much simpler.
- *
- * - ACCSET_STATE:         The TracerState struct.
- * - ACCSET_STACK:         The stack.
- * - ACCSET_RSTACK:        The return stack.
- * - ACCSET_CX:            All JSContext structs.
- * - ACCSET_EOS:           The globals area.
- * - ACCSET_ALLOC:         All memory blocks allocated with LIR_allocp (in
- *                         other words, this region is the AR space).
- * - ACCSET_FRAMEREGS:     All JSFrameRegs structs.
- * - ACCSET_STACKFRAME:    All JSStackFrame objects.
- * - ACCSET_RUNTIME:       The JSRuntime object.
- * - ACCSET_OBJ_CLASP:     The 'clasp'    field of all JSObjects.
- * - ACCSET_OBJ_FLAGS:     The 'flags'    field of all JSObjects.
- * - ACCSET_OBJ_SHAPE:     The 'shape'    field of all JSObjects.
- * - ACCSET_OBJ_PROTO:     The 'proto'    field of all JSObjects.
- * - ACCSET_OBJ_PARENT:    The 'parent'   field of all JSObjects.
- * - ACCSET_OBJ_PRIVATE:   The 'private'  field of all JSObjects.
- * - ACCSET_OBJ_CAPACITY:  The 'capacity' field of all JSObjects.
- * - ACCSET_OBJ_SLOTS:     The 'slots'    field of all JSObjects.
- * - ACCSET_SLOTS:         The slots (be they fixed or dynamic) of all JSObjects.
- * - ACCSET_TARRAY:        All TypedArray structs.
- * - ACCSET_TARRAY_DATA:   All TypedArray data arrays.
- * - ACCSET_ITER:          All NativeIterator structs.
- * - ACCSET_ITER_PROPS:    The props_arrays of all NativeIterator structs.
- * - ACCSET_STRING:        All JSString structs.
- * - ACCSET_STRING_MCHARS: All JSString mchars arrays.
- * - ACCSET_TYPEMAP:       All typemaps form a single region.
- * - ACCSET_FCSLOTS:       All fcslots arrays form a single region.
- * - ACCSET_ARGS_DATA:     All Arguments data arrays form a single region.
- */
-static const nanojit::AccSet ACCSET_STATE         = (1 <<  0);
-static const nanojit::AccSet ACCSET_STACK         = (1 <<  1);
-static const nanojit::AccSet ACCSET_RSTACK        = (1 <<  2);
-static const nanojit::AccSet ACCSET_CX            = (1 <<  3);
-static const nanojit::AccSet ACCSET_EOS           = (1 <<  4);
-static const nanojit::AccSet ACCSET_ALLOC         = (1 <<  5);
-static const nanojit::AccSet ACCSET_FRAMEREGS     = (1 <<  6);
-static const nanojit::AccSet ACCSET_STACKFRAME    = (1 <<  7);
-static const nanojit::AccSet ACCSET_RUNTIME       = (1 <<  8);
-
-// Nb: JSObject::{lastProp,map} don't have an AccSet because they are never accessed on trace
-static const nanojit::AccSet ACCSET_OBJ_CLASP     = (1 <<  9);
-static const nanojit::AccSet ACCSET_OBJ_FLAGS     = (1 << 10);
-static const nanojit::AccSet ACCSET_OBJ_SHAPE     = (1 << 11);
-static const nanojit::AccSet ACCSET_OBJ_PROTO     = (1 << 12);
-static const nanojit::AccSet ACCSET_OBJ_PARENT    = (1 << 13);
-static const nanojit::AccSet ACCSET_OBJ_PRIVATE   = (1 << 14);
-static const nanojit::AccSet ACCSET_OBJ_CAPACITY  = (1 << 15);
-static const nanojit::AccSet ACCSET_OBJ_SLOTS     = (1 << 16);  // the pointer to the slots
-
-static const nanojit::AccSet ACCSET_SLOTS         = (1 << 17);  // the slots themselves
-static const nanojit::AccSet ACCSET_TARRAY        = (1 << 18);
-static const nanojit::AccSet ACCSET_TARRAY_DATA   = (1 << 19);
-static const nanojit::AccSet ACCSET_ITER          = (1 << 20);
-static const nanojit::AccSet ACCSET_ITER_PROPS    = (1 << 21);
-static const nanojit::AccSet ACCSET_STRING        = (1 << 22);
-static const nanojit::AccSet ACCSET_STRING_MCHARS = (1 << 23);
-static const nanojit::AccSet ACCSET_TYPEMAP       = (1 << 24);
-static const nanojit::AccSet ACCSET_FCSLOTS       = (1 << 25);
-static const nanojit::AccSet ACCSET_ARGS_DATA     = (1 << 26);
-}
-
-static const uint8_t TM_NUM_USED_ACCS = 27; // number of access regions used by TraceMonkey
-
 enum JSTNErrType { INFALLIBLE, FAIL_STATUS, FAIL_NULL, FAIL_NEG, FAIL_NEITHER };
 enum { 
     JSTN_ERRTYPE_MASK        = 0x07,
     JSTN_UNBOX_AFTER         = 0x08,
     JSTN_MORE                = 0x10,
     JSTN_CONSTRUCTOR         = 0x20,
     JSTN_RETURN_NULLABLE_STR = 0x40,
     JSTN_RETURN_NULLABLE_OBJ = 0x80
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -491,19 +491,16 @@ JSThreadData::init()
     for (size_t i = 0; i != sizeof(*this); ++i)
         JS_ASSERT(reinterpret_cast<uint8*>(this)[i] == 0);
 #endif
     if (!stackSpace.init())
         return false;
 #ifdef JS_TRACER
     InitJIT(&traceMonitor);
 #endif
-#ifdef JS_METHODJIT
-    jmData.Initialize();
-#endif
     dtoaState = js_NewDtoaState();
     if (!dtoaState) {
         finish();
         return false;
     }
     nativeStackBase = GetNativeStackBase();
     return true;
 }
@@ -529,19 +526,16 @@ JSThreadData::finish()
     if (dtoaState)
         js_DestroyDtoaState(dtoaState);
 
     js_FinishGSNCache(&gsnCache);
     propertyCache.~PropertyCache();
 #if defined JS_TRACER
     FinishJIT(&traceMonitor);
 #endif
-#if defined JS_METHODJIT
-    jmData.Finish();
-#endif
     stackSpace.finish();
     delete mathCache;
 }
 
 void
 JSThreadData::mark(JSTracer *trc)
 {
     stackSpace.mark(trc);
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -123,20 +123,16 @@ template<typename T> class Seq;
 }  /* namespace nanojit */
 
 namespace JSC {
     class ExecutableAllocator;
 }
 
 namespace js {
 
-#ifdef JS_METHODJIT
-struct VMFrame;
-#endif
-
 /* Tracer constants. */
 static const size_t MONITOR_N_GLOBAL_STATES = 4;
 static const size_t FRAGMENT_TABLE_SIZE = 512;
 static const size_t MAX_NATIVE_STACK_SLOTS = 4096;
 static const size_t MAX_CALL_STACK_ENTRIES = 500;
 static const size_t MAX_GLOBAL_SLOTS = 4096;
 static const size_t GLOBAL_SLOTS_BUFFER_SIZE = MAX_GLOBAL_SLOTS + 1;
 static const size_t MAX_SLOW_NATIVE_EXTRA_SLOTS = 16;
@@ -158,17 +154,17 @@ typedef nanojit::HashMap<REHashKey, REFr
 class LoopProfile;
 
 #if defined(JS_JIT_SPEW) || defined(DEBUG)
 struct FragPI;
 typedef nanojit::HashMap<uint32, FragPI, nanojit::DefaultHash<uint32> > FragStatsMap;
 #endif
 
 namespace mjit {
-class CallStackIterator;
+class JaegerCompartment;
 }
 
 /*
  * Allocation policy that calls JSContext memory functions and reports errors
  * to the context. Since the JSContext given on construction is stored for
  * the lifetime of the container, this policy may only be used for containers
  * whose lifetime is a shorter than the given JSContext.
  */
@@ -222,44 +218,16 @@ struct TracerState
     uintN          nativeVpLen;
     js::Value*     nativeVp;
 
     TracerState(JSContext *cx, TraceMonitor *tm, TreeFragment *ti,
                 uintN &inlineCallCountp, VMSideExit** innermostNestedGuardp);
     ~TracerState();
 };
 
-#ifdef JS_METHODJIT
-namespace mjit {
-    struct Trampolines
-    {
-        typedef void (*TrampolinePtr)();
-        TrampolinePtr forceReturn;
-        JSC::ExecutablePool *forceReturnPool;
-#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
-        TrampolinePtr forceReturnFast;
-        JSC::ExecutablePool *forceReturnFastPool;
-#endif
-    };
-
-    struct ThreadData
-    {
-        JSC::ExecutableAllocator *execAlloc;
-
-        // Trampolines for JIT code.
-        Trampolines trampolines;
-
-        VMFrame *activeFrame;
-
-        bool Initialize();
-        void Finish();
-    };
-}
-#endif /* JS_METHODJIT */
-
 /*
  * Storage for the execution state and store during trace execution. Generated
  * code depends on the fact that the globals begin |MAX_NATIVE_STACK_SLOTS|
  * doubles after the stack begins. Thus, on trace, |TracerState::eos| holds a
  * pointer to the first global.
  */
 struct TraceNativeStorage
 {
@@ -1153,20 +1121,16 @@ struct JSThreadData {
 #ifdef JS_TRACER
     /* Trace-tree JIT recorder/interpreter state. */
     js::TraceMonitor    traceMonitor;
 
     /* Counts the number of iterations run by a trace. */
     unsigned            iterationCounter;
 #endif
 
-#ifdef JS_METHODJIT
-    js::mjit::ThreadData jmData;
-#endif
-
     /* Lock-free hashed lists of scripts created by eval to garbage-collect. */
     JSScript            *scriptsToGC[JS_EVAL_CACHE_SIZE];
 
 #ifdef DEBUG
     JSEvalCacheMeter    evalCacheMeter;
 #endif
 
     /* State used by dtoa.c. */
@@ -1411,16 +1375,21 @@ struct JSRuntime {
     JSString            *emptyString;
 
     /* List of active contexts sharing this runtime; protected by gcLock. */
     JSCList             contextList;
 
     /* Per runtime debug hooks -- see jsprvtd.h and jsdbgapi.h. */
     JSDebugHooks        globalDebugHooks;
 
+    /*
+     * Right now, we only support runtime-wide debugging.
+     */
+    JSBool              debugMode;
+
 #ifdef JS_TRACER
     /* True if any debug hooks not supported by the JIT are enabled. */
     bool debuggerInhibitsJIT() const {
         return (globalDebugHooks.interruptHook ||
                 globalDebugHooks.callHook);
     }
 #endif
 
@@ -1747,17 +1716,16 @@ struct JSRuntime {
      */
     JS_FRIEND_API(void *) onOutOfMemory(void *p, size_t nbytes, JSContext *cx);
 };
 
 /* Common macros to access thread-local caches in JSThread or JSRuntime. */
 #define JS_GSN_CACHE(cx)        (JS_THREAD_DATA(cx)->gsnCache)
 #define JS_PROPERTY_CACHE(cx)   (JS_THREAD_DATA(cx)->propertyCache)
 #define JS_TRACE_MONITOR(cx)    (JS_THREAD_DATA(cx)->traceMonitor)
-#define JS_METHODJIT_DATA(cx)   (JS_THREAD_DATA(cx)->jmData)
 #define JS_SCRIPTS_TO_GC(cx)    (JS_THREAD_DATA(cx)->scriptsToGC)
 
 #ifdef DEBUG
 # define EVAL_CACHE_METER(x)    (JS_THREAD_DATA(cx)->evalCacheMeter.x++)
 #else
 # define EVAL_CACHE_METER(x)    ((void) 0)
 #endif
 
@@ -2244,16 +2212,20 @@ struct JSContext
      * To go from a live generator frame (on the stack) to its generator object
      * (see comment js_FloatingFrameIfGenerator), we maintain a stack of active
      * generators, pushing and popping when entering and leaving generator
      * frames, respectively.
      */
     js::Vector<JSGenerator *, 2, js::SystemAllocPolicy> genStack;
 
   public:
+#ifdef JS_METHODJIT
+    inline js::mjit::JaegerCompartment *jaegerCompartment();
+#endif
+
     /* Return the generator object for the given generator frame. */
     JSGenerator *generatorFor(JSStackFrame *fp) const;
 
     /* Early OOM-check. */
     inline bool ensureGeneratorStackSpace();
 
     bool enterGenerator(JSGenerator *gen) {
         return genStack.append(gen);
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -42,32 +42,54 @@
 #define jscntxtinlines_h___
 
 #include "jscntxt.h"
 #include "jsparse.h"
 #include "jsstaticcheck.h"
 #include "jsxml.h"
 #include "jsregexp.h"
 #include "jsgc.h"
+#include "jscompartment.h"
 
-inline js::RegExpStatics *
-JSContext::regExpStatics()
+namespace js {
+
+static inline JSObject *
+GetGlobalForScopeChain(JSContext *cx)
 {
-    VOUCH_HAVE_STACK();
     /*
-     * Whether we're on trace or not, the scope chain associated with cx->fp
-     * will lead us to the appropriate global. Although cx->fp is stale on
-     * trace, trace execution never crosses globals.
+     * This is essentially GetScopeChain(cx)->getGlobal(), but without
+     * falling off trace.
+     *
+     * This use of cx->fp, possibly on trace, is deliberate:
+     * cx->fp->scopeChain->getGlobal() returns the same object whether we're on
+     * trace or not, since we do not trace calls across global objects.
      */
-    JS_ASSERT(hasfp());
-    JSObject *global = fp()->scopeChain().getGlobal();
-    js::RegExpStatics *res = js::RegExpStatics::extractFrom(global);
-    return res;
+    VOUCH_DOES_NOT_REQUIRE_STACK();
+
+    if (cx->hasfp())
+        return cx->fp()->scopeChain().getGlobal();
+
+    JSObject *scope = cx->globalObject;
+    if (!scope) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INACTIVE);
+        return NULL;
+    }
+    OBJ_TO_INNER_OBJECT(cx, scope);
+    return scope;
 }
 
+}
+
+#ifdef JS_METHODJIT
+inline js::mjit::JaegerCompartment *JSContext::jaegerCompartment()
+{
+    return compartment->jaegerCompartment;
+}
+#endif
+
 inline bool
 JSContext::ensureGeneratorStackSpace()
 {
     bool ok = genStack.reserve(genStack.length() + 1);
     if (!ok)
         js_ReportOutOfMemory(this);
     return ok;
 }
@@ -82,16 +104,22 @@ JSContext::computeNextFrame(JSStackFrame
             if (f == fp)
                 return next;
         }
         if (end != ss->getPreviousInContext()->getCurrentFrame())
             next = NULL;
     }
 }
 
+inline js::RegExpStatics *
+JSContext::regExpStatics()
+{
+    return js::RegExpStatics::extractFrom(js::GetGlobalForScopeChain(this));
+}
+
 namespace js {
 
 JS_REQUIRES_STACK JS_ALWAYS_INLINE JSFrameRegs *
 StackSegment::getCurrentRegs() const
 {
     JS_ASSERT(inContext());
     return isActive() ? cx->regs : getSuspendedRegs();
 }
@@ -565,16 +593,20 @@ class CompartmentChecker
     void check(JSScript *script) {
         if (script && script != JSScript::emptyScript()) {
             check(script->compartment);
             if (script->u.object)
                 check(script->u.object);
         }
     }
 
+    void check(JSStackFrame *fp) {
+        check(&fp->scopeChain());
+    }
+
     void check(JSString *) { /* nothing for now */ }
 };
 
 #endif
 
 /*
  * Don't perform these checks when called from a finalizer. The checking
  * depends on other objects not having been swept yet.
@@ -701,11 +733,26 @@ CallJSPropertyOp(JSContext *cx, js::Prop
 
 JS_ALWAYS_INLINE bool
 CallJSPropertyOpSetter(JSContext *cx, js::PropertyOp op, JSObject *obj, jsid id, js::Value *vp)
 {
     assertSameCompartment(cx, obj, id, *vp);
     return op(cx, obj, id, vp);
 }
 
+inline bool
+CallSetter(JSContext *cx, JSObject *obj, jsid id, PropertyOp op, uintN attrs, uintN shortid,
+           js::Value *vp)
+{
+    if (attrs & JSPROP_SETTER)
+        return ExternalGetOrSet(cx, obj, id, CastAsObjectJsval(op), JSACC_WRITE, 1, vp, vp);
+
+    if (attrs & JSPROP_GETTER)
+        return js_ReportGetterOnlyAssignment(cx);
+
+    if (attrs & JSPROP_SHORTID)
+        id = INT_TO_JSID(shortid);
+    return CallJSPropertyOpSetter(cx, op, obj, id, vp);
+}
+
 }  /* namespace js */
 
 #endif /* jscntxtinlines_h___ */
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -39,47 +39,60 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "jscntxt.h"
 #include "jscompartment.h"
 #include "jsgc.h"
 #include "jsiter.h"
 #include "jsproxy.h"
 #include "jsscope.h"
+#include "methodjit/MethodJIT.h"
 #include "methodjit/PolyIC.h"
 #include "methodjit/MonoIC.h"
 
 #include "jsgcinlines.h"
 
 using namespace js;
 using namespace js::gc;
 
 JSCompartment::JSCompartment(JSRuntime *rt)
-  : rt(rt), principals(NULL), data(NULL), marked(false), debugMode(false),
+  : rt(rt), principals(NULL), data(NULL), marked(false), debugMode(rt->debugMode),
     anynameObject(NULL), functionNamespaceObject(NULL)
 {
     JS_INIT_CLIST(&scripts);
 }
 
 JSCompartment::~JSCompartment()
 {
+#ifdef JS_METHODJIT
+    delete jaegerCompartment;
+#endif
 }
 
 bool
 JSCompartment::init()
 {
     chunk = NULL;
     for (unsigned i = 0; i < FINALIZE_LIMIT; i++)
         arenas[i].init();
     for (unsigned i = 0; i < FINALIZE_LIMIT; i++)
         freeLists.finalizables[i] = NULL;
 #ifdef JS_GCMETER
     memset(&compartmentStats, 0, sizeof(JSGCArenaStats) * FINALIZE_LIMIT);
 #endif
-    return crossCompartmentWrappers.init();
+    if (!crossCompartmentWrappers.init())
+        return false;
+
+#ifdef JS_METHODJIT
+    if (!(jaegerCompartment = new mjit::JaegerCompartment))
+        return false;
+    return jaegerCompartment->Initialize();
+#else
+    return true;
+#endif
 }
 
 bool
 JSCompartment::arenaListsAreEmpty()
 {
   for (unsigned i = 0; i < FINALIZE_LIMIT; i++) {
        if (!arenas[i].isEmpty())
            return false;
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -49,45 +49,54 @@
 #include "jsclist.h"
 #include "jsxml.h"
 
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable:4251) /* Silence warning about JS_FRIEND_API and data members. */
 #endif
 
+namespace js {
+namespace mjit {
+class JaegerCompartment;
+}
+}
+
 struct JS_FRIEND_API(JSCompartment) {
-    JSRuntime       *rt;
-    JSPrincipals    *principals;
-    js::gc::Chunk   *chunk;
+    JSRuntime                    *rt;
+    JSPrincipals                 *principals;
+    js::gc::Chunk                *chunk;
 
-    js::gc::ArenaList arenas[js::gc::FINALIZE_LIMIT];
-    js::gc::FreeLists freeLists;
+    js::gc::ArenaList            arenas[js::gc::FINALIZE_LIMIT];
+    js::gc::FreeLists            freeLists;
 
 #ifdef JS_GCMETER
-    js::gc::JSGCArenaStats compartmentStats[js::gc::FINALIZE_LIMIT];
+    js::gc::JSGCArenaStats       compartmentStats[js::gc::FINALIZE_LIMIT];
 #endif
 
-    void *data;
-    bool marked;
-    js::WrapperMap crossCompartmentWrappers;
-    bool debugMode;
+    void                         *data;
+    bool                         marked;
+    js::WrapperMap               crossCompartmentWrappers;
 
-    /* List all scripts in this compartment. */
-    JSCList scripts;
+#ifdef JS_METHODJIT
+    js::mjit::JaegerCompartment  *jaegerCompartment;
+#endif
+
+    bool                         debugMode;  // true iff debug mode on
+    JSCList                      scripts;    // scripts in this compartment
 
     /*
      * Weak references to lazily-created, well-known XML singletons.
      *
      * NB: Singleton objects must be carefully disconnected from the rest of
      * the object graph usually associated with a JSContext's global object,
      * including the set of standard class objects.  See jsxml.c for details.
      */
-    JSObject            *anynameObject;
-    JSObject            *functionNamespaceObject;
+    JSObject                     *anynameObject;
+    JSObject                     *functionNamespaceObject;
 
     JSCompartment(JSRuntime *cx);
     ~JSCompartment();
 
     bool init();
 
     bool wrap(JSContext *cx, js::Value *vp);
     bool wrap(JSContext *cx, JSString **strp);
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -57,16 +57,17 @@
 #include "jslock.h"
 #include "jsobj.h"
 #include "jsopcode.h"
 #include "jsparse.h"
 #include "jsscope.h"
 #include "jsscript.h"
 #include "jsstaticcheck.h"
 #include "jsstr.h"
+#include "jswrapper.h"
 
 #include "jsatominlines.h"
 #include "jsinterpinlines.h"
 #include "jsobjinlines.h"
 #include "jsscopeinlines.h"
 
 #include "jsautooplen.h"
 
@@ -102,34 +103,40 @@ IsScriptLive(JSContext *cx, JSScript *sc
     for (AllFramesIter i(cx); !i.done(); ++i) {
         if (i.fp()->maybeScript() == script)
             return true;
     }
     return false;
 }
 #endif
 
+JS_PUBLIC_API(void)
+JS_SetRuntimeDebugMode(JSRuntime *rt, JSBool debug)
+{
+    rt->debugMode = debug;
+}
+
 JS_FRIEND_API(JSBool)
 js_SetDebugMode(JSContext *cx, JSBool debug)
 {
     cx->compartment->debugMode = debug;
 #ifdef JS_METHODJIT
     for (JSScript *script = (JSScript *)cx->compartment->scripts.next;
          &script->links != &cx->compartment->scripts;
          script = (JSScript *)script->links.next) {
-        if (script->debugMode != debug &&
+        if (script->debugMode != (bool) debug &&
             script->hasJITCode() &&
             !IsScriptLive(cx, script)) {
             /*
              * In the event that this fails, debug mode is left partially on,
              * leading to a small performance overhead but no loss of
              * correctness. We set the debug flag to false so that the caller
              * will not later attempt to use debugging features.
              */
-            mjit::Recompiler recompiler(cx, script);
+            js::mjit::Recompiler recompiler(cx, script);
             if (!recompiler.recompile()) {
                 cx->compartment->debugMode = JS_FALSE;
                 return JS_FALSE;
             }
         }
     }
 #endif
     return JS_TRUE;
@@ -269,17 +276,17 @@ JS_SetTrap(JSContext *cx, JSScript *scri
     trap->handler = handler;
     trap->closure = closure;
     DBG_UNLOCK(rt);
     if (junk)
         cx->free(junk);
 
 #ifdef JS_METHODJIT
     if (script->hasJITCode()) {
-        mjit::Recompiler recompiler(cx, script);
+        js::mjit::Recompiler recompiler(cx, script);
         if (!recompiler.recompile())
             return JS_FALSE;
     }
 #endif
 
     return JS_TRUE;
 }
 
@@ -1175,44 +1182,57 @@ JS_GetFrameObject(JSContext *cx, JSStack
     return &fp->scopeChain();
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp)
 {
     JS_ASSERT(cx->stack().contains(fp));
 
+    js::AutoCompartment ac(cx, &fp->scopeChain());
+    if (!ac.enter())
+        return NULL;
+
     /* Force creation of argument and call objects if not yet created */
     (void) JS_GetFrameCallObject(cx, fp);
-    return js_GetScopeChain(cx, fp);
+    return GetScopeChain(cx, fp);
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp)
 {
     JS_ASSERT(cx->stack().contains(fp));
 
     if (!fp->isFunctionFrame())
         return NULL;
 
+    js::AutoCompartment ac(cx, &fp->scopeChain());
+    if (!ac.enter())
+        return NULL;
+
     /* Force creation of argument object if not yet created */
     (void) js_GetArgsObject(cx, fp);
 
     /*
      * XXX ill-defined: null return here means error was reported, unlike a
      *     null returned above or in the #else
      */
     return js_GetCallObject(cx, fp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetFrameThis(JSContext *cx, JSStackFrame *fp, jsval *thisv)
 {
     if (fp->isDummyFrame())
         return false;
+
+    js::AutoCompartment ac(cx, &fp->scopeChain());
+    if (!ac.enter())
+        return false;
+
     if (!fp->computeThis(cx))
         return false;
     *thisv = Jsvalify(fp->thisValue());
     return true;
 }
 
 JS_PUBLIC_API(JSFunction *)
 JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp)
@@ -1264,16 +1284,17 @@ JS_PUBLIC_API(jsval)
 JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp)
 {
     return Jsvalify(fp->returnValue());
 }
 
 JS_PUBLIC_API(void)
 JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval)
 {
+    assertSameCompartment(cx, fp, rval);
     fp->setReturnValue(Valueify(rval));
 }
 
 /************************************************************************/
 
 JS_PUBLIC_API(const char *)
 JS_GetScriptFilename(JSContext *cx, JSScript *script)
 {
@@ -1327,16 +1348,20 @@ JS_EvaluateUCInStackFrame(JSContext *cx,
 
     if (!CheckDebugMode(cx))
         return JS_FALSE;
 
     JSObject *scobj = JS_GetFrameScopeChain(cx, fp);
     if (!scobj)
         return false;
 
+    js::AutoCompartment ac(cx, scobj);
+    if (!ac.enter())
+        return NULL;
+
     /*
      * NB: This function breaks the assumption that the compiler can see all
      * calls and properly compute a static level. In order to get around this,
      * we use a static level that will cause us not to attempt to optimize
      * variable references made by this frame.
      */
     JSScript *script = Compiler::compileScript(cx, scobj, fp, js_StackFramePrincipals(cx, fp),
                                                TCF_COMPILE_N_GO, chars, length, NULL,
@@ -1399,16 +1424,17 @@ JS_PropertyIterator(JSObject *obj, JSSco
 
     return *iteratorp = reinterpret_cast<JSScopeProperty *>(const_cast<Shape *>(shape));
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
                    JSPropertyDesc *pd)
 {
+    assertSameCompartment(cx, obj);
     Shape *shape = (Shape *) sprop;
     pd->id = IdToJsval(shape->id);
 
     JSBool wasThrowing = cx->throwing;
     AutoValueRooter lastException(cx, cx->exception);
     cx->throwing = JS_FALSE;
 
     if (!js_GetProperty(cx, obj, shape->id, Valueify(&pd->value))) {
@@ -1452,16 +1478,17 @@ JS_GetPropertyDesc(JSContext *cx, JSObje
         }
     }
     return JS_TRUE;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda)
 {
+    assertSameCompartment(cx, obj);
     Class *clasp = obj->getClass();
     if (!obj->isNative() || (clasp->flags & JSCLASS_NEW_ENUMERATE)) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                              JSMSG_CANT_DESCRIBE_PROPS, clasp->name);
         return JS_FALSE;
     }
     if (!clasp->enumerate(cx, obj))
         return JS_FALSE;
--- a/js/src/jsdbgapi.h
+++ b/js/src/jsdbgapi.h
@@ -45,16 +45,23 @@
  */
 #include "jsapi.h"
 #include "jsopcode.h"
 #include "jsprvtd.h"
 
 JS_BEGIN_EXTERN_C
 
 /*
+ * Currently, we only support runtime-wide debugging. In the future, we should
+ * be able to support compartment-wide debugging.
+ */
+extern JS_PUBLIC_API(void)
+JS_SetRuntimeDebugMode(JSRuntime *rt, JSBool debug);
+
+/*
  * Debug mode is a compartment-wide mode that enables a debugger to attach
  * to and interact with running methodjit-ed frames. In particular, it causes
  * every function to be compiled as if an eval was present (so eval-in-frame)
  * can work, and it ensures that functions can be re-JITed for other debug
  * features. In general, it is not safe to interact with frames that were live
  * before debug mode was enabled. For this reason, it is also not safe to
  * enable debug mode while frames are live.
  */
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -353,17 +353,17 @@ WrapEscapingClosure(JSContext *cx, JSSta
 
     /*
      * We do not attempt to reify Call and Block objects on demand for outer
      * scopes. This could be done (see the "v8" patch in bug 494235) but it is
      * fragile in the face of ongoing compile-time optimization. Instead, the
      * _DBG* opcodes used by wrappers created here must cope with unresolved
      * upvars and throw them as reference errors. Caveat debuggers!
      */
-    JSObject *scopeChain = js_GetScopeChain(cx, fp);
+    JSObject *scopeChain = GetScopeChain(cx, fp);
     if (!scopeChain)
         return NULL;
 
     JSObject *wfunobj = NewFunction(cx, scopeChain);
     if (!wfunobj)
         return NULL;
     AutoObjectRooter tvr(cx, wfunobj);
 
@@ -2923,17 +2923,17 @@ JS_DEFINE_CALLINFO_3(extern, OBJECT, js_
 
 JS_REQUIRES_STACK JSObject *
 js_NewFlatClosure(JSContext *cx, JSFunction *fun, JSOp op, size_t oplen)
 {
     /*
      * Flat closures can be partial, they may need to search enclosing scope
      * objects via JSOP_NAME, etc.
      */
-    JSObject *scopeChain = js_GetScopeChainFast(cx, cx->fp(), op, oplen);
+    JSObject *scopeChain = GetScopeChainFast(cx, cx->fp(), op, oplen);
     if (!scopeChain)
         return NULL;
 
     JSObject *closure = js_AllocFlatClosure(cx, fun, scopeChain);
     if (!closure || fun->u.i.nupvars == 0)
         return closure;
 
     Value *upvars = closure->getFlatClosureUpvars();
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -157,25 +157,52 @@ JSStackFrame::pc(JSContext *cx, JSStackF
     JS_ASSERT((uint8*)callIC.funGuard.executableAddress() + callIC.joinPointOffset == next->ncode_);
     return callIC.pc;
 #else
     JS_NOT_REACHED("Unknown PC for frame");
     return NULL;
 #endif
 }
 
+JSObject *
+js::GetScopeChain(JSContext *cx)
+{
+    JSStackFrame *fp = js_GetTopStackFrame(cx);
+    if (!fp) {
+        /*
+         * There is no code active on this context. In place of an actual
+         * scope chain, use the context's global object, which is set in
+         * js_InitFunctionAndObjectClasses, and which represents the default
+         * scope chain for the embedding. See also js_FindClassObject.
+         *
+         * For embeddings that use the inner and outer object hooks, the inner
+         * object represents the ultimate global object, with the outer object
+         * acting as a stand-in.
+         */
+        JSObject *obj = cx->globalObject;
+        if (!obj) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INACTIVE);
+            return NULL;
+        }
+
+        OBJ_TO_INNER_OBJECT(cx, obj);
+        return obj;
+    }
+    return GetScopeChain(cx, fp);
+}
+
 /*
  * This computes the blockChain by iterating through the bytecode
  * of the current script until it reaches the PC. Each time it sees
  * an ENTERBLOCK or LEAVEBLOCK instruction, it records the new
  * blockChain. A faster variant of this function that doesn't
  * require bytecode scanning appears below.
  */
 JSObject *
-js_GetBlockChain(JSContext *cx, JSStackFrame *fp)
+js::GetBlockChain(JSContext *cx, JSStackFrame *fp)
 {
     if (!fp->isScriptFrame())
         return NULL;
 
     JSScript *script = fp->script();
     jsbytecode *start = script->code;
     /* Assume that imacros don't affect blockChain */
     jsbytecode *pc = fp->hasImacropc() ? fp->imacropc() : fp->pc(cx);
@@ -213,17 +240,17 @@ js_GetBlockChain(JSContext *cx, JSStackF
 /*
  * This function computes the current blockChain, but only in
  * the special case where a BLOCKCHAIN or NULLBLOCKCHAIN
  * instruction appears immediately after the current PC.
  * We ensure this happens for a few important ops like DEFFUN.
  * |oplen| is the length of opcode at the current PC.
  */
 JSObject *
-js_GetBlockChainFast(JSContext *cx, JSStackFrame *fp, JSOp op, size_t oplen)
+js::GetBlockChainFast(JSContext *cx, JSStackFrame *fp, JSOp op, size_t oplen)
 {
     /* Assume that we're in a script frame. */
     jsbytecode *pc = fp->pc(cx);
 
     /* The fast path. */
     if (pc[oplen] == JSOP_NULLBLOCKCHAIN) {
         JS_ASSERT(js_GetOpcode(cx, fp->script(), pc) == op);
         return NULL;
@@ -269,21 +296,21 @@ js_GetBlockChainFast(JSContext *cx, JSSt
  * currently executing in, and 'with' objects for with statements; the chain is
  * typically terminated by a global object.  However, as an optimization, the
  * young end of the chain omits block objects we have not yet cloned.  To create
  * a closure, we clone the missing blocks from blockChain (which is always
  * current), place them at the head of scopeChain, and use that for the
  * closure's scope chain.  If we never close over a lexical block, we never
  * place a mutable clone of it on scopeChain.
  *
- * This lazy cloning is implemented in js_GetScopeChain, which is also used in
+ * This lazy cloning is implemented in GetScopeChain, which is also used in
  * some other cases --- entering 'with' blocks, for example.
  */
 static JSObject *
-js_GetScopeChainFull(JSContext *cx, JSStackFrame *fp, JSObject *blockChain)
+GetScopeChainFull(JSContext *cx, JSStackFrame *fp, JSObject *blockChain)
 {
     JSObject *sharedBlock = blockChain;
 
     if (!sharedBlock) {
         /*
          * Don't force a call object for a lightweight function call, but do
          * insist that there is a call object for a heavyweight function call.
          */
@@ -394,25 +421,25 @@ js_GetScopeChainFull(JSContext *cx, JSSt
                  sharedBlock);
 
     /* Place our newly cloned blocks at the head of the scope chain.  */
     fp->setScopeChainNoCallObj(*innermostNewChild);
     return innermostNewChild;
 }
 
 JSObject *
-js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
-{
-    return js_GetScopeChainFull(cx, fp, js_GetBlockChain(cx, fp));
+js::GetScopeChain(JSContext *cx, JSStackFrame *fp)
+{
+    return GetScopeChainFull(cx, fp, GetBlockChain(cx, fp));
 }
 
 JSObject *
-js_GetScopeChainFast(JSContext *cx, JSStackFrame *fp, JSOp op, size_t oplen)
-{
-    return js_GetScopeChainFull(cx, fp, js_GetBlockChainFast(cx, fp, op, oplen));
+js::GetScopeChainFast(JSContext *cx, JSStackFrame *fp, JSOp op, size_t oplen)
+{
+    return GetScopeChainFull(cx, fp, GetBlockChainFast(cx, fp, op, oplen));
 }
 
 /* Some objects (e.g., With) delegate 'this' to another object. */
 static inline JSObject *
 CallThisObjectHook(JSContext *cx, JSObject *obj, Value *argv)
 {
     JSObject *thisp = obj->thisObject(cx);
     if (!thisp)
@@ -711,17 +738,17 @@ Invoke(JSContext *cx, const CallArgs &ar
     if (fun->isHeavyweight() && !js_GetCallObject(cx, fp))
         return false;
 
     /*
      * FIXME bug 592992: hoist to ExternalInvoke
      *
      * Compute |this|. Currently, this must happen after the frame is pushed
      * and fp->scopeChain is correct because the thisObject hook may call
-     * JS_GetScopeChain.
+     * GetScopeChain.
      */
     if (!(flags & JSINVOKE_CONSTRUCT)) {
         Value &thisv = fp->functionThis();
         if (thisv.isObject()) {
             /*
              * We must call the thisObject hook in case we are not called from the
              * interpreter, where a prior bytecode has computed an appropriate
              * |this| already.
@@ -756,49 +783,49 @@ InvokeSessionGuard::start(JSContext *cx,
     LeaveTrace(cx);
 #endif
 
     /* Always push arguments, regardless of optimized/normal invoke. */
     StackSpace &stack = cx->stack();
     if (!stack.pushInvokeArgs(cx, argc, &args_))
         return false;
 
+    /* Callees may clobber 'this' or 'callee'. */
+    savedCallee_ = args_.callee() = calleev;
+    savedThis_ = args_.thisv() = thisv;
+
     do {
         /* Hoist dynamic checks from scripted Invoke. */
         if (!calleev.isObject())
             break;
         JSObject &callee = calleev.toObject();
         if (callee.getClass() != &js_FunctionClass)
             break;
         JSFunction *fun = callee.getFunctionPrivate();
         if (fun->isNative())
             break;
         script_ = fun->script();
         if (fun->isHeavyweight() || script_->isEmpty() || cx->compartment->debugMode)
             break;
 
-        /* Set (callee, this) once for the session (before args are duped). */
-        args_.callee().setObject(callee);
-        args_.thisv() = thisv;
-
         /* Push the stack frame once for the session. */
         uint32 flags = 0;
         if (!stack.getInvokeFrame(cx, args_, fun, script_, &flags, &frame_))
             return false;
         JSStackFrame *fp = frame_.fp();
         fp->initCallFrame(cx, calleev.toObject(), fun, argc, flags);
         stack.pushInvokeFrame(cx, args_, &frame_);
 
         // FIXME bug 592992: hoist thisObject hook to ExternalInvoke
         if (thisv.isObject()) {
             JSObject *thisp = thisv.toObject().thisObject(cx);
             if (!thisp)
                 return false;
             JS_ASSERT(IsSaneThisObject(*thisp));
-            fp->functionThis().setObject(*thisp);
+            savedThis_.setObject(*thisp);
         }
 
 #ifdef JS_METHODJIT
         /* Hoist dynamic checks from RunScript. */
         mjit::CompileStatus status = mjit::CanMethodJIT(cx, script_, fp);
         if (status == mjit::Compile_Error)
             return false;
         if (status != mjit::Compile_Okay)
@@ -827,18 +854,16 @@ InvokeSessionGuard::start(JSContext *cx,
      * Use the normal invoke path.
      *
      * The callee slot gets overwritten during an unoptimized Invoke, so we
      * cache it here and restore it before every Invoke call. The 'this' value
      * does not get overwritten, so we can fill it here once.
      */
     if (frame_.pushed())
         frame_.pop();
-    args_.thisv() = thisv;
-    savedCallee_ = calleev;
     formals_ = actuals_ = args_.argv();
     nformals_ = (unsigned)-1;
     return true;
 }
 
 bool
 ExternalInvoke(JSContext *cx, const Value &thisv, const Value &fval,
                uintN argc, Value *argv, Value *rval)
@@ -1298,16 +1323,37 @@ InvokeConstructorWithGivenThis(JSContext
         ok = Invoke(cx, args, JSINVOKE_CONSTRUCT);
     }
 
     *rval = args.rval();
     return ok;
 }
 
 bool
+DirectEval(JSContext *cx, JSFunction *evalfun, uint32 argc, Value *vp)
+{
+    JS_ASSERT(vp == cx->regs->sp - argc - 2);
+    JS_ASSERT(vp[0].isObject());
+    JS_ASSERT(vp[0].toObject().isFunction());
+    JS_ASSERT(vp[0].toObject().getFunctionPrivate() == evalfun);
+    JS_ASSERT(IsBuiltinEvalFunction(evalfun));
+
+    AutoFunctionCallProbe callProbe(cx, evalfun);
+
+    JSStackFrame *caller = cx->fp();
+    JS_ASSERT(caller->isScriptFrame());
+    JSObject *scopeChain =
+        GetScopeChainFast(cx, caller, JSOP_EVAL, JSOP_EVAL_LENGTH + JSOP_LINENO_LENGTH);
+    if (!scopeChain || !EvalKernel(cx, argc, vp, DIRECT_EVAL, caller, scopeChain))
+        return false;
+    cx->regs->sp = vp + 1;
+    return true;
+}
+
+bool
 ValueToId(JSContext *cx, const Value &v, jsid *idp)
 {
     int32_t i;
     if (ValueFitsInInt32(v, &i) && INT_FITS_IN_JSID(i)) {
         *idp = INT_TO_JSID(i);
         return true;
     }
 
@@ -1343,17 +1389,17 @@ js_EnterWith(JSContext *cx, jsint stackI
         obj = &sp[-1].toObject();
     } else {
         obj = js_ValueToNonNullObject(cx, sp[-1]);
         if (!obj)
             return JS_FALSE;
         sp[-1].setObject(*obj);
     }
 
-    JSObject *parent = js_GetScopeChainFast(cx, fp, op, oplen);
+    JSObject *parent = GetScopeChainFast(cx, fp, op, oplen);
     if (!parent)
         return JS_FALSE;
 
     OBJ_TO_INNER_OBJECT(cx, obj);
     if (!obj)
         return JS_FALSE;
 
     JSObject *withobj = js_NewWithObject(cx, obj, parent,
@@ -2711,17 +2757,17 @@ BEGIN_CASE(JSOP_POP)
     regs.sp--;
 END_CASE(JSOP_POP)
 
 BEGIN_CASE(JSOP_POPN)
 {
     regs.sp -= GET_UINT16(regs.pc);
 #ifdef DEBUG
     JS_ASSERT(regs.fp->base() <= regs.sp);
-    JSObject *obj = js_GetBlockChain(cx, regs.fp);
+    JSObject *obj = GetBlockChain(cx, regs.fp);
     JS_ASSERT_IF(obj,
                  OBJ_BLOCK_DEPTH(cx, obj) + OBJ_BLOCK_COUNT(cx, obj)
                  <= (size_t) (regs.sp - regs.fp->base()));
     for (obj = &regs.fp->scopeChain(); obj; obj = obj->getParent()) {
         Class *clasp = obj->getClass();
         if (clasp != &js_BlockClass && clasp != &js_WithClass)
             continue;
         if (obj->getPrivate() != js_FloatingFrameIfGenerator(cx, regs.fp))
@@ -4602,21 +4648,17 @@ BEGIN_CASE(JSOP_EVAL)
 
     if (!IsFunctionObject(*vp, &callee))
         goto call_using_invoke;
 
     newfun = callee->getFunctionPrivate();
     if (!IsBuiltinEvalFunction(newfun))
         goto not_direct_eval;
 
-    Probes::enterJSFun(cx, newfun);
-    JSBool ok = CallJSNative(cx, newfun->u.n.native, argc, vp);
-    Probes::exitJSFun(cx, newfun);
-    regs.sp = vp + 1;
-    if (!ok)
+    if (!DirectEval(cx, newfun, argc, vp))
         goto error;
 }
 END_CASE(JSOP_EVAL)
 
 BEGIN_CASE(JSOP_CALL)
 BEGIN_CASE(JSOP_APPLY)
 {
     argc = GET_ARGC(regs.pc);
@@ -4903,17 +4945,17 @@ END_CASE(JSOP_OBJECT)
 
 BEGIN_CASE(JSOP_REGEXP)
 {
     /*
      * Push a regexp object cloned from the regexp literal object mapped by the
      * bytecode at pc. ES5 finally fixed this bad old ES3 design flaw which was
      * flouted by many browser-based implementations.
      *
-     * We avoid the js_GetScopeChain call here and pass fp->scopeChain as
+     * We avoid the GetScopeChain call here and pass fp->scopeChain as
      * js_GetClassPrototype uses the latter only to locate the global.
      */
     jsatomid index = GET_FULL_INDEX(0);
     JSObject *proto;
     if (!js_GetClassPrototype(cx, &regs.fp->scopeChain(), JSProto_RegExp, &proto))
         goto error;
     JS_ASSERT(proto);
     JSObject *obj = js_CloneRegExpObject(cx, script->getRegExp(index), proto);
@@ -5363,17 +5405,17 @@ BEGIN_CASE(JSOP_DEFFUN)
          * Even a null closure needs a parent for principals finding.
          * FIXME: bug 476950, although debugger users may also demand some kind
          * of scope link for debugger-assisted eval-in-frame.
          */
         obj2 = &regs.fp->scopeChain();
     } else {
         JS_ASSERT(!FUN_FLAT_CLOSURE(fun));
 
-        obj2 = js_GetScopeChainFast(cx, regs.fp, JSOP_DEFFUN, JSOP_DEFFUN_LENGTH);
+        obj2 = GetScopeChainFast(cx, regs.fp, JSOP_DEFFUN, JSOP_DEFFUN_LENGTH);
         if (!obj2)
             goto error;
     }
 
     /*
      * If static link is not current scope, clone fun's object to link to the
      * current scope via parent. We do this to enable sharing of compiled
      * functions among multiple equivalent scopes, amortizing the cost of
@@ -5510,18 +5552,18 @@ BEGIN_CASE(JSOP_DEFLOCALFUN)
     JS_ASSERT(!FUN_FLAT_CLOSURE(fun));
     JSObject *obj = FUN_OBJECT(fun);
 
     if (FUN_NULL_CLOSURE(fun)) {
         obj = CloneFunctionObject(cx, fun, &regs.fp->scopeChain());
         if (!obj)
             goto error;
     } else {
-        JSObject *parent = js_GetScopeChainFast(cx, regs.fp, JSOP_DEFLOCALFUN,
-                                                JSOP_DEFLOCALFUN_LENGTH);
+        JSObject *parent = GetScopeChainFast(cx, regs.fp, JSOP_DEFLOCALFUN,
+                                             JSOP_DEFLOCALFUN_LENGTH);
         if (!parent)
             goto error;
 
         if (obj->getParent() != parent) {
 #ifdef JS_TRACER
             if (TRACE_RECORDER(cx))
                 AbortRecording(cx, "DEFLOCALFUN for closure");
 #endif
@@ -5674,17 +5716,17 @@ BEGIN_CASE(JSOP_LAMBDA)
                     h.add(p, fun, 1);
                 } else {
                     JS_ASSERT(p->key == fun);
                     ++p->value;
                 }
             }
 #endif
         } else {
-            parent = js_GetScopeChainFast(cx, regs.fp, JSOP_LAMBDA, JSOP_LAMBDA_LENGTH);
+            parent = GetScopeChainFast(cx, regs.fp, JSOP_LAMBDA, JSOP_LAMBDA_LENGTH);
             if (!parent)
                 goto error;
         }
 
         obj = CloneFunctionObject(cx, fun, parent);
         if (!obj)
             goto error;
     } while (0);
--- a/js/src/jsinterp.h
+++ b/js/src/jsinterp.h
@@ -778,39 +778,37 @@ struct JSStackFrame
     static JSObject *const sInvalidScopeChain;
 #endif
 };
 
 namespace js {
 
 static const size_t VALUES_PER_STACK_FRAME = sizeof(JSStackFrame) / sizeof(Value);
 
-} /* namespace js */
-
+extern JSObject *
+GetBlockChain(JSContext *cx, JSStackFrame *fp);
 
 extern JSObject *
-js_GetBlockChain(JSContext *cx, JSStackFrame *fp);
+GetBlockChainFast(JSContext *cx, JSStackFrame *fp, JSOp op, size_t oplen);
 
 extern JSObject *
-js_GetBlockChainFast(JSContext *cx, JSStackFrame *fp, JSOp op, size_t oplen);
+GetScopeChain(JSContext *cx);
 
 /*
  * Refresh and return fp->scopeChain.  It may be stale if block scopes are
  * active but not yet reflected by objects in the scope chain.  If a block
  * scope contains a with, eval, XML filtering predicate, or similar such
  * dynamically scoped construct, then compile-time block scope at fp->blocks
  * must reflect at runtime.
  */
 extern JSObject *
-js_GetScopeChain(JSContext *cx, JSStackFrame *fp);
+GetScopeChain(JSContext *cx, JSStackFrame *fp);
 
 extern JSObject *
-js_GetScopeChainFast(JSContext *cx, JSStackFrame *fp, JSOp op, size_t oplen);
-
-namespace js {
+GetScopeChainFast(JSContext *cx, JSStackFrame *fp, JSOp op, size_t oplen);
 
 /*
  * Report an error that the this value passed as |this| in the given arguments
  * vector is not compatible with the specified class.
  */
 void
 ReportIncompatibleMethod(JSContext *cx, Value *vp, Class *clasp);
 
@@ -971,16 +969,26 @@ ExternalGetOrSet(JSContext *cx, JSObject
 extern JS_REQUIRES_STACK bool
 InvokeConstructor(JSContext *cx, const CallArgs &args);
 
 extern JS_REQUIRES_STACK bool
 InvokeConstructorWithGivenThis(JSContext *cx, JSObject *thisobj, const Value &fval,
                                uintN argc, Value *argv, Value *rval);
 
 /*
+ * Performs a direct eval for the given arguments, which must correspond to the
+ * currently-executing stack frame, which must be a script frame.  evalfun must
+ * be the built-in eval function and must correspond to the callee in vp[0].
+ * When this function succeeds it returns the result in *vp, adjusts the JS
+ * stack pointer, and returns true.
+ */
+extern JS_REQUIRES_STACK bool
+DirectEval(JSContext *cx, JSFunction *evalfun, uint32 argc, Value *vp);
+
+/*
  * Executes a script with the given scope chain in the context of the given
  * frame.
  */
 extern JS_FORCES_STACK bool
 Execute(JSContext *cx, JSObject *chain, JSScript *script,
         JSStackFrame *prev, uintN flags, Value *result);
 
 /*
--- a/js/src/jsinterpinlines.h
+++ b/js/src/jsinterpinlines.h
@@ -506,17 +506,17 @@ PutActivationObjects(JSContext *cx, JSSt
         js_PutArgsObject(cx, fp);
     }
 }
 
 class InvokeSessionGuard
 {
     InvokeArgsGuard args_;
     InvokeFrameGuard frame_;
-    Value savedCallee_;
+    Value savedCallee_, savedThis_;
     Value *formals_, *actuals_;
     unsigned nformals_;
     JSScript *script_;
     void *code_;
     Value *stackLimit_;
     jsbytecode *stop_;
 
     bool optimized() const { return frame_.pushed(); }
@@ -549,20 +549,22 @@ class InvokeSessionGuard
     }
 };
 
 inline bool
 InvokeSessionGuard::invoke(JSContext *cx) const
 {
     /* N.B. Must be kept in sync with Invoke */
 
-    if (!optimized()) {
-        args_.callee() = savedCallee_;
+    /* Refer to canonical (callee, this) for optimized() sessions. */
+    formals_[-2] = savedCallee_;
+    formals_[-1] = savedThis_;
+
+    if (!optimized())
         return Invoke(cx, args_, 0);
-    }
 
     /* Clear any garbage left from the last Invoke. */
     JSStackFrame *fp = frame_.fp();
     fp->clearMissingArgs();
     fp->resetInvokeCallFrame();
     SetValueRangeToUndefined(fp->slots(), script_->nfixed);
 
     JSBool ok;
--- a/js/src/jsiter.h
+++ b/js/src/jsiter.h
@@ -38,16 +38,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef jsiter_h___
 #define jsiter_h___
 
 /*
  * JavaScript iterators.
  */
+#include "jscntxt.h"
 #include "jsprvtd.h"
 #include "jspubtd.h"
 #include "jsversion.h"
 
 /*
  * NB: these flag bits are encoded into the bytecode stream in the immediate
  * operand of JSOP_ITER, so don't change them without advancing jsxdrapi.h's
  * JSXDR_BYTECODE_VERSION.
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -110,18 +110,18 @@ Class js_MathClass = {
     PropertyStub,   /* delProperty */
     PropertyStub,   /* getProperty */
     PropertyStub,   /* setProperty */
     EnumerateStub,
     ResolveStub,
     ConvertStub
 };
 
-static JSBool
-math_abs(JSContext *cx, uintN argc, Value *vp)
+JSBool
+js_math_abs(JSContext *cx, uintN argc, Value *vp)
 {
     jsdouble x, z;
 
     if (argc == 0) {
         vp->setDouble(js_NaN);
         return JS_TRUE;
     }
     if (!ValueToNumber(cx, vp[2], &x))
@@ -664,30 +664,29 @@ math_toSource(JSContext *cx, uintN argc,
 {
     vp->setString(ATOM_TO_STRING(CLASS_ATOM(cx, Math)));
     return JS_TRUE;
 }
 #endif
 
 #ifdef JS_TRACER
 
-#define MATH_BUILTIN_1(name) MATH_BUILTIN_CFUN_1(name, name)
-#define MATH_BUILTIN_CFUN_1(name, cfun)                                       \
-    static jsdouble FASTCALL math_##name##_tn(MathCache *cache, jsdouble d) { \
+#define MATH_BUILTIN_1(name, cfun)                                            \
+    static jsdouble FASTCALL name##_tn(MathCache *cache, jsdouble d) {        \
         return cache->lookup(cfun, d);                                        \
     }                                                                         \
-    JS_DEFINE_TRCINFO_1(math_##name,                                          \
-        (2, (static, DOUBLE, math_##name##_tn, MATHCACHE, DOUBLE, 1, nanojit::ACCSET_NONE)))
+    JS_DEFINE_TRCINFO_1(name,                                                 \
+        (2, (static, DOUBLE, name##_tn, MATHCACHE, DOUBLE, 1, nanojit::ACCSET_NONE)))
 
-MATH_BUILTIN_CFUN_1(abs, fabs)
-MATH_BUILTIN_1(atan)
-MATH_BUILTIN_1(sin)
-MATH_BUILTIN_1(cos)
-MATH_BUILTIN_1(sqrt)
-MATH_BUILTIN_1(tan)
+MATH_BUILTIN_1(js_math_abs, fabs)
+MATH_BUILTIN_1(math_atan, atan)
+MATH_BUILTIN_1(math_sin, sin)
+MATH_BUILTIN_1(math_cos, cos)
+MATH_BUILTIN_1(math_sqrt, sqrt)
+MATH_BUILTIN_1(math_tan, tan)
 
 static jsdouble FASTCALL
 math_acos_tn(MathCache *cache, jsdouble d)
 {
 #if defined(SOLARIS) && defined(__GNUC__)
     if (d < -1 || 1 < d) {
         return js_NaN;
     }
@@ -828,17 +827,17 @@ JS_DEFINE_TRCINFO_1(js_math_ceil,
     (1, (static, DOUBLE, math_ceil_tn, DOUBLE,          1, nanojit::ACCSET_NONE)))
 
 #endif /* JS_TRACER */
 
 static JSFunctionSpec math_static_methods[] = {
 #if JS_HAS_TOSOURCE
     JS_FN(js_toSource_str,  math_toSource,        0, 0),
 #endif
-    JS_TN("abs",            math_abs,             1, 0, &math_abs_trcinfo),
+    JS_TN("abs",            js_math_abs,          1, 0, &js_math_abs_trcinfo),
     JS_TN("acos",           math_acos,            1, 0, &math_acos_trcinfo),
     JS_TN("asin",           math_asin,            1, 0, &math_asin_trcinfo),
     JS_TN("atan",           math_atan,            1, 0, &math_atan_trcinfo),
     JS_TN("atan2",          math_atan2,           2, 0, &math_atan2_trcinfo),
     JS_TN("ceil",           js_math_ceil,         1, 0, &js_math_ceil_trcinfo),
     JS_TN("cos",            math_cos,             1, 0, &math_cos_trcinfo),
     JS_TN("exp",            math_exp,             1, 0, &math_exp_trcinfo),
     JS_TN("floor",          js_math_floor,        1, 0, &js_math_floor_trcinfo),
--- a/js/src/jsmath.h
+++ b/js/src/jsmath.h
@@ -89,16 +89,19 @@ js_InitMathClass(JSContext *cx, JSObject
 
 extern bool
 js_IsMathFunction(JSNative native);
 
 extern void
 js_InitRandom(JSContext *cx);
 
 extern JSBool
+js_math_abs(JSContext *cx, uintN argc, js::Value *vp);
+
+extern JSBool
 js_math_ceil(JSContext *cx, uintN argc, js::Value *vp);
 
 extern JSBool
 js_math_floor(JSContext *cx, uintN argc, js::Value *vp);
 
 extern JSBool
 js_math_max(JSContext *cx, uintN argc, js::Value *vp);
 
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -926,43 +926,37 @@ js_CheckPrincipalsAccess(JSContext *cx, 
             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                                  JSMSG_BAD_INDIRECT_CALL, callerstr);
             return JS_FALSE;
         }
     }
     return JS_TRUE;
 }
 
-static JSObject *
-CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller)
-{
-    JSObject *inner;
-
-    if (!scopeobj)
-        goto bad;
-
-    OBJ_TO_INNER_OBJECT(cx, scopeobj);
-    if (!scopeobj)
-        return NULL;
+static bool
+CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj)
+{
+    JSObject *inner = scopeobj;
+    OBJ_TO_INNER_OBJECT(cx, inner);
+    if (!inner)
+        return false;
+    JS_ASSERT(inner == scopeobj);
 
     /* XXX This is an awful gross hack. */
-    inner = scopeobj;
     while (scopeobj) {
         JSObjectOp op = scopeobj->getClass()->ext.innerObject;
-        if (op && op(cx, scopeobj) != scopeobj)
-            goto bad;
+        if (op && op(cx, scopeobj) != scopeobj) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_INDIRECT_CALL,
+                                 js_eval_str);
+            return false;
+        }
         scopeobj = scopeobj->getParent();
     }
 
-    return inner;
-
-bad:
-    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
-                         JSMSG_BAD_INDIRECT_CALL, caller);
-    return NULL;
+    return true;
 }
 
 const char *
 js_ComputeFilename(JSContext *cx, JSStackFrame *caller,
                    JSPrincipals *principals, uintN *linenop)
 {
     uint32 flags;
 #ifdef DEBUG
@@ -1088,151 +1082,161 @@ EvalCacheLookup(JSContext *cx, JSString 
     }
     return NULL;
 }
 
 /* ES5 15.1.2.1. */
 static JSBool
 eval(JSContext *cx, uintN argc, Value *vp)
 {
-    if (argc < 1) {
-        vp->setUndefined();
-        return true;
-    }
+    /*
+     * NB: This method handles only indirect eval: direct eval is handled by
+     *     JSOP_EVAL.
+     */
 
     JSStackFrame *caller = js_GetScriptedCaller(cx, NULL);
+
+    /* FIXME Bug 602994: This really should be perfectly cromulent. */
     if (!caller) {
         /* Eval code needs to inherit principals from the caller. */
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                              JSMSG_BAD_INDIRECT_CALL, js_eval_str);
         return false;
     }
 
-    jsbytecode *callerPC = caller->pc(cx);
-    bool directCall = (callerPC && js_GetOpcode(cx, caller->script(), callerPC) == JSOP_EVAL);
-
-    /*
-     * If the callee was originally a cross-compartment wrapper, this is an
-     * indirect call.
-     */
-    if (directCall && caller->scopeChain().compartment() != vp[0].toObject().compartment())
-        directCall = false;
-
+    return EvalKernel(cx, argc, vp, INDIRECT_EVAL, caller, vp[0].toObject().getGlobal());
+}
+
+namespace js {
+
+bool
+EvalKernel(JSContext *cx, uintN argc, Value *vp, EvalType evalType, JSStackFrame *caller,
+           JSObject *scopeobj)
+{
     /*
-     * Direct calls to eval are supposed to see the caller's |this|. If we
-     * haven't wrapped that yet, do so now, before we make a copy of it for
-     * the eval code to use.
+     * FIXME Bug 602994: Calls with no scripted caller should be permitted and
+     *       should be implemented as indirect calls.
      */
-    if (!caller->computeThis(cx))
-        return false;
-        
-    Value *argv = JS_ARGV(cx, vp);
-    if (!argv[0].isString()) {
-        *vp = argv[0];
-        return true;
-    }
+    JS_ASSERT(caller);
+    JS_ASSERT(scopeobj);
 
     /*
      * We once supported a second argument to eval to use as the scope chain
      * when evaluating the code string.  Warn when such uses are seen so that
      * authors will know that support for eval(s, o) has been removed.
      */
-    if (argc > 1 && !caller->script()->warnedAboutTwoArgumentEval) {
+    JSScript *callerScript = caller->script();
+    if (argc > 1 && !callerScript->warnedAboutTwoArgumentEval) {
         static const char TWO_ARGUMENT_WARNING[] =
             "Support for eval(code, scopeObject) has been removed. "
             "Use |with (scopeObject) eval(code);| instead.";
         if (!JS_ReportWarning(cx, TWO_ARGUMENT_WARNING))
             return false;
-        caller->script()->warnedAboutTwoArgumentEval = true;
-    }
-
-    /*
-     * Per ES5, if we see an indirect call, then run in the global scope.
-     * (eval is specified this way so that the compiler can make assumptions
-     * about what bindings may or may not exist in the current frame if it
-     * doesn't see 'eval'.)
-     */
-    uintN staticLevel;
-    JSObject *scopeobj;
-    if (directCall) {
-        /* Compile using the caller's current scope object. */
-        staticLevel = caller->script()->staticLevel + 1;
-        scopeobj = js_GetScopeChainFast(cx, caller, JSOP_EVAL,
-                                        JSOP_EVAL_LENGTH + JSOP_LINENO_LENGTH);
-        if (!scopeobj)
-            return false;
-
-        JS_ASSERT_IF(caller->isFunctionFrame(), caller->hasCallObj());
-    } else {
-        /* Pretend that we're top level. */
-        staticLevel = 0;
-        scopeobj = vp[0].toObject().getGlobal();
-    }
-
-    /* Ensure we compile this eval with the right object in the scope chain. */
-    JSObject *result = CheckScopeChainValidity(cx, scopeobj, js_eval_str);
-    if (!result)
-        return false;
-    JS_ASSERT(result == scopeobj);
+        callerScript->warnedAboutTwoArgumentEval = true;
+    }
 
     /*
      * CSP check: Is eval() allowed at all?
      * Report errors via CSP is done in the script security mgr.
      */
     if (!js_CheckContentSecurityPolicy(cx)) {
         JS_ReportError(cx, "call to eval() blocked by CSP");
         return false;
     }
 
-    JSObject *callee = &vp[0].toObject();
+    /* ES5 15.1.2.1 step 1. */
+    if (argc < 1) {
+        vp->setUndefined();
+        return true;
+    }
+    if (!vp[2].isString()) {
+        *vp = vp[2];
+        return true;
+    }
+    JSString *str = vp[2].toString();
+
+    /* ES5 15.1.2.1 steps 2-8. */
+    JSObject *callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, Jsvalify(vp)));
+    JS_ASSERT(IsBuiltinEvalFunction(callee->getFunctionPrivate()));
     JSPrincipals *principals = js_EvalFramePrincipals(cx, callee, caller);
-    uintN line;
-    const char *file = js_ComputeFilename(cx, caller, principals, &line);
-
-    JSString *str = argv[0].toString();
-    JSScript *script = NULL;
+
+    /*
+     * Per ES5, indirect eval runs in the global scope. (eval is specified this
+     * way so that the compiler can make assumptions about what bindings may or
+     * may not exist in the current frame if it doesn't see 'eval'.)
+     */
+    uintN staticLevel;
+    if (evalType == DIRECT_EVAL) {
+        staticLevel = caller->script()->staticLevel + 1;
+
+#ifdef DEBUG
+        jsbytecode *callerPC = caller->pc(cx);
+        JS_ASSERT_IF(caller->isFunctionFrame(), caller->hasCallObj());
+        JS_ASSERT(callerPC && js_GetOpcode(cx, caller->script(), callerPC) == JSOP_EVAL);
+#endif
+    } else {
+        /* Pretend that we're top level. */
+        staticLevel = 0;
+
+        JS_ASSERT(scopeobj == scopeobj->getGlobal());
+        JS_ASSERT(scopeobj->isGlobal());
+    }
+
+    /* Ensure we compile this eval with the right object in the scope chain. */
+    if (!CheckScopeChainValidity(cx, scopeobj))
+        return false;
 
     const jschar *chars;
     size_t length;
     str->getCharsAndLength(chars, length);
 
     /*
      * If the eval string starts with '(' and ends with ')', it may be JSON.
      * Try the JSON parser first because it's much faster.  If the eval string
      * isn't JSON, JSON parsing will probably fail quickly, so little time
      * will be lost.
      */
-    if (length > 2 && chars[0] == '(' && chars[length-1] == ')') {
+    if (length > 2 && chars[0] == '(' && chars[length - 1] == ')') {
         JSONParser *jp = js_BeginJSONParse(cx, vp, /* suppressErrors = */true);
-        JSBool ok = jp != NULL;
-        if (ok) {
+        if (jp != NULL) {
             /* Run JSON-parser on string inside ( and ). */
-            ok = js_ConsumeJSONText(cx, jp, chars+1, length-2);
+            JSBool ok = js_ConsumeJSONText(cx, jp, chars + 1, length - 2);
             ok &= js_FinishJSONParse(cx, jp, NullValue());
             if (ok)
                 return true;
         }
     }
 
+    /*
+     * Direct calls to eval are supposed to see the caller's |this|. If we
+     * haven't wrapped that yet, do so now, before we make a copy of it for
+     * the eval code to use.
+     */
+    if (evalType == DIRECT_EVAL && !caller->computeThis(cx))
+        return false;
+
+    JSScript *script = NULL;
     JSScript **bucket = EvalCacheHash(cx, str);
-    if (directCall && caller->isFunctionFrame())
+    if (evalType == DIRECT_EVAL && caller->isFunctionFrame())
         script = EvalCacheLookup(cx, str, caller, staticLevel, principals, scopeobj, bucket);
 
     /*
-     * We can't have a callerFrame (down in js_Execute's terms) if we're in
-     * global code. This includes indirect eval and direct eval called with a
-     * scope object parameter.
+     * We can't have a callerFrame (down in js::Execute's terms) if we're in
+     * global code (or if we're an indirect eval).
      */
     JSStackFrame *callerFrame = (staticLevel != 0) ? caller : NULL;
     if (!script) {
+        uintN lineno;
+        const char *filename = js_ComputeFilename(cx, caller, principals, &lineno);
+
         uint32 tcflags = TCF_COMPILE_N_GO | TCF_NEED_MUTABLE_SCRIPT | TCF_COMPILE_FOR_EVAL;
         script = Compiler::compileScript(cx, scopeobj, callerFrame,
                                          principals, tcflags,
                                          chars, length,
-                                         NULL, file, line, str, staticLevel);
+                                         NULL, filename, lineno, str, staticLevel);
         if (!script)
             return false;
     }
 
     assertSameCompartment(cx, scopeobj, script);
 
     /*
      * Belt-and-braces: check that the lesser of eval's principals and the
@@ -1246,18 +1250,16 @@ eval(JSContext *cx, uintN argc, Value *v
     *bucket = script;
 #ifdef CHECK_SCRIPT_OWNER
     script->owner = NULL;
 #endif
 
     return ok;
 }
 
-namespace js {
-
 bool
 IsBuiltinEvalFunction(JSFunction *fun)
 {
     return fun->maybeNative() == eval;
 }
 
 }
 
@@ -3016,17 +3018,17 @@ with_LookupProperty(JSContext *cx, JSObj
     if (flags == JSRESOLVE_INFER)
         flags = js_InferFlags(cx, flags);
     flags |= JSRESOLVE_WITH;
     JSAutoResolveFlags rf(cx, flags);
     return obj->getProto()->lookupProperty(cx, id, objp, propp);
 }
 
 static JSBool
-with_GetProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
+with_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
 {
     return obj->getProto()->getProperty(cx, id, vp);
 }
 
 static JSBool
 with_SetProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
 {
     return obj->getProto()->setProperty(cx, id, vp, strict);
@@ -4454,24 +4456,16 @@ js_DefineNativeProperty(JSContext *cx, J
     if (propp)
         *propp = (JSProperty *) shape;
     return true;
 
 error: // TRACE_2 jumps here on error.
     return false;
 }
 
-JS_FRIEND_API(JSBool)
-js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
-                  JSProperty **propp)
-{
-    return js_LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags,
-                                      objp, propp) >= 0;
-}
-
 #define SCOPE_DEPTH_ACCUM(bs,val)                                             \
     JS_SCOPE_DEPTH_METERING(JS_BASIC_STATS_ACCUM(bs, val))
 
 /*
  * Call obj's resolve hook. obj is a native object and the caller holds its
  * scope lock.
  *
  * cx, start, id, and flags are the parameters initially passed to the ongoing
@@ -4582,18 +4576,18 @@ cleanup:
     js_StopResolving(cx, &key, JSRESFLAG_LOOKUP, entry, generation);
     return ok;
 }
 
 static JS_ALWAYS_INLINE int
 js_LookupPropertyWithFlagsInline(JSContext *cx, JSObject *obj, jsid id, uintN flags,
                                  JSObject **objp, JSProperty **propp)
 {
-    /* Convert string indices to integers if appropriate. */
-    id = js_CheckForStringIndex(id);
+    /* We should not get string indices which aren't already integers here. */
+    JS_ASSERT(id == js_CheckForStringIndex(id));
 
     /* Search scopes starting with obj and following the prototype link. */
     JSObject *start = obj;
     int protoIndex;
     for (protoIndex = 0; ; protoIndex++) {
         const Shape *shape = obj->nativeLookup(id);
         if (shape) {
             SCOPE_DEPTH_ACCUM(&cx->runtime->protoLookupDepthStats, protoIndex);
@@ -4631,20 +4625,33 @@ js_LookupPropertyWithFlagsInline(JSConte
         obj = proto;
     }
 
     *objp = NULL;
     *propp = NULL;
     return protoIndex;
 }
 
+JS_FRIEND_API(JSBool)
+js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
+                  JSProperty **propp)
+{
+    /* Convert string indices to integers if appropriate. */
+    id = js_CheckForStringIndex(id);
+
+    return js_LookupPropertyWithFlagsInline(cx, obj, id, cx->resolveFlags, objp, propp) >= 0;
+}
+
 int
 js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
                            JSObject **objp, JSProperty **propp)
 {
+    /* Convert string indices to integers if appropriate. */
+    id = js_CheckForStringIndex(id);
+
     return js_LookupPropertyWithFlagsInline(cx, obj, id, flags, objp, propp);
 }
 
 PropertyCacheEntry *
 js_FindPropertyHelper(JSContext *cx, jsid id, JSBool cacheResult,
                       JSObject **objp, JSObject **pobjp, JSProperty **propp)
 {
     JSObject *scopeChain, *obj, *parent, *pobj;
@@ -4921,17 +4928,17 @@ js_NativeSet(JSContext *cx, JSObject *ob
             return false;
         obj->setSlot(slot, *vp);
     }
 
     return true;
 }
 
 static JS_ALWAYS_INLINE bool
-js_GetPropertyHelperWithShapeInline(JSContext *cx, JSObject *obj, jsid id,
+js_GetPropertyHelperWithShapeInline(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id,
                                     uintN getHow, Value *vp,
                                     const Shape **shapeOut, JSObject **holderOut)
 {
     JSObject *aobj, *obj2;
     int protoIndex;
     JSProperty *prop;
     const Shape *shape;
 
@@ -5007,61 +5014,66 @@ js_GetPropertyHelperWithShapeInline(JSCo
                                           JSDVG_IGNORE_STACK, IdToValue(id),
                                           NULL, NULL, NULL)) {
                 return JS_FALSE;
             }
         }
         return JS_TRUE;
     }
 
-    if (!obj2->isNative())
-        return obj2->getProperty(cx, id, vp);
+    if (!obj2->isNative()) {
+        return obj2->isProxy()
+               ? JSProxy::get(cx, obj2, receiver, id, vp)
+               : obj2->getProperty(cx, id, vp);
+    }
 
     shape = (Shape *) prop;
     *shapeOut = shape;
 
     if (getHow & JSGET_CACHE_RESULT) {
         JS_ASSERT_NOT_ON_TRACE(cx);
         JS_PROPERTY_CACHE(cx).fill(cx, aobj, 0, protoIndex, obj2, shape);
     }
 
     /* This call site is hot -- use the always-inlined variant of js_NativeGet(). */
-    if (!js_NativeGetInline(cx, obj, obj2, shape, getHow, vp))
+    if (!js_NativeGetInline(cx, receiver, obj2, shape, getHow, vp))
         return JS_FALSE;
 
     return JS_TRUE;
 }
 
-extern bool
-js_GetPropertyHelperWithShape(JSContext *cx, JSObject *obj, jsid id,
+bool
+js_GetPropertyHelperWithShape(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id,
                               uint32 getHow, Value *vp,
                               const Shape **shapeOut, JSObject **holderOut)
 {
-    return js_GetPropertyHelperWithShapeInline(cx, obj, id, getHow, vp, shapeOut, holderOut);
+    return js_GetPropertyHelperWithShapeInline(cx, obj, receiver, id, getHow, vp,
+                                               shapeOut, holderOut);
 }
 
 static JS_ALWAYS_INLINE JSBool
-js_GetPropertyHelperInline(JSContext *cx, JSObject *obj, jsid id, uint32 getHow, Value *vp)
+js_GetPropertyHelperInline(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id,
+                           uint32 getHow, Value *vp)
 {
     const Shape *shape;
     JSObject *holder;
-    return js_GetPropertyHelperWithShapeInline(cx, obj, id, getHow, vp, &shape, &holder);
-}
-
-extern JSBool
-js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uint32 getHow, Value *vp)
-{
-    return js_GetPropertyHelperInline(cx, obj, id, getHow, vp);
+    return js_GetPropertyHelperWithShapeInline(cx, obj, receiver, id, getHow, vp, &shape, &holder);
 }
 
 JSBool
-js_GetProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
+js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uint32 getHow, Value *vp)
+{
+    return js_GetPropertyHelperInline(cx, obj, obj, id, getHow, vp);
+}
+
+JSBool
+js_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
 {
     /* This call site is hot -- use the always-inlined variant of js_GetPropertyHelper(). */
-    return js_GetPropertyHelperInline(cx, obj, id, JSGET_METHOD_BARRIER, vp);
+    return js_GetPropertyHelperInline(cx, obj, receiver, id, JSGET_METHOD_BARRIER, vp);
 }
 
 JSBool
 js::GetPropertyDefault(JSContext *cx, JSObject *obj, jsid id, Value def, Value *vp)
 {
     JSProperty *prop;
     JSObject *obj2;
     if (js_LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_QUALIFIED, &obj2, &prop) < 0)
@@ -5087,17 +5099,17 @@ js_GetMethod(JSContext *cx, JSObject *ob
 #endif
         return js_GetPropertyHelper(cx, obj, id, getHow, vp);
     }
     JS_ASSERT_IF(getHow & JSGET_CACHE_RESULT, obj->isDenseArray());
 #if JS_HAS_XML_SUPPORT
     if (obj->isXML())
         return js_GetXMLMethod(cx, obj, id, vp);
 #endif
-    return op(cx, obj, id, vp);
+    return op(cx, obj, obj, id, vp);
 }
 
 JS_FRIEND_API(bool)
 js_CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname)
 {
     JSStackFrame *const fp = js_GetTopStackFrame(cx);
     if (!fp)
         return true;
@@ -5168,18 +5180,36 @@ js_SetPropertyHelper(JSContext *cx, JSOb
     /* Convert string indices to integers if appropriate. */
     id = js_CheckForStringIndex(id);
 
     protoIndex = js_LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags,
                                             &pobj, &prop);
     if (protoIndex < 0)
         return JS_FALSE;
     if (prop) {
-        if (!pobj->isNative())
+        if (!pobj->isNative()) {
+            if (pobj->isProxy()) {
+                AutoPropertyDescriptorRooter pd(cx);
+                if (!pobj->getProxyHandler()->getPropertyDescriptor(cx, pobj, id, true, &pd))
+                    return false;
+
+                if (pd.attrs & JSPROP_SHARED)
+                    return CallSetter(cx, obj, id, pd.setter, pd.attrs, pd.shortid, vp);
+
+                if (pd.attrs & JSPROP_READONLY) {
+                    if (strict)
+                        return obj->reportReadOnly(cx, id);
+                    if (JS_HAS_STRICT_OPTION(cx))
+                        return obj->reportReadOnly(cx, id, JSREPORT_STRICT | JSREPORT_WARNING);
+                    return true;
+                }
+            }
+
             prop = NULL;
+        }
     } else {
         /* We should never add properties to lexical blocks.  */
         JS_ASSERT(!obj->isBlock());
 
         if (!obj->getParent() &&
             (defineHow & JSDNP_UNQUALIFIED) &&
             !js_CheckUndeclaredVarAssignment(cx, JSID_TO_STRING(id))) {
             return JS_FALSE;
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -204,17 +204,23 @@ extern JS_FRIEND_API(JSBool)
 js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
                   JSProperty **propp);
 
 extern JSBool
 js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value *value,
                   js::PropertyOp getter, js::PropertyOp setter, uintN attrs);
 
 extern JSBool
-js_GetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
+js_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, js::Value *vp);
+
+inline JSBool
+js_GetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp)
+{
+    return js_GetProperty(cx, obj, obj, id, vp);
+}
 
 namespace js {
 
 extern JSBool
 GetPropertyDefault(JSContext *cx, JSObject *obj, jsid id, Value def, Value *vp);
 
 } /* namespace js */
 
@@ -1059,19 +1065,23 @@ struct JSObject : js::gc::Cell {
     JSBool defineProperty(JSContext *cx, jsid id, const js::Value &value,
                           js::PropertyOp getter = js::PropertyStub,
                           js::PropertyOp setter = js::PropertyStub,
                           uintN attrs = JSPROP_ENUMERATE) {
         js::DefinePropOp op = getOps()->defineProperty;
         return (op ? op : js_DefineProperty)(cx, this, id, &value, getter, setter, attrs);
     }
 
-    JSBool getProperty(JSContext *cx, jsid id, js::Value *vp) {
+    JSBool getProperty(JSContext *cx, JSObject *receiver, jsid id, js::Value *vp) {
         js::PropertyIdOp op = getOps()->getProperty;
-        return (op ? op : js_GetProperty)(cx, this, id, vp);
+        return (op ? op : (js::PropertyIdOp)js_GetProperty)(cx, this, receiver, id, vp);
+    }
+
+    JSBool getProperty(JSContext *cx, jsid id, js::Value *vp) {
+        return getProperty(cx, this, id, vp);
     }
 
     JSBool setProperty(JSContext *cx, jsid id, js::Value *vp, JSBool strict) {
         js::StrictPropertyIdOp op = getOps()->setProperty;
         return (op ? op : js_SetProperty)(cx, this, id, vp, strict);
     }
 
     JSBool getAttributes(JSContext *cx, jsid id, uintN *attrsp) {
@@ -1080,17 +1090,17 @@ struct JSObject : js::gc::Cell {
     }
 
     JSBool setAttributes(JSContext *cx, jsid id, uintN *attrsp) {
         js::AttributesOp op = getOps()->setAttributes;
         return (op ? op : js_SetAttributes)(cx, this, id, attrsp);
     }
 
     JSBool deleteProperty(JSContext *cx, jsid id, js::Value *rval, JSBool strict) {
-        js::StrictPropertyIdOp op = getOps()->deleteProperty;
+        js::DeleteIdOp op = getOps()->deleteProperty;
         return (op ? op : js_DeleteProperty)(cx, this, id, rval, strict);
     }
 
     JSBool enumerate(JSContext *cx, JSIterateOp iterop, js::Value *statep, jsid *idp) {
         js::NewEnumerateOp op = getOps()->enumerate;
         return (op ? op : js_Enumerate)(cx, this, iterop, statep, idp);
     }
 
@@ -1564,18 +1574,19 @@ js_NativeGet(JSContext *cx, JSObject *ob
 extern JSBool
 js_NativeSet(JSContext *cx, JSObject *obj, const js::Shape *shape, bool added,
              js::Value *vp);
 
 extern JSBool
 js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uint32 getHow, js::Value *vp);
 
 extern bool
-js_GetPropertyHelperWithShape(JSContext *cx, JSObject *obj, jsid id, uint32 getHow,
-                              js::Value *vp, const js::Shape **shapeOut, JSObject **holderOut);
+js_GetPropertyHelperWithShape(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id,
+                              uint32 getHow, js::Value *vp,
+                              const js::Shape **shapeOut, JSObject **holderOut);
 
 extern JSBool
 js_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
 
 extern JSBool
 js_GetMethod(JSContext *cx, JSObject *obj, jsid id, uintN getHow, js::Value *vp);
 
 /*
@@ -1712,13 +1723,29 @@ js_Object(JSContext *cx, uintN argc, js:
 namespace js {
 
 extern bool
 SetProto(JSContext *cx, JSObject *obj, JSObject *proto, bool checkForCycles);
 
 extern JSString *
 obj_toStringHelper(JSContext *cx, JSObject *obj);
 
+enum EvalType { INDIRECT_EVAL, DIRECT_EVAL };
+
+/*
+ * Common code implementing direct and indirect eval.
+ *
+ * Evaluate vp[2], if it is a string, in the context of the given calling
+ * frame, with the provided scope chain, with the semantics of either a direct
+ * or indirect eval (see ES5 10.4.2).  If this is an indirect eval, scopeobj
+ * must be a global object.
+ *
+ * On success, store the completion value in *vp and return true.
+ */
+extern bool
+EvalKernel(JSContext *cx, uintN argc, js::Value *vp, EvalType evalType, JSStackFrame *caller,
+           JSObject *scopeobj);
+
 extern bool
 IsBuiltinEvalFunction(JSFunction *fun);
 
 }
 #endif /* jsobj_h___ */
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -5114,17 +5114,17 @@ js_DecompileValueGenerator(JSContext *cx
     LeaveTrace(cx);
     
     if (!cx->regs || !cx->regs->fp || !cx->regs->fp->isScriptFrame())
         goto do_fallback;
 
     fp = cx->regs->fp;
     script = fp->script();
     pc = fp->hasImacropc() ? fp->imacropc() : cx->regs->pc;
-    JS_ASSERT(pc >= script->main && pc < script->code + script->length);
+    JS_ASSERT(script->code <= pc && pc < script->code + script->length);
 
     if (spindex != JSDVG_IGNORE_STACK) {
         jsbytecode **pcstack;
 
         /*
          * Prepare computing pcstack containing pointers to opcodes that
          * populated interpreter's stack with its current content.
          */
@@ -5223,17 +5223,17 @@ DecompileExpression(JSContext *cx, JSScr
     jsbytecode *begin, *end;
     jssrcnote *sn;
     ptrdiff_t len;
     jsbytecode **pcstack;
     intN pcdepth;
     JSPrinter *jp;
     char *name;
 
-    JS_ASSERT(script->main <= pc && pc < script->code + script->length);
+    JS_ASSERT(script->code <= pc && pc < script->code + script->length);
 
     pcstack = NULL;
     oldcode = script->code;
     oldmain = script->main;
 
     MUST_FLOW_THROUGH("out");
     code = js_UntrapScriptCode(cx, script);
     if (code != oldcode) {
--- a/js/src/jsotypes.h
+++ b/js/src/jsotypes.h
@@ -70,21 +70,17 @@ typedef JSIntn intn;
 #ifdef XP_UNIX
 #include <sys/types.h>
 #else
 typedef JSUintn uint;
 #endif
 
 typedef JSUintn uintn;
 typedef JSUint64 uint64;
-#if !defined(XP_OS2)
 typedef JSUint32 uint32;
-#else
-typedef unsigned long uint32;
-#endif
 typedef JSUint16 uint16;
 typedef JSUint8 uint8;
 
 #ifndef _XP_Core_
 typedef JSIntn intn;
 #endif
 
 /*
@@ -94,21 +90,17 @@ typedef JSIntn intn;
  * the code also includes sys/types.h.
  */
 #if defined(AIX) && defined(HAVE_SYS_INTTYPES_H)
 #include <sys/inttypes.h>
 #else
 typedef JSInt64 int64;
 
 /* /usr/include/model.h on HP-UX defines int8, int16, and int32 */
-#if !defined(XP_OS2)
 typedef JSInt32 int32;
-#else
-typedef long int32;
-#endif
 typedef JSInt16 int16;
 typedef JSInt8 int8;
 #endif /* AIX && HAVE_SYS_INTTYPES_H */
 
 #endif  /* XP_BEOS */
 
 typedef JSFloat64 float64;
 
--- a/js/src/jsprobes.h
+++ b/js/src/jsprobes.h
@@ -211,11 +211,30 @@ inline void Probes::GCEnd(JSCompartment 
 inline void Probes::GCStartMarkPhase(JSCompartment *compartment) {}
 inline void Probes::GCEndMarkPhase(JSCompartment *compartment) {}
 inline void Probes::GCStartSweepPhase(JSCompartment *compartment) {}
 inline void Probes::GCEndSweepPhase(JSCompartment *compartment) {}
 inline JSBool Probes::CustomMark(JSString *string) { return JS_TRUE; }
 inline JSBool Probes::CustomMark(const char *string) { return JS_TRUE; }
 inline JSBool Probes::CustomMark(int marker) { return JS_TRUE; }
 
+struct AutoFunctionCallProbe {
+    JSContext * const cx;
+    JSFunction *fun;
+    js::Value *lval;
+    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
+
+    AutoFunctionCallProbe(JSContext *cx, JSFunction *fun, js::Value *lval = NULL
+                          JS_GUARD_OBJECT_NOTIFIER_PARAM)
+      : cx(cx), fun(fun), lval(lval)
+    {
+        JS_GUARD_OBJECT_NOTIFIER_INIT;
+        Probes::enterJSFun(cx, fun, lval);
+    }
+
+    ~AutoFunctionCallProbe() {
+        Probes::exitJSFun(cx, fun, lval);
+    }
+};
+
 } /* namespace js */
     
 #endif /* _JSPROBES_H */
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -122,74 +122,60 @@ JSProxyHandler::get(JSContext *cx, JSObj
         return true;
     }
     if (!desc.getter ||
         (!(desc.attrs & JSPROP_GETTER) && desc.getter == PropertyStub)) {
         *vp = desc.value;
         return true;
     }
     if (desc.attrs & JSPROP_GETTER) {
-        return ExternalGetOrSet(cx, proxy, id, CastAsObjectJsval(desc.getter),
+        return ExternalGetOrSet(cx, receiver, id, CastAsObjectJsval(desc.getter),
                                 JSACC_READ, 0, NULL, vp);
     }
     if (!(desc.attrs & JSPROP_SHARED))
         *vp = desc.value;
     else
         vp->setUndefined();
     if (desc.attrs & JSPROP_SHORTID)
         id = INT_TO_JSID(desc.shortid);
-    return CallJSPropertyOp(cx, desc.getter, proxy, id, vp);
+    return CallJSPropertyOp(cx, desc.getter, receiver, id, vp);
 }
 
 bool
 JSProxyHandler::set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, Value *vp)
 {
     JS_ASSERT(OperationInProgress(cx, proxy));
     AutoPropertyDescriptorRooter desc(cx);
     if (!getOwnPropertyDescriptor(cx, proxy, id, true, &desc))
         return false;
     /* The control-flow here differs from ::get() because of the fall-through case below. */
     if (desc.obj) {
-        if (desc.setter && ((desc.attrs & JSPROP_SETTER) || desc.setter != PropertyStub)) {
-            if (desc.attrs & JSPROP_SETTER) {
-                return ExternalGetOrSet(cx, proxy, id, CastAsObjectJsval(desc.setter),
-                                        JSACC_WRITE, 1, vp, vp);
-            }
-            if (desc.attrs & JSPROP_SHORTID)
-                id = INT_TO_JSID(desc.shortid);
-            return CallJSPropertyOpSetter(cx, desc.setter, proxy, id, vp);
-        }
+        if (desc.setter && ((desc.attrs & JSPROP_SETTER) || desc.setter != PropertyStub))
+            return CallSetter(cx, receiver, id, desc.setter, desc.attrs, desc.shortid, vp);
         if (desc.attrs & JSPROP_READONLY)
             return true;
         desc.value = *vp;
-        return defineProperty(cx, proxy, id, &desc);
+        return defineProperty(cx, receiver, id, &desc);
     }
     if (!getPropertyDescriptor(cx, proxy, id, true, &desc))
         return false;
     if (desc.obj) {
-        if (desc.setter && ((desc.attrs & JSPROP_SETTER) || desc.setter != PropertyStub)) {
-            if (desc.attrs & JSPROP_SETTER) {
-                return ExternalGetOrSet(cx, proxy, id, CastAsObjectJsval(desc.setter),
-                                        JSACC_WRITE, 1, vp, vp);
-            }
-            if (desc.attrs & JSPROP_SHORTID)
-                id = INT_TO_JSID(desc.shortid);
-            return CallJSPropertyOpSetter(cx, desc.setter, proxy, id, vp);
-        }
+        if (desc.setter && ((desc.attrs & JSPROP_SETTER) || desc.setter != PropertyStub))
+            return CallSetter(cx, receiver, id, desc.setter, desc.attrs, desc.shortid, vp);
         if (desc.attrs & JSPROP_READONLY)
             return true;
         /* fall through */
     }
-    desc.obj = proxy;
+    desc.obj = receiver;
     desc.value = *vp;
     desc.attrs = JSPROP_ENUMERATE;
     desc.getter = NULL;
     desc.setter = NULL;
     desc.shortid = 0;
-    return defineProperty(cx, proxy, id, &desc);
+    return defineProperty(cx, receiver, id, &desc);
 }
 
 bool
 JSProxyHandler::enumerateOwn(JSContext *cx, JSObject *proxy, AutoIdVector &props)
 {
     JS_ASSERT(OperationInProgress(cx, proxy));
     JS_ASSERT(props.length() == 0);
 
@@ -857,25 +843,25 @@ proxy_DefineProperty(JSContext *cx, JSOb
     desc.attrs = (attrs & (~JSPROP_SHORTID));
     desc.getter = getter;
     desc.setter = setter;
     desc.shortid = 0;
     return JSProxy::defineProperty(cx, obj, id, &desc);
 }
 
 static JSBool
-proxy_GetProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
+proxy_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
 {
-    return JSProxy::get(cx, obj, obj, id, vp);
+    return JSProxy::get(cx, obj, receiver, id, vp);
 }
 
 static JSBool
 proxy_SetProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
 {
-    // TODO: throwing away strict
+    // FIXME (bug 596351): throwing away strict.
     return JSProxy::set(cx, obj, obj, id, vp);
 }
 
 static JSBool
 proxy_GetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp)
 {
     AutoPropertyDescriptorRooter desc(cx);
     if (!JSProxy::getOwnPropertyDescriptor(cx, obj, id, false, &desc))
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -76,16 +76,17 @@
 #include "jsvector.h"
 #include "jsversion.h"
 
 #include "jscntxtinlines.h"
 #include "jsinterpinlines.h"
 #include "jsobjinlines.h"
 #include "jsregexpinlines.h"
 #include "jsstrinlines.h"
+#include "jsautooplen.h"        // generated headers last
 
 using namespace js;
 using namespace js::gc;
 
 JS_STATIC_ASSERT(size_t(JSString::MAX_LENGTH) <= size_t(JSVAL_INT_MAX));
 JS_STATIC_ASSERT(JSString::MAX_LENGTH <= JSVAL_INT_MAX);
 
 JS_STATIC_ASSERT(JS_EXTERNAL_STRING_LIMIT == 8);
@@ -1964,16 +1965,17 @@ struct ReplaceData
 {
     ReplaceData(JSContext *cx)
      : g(cx), cb(cx)
     {}
 
     JSString           *str;           /* 'this' parameter object as a string */
     RegExpGuard        g;              /* regexp parameter object and private data */
     JSObject           *lambda;        /* replacement function object or null */
+    JSObject           *elembase;      /* object for function(a){return b[a]} replace */
     JSString           *repstr;        /* replacement string */
     jschar             *dollar;        /* null or pointer to first $ in repstr */
     jschar             *dollarEnd;     /* limit pointer for js_strchr_limit */
     jsint              index;          /* index in result of next replacement */
     jsint              leftIndex;      /* left context index in str->chars */
     JSSubString        dollarStr;      /* for "$$" InterpretDollar result */
     bool               calledBack;     /* record whether callback has been called */
     InvokeSessionGuard session;        /* arguments for repeated lambda Invoke call */
@@ -2061,16 +2063,68 @@ class PreserveRegExpStatics
     ~PreserveRegExpStatics() {
         original->restore();
     }
 };
 
 static bool
 FindReplaceLength(JSContext *cx, RegExpStatics *res, ReplaceData &rdata, size_t *sizep)
 {
+    JSObject *base = rdata.elembase;
+    if (base) {
+        /*
+         * The base object is used when replace was passed a lambda which looks like
+         * 'function(a) { return b[a]; }' for the base object b.  b will not change
+         * in the course of the replace unless we end up making a scripted call due
+         * to accessing a scripted getter or a value with a scripted toString.
+         */
+        JS_ASSERT(rdata.lambda);
+        JS_ASSERT(!base->getOps()->lookupProperty);
+        JS_ASSERT(!base->getOps()->getProperty);
+
+        Value match;
+        if (!res->createLastMatch(cx, &match))
+            return false;
+        JSString *str = match.toString();
+
+        JSAtom *atom;
+        if (str->isAtomized()) {
+            atom = STRING_TO_ATOM(str);
+        } else {
+            atom = js_AtomizeString(cx, str, 0);
+            if (!atom)
+                return false;
+        }
+        jsid id = ATOM_TO_JSID(atom);
+
+        JSObject *holder;
+        JSProperty *prop = NULL;
+        if (js_LookupPropertyWithFlags(cx, base, id, JSRESOLVE_QUALIFIED, &holder, &prop) < 0)
+            return false;
+
+        /* Only handle the case where the property exists and is on this object. */
+        if (prop && holder == base) {
+            Shape *shape = (Shape *) prop;
+            if (shape->slot != SHAPE_INVALID_SLOT && shape->hasDefaultGetter()) {
+                Value value = base->getSlot(shape->slot);
+                if (value.isString()) {
+                    rdata.repstr = value.toString();
+                    *sizep = rdata.repstr->length();
+                    return true;
+                }
+            }
+        }
+
+        /*
+         * Couldn't handle this property, fall through and despecialize to the
+         * general lambda case.
+         */
+        rdata.elembase = NULL;
+    }
+
     JSObject *lambda = rdata.lambda;
     if (lambda) {
         /*
          * In the lambda case, not only do we find the replacement string's
          * length, we compute repstr and return it via rdata for use within
          * DoReplace.  The lambda is called with arguments ($&, $1, $2, ...,
          * index, input), i.e., all the properties of a regexp match array.
          * For $&, etc., we must create string jsvals from cx->regExpStatics.
@@ -2431,20 +2485,56 @@ js::str_replace(JSContext *cx, uintN arg
 {
     ReplaceData rdata(cx);
     NORMALIZE_THIS(cx, vp, rdata.str);
     static const uint32 optarg = 2;
 
     /* Extract replacement string/function. */
     if (argc >= optarg && js_IsCallable(vp[3])) {
         rdata.lambda = &vp[3].toObject();
+        rdata.elembase = NULL;
         rdata.repstr = NULL;
         rdata.dollar = rdata.dollarEnd = NULL;
+
+        if (rdata.lambda->isFunction()) {
+            JSFunction *fun = rdata.lambda->getFunctionPrivate();
+            if (fun->isInterpreted()) {
+                /*
+                 * Pattern match the script to check if it is is indexing into a
+                 * particular object, e.g. 'function(a) { return b[a]; }'.  Avoid
+                 * calling the script in such cases, which are used by javascript
+                 * packers (particularly the popular Dean Edwards packer) to efficiently
+                 * encode large scripts.  We only handle the code patterns generated
+                 * by such packers here.
+                 */
+                JSScript *script = fun->u.i.script;
+                jsbytecode *pc = script->code;
+
+                Value table = UndefinedValue();
+                if (JSOp(*pc) == JSOP_GETFCSLOT) {
+                    table = rdata.lambda->getFlatClosureUpvar(GET_UINT16(pc));
+                    pc += JSOP_GETFCSLOT_LENGTH;
+                }
+
+                if (table.isObject() &&
+                    JSOp(*pc) == JSOP_GETARG && GET_SLOTNO(pc) == 0 &&
+                    JSOp(*(pc + JSOP_GETARG_LENGTH)) == JSOP_GETELEM &&
+                    JSOp(*(pc + JSOP_GETARG_LENGTH + JSOP_GETELEM_LENGTH)) == JSOP_RETURN) {
+                    Class *clasp = table.toObject().getClass();
+                    if (clasp->isNative() &&
+                        !clasp->ops.lookupProperty &&
+                        !clasp->ops.getProperty) {
+                        rdata.elembase = &table.toObject();
+                    }
+                }
+            }
+        }
     } else {
         rdata.lambda = NULL;
+        rdata.elembase = NULL;
         rdata.repstr = ArgToRootedString(cx, argc, vp, 1);
         if (!rdata.repstr)
             return false;
 
         /* We're about to store pointers into the middle of our string. */
         if (!js_MakeStringImmutable(cx, rdata.repstr))
             return false;
         rdata.dollarEnd = rdata.repstr->chars() + rdata.repstr->length();
@@ -3411,25 +3501,71 @@ js_NewString(JSContext *cx, jschar *char
     JS_LOCK_RUNTIME_VOID(rt,
         (rt->lengthSum += (double)length,
          rt->lengthSquaredSum += (double)length * (double)length));
   }
 #endif
     return str;
 }
 
+static JS_ALWAYS_INLINE JSString *
+NewShortString(JSContext *cx, const jschar *chars, size_t length)
+{
+    JS_ASSERT(JSShortString::fitsIntoShortString(length));
+    JSShortString *str = js_NewGCShortString(cx);
+    if (!str)
+        return NULL;
+    jschar *storage = str->init(length);
+    js_short_strncpy(storage, chars, length);
+    storage[length] = 0;
+    return str->header();
+}
+
+static JSString *
+NewShortString(JSContext *cx, const char *chars, size_t length)
+{
+    JS_ASSERT(JSShortString::fitsIntoShortString(length));
+    JSShortString *str = js_NewGCShortString(cx);
+    if (!str)
+        return NULL;
+    jschar *storage = str->init(length);
+
+    if (js_CStringsAreUTF8) {
+#ifdef DEBUG
+        size_t oldLength = length;
+#endif
+        if (!js_InflateStringToBuffer(cx, chars, length, storage, &length))
+            return NULL;
+        JS_ASSERT(length <= oldLength);
+        storage[length] = 0;
+        str->resetLength(length);
+    } else {
+        size_t n = length;
+        jschar *p = storage;
+        while (n--)
+            *p++ = jschar(*chars++);
+        *p = 0;
+    }
+    return str->header();
+}
+
 static const size_t sMinWasteSize = 16;
 
 JSString *
 js_NewStringFromCharBuffer(JSContext *cx, JSCharBuffer &cb)
 {
     if (cb.empty())
         return ATOM_TO_STRING(cx->runtime->atomState.emptyAtom);
 
     size_t length = cb.length();
+
+    JS_STATIC_ASSERT(JSShortString::MAX_SHORT_STRING_LENGTH < JSCharBuffer::InlineLength);
+    if (JSShortString::fitsIntoShortString(length))
+        return NewShortString(cx, cb.begin(), length);
+
     if (!cb.append('\0'))
         return NULL;
 
     size_t capacity = cb.capacity();
 
     jschar *buf = cb.extractRawBuffer();
     if (!buf)
         return NULL;
@@ -3461,18 +3597,19 @@ js_NewDependentString(JSContext *cx, JSS
     if (length == 0)
         return cx->runtime->emptyString;
 
     if (start == 0 && length == base->length())
         return base;
 
     jschar *chars = base->chars() + start;
 
-    if (length == 1 && *chars < UNIT_STRING_LIMIT)
-        return const_cast<JSString *>(&JSString::unitStringTable[*chars]);
+    JSString *staticStr = JSString::lookupStaticString(chars, length);
+    if (staticStr)
+        return staticStr;
 
     /* Try to avoid long chains of dependent strings. */
     while (base->isDependent())
         base = base->dependentBase();
 
     JS_ASSERT(base->isFlat());
 
     ds = js_NewGCString(cx);
@@ -3514,57 +3651,16 @@ void printJSStringStats(JSRuntime *rt)
                             rt->strdepLengthSquaredSum, &sigma);
 
     fprintf(stderr, "%lu total dependent strings, mean length %g (sigma %g)\n",
             (unsigned long)rt->totalDependentStrings, mean, sigma);
 }
 #endif
 
 JSString *
-NewShortString(JSContext *cx, const jschar *chars, size_t length)
-{
-    JS_ASSERT(JSShortString::fitsIntoShortString(length));
-    JSShortString *str = js_NewGCShortString(cx);
-    if (!str)
-        return NULL;
-    jschar *storage = str->init(length);
-    js_short_strncpy(storage, chars, length);
-    storage[length] = 0;
-    return str->header();
-}
-
-JSString *
-NewShortString(JSContext *cx, const char *chars, size_t length)
-{
-    JS_ASSERT(JSShortString::fitsIntoShortString(length));
-    JSShortString *str = js_NewGCShortString(cx);
-    if (!str)
-        return NULL;
-    jschar *storage = str->init(length);
-
-    if (js_CStringsAreUTF8) {
-#ifdef DEBUG
-        size_t oldLength = length;
-#endif
-        if (!js_InflateStringToBuffer(cx, chars, length, storage, &length))
-            return NULL;
-        JS_ASSERT(length <= oldLength);
-        storage[length] = 0;
-        str->resetLength(length);
-    } else {
-        size_t n = length;
-        jschar *p = storage;
-        while (n--)
-            *p++ = jschar(*chars++);
-        *p = 0;
-    }
-    return str->header();
-}
-
-JSString *
 js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n)
 {
     if (JSShortString::fitsIntoShortString(n))
         return NewShortString(cx, s, n);
 
     jschar *news;
     JSString *str;
 
--- a/js/src/jsstr.h
+++ b/js/src/jsstr.h
@@ -538,16 +538,18 @@ struct JSString {
     static const char deflatedIntStringTable[];
     static const char deflatedUnitStringTable[];
     static const char deflatedLength2StringTable[];
 
     static JSString *unitString(jschar c);
     static JSString *getUnitString(JSContext *cx, JSString *str, size_t index);
     static JSString *length2String(jschar c1, jschar c2);
     static JSString *intString(jsint i);
+
+    static JSString *lookupStaticString(const jschar *chars, size_t length);
     
     JS_ALWAYS_INLINE void finalize(JSContext *cx, unsigned thingKind);
 };
 
 /*
  * Short strings should be created in cases where it's worthwhile to avoid
  * mallocing the string buffer for a small string. We keep 2 string headers'
  * worth of space in short strings so that more strings can be stored this way.
--- a/js/src/jsstrinlines.h
+++ b/js/src/jsstrinlines.h
@@ -71,16 +71,53 @@ JSString::length2String(jschar c1, jscha
 inline JSString *
 JSString::intString(jsint i)
 {
     jsuint u = jsuint(i);
     JS_ASSERT(u < INT_STRING_LIMIT);
     return const_cast<JSString *>(JSString::intStringTable[u]);
 }
 
+/* Get a static atomized string for chars if possible. */
+inline JSString *
+JSString::lookupStaticString(const jschar *chars, size_t length)
+{
+    if (length == 1) {
+        if (chars[0] < UNIT_STRING_LIMIT)
+            return unitString(chars[0]);
+    }
+
+    if (length == 2) {
+        if (fitsInSmallChar(chars[0]) && fitsInSmallChar(chars[1]))
+            return length2String(chars[0], chars[1]);
+    }
+
+    /*
+     * Here we know that JSString::intStringTable covers only 256 (or at least
+     * not 1000 or more) chars. We rely on order here to resolve the unit vs.
+     * int string/length-2 string atom identity issue by giving priority to unit
+     * strings for "0" through "9" and length-2 strings for "10" through "99".
+     */
+    JS_STATIC_ASSERT(INT_STRING_LIMIT <= 999);
+    if (length == 3) {
+        if ('1' <= chars[0] && chars[0] <= '9' &&
+            '0' <= chars[1] && chars[1] <= '9' &&
+            '0' <= chars[2] && chars[2] <= '9') {
+            jsint i = (chars[0] - '0') * 100 +
+                      (chars[1] - '0') * 10 +
+                      (chars[2] - '0');
+
+            if (jsuint(i) < INT_STRING_LIMIT)
+                return intString(i);
+        }
+    }
+
+    return NULL;
+}
+
 inline void
 JSString::finalize(JSContext *cx, unsigned thingKind) {
     if (JS_LIKELY(thingKind == js::gc::FINALIZE_STRING)) {
         JS_ASSERT(!JSString::isStatic(this));
         JS_RUNTIME_UNMETER(cx->runtime, liveStrings);
         if (isDependent()) {
             JS_ASSERT(dependentBase());
             JS_RUNTIME_UNMETER(cx->runtime, liveDependentStrings);
--- a/js/src/jstl.h
+++ b/js/src/jstl.h
@@ -43,16 +43,17 @@
 /* Gross special case for Gecko, which defines malloc/calloc/free. */
 #ifdef mozilla_mozalloc_macro_wrappers_h
 #  define JS_UNDEFD_MOZALLOC_WRAPPERS
 /* The "anti-header" */
 #  include "mozilla/mozalloc_undef_macro_wrappers.h"
 #endif
 
 #include "jsbit.h"
+#include "jsstaticcheck.h"
 
 #include <new>
 #include <string.h>
 
 namespace js {
 
 /* JavaScript Template Library. */
 namespace tl {
@@ -451,11 +452,19 @@ Min(T t1, T t2)
 
 template <class T>
 static inline T
 Max(T t1, T t2)
 {
     return t1 > t2 ? t1 : t2;
 }
 
+/* Allows a const variable to be initialized after its declaration. */
+template <class T>
+static T&
+InitConst(const T &t)
+{
+    return const_cast<T &>(t);
+}
+
 } /* namespace js */
 
 #endif /* jstl_h_ */
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -68,16 +68,17 @@
 #include "jsiter.h"
 #include "jsmath.h"
 #include "jsobj.h"
 #include "jsopcode.h"
 #include "jsregexp.h"
 #include "jsscope.h"
 #include "jsscript.h"
 #include "jsstaticcheck.h"
+#include "jstl.h"
 #include "jstracer.h"
 #include "jsxml.h"
 #include "jstypedarray.h"
 
 #include "jsatominlines.h"
 #include "jscntxtinlines.h"
 #include "jsfuninlines.h"
 #include "jsinterpinlines.h"
@@ -104,16 +105,17 @@
 #include <fcntl.h>
 #include <string.h>
 #include <elf.h>
 #endif
 
 namespace nanojit {
 using namespace js;
 using namespace js::gc;
+using namespace js::tjit;
 
 /* Implement embedder-specific nanojit members. */
 
 void*
 nanojit::Allocator::allocChunk(size_t nbytes)
 {
     VMAllocator *vma = (VMAllocator*)this;
     JS_ASSERT(!vma->outOfMemory());
@@ -452,43 +454,16 @@ InitJITStatsClass(JSContext *cx, JSObjec
     JS_InitClass(cx, glob, NULL, &jitstats_class, NULL, 0, jitstats_props, NULL, NULL, NULL);
 }
 
 #define AUDIT(x) (jitstats.x++)
 #else
 #define AUDIT(x) ((void)0)
 #endif /* JS_JIT_SPEW */
 
-/*
- * INS_CONSTPTR can be used to embed arbitrary pointers into the native code. It should not
- * be used directly to embed GC thing pointers. Instead, use the INS_CONSTOBJ/FUN/STR/SHAPE
- * variants which ensure that the embedded pointer will be kept alive across GCs.
- */
-
-#define INS_CONST(c)          addName(lir->insImmI(c), #c)
-#define INS_CONSTU(c)         addName(lir->insImmI((uint32_t)c), #c)
-#define INS_CONSTPTR(p)       addName(lir->insImmP(p), #p)
-#define INS_CONSTWORD(v)      addName(lir->insImmP((void *) (v)), #v)
-#define INS_CONSTQWORD(c)     addName(lir->insImmQ(c), #c)
-#define INS_CONSTOBJ(obj)     addName(insImmObj(obj), #obj)
-#define INS_CONSTFUN(fun)     addName(insImmFun(fun), #fun)
-#define INS_CONSTSTR(str)     addName(insImmStr(str), #str)
-#define INS_CONSTSHAPE(shape) addName(insImmShape(shape), #shape)
-#define INS_CONSTID(id)       addName(insImmId(id), #id)
-#define INS_ATOM(atom)        INS_CONSTSTR(ATOM_TO_STRING(atom))
-#define INS_NULL()            INS_CONSTPTR(NULL)
-#define INS_UNDEFINED()       INS_CONST(0)
-#define INS_MAGIC_WHY(why)    INS_CONSTWORD((size_t)why)
-#define INS_MAGIC_NULL()      INS_NULL()
-
-static const size_t sPayloadOffset = offsetof(jsval_layout, s.payload);
-#if JS_BITS_PER_WORD == 32
-static const size_t sTagOffset = offsetof(jsval_layout, s.tag);
-#endif
-
 static avmplus::AvmCore s_core = avmplus::AvmCore();
 static avmplus::AvmCore* core = &s_core;
 
 static void OutOfMemoryAbort()
 {
     JS_NOT_REACHED("out of memory");
     abort();
 }
@@ -579,17 +554,16 @@ InitJITLogController()
     bits = 0;
 
     /* flags for jstracer.cpp */
     if (strstr(tmf, "minimal")  || strstr(tmf, "full")) bits |= LC_TMMinimal;
     if (strstr(tmf, "tracer")   || strstr(tmf, "full")) bits |= LC_TMTracer;
     if (strstr(tmf, "recorder") || strstr(tmf, "full")) bits |= LC_TMRecorder;
     if (strstr(tmf, "abort")    || strstr(tmf, "full")) bits |= LC_TMAbort;
     if (strstr(tmf, "stats")    || strstr(tmf, "full")) bits |= LC_TMStats;
-    if (strstr(tmf, "regexp")   || strstr(tmf, "full")) bits |= LC_TMRegexp;
     if (strstr(tmf, "profiler") || strstr(tmf, "full")) bits |= LC_TMProfiler;
     if (strstr(tmf, "treevis"))                         bits |= LC_TMTreeVis;
 
     /* flags for nanojit */
     if (strstr(tmf, "fragprofile"))                       bits |= LC_FragProfile;
     if (strstr(tmf, "liveness")   || strstr(tmf, "full")) bits |= LC_Liveness;
     if (strstr(tmf, "readlir")    || strstr(tmf, "full")) bits |= LC_ReadLIR;
     if (strstr(tmf, "aftersf")    || strstr(tmf, "full")) bits |= LC_AfterSF;
@@ -955,25 +929,23 @@ JS_DEFINE_CALLINFO_3(extern, BOOL, Print
 void
 TraceRecorder::tprint(const char *format, int count, nanojit::LIns *insa[])
 {
     size_t size = strlen(format) + 1;
     char* data = (char*) traceMonitor->traceAlloc->alloc(size);
     memcpy(data, format, size);
 
     double *args = (double*) traceMonitor->traceAlloc->alloc(count * sizeof(double));
-    for (int i = 0; i < count; ++i) {
-        JS_ASSERT(insa[i]);
-        // The AccSet doesn't matter much here, this isn't perf-critical code.
-        lir->insStore(insa[i], INS_CONSTPTR(args), sizeof(double) * i, ACCSET_STORE_ANY);
-    }
-
-    LIns* args_ins[] = { INS_CONSTPTR(args), INS_CONST(count), INS_CONSTPTR(data) };
-    LIns* call_ins = lir->insCall(&PrintOnTrace_ci, args_ins);
-    guard(false, lir->insEqI_0(call_ins), MISMATCH_EXIT);
+    LIns* argsp_ins = w.nameImmpNonGC(args);
+    for (int i = 0; i < count; ++i)
+        w.stTprintArg(insa, argsp_ins, i);
+
+    LIns* args_ins[] = { w.nameImmpNonGC(args), w.nameImmi(count), w.nameImmpNonGC(data) };
+    LIns* call_ins = w.call(&PrintOnTrace_ci, args_ins);
+    guard(false, w.eqi0(call_ins), MISMATCH_EXIT);
 }
 
 // Generate a 'printf'-type call from trace for debugging.
 void
 TraceRecorder::tprint(const char *format)
 {
     LIns* insa[] = { NULL };
     tprint(format, 0, insa);
@@ -1651,122 +1623,20 @@ AttemptCompilation(JSContext *cx, JSObje
     while (f) {
         JS_ASSERT(f->root == f);
         --f->recordAttempts;
         f->hits() = HOTLOOP;
         f = f->peer;
     }
 }
 
-
-static bool
-isfop(LIns* i, LOpcode op)
-{
-    if (i->isop(op))
-        return true;
-#if NJ_SOFTFLOAT_SUPPORTED
-    if (nanojit::AvmCore::config.soft_float &&
-        i->isop(LIR_ii2d) &&
-        i->oprnd1()->isop(LIR_calli) &&
-        i->oprnd2()->isop(LIR_hcalli)) {
-        return i->oprnd1()->callInfo() == softFloatOps.opmap[op];
-    }
-#endif
-    return false;
-}
-
 static const CallInfo *
-fcallinfo(LIns *i)
-{
-#if NJ_SOFTFLOAT_SUPPORTED
-    if (nanojit::AvmCore::config.soft_float) {
-        if (!i->isop(LIR_ii2d))
-            return NULL;
-        i = i->oprnd1();
-        return i->isop(LIR_calli) ? i->callInfo() : NULL;
-    }
-#endif
-    return i->isop(LIR_calld) ? i->callInfo() : NULL;
-}
-
-static LIns*
-fcallarg(LIns* i, int n)
-{
-#if NJ_SOFTFLOAT_SUPPORTED
-    if (nanojit::AvmCore::config.soft_float) {
-        NanoAssert(i->isop(LIR_ii2d));
-        return i->oprnd1()->callArgN(n);
-    }
-#endif
-    NanoAssert(i->isop(LIR_calld));
-    return i->callArgN(n);
-}
-
-static LIns*
-foprnd1(LIns* i)
-{
-#if NJ_SOFTFLOAT_SUPPORTED
-    if (nanojit::AvmCore::config.soft_float)
-        return fcallarg(i, 0);
-#endif
-    return i->oprnd1();
-}
-
-static LIns*
-foprnd2(LIns* i)
-{
-#if NJ_SOFTFLOAT_SUPPORTED
-    if (nanojit::AvmCore::config.soft_float)
-        return fcallarg(i, 1);
-#endif
-    return i->oprnd2();
-}
-
-static LIns*
-demote(LirWriter *out, LIns* ins)
-{
-    JS_ASSERT(ins->isD());
-    if (ins->isCall())
-        return ins->callArgN(0);
-    if (isfop(ins, LIR_i2d) || isfop(ins, LIR_ui2d))
-        return foprnd1(ins);
-    JS_ASSERT(ins->isImmD());
-    double cf = ins->immD();
-    int32_t ci = cf > 0x7fffffff ? uint32_t(cf) : int32_t(cf);
-    return out->insImmI(ci);
-}
-
-static bool
-isPromoteInt(LIns* ins)
-{
-    if (isfop(ins, LIR_i2d))
-        return true;
-    if (ins->isImmD()) {
-        jsdouble d = ins->immD();
-        return d == jsdouble(jsint(d)) && !JSDOUBLE_IS_NEGZERO(d);
-    }
-    return false;
-}
-
-static bool
-isPromoteUint(LIns* ins)
-{
-    if (isfop(ins, LIR_ui2d))
-        return true;
-    if (ins->isImmD()) {
-        jsdouble d = ins->immD();
-        return d == jsdouble(jsuint(d)) && !JSDOUBLE_IS_NEGZERO(d);
-    }
-    return false;
-}
-
-static bool
-isPromote(LIns* ins)
-{
-    return isPromoteInt(ins) || isPromoteUint(ins);
+fcallinfo(LIns *ins)
+{
+    return ins->isop(LIR_calld) ? ins->callInfo() : NULL;
 }
 
 /*
  * Determine whether this operand is guaranteed to not overflow the specified
  * integer operation.
  */
 static void
 ChecksRequired(LOpcode op, LIns* op1, LIns* op2,
@@ -1804,54 +1674,16 @@ ChecksRequired(LOpcode op, LIns* op1, LI
 
       default:
         JS_NOT_REACHED("needsOverflowCheck");
     }
 
     *needsOverflowCheck = z.hasOverflowed;
 }
 
-class FuncFilter: public LirWriter
-{
-public:
-    FuncFilter(LirWriter* out):
-        LirWriter(out)
-    {
-    }
-
-    LIns* ins2(LOpcode v, LIns* s0, LIns* s1)
-    {
-        if (s0 == s1 && v == LIR_eqd) {
-            if (isPromote(s0)) {
-                // double(int) and double(uint) cannot be nan
-                return insImmI(1);
-            }
-            if (s0->isop(LIR_muld) || s0->isop(LIR_subd) || s0->isop(LIR_addd)) {
-                LIns* lhs = s0->oprnd1();
-                LIns* rhs = s0->oprnd2();
-                if (isPromote(lhs) && isPromote(rhs)) {
-                    // add/sub/mul promoted ints can't be nan
-                    return insImmI(1);
-                }
-            }
-        } else if (isCmpDOpcode(v)) {
-            if (isPromoteInt(s0) && isPromoteInt(s1)) {
-                // demote fcmp to cmp
-                v = cmpOpcodeD2I(v);
-                return out->ins2(v, demote(out, s0), demote(out, s1));
-            } else if (isPromoteUint(s0) && isPromoteUint(s1)) {
-                // uint compare
-                v = cmpOpcodeD2UI(v);
-                return out->ins2(v, demote(out, s0), demote(out, s1));
-            }
-        }
-        return out->ins2(v, s0, s1);
-    }
-};
-
 /*
  * JSStackFrame::numActualArgs is only defined for function frames. Since the
  * actual arguments of the entry frame are kept on trace, argc is included in
  * the tuple identifying a fragment so that two fragments for the same loop but
  * recorded with different number of actual arguments are treated as two
  * completely separate trees. For this particular use, we define the number of
  * actuals for global and eval frames to be 0.
  */
@@ -2336,47 +2168,31 @@ void
 FlushJITCache(JSContext *cx)
 {
     ResetJIT(cx, FR_OOM);
 }
 
 static void
 TrashTree(TreeFragment* f);
 
-template <class T>
-static T&
-InitConst(const T &t)
-{
-    return const_cast<T &>(t);
-}
-
-/* These must be macros because 'field' is a field name. */
-#define loadFromState(op, field) \
-    lir->insLoad(op, lirbuf->state, offsetof(TracerState, field), ACCSET_STATE)
-
-#define storeToState(value, field) \
-    lir->insStore(value, lirbuf->state, offsetof(TracerState, field), ACCSET_STATE)
-
 JS_REQUIRES_STACK
 TraceRecorder::TraceRecorder(JSContext* cx, VMSideExit* anchor, VMFragment* fragment,
                              unsigned stackSlots, unsigned ngslots, JSValueType* typeMap,
                              VMSideExit* innermost, JSScript* outerScript, jsbytecode* outerPC,
                              uint32 outerArgc, bool speculate)
   : cx(cx),
     traceMonitor(&JS_TRACE_MONITOR(cx)),
     oracle(speculate ? JS_TRACE_MONITOR(cx).oracle : NULL),
     fragment(fragment),
     tree(fragment->root),
     globalObj(tree->globalObj),
     outerScript(outerScript),
     outerPC(outerPC),
     outerArgc(outerArgc),
     anchor(anchor),
-    lir(NULL),
-    cse_filter(NULL),
     cx_ins(NULL),
     eos_ins(NULL),
     eor_ins(NULL),
     loopLabel(NULL),
     importTypeMap(&tempAlloc()),
     lirbuf(new (tempAlloc()) LirBuffer(tempAlloc())),
     mark(*traceMonitor->traceAlloc),
     numSideExitsBefore(tree->sideExits.length()),
@@ -2396,23 +2212,23 @@ TraceRecorder::TraceRecorder(JSContext* 
     rval_ins(NULL),
     native_rval_ins(NULL),
     newobj_ins(NULL),
     pendingSpecializedNative(NULL),
     pendingUnboxSlot(NULL),
     pendingGuardCondition(NULL),
     pendingLoop(true),
     generatedSpecializedNative(),
-    tempTypeMap(cx)
+    tempTypeMap(cx),
+    w(&tempAlloc(), lirbuf)
 {
     JS_ASSERT(globalObj == cx->fp()->scopeChain().getGlobal());
     JS_ASSERT(globalObj->hasOwnShape());
     JS_ASSERT(cx->regs->pc == (jsbytecode*)fragment->ip);
 
-    fragment->lirbuf = lirbuf;
 #ifdef DEBUG
     lirbuf->printer = new (tempAlloc()) LInsPrinter(tempAlloc(), TM_NUM_USED_ACCS);
 #endif
 
     /*
      * Reset the fragment state we care about in case we got a recycled
      * fragment.  This includes resetting any profiling data we might have
      * accumulated.
@@ -2443,131 +2259,113 @@ TraceRecorder::TraceRecorder(JSContext* 
                       fragment->profFragID);
 
     debug_only_printf(LC_TMTracer, "globalObj=%p, shape=%d\n",
                       (void*)this->globalObj, this->globalObj->shape());
     debug_only_printf(LC_TMTreeVis, "TREEVIS RECORD FRAG=%p ANCHOR=%p\n", (void*)fragment,
                       (void*)anchor);
 #endif
 
-    nanojit::LirWriter*& lir = InitConst(this->lir);
-    nanojit::CseFilter*& cse_filter = InitConst(this->cse_filter);
-    lir = new (tempAlloc()) LirBufWriter(lirbuf, nanojit::AvmCore::config);
-#ifdef DEBUG
-    ValidateWriter* validate2;
-    lir = validate2 =
-        new (tempAlloc()) ValidateWriter(lir, lirbuf->printer, "end of writer pipeline");
-#endif
-    debug_only_stmt(
-        if (LogController.lcbits & LC_TMRecorder) {
-           lir = new (tempAlloc()) VerboseWriter(tempAlloc(), lir, lirbuf->printer,
-                                               &LogController);
-        }
-    )
-    // CseFilter must be downstream of SoftFloatFilter (see bug 527754 for why).
-    if (avmplus::AvmCore::config.cseopt)
-        lir = cse_filter = new (tempAlloc()) CseFilter(lir, TM_NUM_USED_ACCS, tempAlloc());
-#if NJ_SOFTFLOAT_SUPPORTED
-    if (nanojit::AvmCore::config.soft_float)
-        lir = new (tempAlloc()) SoftFloatFilter(lir);
-#endif
-    lir = new (tempAlloc()) ExprFilter(lir);
-    lir = new (tempAlloc()) FuncFilter(lir);
-#ifdef DEBUG
-    ValidateWriter* validate1;
-    lir = validate1 =
-        new (tempAlloc()) ValidateWriter(lir, lirbuf->printer, "start of writer pipeline");
-#endif
-    lir->ins0(LIR_start);
+    /* This creates the LIR writer pipeline. */
+    w.init(&LogController);
+
+    w.start();
 
     for (int i = 0; i < NumSavedRegs; ++i)
-        lir->insParam(i, 1);
+        w.paramp(i, 1);
 #ifdef DEBUG
     for (int i = 0; i < NumSavedRegs; ++i)
-        addName(lirbuf->savedRegs[i], regNames[REGNUM(Assembler::savedRegs[i])]);
-#endif
-
-    lirbuf->state = addName(lir->insParam(0, 0), "state");
-
-    if (fragment == fragment->root)
-        InitConst(loopLabel) = lir->ins0(LIR_label);
+        w.name(lirbuf->savedRegs[i], regNames[REGNUM(Assembler::savedRegs[i])]);
+#endif
+
+    lirbuf->state = w.name(w.paramp(0, 0), "state");
+
+    if (fragment == fragment->root) {
+        w.comment("begin-loop");
+        InitConst(loopLabel) = w.label();
+    }
+    w.comment("begin-setup");
 
     // if profiling, drop a label, so the assembler knows to put a
     // frag-entry-counter increment at this point.  If there's a
     // loopLabel, use that; else we'll have to make a dummy label
     // especially for this purpose.
     verbose_only( if (LogController.lcbits & LC_FragProfile) {
         LIns* entryLabel = NULL;
         if (fragment == fragment->root) {
             entryLabel = loopLabel;
         } else {
-            entryLabel = lir->ins0(LIR_label);
+            entryLabel = w.label();
         }
         NanoAssert(entryLabel);
         NanoAssert(!fragment->loopLabel);
         fragment->loopLabel = entryLabel;
     })
 
-    lirbuf->sp = addName(loadFromState(LIR_ldp, sp), "sp");
-    lirbuf->rp = addName(loadFromState(LIR_ldp, rp), "rp");
-    InitConst(cx_ins) = addName(loadFromState(LIR_ldp, cx), "cx");